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 1.9KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. from django.contrib.auth.models import User
  2. from django.contrib.auth.backends import ModelBackend
  3. from django.core.mail import mail_admins
  4. class Emailbackend(ModelBackend):
  5. def authenticate(self, email=None, password=None, *args, **kwargs):
  6. if email is None:
  7. if not 'username' in kwargs or kwargs['username'] is None:
  8. return None
  9. email = kwargs['username']
  10. # Check if we're dealing with an email address
  11. if '@' not in email:
  12. return None
  13. # We lowercase the host part as this is what Django does when saving a
  14. # user
  15. local, host = email.split('@')
  16. clean_email = local + '@' + host.lower()
  17. # Since Django doesn't enforce emails to be unique, we look for all
  18. # matching users and try to authenticate them all. If we get more than
  19. # one success, then we mail admins as this is a problem.
  20. authenticated_users = []
  21. for user in User.objects.filter(email=clean_email):
  22. if user.check_password(password):
  23. authenticated_users.append(user)
  24. if len(authenticated_users) == 1:
  25. # Happy path
  26. return authenticated_users[0]
  27. elif len(authenticated_users) > 1:
  28. # This is the problem scenario where we have multiple users with
  29. # the same email address AND password. We can't safely authentiate
  30. # either. This situation requires intervention by an admin and so
  31. # we mail them to let them know!
  32. mail_admins(
  33. "There are multiple users with email address: %s" % clean_email,
  34. ("There are %s users with email %s and the same password "
  35. "which means none of them are able to authenticate") % (len(authenticated_users),
  36. clean_email))
  37. return None