Commit 32ce8428 authored by Okhin's avatar Okhin
Browse files

Fixing the auth backend to allow username or email validation

parent 2c0989b3
from django.contrib.auth.backends import ModelBackend from django.contrib.auth.backends import ModelBackend
from django.contrib.auth.models import User from django.contrib.auth import get_user_model
class EmailOrUsernameModelBackend(ModelBackend): class EmailOrUsernameModelBackend(ModelBackend):
""" """
Authentification backend to allow email We allow for email or username to be used as a login.
overide AUTHENTICATION_BACKENDS with Case insensitive.
fabauth.auth_backends.EmailOrUsernameModelBackend
""" """
def authenticate(self, username=None, password=None, **kwargs): def authenticate(self, request, username=None, password=None):
if "@" in username: # If we call this function, it means we're not authenticated yet.
kwargs = {"email": username} # Since we're going through the classic Model backend first, it means
else: # that the user does not exists.
kwargs = {"username": username} UserModel = get_user_model()
try: try:
user = User.objects.get(**kwargs) user = UserModel.objects.get(email=username)
if user.check_password(password):
if user.check_password(raw_password=password):
return user return user
except User.DoesNotExist: except UserModel.DoesNotExist:
# The User does not exist. Hashing the password anyway,
# to limit Time attacks efficiency
UserModel().set_password(raw_password=password)
return None return None
def get_user(self, user_id):
# This is used to get the User objects
UserModel = get_user_model()
print("get_user: {}".format(user_id))
try:
return UserModel.objects.get(pk=user_id)
except UserModel.DoesNotExist:
return None
from django.test import TestCase from django.test import TestCase
from django.test import Client from django.test import Client, override_settings
from django_factory_boy import auth as auth_factories from django_factory_boy import auth as auth_factories
AUTHENTICATION_BACKENDS = [
@override_settings(AUTHENTICATION_BACKENDS=[
# Default # Default
"django.contrib.auth.backends.ModelBackend", "django.contrib.auth.backends.ModelBackend",
# Email or Username for login # Email or Username for login
"core.auth_backends.EmailOrUsernameModelBackend" "core.auth_backends.EmailOrUsernameModelBackend"
] ])
class ApiTest(TestCase): class ApiTest(TestCase):
def setUp(self): def setUp(self):
self.client = Client() self.client = Client()
self.user = auth_factories.UserFactory(password="dummypassword") self.user = auth_factories.UserFactory(password="dummypassword")
def test_authenticate(self): def test_authenticate(self):
with self.settings(AUTHENTICATION_BACKENDS=AUTHENTICATION_BACKENDS): # username, wrong password
# username, wrong password login_status = self.client.login(
login_status = self.client.login( username=self.user.username,
username=self.user.username, password="notthepassword"
password="notthepassword" )
) assert not login_status
assert not login_status
# username, correct password
# username, correct password login_status = self.client.login(
login_status = self.client.login( username=self.user.username,
username=self.user.username, password="dummypassword"
password="dummypassword" )
) assert login_status
assert login_status
# email, wrong password
# email, wrong password login_status = self.client.login(
login_status = self.client.login( username=self.user.email,
username=self.user.email, password="notthepassowrd"
password="notthepassowrd" )
) assert not login_status
assert not login_status
# email, correct password
# email, correct password login_status = self.client.login(
login_status = self.client.login( username=self.user.email,
username=self.user.email, password="dummypassword"
password="dummypassword" )
) assert login_status
assert login_status
# username, wrong user
# username, wrong user login_status = self.client.login(
login_status = self.client.login( username="{}-2".format(self.user.username),
username="{}-2".format(self.user.username), password="dummypassword"
password="dummypassword" )
) assert not login_status
assert not login_status
# email, wrong user
# email, wrong user login_status = self.client.login(
login_status = self.client.login( username="{}-2".format(self.user.email),
username="{}-2".format(self.user.email), password="dummypassword"
password="dummypassword" )
) assert not login_status
assert not login_status
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment