[Fixed]-Django-allauth – Critical login required : Allow users stored in a database only to login

0👍

Finally After reading the documents thoroughly and doing a lot of trials and errors I got to what I was looking for.

I had to set following parameters as a part of configuration specified in docs.

ACCOUNT_EMAIL_REQUIRED (=False)
The user is required to hand over an e-mail address when signing up.

and

SOCIALACCOUNT_QUERY_EMAIL (=ACCOUNT_EMAIL_REQUIRED)
Request e-mail address from 3rd party account provider? E.g. using OpenID AX, or the Facebook “email” permission.

I had to set ACCOUNT_EMAIL_REQUIRED = True as it was required to check if that email id is already registerd with us.

and then finally I overridden pre_social_login like below.

from allauth.socialaccount.adapter import DefaultSocialAccountAdapter  

class NoNewSocialLogin(DefaultSocialAccountAdapter):

    def pre_social_login(self, request, sociallogin):
        try:
            cr_user = auth_user.objects.get(email=sociallogin.user.email)

            if cr_user and cr_user.is_active:
                user_login = login(request, cr_user, 'django.contrib.auth.backends.ModelBackend')
                raise ImmediateHttpResponse(HttpResponseRedirect(reverse('protect')))
            else:
                raise  ImmediateHttpResponse(render_to_response("account/authentication_error.html"))
        except ObjectDoesNotExist as e:
            raise ImmediateHttpResponse(render_to_response("socialaccount/authentication_error.html"))
        except Exception as e:
            raise ImmediateHttpResponse(HttpResponseRedirect(reverse('protect')))

1👍

To simply disable registration, you have to overwrite the default account adaptor. If you also want to support social login, you also need to overwrite the default soculaaccount adapter. Add the following code somewhere in one of your apps (e.g. adapter.py):

from allauth.account.adapter import DefaultAccountAdapter
from allauth.socialaccount.adapter import DefaultSocialAccountAdapter
from allauth.exceptions import ImmediateHttpResponse

class NoNewUsersAccountAdapter(DefaultAccountAdapter):

    def is_open_for_signup(self, request):
        return False

class SocialAccountWhitelist(DefaultSocialAccountAdapter):

    def pre_social_login(self, request, sociallogin):
        u = sociallogin.user
        print('User {0} is trying to login'.format(u.email))
        # Write code here to check your whitelist
        if not_in_your_list(u):
            raise ImmediateHttpResponse(HttpResponseRedirect('/account/login'))

and then add the following to your settings:

ACCOUNT_ADAPTER = 'path_to_app.adapter.NoNewUsersAccountAdapter'
SOCIALACCOUNT_ADAPTER = 'path_to_app.adapters.SocialAccountWhitelist'

After that, all you need to do is manually create an Account from the Admin pages, and manually create an EmailAddress. For the social login, you will need to write code to somehow check if the email is allowed

I would recommend you add a Staff-Only form to make this easy on you, where you can ask for username, email (and even password) and then do

new_user = Account.objects.create_user(email=email, username=username, password=password)
EmailAddress.objects.create(email=email, user=new_user, verified=True, primary=True)

You can also develop an Invitation scheme, but that is a lot more complicated but quickly googled and found the following project, which I have not personally used, but looks like what you need:

https://github.com/bee-keeper/django-invitations

Leave a comment