You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

auth_backends.py 2.2KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. from django.contrib.auth.backends import ModelBackend
  2. from django.core.exceptions import ImproperlyConfigured
  3. from oscar.apps.customer.utils import normalise_email
  4. from oscar.core.compat import get_user_model
  5. User = get_user_model()
  6. if hasattr(User, 'REQUIRED_FIELDS'):
  7. if not (User.USERNAME_FIELD == 'email' or 'email' in User.REQUIRED_FIELDS):
  8. raise ImproperlyConfigured(
  9. "EmailBackend: Your User model must have an email"
  10. " field with blank=False")
  11. class EmailBackend(ModelBackend):
  12. """
  13. Custom auth backend that uses an email address and password
  14. For this to work, the User model must have an 'email' field
  15. """
  16. def authenticate(self, email=None, password=None, *args, **kwargs):
  17. if email is None:
  18. if 'username' not in kwargs or kwargs['username'] is None:
  19. return None
  20. clean_email = normalise_email(kwargs['username'])
  21. else:
  22. clean_email = normalise_email(email)
  23. # Check if we're dealing with an email address
  24. if '@' not in clean_email:
  25. return None
  26. # Since Django doesn't enforce emails to be unique, we look for all
  27. # matching users and try to authenticate them all. Note that we
  28. # intentionally allow multiple users with the same email address
  29. # (has been a requirement in larger system deployments),
  30. # we just enforce that they don't share the same password.
  31. matching_users = User.objects.filter(email=clean_email)
  32. authenticated_users = [
  33. user for user in matching_users if user.check_password(password)]
  34. if len(authenticated_users) == 1:
  35. # Happy path
  36. return authenticated_users[0]
  37. elif len(authenticated_users) > 1:
  38. # This is the problem scenario where we have multiple users with
  39. # the same email address AND password. We can't safely authenticate
  40. # either.
  41. raise User.MultipleObjectsReturned(
  42. "There are multiple users with the given email address and "
  43. "password")
  44. return None
  45. # Deprecated in Oscar 0.8: Spelling
  46. Emailbackend = EmailBackend