# Path: account/models.py
# class EmailAddress(models.Model):
# 
#     user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
#     email = models.EmailField(max_length=254, unique=settings.ACCOUNT_EMAIL_UNIQUE)
#     verified = models.BooleanField(_("verified"), default=False)
#     primary = models.BooleanField(_("primary"), default=False)
# 
#     objects = EmailAddressManager()
# 
#     class Meta:
#         verbose_name = _("email address")
#         verbose_name_plural = _("email addresses")
#         if not settings.ACCOUNT_EMAIL_UNIQUE:
#             unique_together = [("user", "email")]
# 
#     def __str__(self):
#         return "{0} ({1})".format(self.email, self.user)
# 
#     def set_as_primary(self, conditional=False):
#         old_primary = EmailAddress.objects.get_primary(self.user)
#         if old_primary:
#             if conditional:
#                 return False
#             old_primary.primary = False
#             old_primary.save()
#         self.primary = True
#         self.save()
#         self.user.email = self.email
#         self.user.save()
#         return True
# 
#     def send_confirmation(self, **kwargs):
#         confirmation = EmailConfirmation.create(self)
#         confirmation.send(**kwargs)
#         return confirmation
# 
#     def change(self, new_email, confirm=True):
#         """
#         Given a new email address, change self and re-confirm.
#         """
#         with transaction.atomic():
#             self.user.email = new_email
#             self.user.save()
#             self.email = new_email
#             self.verified = False
#             self.save()
#             if confirm:
#                 self.send_confirmation()
# 
#     def validate_unique(self, exclude=None):
#         super(EmailAddress, self).validate_unique(exclude=exclude)
# 
#         qs = EmailAddress.objects.filter(email__iexact=self.email)
# 
#         if qs.exists() and settings.ACCOUNT_EMAIL_UNIQUE:
#             raise forms.ValidationError({
#                 "email": _("A user is registered with this email address."),
#             })
# 
# Path: account/utils.py
# def get_user_lookup_kwargs(kwargs):
#     result = {}
#     username_field = getattr(get_user_model(), "USERNAME_FIELD", "username")
#     for key, value in kwargs.items():
#         result[key.format(username=username_field)] = value
#     return result


from django.contrib.auth import get_user_model
from django.contrib.auth.backends import ModelBackend
from django.db.models import Q
from account.models import EmailAddress
from account.utils import get_user_lookup_kwargs

    def authenticate(self, request, username=None, password=None, **kwargs):
        """Authenticate the user based on user"""
        if username is None or password is None:
            return None

        try:
            lookup_kwargs = get_user_lookup_kwargs({
                "{username}__iexact": username
            })
            user = User.objects.get(**lookup_kwargs)
        except User.DoesNotExist:
            return None

        if user.check_password(password):
            return user


class EmailAuthenticationBackend(AccountModelBackend):
    """Email authentication"""

    def authenticate(self, request, username=None, password=None, **kwargs):
        """Authenticate the user based email"""
        qs = EmailAddress.objects.filter(Q(primary=True) | Q(verified=True))

        if username is None or password is None:
            return None

        try:
            email_address = qs.get(email__iexact=username)

# Path: account/models.py
# class EmailAddress(models.Model):
# 
#     user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
#     email = models.EmailField(max_length=254, unique=settings.ACCOUNT_EMAIL_UNIQUE)
#     verified = models.BooleanField(_("verified"), default=False)
#     primary = models.BooleanField(_("primary"), default=False)
# 
#     objects = EmailAddressManager()
# 
#     class Meta:
#         verbose_name = _("email address")
#         verbose_name_plural = _("email addresses")
#         if not settings.ACCOUNT_EMAIL_UNIQUE:
#             unique_together = [("user", "email")]
# 
#     def __str__(self):
#         return "{0} ({1})".format(self.email, self.user)
# 
#     def set_as_primary(self, conditional=False):
#         old_primary = EmailAddress.objects.get_primary(self.user)
#         if old_primary:
#             if conditional:
#                 return False
#             old_primary.primary = False
#             old_primary.save()
#         self.primary = True
#         self.save()
#         self.user.email = self.email
#         self.user.save()
#         return True
# 
#     def send_confirmation(self, **kwargs):
#         confirmation = EmailConfirmation.create(self)
#         confirmation.send(**kwargs)
#         return confirmation
# 
#     def change(self, new_email, confirm=True):
#         """
#         Given a new email address, change self and re-confirm.
#         """
#         with transaction.atomic():
#             self.user.email = new_email
#             self.user.save()
#             self.email = new_email
#             self.verified = False
#             self.save()
#             if confirm:
#                 self.send_confirmation()
# 
#     def validate_unique(self, exclude=None):
#         super(EmailAddress, self).validate_unique(exclude=exclude)
# 
#         qs = EmailAddress.objects.filter(email__iexact=self.email)
# 
#         if qs.exists() and settings.ACCOUNT_EMAIL_UNIQUE:
#             raise forms.ValidationError({
#                 "email": _("A user is registered with this email address."),
#             })
# 
# Path: account/utils.py
# def get_user_lookup_kwargs(kwargs):
#     result = {}
#     username_field = getattr(get_user_model(), "USERNAME_FIELD", "username")
#     for key, value in kwargs.items():
#         result[key.format(username=username_field)] = value
#     return result


# Path: account/auth_backends.py
from django.contrib.auth import get_user_model
from django.contrib.auth.backends import ModelBackend
from django.db.models import Q
from account.models import EmailAddress
from account.utils import get_user_lookup_kwargs


    def authenticate(self, request, username=None, password=None, **kwargs):
        """Authenticate the user based on user"""
        if username is None or password is None:
            return None

        try:
            lookup_kwargs = get_user_lookup_kwargs({
                "{username}__iexact": username
            })
            user = User.objects.get(**lookup_kwargs)
        except User.DoesNotExist:
            return None

        if user.check_password(password):
            return user


class EmailAuthenticationBackend(AccountModelBackend):
    """Email authentication"""

    def authenticate(self, request, username=None, password=None, **kwargs):
        """Authenticate the user based email"""
        qs = EmailAddress.objects.filter(Q(primary=True) | Q(verified=True))

        if username is None or password is None:
            return None

        try:
            email_address = qs.get(email__iexact=username)

        except EmailAddress.DoesNotExist: