From bb002262acef03be4d17f050fdc7157e89dbd5ba Mon Sep 17 00:00:00 2001 From: Petros Moisiadis Date: Tue, 19 May 2015 17:42:44 +0300 Subject: [PATCH 1/6] Support basic authentication with custom user models that change username field Support basic authentication with custom user models with a username field that is not named 'username'. --- rest_framework/authentication.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/rest_framework/authentication.py b/rest_framework/authentication.py index f0702286c1..b03e7c1670 100644 --- a/rest_framework/authentication.py +++ b/rest_framework/authentication.py @@ -4,6 +4,7 @@ from __future__ import unicode_literals import base64 from django.contrib.auth import authenticate +from django.contrib.auth import get_user_model from django.middleware.csrf import CsrfViewMiddleware from django.utils.translation import ugettext_lazy as _ from rest_framework import exceptions, HTTP_HEADER_ENCODING @@ -85,7 +86,11 @@ def authenticate_credentials(self, userid, password): """ Authenticate the userid and password against username and password. """ - user = authenticate(username=userid, password=password) + credentials = { + get_user_model().USERNAME_FIELD: userid, + 'password': password + } + user = authenticate(**credentials) if user is None: raise exceptions.AuthenticationFailed(_('Invalid username/password.')) From a13075486deed9e14b7979542303aa9dcc255be0 Mon Sep 17 00:00:00 2001 From: Petros Moisiadis Date: Tue, 19 May 2015 17:57:27 +0300 Subject: [PATCH 2/6] Compatibility code for getting user model Compatibility code for getting user model --- rest_framework/compat.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/rest_framework/compat.py b/rest_framework/compat.py index c6a4a8698f..1ba9073147 100644 --- a/rest_framework/compat.py +++ b/rest_framework/compat.py @@ -119,6 +119,14 @@ def get_model_name(model_cls): return model_cls._meta.module_name +# Support custom user models in Django 1.5+ +try: + from django.contrib.auth import get_user_model +except ImportError: + from django.contrib.auth.models import User + get_user_model = lambda: User + + # View._allowed_methods only present from 1.5 onwards if django.VERSION >= (1, 5): from django.views.generic import View From 43b4ae752d20a1752e3430f0792552b801a4d347 Mon Sep 17 00:00:00 2001 From: Petros Moisiadis Date: Tue, 19 May 2015 18:00:17 +0300 Subject: [PATCH 3/6] Import get_user_model from compat module Import get_user_model from compat module to be compatible with older django versions (e.g. 1.4). --- rest_framework/authentication.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/rest_framework/authentication.py b/rest_framework/authentication.py index b03e7c1670..0d73a5846d 100644 --- a/rest_framework/authentication.py +++ b/rest_framework/authentication.py @@ -4,12 +4,11 @@ from __future__ import unicode_literals import base64 from django.contrib.auth import authenticate -from django.contrib.auth import get_user_model from django.middleware.csrf import CsrfViewMiddleware from django.utils.translation import ugettext_lazy as _ from rest_framework import exceptions, HTTP_HEADER_ENCODING from rest_framework.authtoken.models import Token - +from rest_framework.compat import get_user_model def get_authorization_header(request): """ From c63ea01f4fde7b21bdc5722920a9d5f926a680ab Mon Sep 17 00:00:00 2001 From: Petros Moisiadis Date: Tue, 19 May 2015 19:05:50 +0300 Subject: [PATCH 4/6] Support User model in Django 1.4 that has not a USERNAME_FIELD attribute Support User model in Django 1.4 that has not a USERNAME_FIELD attribute. --- rest_framework/authentication.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/rest_framework/authentication.py b/rest_framework/authentication.py index 0d73a5846d..6172567627 100644 --- a/rest_framework/authentication.py +++ b/rest_framework/authentication.py @@ -85,8 +85,13 @@ def authenticate_credentials(self, userid, password): """ Authenticate the userid and password against username and password. """ + user_model = get_user_model() + if hasattr(user_model, 'USERNAME_FIELD'): + username_field = user_model.USERNAME_FIELD + else: + username_field = 'username' credentials = { - get_user_model().USERNAME_FIELD: userid, + username_field: userid, 'password': password } user = authenticate(**credentials) From a96ebd74b1c27f4fa63f7bae5f9157f1140f9570 Mon Sep 17 00:00:00 2001 From: Petros Moisiadis Date: Tue, 19 May 2015 19:48:53 +0300 Subject: [PATCH 5/6] Fix flake8 error Fix flake8 error --- rest_framework/authentication.py | 1 + 1 file changed, 1 insertion(+) diff --git a/rest_framework/authentication.py b/rest_framework/authentication.py index 6172567627..cf54d45635 100644 --- a/rest_framework/authentication.py +++ b/rest_framework/authentication.py @@ -10,6 +10,7 @@ from rest_framework.authtoken.models import Token from rest_framework.compat import get_user_model + def get_authorization_header(request): """ Return request's 'Authorization:' header, as a bytestring. From 192719eed0ffc8ecd423b18e07bf52921dbfbcc2 Mon Sep 17 00:00:00 2001 From: Petros Moisiadis Date: Tue, 19 May 2015 20:00:19 +0300 Subject: [PATCH 6/6] Improve coding style On Tom's suggestion, improve coding style by using a single-line call to getattr() with a default value instead of a multi-line if/else clause. --- rest_framework/authentication.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/rest_framework/authentication.py b/rest_framework/authentication.py index cf54d45635..8b5c200907 100644 --- a/rest_framework/authentication.py +++ b/rest_framework/authentication.py @@ -86,11 +86,7 @@ def authenticate_credentials(self, userid, password): """ Authenticate the userid and password against username and password. """ - user_model = get_user_model() - if hasattr(user_model, 'USERNAME_FIELD'): - username_field = user_model.USERNAME_FIELD - else: - username_field = 'username' + username_field = getattr(get_user_model(), 'USERNAME_FIELD', 'username') credentials = { username_field: userid, 'password': password