Reputation: 762
I want social users are only able to login without password. Therefore, I want to disable password reset at /accounts/password/reset/ for social users.
I know that I need to add a conditional in this code at allauth.accounts.forms.py
class ResetPasswordForm(forms.Form):
email = forms.EmailField(
label=_("E-mail"),
required=True,
widget=forms.TextInput(attrs={"type": "email", "size": "30"}))
def clean_email(self):
email = self.cleaned_data["email"]
email = get_adapter().clean_email(email)
self.users = filter_users_by_email(email)
if not self.users.exists():
raise forms.ValidationError(_("The e-mail address is not assigned"
" to any user account"))
return self.cleaned_data["email"]
I'm thinking about this solution, but I don't know how to do it properly:
elif SocialAccount.objects.filter(provider='facebook'):
raise forms.ValidationError(_("You are using a social account.")
Upvotes: 2
Views: 2086
Reputation: 81
@bellum answer is kind off right but now Allauth return a list on filter_users_by_email(email)
So this worked for me
from allauth.account.forms import SignupForm, LoginForm, ResetPasswordForm
from allauth.account.adapter import get_adapter
from django.utils.translation import ugettext_lazy as _
from allauth.account.utils import filter_users_by_email
class MyResetPasswordForm(ResetPasswordForm):
def clean_email(self):
email = self.cleaned_data["email"]
email = get_adapter().clean_email(email)
self.users = filter_users_by_email(email)
if not self.users:
raise forms.ValidationError(_("Unfortunately no account with that"
" email was found"))
# custom code start
elif self.users[0].socialaccount_set.filter(provider='google').exists():
raise forms.ValidationError(_("Looks like the email/password combination was not used. Maybe try Social?"))
# custom code end
return self.cleaned_data["email"]
Note: I am using google social authentication if you are using Facebook then change it to facebook.
Upvotes: 1
Reputation: 3710
Allauth extendability is not a problem. self.users
contain all users with provided email but if you have setting ACCOUNT_UNIQUE_EMAIL=True
or just didn't change it (so it's True
by default) then you can take just first user. Every user contain socialaccount_set
related manager. So we just filter that set by provider
name and if there is any item then this user has related socialaccount. So you can inherit allauth form and put additional check there:
# forms.py
class MyResetPasswordForm(ResetPasswordForm):
def clean_email(self):
email = self.cleaned_data["email"]
email = get_adapter().clean_email(email)
self.users = filter_users_by_email(email)
if not self.users.exists():
raise forms.ValidationError(_("The e-mail address is not assigned"
" to any user account"))
# custom code start
elif self.users.first().socialaccount_set.filter(provider='facebook').exists():
raise forms.ValidationError(_("You are using a social account.")
# custom code end
return self.cleaned_data["email"]
And then override allauth settings to use your form in their reset password view:
# your settings
ACCOUNT_FORMS = {
'reset_password': 'your_app.forms.MyResetPasswordForm'
}
I have not tested this code so it can contain typos so feel free to post any further questions.
Upvotes: 1