6
6
7
7
from django .conf .urls import include , url
8
8
from django .contrib .auth .models import User
9
+ from django .db import models
9
10
from django .http import HttpResponse
10
11
from django .test import TestCase
11
12
from django .utils import six
25
26
factory = APIRequestFactory ()
26
27
27
28
29
+ class CustomToken (models .Model ):
30
+ key = models .CharField (max_length = 40 , primary_key = True )
31
+ user = models .OneToOneField (User )
32
+
33
+
34
+ class CustomTokenAuthentication (TokenAuthentication ):
35
+ model = CustomToken
36
+
37
+
28
38
class MockView (APIView ):
29
39
permission_classes = (permissions .IsAuthenticated ,)
30
40
@@ -42,6 +52,7 @@ def put(self, request):
42
52
url (r'^session/$' , MockView .as_view (authentication_classes = [SessionAuthentication ])),
43
53
url (r'^basic/$' , MockView .as_view (authentication_classes = [BasicAuthentication ])),
44
54
url (r'^token/$' , MockView .as_view (authentication_classes = [TokenAuthentication ])),
55
+ url (r'^customtoken/$' , MockView .as_view (authentication_classes = [CustomTokenAuthentication ])),
45
56
url (r'^auth-token/$' , 'rest_framework.authtoken.views.obtain_auth_token' ),
46
57
url (r'^auth/' , include ('rest_framework.urls' , namespace = 'rest_framework' )),
47
58
]
@@ -142,9 +153,11 @@ def test_post_form_session_auth_failing(self):
142
153
self .assertEqual (response .status_code , status .HTTP_403_FORBIDDEN )
143
154
144
155
145
- class TokenAuthTests ( TestCase ):
156
+ class BaseTokenAuthTests ( object ):
146
157
"""Token authentication"""
147
158
urls = 'tests.test_authentication'
159
+ model = None
160
+ path = None
148
161
149
162
def setUp (self ):
150
163
self .csrf_client = APIClient (enforce_csrf_checks = True )
@@ -154,54 +167,65 @@ def setUp(self):
154
167
self .user = User .objects .create_user (self .username , self .email , self .password )
155
168
156
169
self .key = 'abcd1234'
157
- self .token = Token .objects .create (key = self .key , user = self .user )
170
+ self .token = self . model .objects .create (key = self .key , user = self .user )
158
171
159
172
def test_post_form_passing_token_auth (self ):
160
173
"""Ensure POSTing json over token auth with correct credentials passes and does not require CSRF"""
161
174
auth = 'Token ' + self .key
162
- response = self .csrf_client .post ('/token/' , {'example' : 'example' }, HTTP_AUTHORIZATION = auth )
175
+ response = self .csrf_client .post (self . path , {'example' : 'example' }, HTTP_AUTHORIZATION = auth )
163
176
self .assertEqual (response .status_code , status .HTTP_200_OK )
164
177
178
+ def test_fail_post_form_passing_nonexistent_token_auth (self ):
179
+ # use a nonexistent token key
180
+ auth = 'Token wxyz6789'
181
+ response = self .csrf_client .post (self .path , {'example' : 'example' }, HTTP_AUTHORIZATION = auth )
182
+ self .assertEqual (response .status_code , status .HTTP_401_UNAUTHORIZED )
183
+
165
184
def test_fail_post_form_passing_invalid_token_auth (self ):
166
185
# add an 'invalid' unicode character
167
186
auth = 'Token ' + self .key + "¸"
168
- response = self .csrf_client .post ('/token/' , {'example' : 'example' }, HTTP_AUTHORIZATION = auth )
187
+ response = self .csrf_client .post (self . path , {'example' : 'example' }, HTTP_AUTHORIZATION = auth )
169
188
self .assertEqual (response .status_code , status .HTTP_401_UNAUTHORIZED )
170
189
171
190
def test_post_json_passing_token_auth (self ):
172
191
"""Ensure POSTing form over token auth with correct credentials passes and does not require CSRF"""
173
192
auth = "Token " + self .key
174
- response = self .csrf_client .post ('/token/' , {'example' : 'example' }, format = 'json' , HTTP_AUTHORIZATION = auth )
193
+ response = self .csrf_client .post (self . path , {'example' : 'example' }, format = 'json' , HTTP_AUTHORIZATION = auth )
175
194
self .assertEqual (response .status_code , status .HTTP_200_OK )
176
195
177
196
def test_post_json_makes_one_db_query (self ):
178
197
"""Ensure that authenticating a user using a token performs only one DB query"""
179
198
auth = "Token " + self .key
180
199
181
200
def func_to_test ():
182
- return self .csrf_client .post ('/token/' , {'example' : 'example' }, format = 'json' , HTTP_AUTHORIZATION = auth )
201
+ return self .csrf_client .post (self . path , {'example' : 'example' }, format = 'json' , HTTP_AUTHORIZATION = auth )
183
202
184
203
self .assertNumQueries (1 , func_to_test )
185
204
186
205
def test_post_form_failing_token_auth (self ):
187
206
"""Ensure POSTing form over token auth without correct credentials fails"""
188
- response = self .csrf_client .post ('/token/' , {'example' : 'example' })
207
+ response = self .csrf_client .post (self . path , {'example' : 'example' })
189
208
self .assertEqual (response .status_code , status .HTTP_401_UNAUTHORIZED )
190
209
191
210
def test_post_json_failing_token_auth (self ):
192
211
"""Ensure POSTing json over token auth without correct credentials fails"""
193
- response = self .csrf_client .post ('/token/' , {'example' : 'example' }, format = 'json' )
212
+ response = self .csrf_client .post (self . path , {'example' : 'example' }, format = 'json' )
194
213
self .assertEqual (response .status_code , status .HTTP_401_UNAUTHORIZED )
195
214
215
+
216
+ class TokenAuthTests (BaseTokenAuthTests , TestCase ):
217
+ model = Token
218
+ path = '/token/'
219
+
196
220
def test_token_has_auto_assigned_key_if_none_provided (self ):
197
221
"""Ensure creating a token with no key will auto-assign a key"""
198
222
self .token .delete ()
199
- token = Token .objects .create (user = self .user )
223
+ token = self . model .objects .create (user = self .user )
200
224
self .assertTrue (bool (token .key ))
201
225
202
226
def test_generate_key_returns_string (self ):
203
227
"""Ensure generate_key returns a string"""
204
- token = Token ()
228
+ token = self . model ()
205
229
key = token .generate_key ()
206
230
self .assertTrue (isinstance (key , six .string_types ))
207
231
@@ -236,6 +260,11 @@ def test_token_login_form(self):
236
260
self .assertEqual (response .data ['token' ], self .key )
237
261
238
262
263
+ class CustomTokenAuthTests (BaseTokenAuthTests , TestCase ):
264
+ model = CustomToken
265
+ path = '/customtoken/'
266
+
267
+
239
268
class IncorrectCredentialsTests (TestCase ):
240
269
def test_incorrect_credentials (self ):
241
270
"""
0 commit comments