Skip to content
This repository was archived by the owner on May 26, 2020. It is now read-only.

Commit 69f363d

Browse files
committed
Merge pull request #21 from doordash/custom-user-model
Custom User Models + Tests
2 parents a581e33 + e52350b commit 69f363d

File tree

4 files changed

+74
-8
lines changed

4 files changed

+74
-8
lines changed

rest_framework_jwt/runtests/models.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from django.contrib.auth.models import User
2+
3+
4+
class CustomUser(User):
5+
USERNAME_FIELD = 'email'

rest_framework_jwt/runtests/settings.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
'django.contrib.sessions',
2222
'django.contrib.messages',
2323
'django.contrib.staticfiles',
24+
'rest_framework_jwt.runtests',
2425
)
2526

2627
# OAuth2 is optional and won't work if there is no provider & oauth2

rest_framework_jwt/serializers.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from django.contrib.auth import authenticate
1+
from django.contrib.auth import authenticate, get_user_model
22
from rest_framework import serializers
33

44
from rest_framework_jwt.settings import api_settings
@@ -12,17 +12,27 @@ class JSONWebTokenSerializer(serializers.Serializer):
1212
"""
1313
Serializer class used to validate a username and password.
1414
15+
'username' is identified by the custom UserModel.USERNAME_FIELD.
16+
1517
Returns a JSON Web Token that can be used to authenticate later calls.
1618
"""
17-
username = serializers.CharField()
19+
1820
password = serializers.CharField(write_only=True)
1921

20-
def validate(self, attrs):
21-
username = attrs.get('username')
22-
password = attrs.get('password')
22+
def __init__(self, *args, **kwargs):
23+
"""Dynamically add the USERNAME_FIELD to self.fields."""
24+
super(JSONWebTokenSerializer, self).__init__(*args, **kwargs)
25+
self.fields[self.username_field] = serializers.CharField()
2326

24-
if username and password:
25-
user = authenticate(username=username, password=password)
27+
@property
28+
def username_field(self):
29+
return get_user_model().USERNAME_FIELD
30+
31+
def validate(self, attrs):
32+
credentials = {self.username_field: attrs.get(self.username_field),
33+
'password': attrs.get('password')}
34+
if all(credentials.values()):
35+
user = authenticate(**credentials)
2636

2737
if user:
2838
if not user.is_active:

rest_framework_jwt/tests/test_views.py

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
from django.test import TestCase
2+
from django.conf import settings
23
from django.contrib.auth.models import User
34
from rest_framework import status
45
from rest_framework.compat import patterns
56
from rest_framework.test import APIClient
67

78
from rest_framework_jwt import utils
8-
9+
from rest_framework_jwt.runtests.models import CustomUser
910

1011
urlpatterns = patterns(
1112
'',
@@ -76,3 +77,52 @@ def test_jwt_login_form(self):
7677

7778
self.assertEqual(response.status_code, status.HTTP_200_OK)
7879
self.assertEqual(decoded_payload['username'], self.username)
80+
81+
82+
class CustomUserObtainJSONWebTokenTests(TestCase):
83+
"""JSON Web Token Authentication"""
84+
urls = 'rest_framework_jwt.tests.test_views'
85+
86+
def setUp(self):
87+
# set custom user model
88+
self.ORIG_AUTH_USER_MODEL = settings.AUTH_USER_MODEL
89+
settings.AUTH_USER_MODEL = 'runtests.CustomUser'
90+
91+
self.email = '[email protected]'
92+
self.password = 'password'
93+
user = CustomUser.objects.create(email=self.email)
94+
user.set_password(self.password)
95+
user.save()
96+
self.user = user
97+
98+
self.data = {
99+
'email': self.email,
100+
'password': self.password
101+
}
102+
103+
def test_jwt_login_json(self):
104+
"""
105+
Ensure JWT login view using JSON POST works.
106+
"""
107+
client = APIClient(enforce_csrf_checks=True)
108+
109+
response = client.post('/auth-token/', self.data, format='json')
110+
111+
self.assertEqual(response.status_code, status.HTTP_200_OK)
112+
decoded_payload = utils.jwt_decode_handler(response.data['token'])
113+
self.assertEqual(decoded_payload['username'], self.email)
114+
115+
def test_jwt_login_json_bad_creds(self):
116+
"""
117+
Ensure JWT login view using JSON POST fails
118+
if bad credentials are used.
119+
"""
120+
client = APIClient(enforce_csrf_checks=True)
121+
122+
self.data['password'] = 'wrong'
123+
response = client.post('/auth-token/', self.data, format='json')
124+
125+
self.assertEqual(response.status_code, 400)
126+
127+
def tearDown(self):
128+
settings.AUTH_USER_MODEL = self.ORIG_AUTH_USER_MODEL

0 commit comments

Comments
 (0)