def test_time(self): token = TokenTresDiasRefresh.for_user(self.user) token_duration = datetime_from_epoch(token['exp']) today = datetime.datetime.now() limit_day = today.day + 3 + 1 self.assertEqual(limit_day, token_duration.day)
def test_refresh_tokens_are_added_to_outstanding_list(self): token = RefreshToken.for_user(self.user) qs = OutstandingToken.objects.all() outstanding_token = qs.first() self.assertEqual(qs.count(), 1) self.assertEqual(outstanding_token.user, self.user) self.assertEqual(outstanding_token.jti, token['jti']) self.assertEqual(outstanding_token.token, str(token)) self.assertEqual(outstanding_token.created_at, token.current_time) self.assertEqual(outstanding_token.expires_at, datetime_from_epoch(token['exp']))
def whitelist(self, refresh_token) -> dict: refresh_str = str(refresh_token) TokenSession.objects.create( user_id=refresh_token[api_settings.USER_ID_CLAIM], refresh_token=refresh_str, jti=refresh_token[api_settings.JTI_CLAIM], ip=get_ip_address(self.context['request']), created_at=refresh_token.current_time, expires_at=datetime_from_epoch(refresh_token['exp'])) return { 'access': str(refresh_token.access_token), 'refresh': refresh_str }
def test_custom_refresh_token(): user = BaseUser.objects.get(id=2) # expired time token = CustomRefreshToken.for_user(user) assert user.token_expired == token.access_token['exp'] assert BlacklistedToken.objects.all().exists() is False outstanding_token = OutstandingToken.objects.first() assert outstanding_token.token == str(token) assert outstanding_token.jti == token['jti'] assert outstanding_token.expires_at == datetime_from_epoch(token['exp']) token.blacklist() black_token = BlacklistedToken.objects.get(token_id=outstanding_token.id) assert black_token
def test_it_should_update_token_exp_claim_if_everything_ok(self): now = aware_utcnow() token = SlidingToken() exp = now + api_settings.SLIDING_TOKEN_LIFETIME - timedelta(seconds=1) token.set_exp(from_time=now, lifetime=api_settings.SLIDING_TOKEN_LIFETIME - timedelta(seconds=1)) # View returns 200 res = self.view_post(data={'token': str(token)}) self.assertEqual(res.status_code, 200) # Expiration claim has moved into future new_token = SlidingToken(res.data['token']) new_exp = datetime_from_epoch(new_token['exp']) self.assertTrue(exp < new_exp)
def test_it_should_update_token_exp_claim_if_everything_ok(self): old_token = SlidingToken() lifetime = api_settings.SLIDING_TOKEN_LIFETIME - timedelta(seconds=1) old_exp = old_token.current_time + lifetime old_token.set_exp(lifetime=lifetime) # Serializer validates s = TokenRefreshSlidingSerializer(data={'token': str(old_token)}) self.assertTrue(s.is_valid()) # Expiration claim has moved into future new_token = SlidingToken(s.validated_data['token']) new_exp = datetime_from_epoch(new_token['exp']) self.assertTrue(old_exp < new_exp)
def get_token(self, user): """ Adds this token to the outstanding token list. """ token = AccessToken.for_user(user) jti = token[api_settings.JTI_CLAIM] exp = token['exp'] OutstandingToken.objects.create( user=user, jti=jti, token=str(token), created_at=token.current_time, expires_at=datetime_from_epoch(exp), ) return token
def blacklist(self): """ Ensures this token is included in the outstanding token list and adds it to the blacklist. """ jti = self.payload[api_settings.JTI_CLAIM] exp = self.payload['exp'] # Ensure outstanding token exists with given jti token, _ = OutstandingToken.objects.get_or_create( jti=jti, defaults={ 'token': str(self), 'expires_at': datetime_from_epoch(exp), }, ) return BlacklistedToken.objects.get_or_create(token=token)
def check_exp(self, claim='exp', current_time=None): """ Checks whether a timestamp value in the given claim has passed (since the given datetime value in `current_time`). Raises a TokenError with a user-facing error message if so. """ if current_time is None: current_time = self.current_time try: claim_value = self.payload[claim] except KeyError: raise TokenError(format_lazy(_("Token has no '{}' claim"), claim)) claim_time = datetime_from_epoch(claim_value) if claim_time <= current_time: raise TokenError( format_lazy(_("Token '{}' claim has expired"), claim))
def save_model(self, request, obj, form, change): if obj.user: refresh = RefreshToken() # custom claims refresh["client"] = "pyintelowl" refresh["user_id"] = obj.user.id # overwrite lifetime/expiry refresh.set_exp( lifetime=jwt_settings.get("PYINTELOWL_TOKEN_LIFETIME", None)) token = OutstandingToken.objects.create( user=obj.user, jti=refresh.payload["jti"], token=str(refresh), created_at=refresh.current_time, expires_at=datetime_from_epoch(refresh["exp"]), ) return token return None
def validate(self, attrs): # wrap the given refresh token as a RefreshToken object refresh = RefreshToken(attrs["refresh"]) # create response data data = {"access": str(refresh.access_token)} if jwt_settings["ROTATE_REFRESH_TOKENS"]: blacklisted_token = None if jwt_settings["BLACKLIST_AFTER_ROTATION"]: try: # Attempt to blacklist the given refresh token blacklisted_token, _ = refresh.blacklist() except AttributeError: # If blacklist app not installed, `blacklist` method will # not be present pass # rotate refresh token refresh.set_jti() if refresh.get("client", False) == "pyintelowl": refresh.set_exp( lifetime=jwt_settings.get("PYINTELOWL_TOKEN_LIFETIME", None) ) else: refresh.set_exp() data["refresh"] = str(refresh) # PATCHED - Create Outstanding Token in the db if blacklisted_token: user = blacklisted_token.token.user if user: OutstandingToken.objects.create( user=user, jti=refresh.payload["jti"], token=str(refresh), created_at=refresh.current_time, expires_at=datetime_from_epoch(refresh["exp"]), ) return data
def test_it_should_return_the_correct_values(self): with self.settings(USE_TZ=False): self.assertEqual(datetime_from_epoch(0), datetime(year=1970, month=1, day=1)) self.assertEqual(datetime_from_epoch(1), datetime(year=1970, month=1, day=1, second=1)) self.assertEqual(datetime_from_epoch(946684800), datetime(year=2000, month=1, day=1), 946684800) with self.settings(USE_TZ=True): self.assertEqual(datetime_from_epoch(0), make_utc(datetime(year=1970, month=1, day=1))) self.assertEqual( datetime_from_epoch(1), make_utc(datetime(year=1970, month=1, day=1, second=1))) self.assertEqual(datetime_from_epoch(946684800), make_utc(datetime(year=2000, month=1, day=1)))
def exp_in_localtime(cls, exp): """Return the expiration in the current timezone.""" return timezone.localtime(datetime_from_epoch(exp))
def expires_at(self): claim_value = self.payload['exp'] return datetime_from_epoch(claim_value)