Allauth - 如何禁用社交帐户的重置密码?

Allauth - How to disable reset password for social accounts?

我希望社交用户只能在没有密码的情况下登录。因此,我想在 /accounts/password/reset/ 为社交用户禁用密码重置。

我知道我需要在这段代码中添加条件 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"]

我正在考虑这个解决方案,但我不知道如何正确执行:

  elif SocialAccount.objects.filter(provider='facebook'):
      raise forms.ValidationError(_("You are using a social account.")

Allauth 的可扩展性不是问题。 self.users 包含所有提供电子邮件的用户,但如果您设置了 ACCOUNT_UNIQUE_EMAIL=True 或只是没有更改它(因此默认为 True),那么您可以只接受第一个用户。每个用户包含 socialaccount_set 相关经理。所以我们只过滤由 provider name 设置的,如果有任何项目那么这个用户有相关的社交帐户。所以你可以继承 allauth 表单并在那里进行额外的检查:

# 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"]

然后覆盖 allauth 设置以在他们的重置密码视图中使用您的表单:

# your settings
ACCOUNT_FORMS = {
    'reset_password': 'your_app.forms.MyResetPasswordForm'
}

我尚未测试此代码,因此它可能包含拼写错误,因此请随时 post 提出任何其他问题。

@bellum 答案还不错,但现在 Allauth return 列表在 filter_users_by_email(email)

所以这对我有用

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"]

注意:我用的是google社交认证,如果你用的是Facebook,那就换成facebook。