# Imports
from django.contrib.auth import get_user_model
from django.contrib.auth.backends import ModelBackend
# Exports
__all__ = (
"CaseInsensitiveModelBackend",
"EmailBackend",
)
# Backends
[docs]class CaseInsensitiveModelBackend(ModelBackend):
"""Validate a user with a username that ignores the case of the submitted user name.
.. warning::
Use this backend with caution. While it allows a user to authenticate with a case-insensitive variation of his
or her user name, it can produce errors (``MultipleObjectsExist``, for example) if you don't also check for
case-insensitive user names upon user account creation.
"""
[docs] def authenticate(self, request, username=None, password=None, **kwargs):
"""Authenticate with iexact."""
# noinspection PyPep8Naming
UserModel = get_user_model()
if username is None:
username = kwargs.get(UserModel.USERNAME_FIELD)
try:
case_insensitive_username_field = '{}__iexact'.format(UserModel.USERNAME_FIELD)
# noinspection PyProtectedMember
user = UserModel._default_manager.get(**{case_insensitive_username_field: username})
except UserModel.DoesNotExist:
# Run the default password hasher once to reduce the timing
# difference between an existing and a non-existing user (#20760).
UserModel().set_password(password)
else:
if user.check_password(password) and self.user_can_authenticate(user):
return user
[docs]class EmailBackend(object):
"""Allow the user to authenticate using an email address.
.. code-block:: python
# settings.py
AUTHENTICATION_BACKENDS = [
'superdjango.accounts.backends.EmailBackend',
'django.contrib.auth.backends.ModelBackend',
]
"""
# noinspection PyMethodMayBeStatic,PyUnusedLocal
[docs] def authenticate(self, username=None, password=None, **kwargs):
"""Authenticate against an email address."""
# noinspection PyPep8Naming
UserModel = get_user_model()
if "@" in username:
try:
user = UserModel.objects.get(email__exact=username)
if user.check_password(password):
return user
else:
return None
except UserModel.DoesNotExist:
return None
else:
return None
# noinspection PyMethodMayBeStatic
[docs] def get_user(self, user_id=None):
"""Comply with backend API."""
# noinspection PyPep8Naming
UserModel = get_user_model()
try:
return UserModel.objects.get(pk=user_id)
except UserModel.DoesNotExist:
return None