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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. from django.contrib.auth.backends import ModelBackend
  2. from django.core.mail import mail_admins
  3. from django.core.exceptions import ImproperlyConfigured
  4. from oscar.apps.customer.utils import normalise_email
  5. from oscar.core.compat import get_user_model
  6. User = get_user_model()
  7. if hasattr(User, 'REQUIRED_FIELDS'):
  8. if not (User.USERNAME_FIELD == 'email' or 'email' in User.REQUIRED_FIELDS):
  9. raise ImproperlyConfigured(
  10. "Emailbackend: Your User model must have an email"
  11. " field with blank=False")
  12. class Emailbackend(ModelBackend):
  13. """
  14. Custom auth backend that users an email address
  15. For this to work, the User model must have an 'email' field
  16. """
  17. def authenticate(self, email=None, password=None, *args, **kwargs):
  18. if email is None:
  19. if not 'username' in kwargs or kwargs['username'] is None:
  20. return None
  21. clean_email = normalise_email(kwargs['username'])
  22. # Check if we're dealing with an email address
  23. if '@' not in clean_email:
  24. return None
  25. # Since Django doesn't enforce emails to be unique, we look for all
  26. # matching users and try to authenticate them all. If we get more than
  27. # one success, then we mail admins as this is a problem.
  28. authenticated_users = []
  29. for user in User.objects.filter(email=clean_email):
  30. if user.check_password(password):
  31. authenticated_users.append(user)
  32. if len(authenticated_users) == 1:
  33. # Happy path
  34. return authenticated_users[0]
  35. elif len(authenticated_users) > 1:
  36. # This is the problem scenario where we have multiple users with
  37. # the same email address AND password. We can't safely authentiate
  38. # either. This situation requires intervention by an admin and so
  39. # we mail them to let them know!
  40. mail_admins(
  41. "There are multiple users with email address: %s" % clean_email,
  42. ("There are %s users with email %s and the same password "
  43. "which means none of them are able to authenticate") % (len(authenticated_users),
  44. clean_email))
  45. return None