1
1
from calendar import timegm
2
2
from datetime import datetime , timedelta
3
+ import time
3
4
4
5
from django .test import TestCase
5
6
from django .conf import settings
6
7
from django .contrib .auth .models import User
7
- import jwt
8
+
8
9
from rest_framework import status
9
10
from rest_framework .compat import patterns
10
11
from rest_framework .test import APIClient
11
12
12
- import rest_framework_jwt .serializers
13
13
from rest_framework_jwt import utils
14
14
from rest_framework_jwt .runtests .models import CustomUser
15
15
from rest_framework_jwt .settings import api_settings , DEFAULTS
16
- from rest_framework_jwt .tests import simtime
17
- from rest_framework_jwt .tests .simtime import SimulationDatetime
18
16
19
17
urlpatterns = patterns (
20
18
'' ,
@@ -168,36 +166,39 @@ def setUp(self):
168
166
super (RefreshJSONWebTokenTests , self ).setUp ()
169
167
api_settings .JWT_ALLOW_TOKEN_RENEWAL = True
170
168
171
- # monkey patch datetime objects in places that use datetime.utcnow()
172
- jwt .datetime = SimulationDatetime
173
- rest_framework_jwt .serializers .datetime = SimulationDatetime
174
- utils .datetime = SimulationDatetime
175
-
176
169
def get_token (self ):
177
170
client = APIClient (enforce_csrf_checks = True )
178
171
response = client .post ('/auth-token/' , self .data , format = 'json' )
179
172
return response .data ['token' ]
180
173
174
+ def create_token (self , user , exp = None , orig_iat = None ):
175
+ payload = utils .jwt_payload_handler (self .user )
176
+ if exp :
177
+ payload ['exp' ] = exp
178
+
179
+ if orig_iat :
180
+ payload ['orig_iat' ] = timegm (orig_iat .utctimetuple ())
181
+
182
+ token = utils .jwt_encode_handler (payload )
183
+ return token
184
+
181
185
def test_refresh_jwt (self ):
182
186
"""
183
187
Test getting a refreshed token from original token works
184
188
"""
185
189
client = APIClient (enforce_csrf_checks = True )
186
190
187
- # Set simulation time to now
188
- currtime = datetime .utcnow ()
189
- simtime .set_simtime (currtime )
190
-
191
191
orig_token = self .get_token ()
192
192
orig_token_decoded = utils .jwt_decode_handler (orig_token )
193
193
194
- # Make sure 'orig_iat' exists and is the current time
194
+ expected_orig_iat = timegm (datetime .utcnow ().utctimetuple ())
195
+
196
+ # Make sure 'orig_iat' exists and is the current time (give some slack)
195
197
orig_iat = orig_token_decoded ['orig_iat' ]
196
- self .assertEquals (orig_iat , timegm ( currtime . utctimetuple ()) )
198
+ self .assertLessEqual (orig_iat - expected_orig_iat , 1 )
197
199
198
- # Fast-forward to later time (but before first token expires)
199
- currtime += api_settings .JWT_EXPIRATION_DELTA - timedelta (seconds = 30 )
200
- simtime .set_simtime (currtime )
200
+ # wait a few seconds, so new token will have different exp
201
+ time .sleep (2 )
201
202
202
203
# Now try to get a refreshed token
203
204
response = client .post ('/auth-token-refresh/' , {'token' : orig_token },
@@ -207,7 +208,7 @@ def test_refresh_jwt(self):
207
208
new_token = response .data ['token' ]
208
209
new_token_decoded = utils .jwt_decode_handler (new_token )
209
210
210
- # Make sure 'orig_iat' on the new token is same as origina
211
+ # Make sure 'orig_iat' on the new token is same as original
211
212
self .assertEquals (new_token_decoded ['orig_iat' ], orig_iat )
212
213
self .assertGreater (new_token_decoded ['exp' ], orig_token_decoded ['exp' ])
213
214
@@ -216,14 +217,13 @@ def test_refresh_jwt_fails_with_expired_token(self):
216
217
Test that using an expired token to refresh won't work
217
218
"""
218
219
client = APIClient (enforce_csrf_checks = True )
219
- token = self .get_token ()
220
220
221
- # Fast-forward to after token expires
222
- after_expire = (
223
- datetime .utcnow () + api_settings .JWT_EXPIRATION_DELTA +
224
- timedelta (seconds = 10 )
221
+ # Make an expired token..
222
+ token = self .create_token (
223
+ self .user ,
224
+ exp = datetime .utcnow () - timedelta (seconds = 5 ),
225
+ orig_iat = datetime .utcnow () - timedelta (hours = 1 )
225
226
)
226
- simtime .set_simtime (after_expire )
227
227
228
228
response = client .post ('/auth-token-refresh/' , {'token' : token },
229
229
format = 'json' )
@@ -235,36 +235,17 @@ def test_refresh_jwt_after_renewal_expiration(self):
235
235
"""
236
236
Test that token can't be refreshed after token renewal limit
237
237
"""
238
- # For simpler test, make the RENEWAL_LIMIT just a bit larger than
239
- # EXPIRATION_DELTA
240
- api_settings .JWT_TOKEN_RENEWAL_LIMIT = (
241
- api_settings .JWT_EXPIRATION_DELTA +
242
- api_settings .JWT_EXPIRATION_DELTA / 2
243
- )
244
-
245
238
client = APIClient (enforce_csrf_checks = True )
246
239
247
- initial_time = datetime .utcnow ()
248
-
249
- token1 = self .get_token ()
250
-
251
- # Token1 refresh to Token2, just before it expires
252
- currtime = (initial_time + api_settings .JWT_EXPIRATION_DELTA -
240
+ orig_iat = (datetime .utcnow () - api_settings .JWT_TOKEN_RENEWAL_LIMIT -
253
241
timedelta (seconds = 5 ))
242
+ token = self .create_token (
243
+ self .user ,
244
+ exp = datetime .utcnow () + timedelta (hours = 1 ),
245
+ orig_iat = orig_iat
246
+ )
254
247
255
- simtime .set_simtime (currtime )
256
-
257
- response = client .post ('/auth-token-refresh/' , {'token' : token1 },
258
- format = 'json' )
259
- token2 = response .data ['token' ]
260
-
261
- # Fast-forward to after token renewal expiration
262
- # Token2 hasn't expired yet, but it can't be used to renew anymore!
263
- currtime = (initial_time + api_settings .JWT_TOKEN_RENEWAL_LIMIT +
264
- timedelta (minutes = 1 ))
265
- simtime .set_simtime (currtime )
266
-
267
- response = client .post ('/auth-token-refresh/' , {'token' : token2 },
248
+ response = client .post ('/auth-token-refresh/' , {'token' : token },
268
249
format = 'json' )
269
250
self .assertEqual (response .status_code , status .HTTP_400_BAD_REQUEST )
270
251
self .assertEqual (response .data ['non_field_errors' ][0 ],
@@ -274,13 +255,3 @@ def tearDown(self):
274
255
# Restore original settings
275
256
api_settings .JWT_ALLOW_TOKEN_RENEWAL = \
276
257
DEFAULTS ['JWT_ALLOW_TOKEN_RENEWAL' ]
277
-
278
- api_settings .JWT_TOKEN_RENEWAL_LIMIT = \
279
- DEFAULTS ['JWT_TOKEN_RENEWAL_LIMIT' ]
280
-
281
- # Undo datetime monkeypatching
282
- jwt .datetime = orig_datetime
283
- rest_framework_jwt .serializers .datetime = orig_datetime
284
- utils .datetime = orig_datetime
285
-
286
- simtime .clear_simtime ()
0 commit comments