Django-allauth: How to disable form login/signup?

Created on 31 Jul 2013  路  9Comments  路  Source: pennersr/django-allauth

Hey guys, first of all, thank you for this app. It's amazing and it has already saved me a bunch of time.

I have the following problem because I couldn't find anything in the docs, so I thought it would be better to ask.

How can I completely disable form login/signup and enable only the providers I set? In my business model, the user can only login/signup with Facebook and, whenever I use the @login_required decorator, it redirects the user to a login page where he can input emal/password.

Thanks in advance.

Feature request

Most helpful comment

I believe direct sign up, should be defined as another optional backends

All 9 comments

There is no easy setting for this, yet, though it can be realized as follows:

You should let is_open_for_signup on the account adapter always return False. The counterpart in the socialaccount adapter should always return True.

Then, in your templates simply do not include the local signup/login forms.

Furthermore, make sure validate_disconnect (SocialAccountAdapter) does not allow to disconnect the last social account.

There's a potential security loophole here.

If you setup allauth to use a social auth provider as the signup/signin process.

Then use a custom SocialAccountAdapter to check the domain of email address to remove the need for email confirmation (set to optional) to remove friction from the process. You can do this with the pre_social_login method of DefaultSocialAccountAdapter

As the DefaultAccountAdapter always returns True from the is_open_for_signup method, someone can just hit the /accounts/signup/ page and create an account which then doesn't need to be verified.

Whilst this is obviously down to the developer to configure correctly, it's not so clear that this would be the case.

I think adding a configuration option to turn on/off the standard account signup page would be sensible and maybe even setting everything to off by default might also be wise, then developers can just switch on what they need.

I support this feature request! :-)

I believe direct sign up, should be defined as another optional backends

here is my adapters as @pennersr mentioned in his comment:

class AccountAdapter(DefaultAccountAdapter):
    def is_open_for_signup(self, request):
        if request.path.rstrip("/") == reverse("account_signup").rstrip("/"):
            return False
        return True


class SocialAccountAdapter(DefaultSocialAccountAdapter):
    def validate_disconnect(self, account, accounts):
        raise ValidationError("Can not disconnect")

but there is another problem here, It's with EmailView (accounts/email) in this view users can add/remove email addresses to their account - I think if you want completly use providers (disable direct login/singup) email management may cause some problems

also password mangement doesn't make sense. (set password/change password/reset password)

I too think configuring social login + registration _only_ should be made easier. I'd even prefer that the Account models/tables were not populated/created at all. In fact, let's look at the setup:

INSTALLED_APPS = [
    # ...
    'allauth',
    'allauth.account',
    'allauth.socialaccount',
    # ...
]

I always had the impression it is actually by design that there is a separation of account and socialaccount. Hence, if I would omit 'allauth.account' from INSTALLED_APPS I would get a django-allauth setup _without_ regular, email-based registration + login. Unfortunately, this does not seem to be the case.

@pennersr Is there an important reason why this is not strictly separated that way?

Even if you would go the social-only route, it typically still makes sense to store the user email address for user communication purposes. So, if you would architect things differently you would either need to dupe email storage (& handling) in both apps, or, you would need to introduce a third base app dedicated to this purpose.

This makes sense---in some way.

Though, really, if I want to communicate with a user who has authenticated with my application, say, 6 months ago, and has, potentially, changed their email address twice in that time span ... how much worth is the email address stored in my Django model? - Not much, right? Maybe zero.

In theory, at least, I should be able to query the social provider again and ask for an updated version of the user details when I need them. Everything else to me seems like a second-class solution. I must admit I don't know if it's actually possible to query the provider at any time. I hope it is.

here is my adapters as @pennersr mentioned in his comment:

class AccountAdapter(DefaultAccountAdapter):
    def is_open_for_signup(self, request):
        if request.path.rstrip("/") == reverse("account_signup").rstrip("/"):
            return False
        return True


class SocialAccountAdapter(DefaultSocialAccountAdapter):
    def validate_disconnect(self, account, accounts):
        raise ValidationError("Can not disconnect")

but there is another problem here, It's with EmailView (accounts/email) in this view users can add/remove email addresses to their account - I think if you want completly use providers (disable direct login/singup) email management may cause some problems

also password mangement doesn't make sense. (set password/change password/reset password)

Your solution was quite good for me.

I decided to override forms to disable password and email managements as mentioned:

class MemberChangePasswordForm(allauthforms.ChangePasswordForm):
    def clean(self):
        raise forms.ValidationError(_('You cannot change password.'))


class MemberSetPasswordForm(allauthforms.SetPasswordForm):
    def clean(self):
        raise forms.ValidationError(_('You cannot set password.'))


class MemberResetPasswordForm(allauthforms.ResetPasswordForm):
    def clean(self):
        raise forms.ValidationError(_('You cannot reset password.'))


class MemberAddEmailForm(allauthforms.AddEmailForm):
    def clean(self):
        raise forms.ValidationError(_('You cannot add an email.'))

and I set their template page as blank.

I believe that it will be okay if we not provide hyperlinks to password/email management pages. Even if some malicious users access those pages directly, the functions won't work.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

hyunwoona picture hyunwoona  路  4Comments

muhammedtufekyapan picture muhammedtufekyapan  路  5Comments

lukeburden picture lukeburden  路  5Comments

nlubega picture nlubega  路  4Comments

eillarra picture eillarra  路  3Comments