from django.contrib.auth.backends import ModelBackend
from django.core.exceptions import ImproperlyConfigured
from oscar.apps.customer.utils import normalise_email

from oscar.core.compat import get_user_model

User = get_user_model()

if hasattr(User, 'REQUIRED_FIELDS'):
    if not (User.USERNAME_FIELD == 'email' or 'email' in User.REQUIRED_FIELDS):
        raise ImproperlyConfigured(
            "EmailBackend: Your User model must have an email"
            " field with blank=False")


class EmailBackend(ModelBackend):
    """
    Custom auth backend that uses an email address and password

    For this to work, the User model must have an 'email' field
    """

    def authenticate(self, email=None, password=None, *args, **kwargs):
        if email is None:
            if 'username' not in kwargs or kwargs['username'] is None:
                return None
            clean_email = normalise_email(kwargs['username'])
        else:
            clean_email = normalise_email(email)

        # Check if we're dealing with an email address
        if '@' not in clean_email:
            return None

        # Since Django doesn't enforce emails to be unique, we look for all
        # matching users and try to authenticate them all. Note that we
        # intentionally allow multiple users with the same email address
        # (has been a requirement in larger system deployments),
        # we just enforce that they don't share the same password.
        # We make a case-insensitive match when looking for emails.
        matching_users = User.objects.filter(email__iexact=clean_email)
        authenticated_users = [
            user for user in matching_users if user.check_password(password)]
        if len(authenticated_users) == 1:
            # Happy path
            return authenticated_users[0]
        elif len(authenticated_users) > 1:
            # This is the problem scenario where we have multiple users with
            # the same email address AND password. We can't safely authenticate
            # either.
            raise User.MultipleObjectsReturned(
                "There are multiple users with the given email address and "
                "password")
        return None

# Deprecated in Oscar 0.8: Spelling
Emailbackend = EmailBackend

@@ -1,20 +1,37 @@
+import warnings%0A%0A
 from django.contrib.
@@ -120,16 +120,17 @@
 figured%0A
+%0A
 from osc
@@ -175,17 +175,16 @@
 e_email%0A
-%0A
 from osc
@@ -2229,16 +2229,17 @@
 n None%0A%0A
+%0A
 # Deprec
@@ -2243,18 +2243,21 @@
 recated 
+s
 in
+ce
  Oscar 0
@@ -2262,43 +2262,419 @@
  0.8
-: Spelling%0AEmailbackend = EmailBackend
+ because of the spelling.%0Aclass Emailbackend(EmailBackend):%0A%0A    def __init__(self):%0A        warnings.warn(%0A            %22Oscar's auth backend EmailBackend has been renamed in Oscar 0.8 %22%0A            %22 and you're using the old name of Emailbackend. Please rename %22%0A            %22 all references; most likely in the AUTH_BACKENDS setting.%22,%0A            DeprecationWarning)%0A        super(Emailbackend, self).__init__()
 %0A

Fix deprecation path for renamed EmailBackend