Last active
January 20, 2018 21:09
-
-
Save devxpy/c3fbc1f0689ded064ac0631071f7be92 to your computer and use it in GitHub Desktop.
Django dynamic Authentication Form that works with Custom Backends. Can also be used as a drop-in replacement for django-admin login
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django import forms | |
from django.utils.translation import ugettext_lazy as _ | |
from django.contrib.auth import forms as auth_forms, authenticate, get_user_model | |
from django.utils.text import capfirst | |
UserModel = get_user_model() | |
class DynamicAuthenticationForm(auth_forms.AuthenticationForm): | |
""" | |
Base class for authenticating users | |
Extend this to get a form that accept logins on username_field parameter and password. | |
""" | |
error_messages = { | |
'invalid_login': _( | |
"Please enter a valid %(username_field)s." | |
), | |
'wrong_password': _( | |
"Please enter the correct password. (passwords are case-sensitive)" | |
), | |
'inactive': _("This account is inactive."), | |
} | |
def __init__(self, request=None, *args, **kwargs): | |
""" | |
The 'request' parameter is set for custom auth use by subclasses. | |
The form data comes in via the standard 'data' kwarg. | |
""" | |
self.request = request | |
self.user_cache = None | |
forms.Form.__init__(self, *args, **kwargs) | |
# trick the default template into believing username_field is username | |
self.fields['username'] = self.fields[self.username_field] | |
# Set the label for the "username" field. | |
if self.fields['username'].label is None: | |
self.fields['username'].label = capfirst(self.username_field) | |
# remove the username_field field since that's not required | |
del self.fields[self.username_field] | |
def clean(self): | |
username_field_value = self.cleaned_data.get('username') | |
password = self.cleaned_data.get('password') | |
if username_field_value is not None and password: | |
self.user_cache = authenticate(self.request, password=password, | |
**{self.username_field: username_field_value}) | |
if self.user_cache is None: | |
# An authentication backend may reject inactive users. Check | |
# if the user exists and is inactive, and raise the 'inactive' | |
# error if so. | |
try: | |
self.user_cache = UserModel._default_manager.get(**{self.username_field: username_field_value}) | |
except UserModel.DoesNotExist: | |
raise forms.ValidationError( | |
self.error_messages['invalid_login'], | |
code='invalid_login', | |
params={'username_field': self.fields['username'].label}, | |
) | |
else: | |
self.confirm_login_allowed(self.user_cache) | |
raise forms.ValidationError( | |
self.error_messages['wrong_password'], | |
code='wrong_password', | |
) | |
else: | |
self.confirm_login_allowed(self.user_cache) | |
return self.cleaned_data | |
## EXAMPLE USAGE | |
class EmailAuthenticationForm(DynamicAuthenticationForm): | |
username_field = 'email' | |
email = forms.EmailField() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment