def test_init_token_given(): # Test successful instantiation original_now = aware_utcnow() with patch('taiga.auth.tokens.aware_utcnow') as fake_aware_utcnow: fake_aware_utcnow.return_value = original_now good_token = MyToken() good_token['some_value'] = 'arst' encoded_good_token = str(good_token) now = aware_utcnow() # Create new token from encoded token with patch('taiga.auth.tokens.aware_utcnow') as fake_aware_utcnow: fake_aware_utcnow.return_value = now # Should raise no exception t = MyToken(encoded_good_token) # Should have expected properties assert t.current_time == now assert t.token == encoded_good_token assert len(t.payload) == 4 assert t['some_value'] == 'arst' assert t['exp'] == datetime_to_epoch(original_now + MyToken.lifetime) assert t[api_settings.TOKEN_TYPE_CLAIM] == MyToken.token_type assert 'jti' in t.payload
def test_decode_rsa_with_expiry(): payload['exp'] = aware_utcnow() - timedelta(seconds=1) expired_token = jwt.encode(payload, PRIVATE_KEY, algorithm='RS256') with pytest.raises(TokenBackendError): rsa_token_backend.decode(expired_token)
def test_decode_hmac_with_expiry(): payload['exp'] = aware_utcnow() - timedelta(seconds=1) expired_token = jwt.encode(payload, SECRET, algorithm='HS256') with pytest.raises(TokenBackendError): hmac_token_backend.decode(expired_token)
def test_decode_rsa_success(): payload['exp'] = aware_utcnow() + timedelta(days=1) payload['foo'] = 'baz' token = jwt.encode(payload, PRIVATE_KEY, algorithm='RS256') # Payload copied payload["exp"] = datetime_to_epoch(payload["exp"]) assert rsa_token_backend.decode(token) == payload
def test_decode_aud_iss_success(): payload['exp'] = aware_utcnow() + timedelta(days=1) payload['foo'] = 'baz' payload['aud'] = AUDIENCE payload['iss'] = ISSUER token = jwt.encode(payload, PRIVATE_KEY, algorithm='RS256') # Payload copied payload["exp"] = datetime_to_epoch(payload["exp"]) assert aud_iss_token_backend.decode(token) == payload
def test_decode_rsa_with_invalid_sig(): payload['exp'] = aware_utcnow() + timedelta(days=1) payload['foo'] = 'baz' token = jwt.encode(payload, PRIVATE_KEY, algorithm='RS256') token_payload = token.rsplit('.', 1)[0] token_sig = token.rsplit('.', 1)[-1] invalid_token = token_payload + '.' + token_sig.replace("a", "A") with pytest.raises(TokenBackendError): rsa_token_backend.decode(invalid_token)
def test_decode_hmac_with_invalid_sig(): payload['exp'] = aware_utcnow() + timedelta(days=1) token_1 = jwt.encode(payload, SECRET, algorithm='HS256') payload['foo'] = 'baz' token_2 = jwt.encode(payload, SECRET, algorithm='HS256') token_2_payload = token_2.rsplit('.', 1)[0] token_1_sig = token_1.rsplit('.', 1)[-1] invalid_token = token_2_payload + '.' + token_1_sig with pytest.raises(TokenBackendError): hmac_token_backend.decode(invalid_token)
def test_decode_rsa_with_invalid_sig_no_verify(): payload['exp'] = aware_utcnow() + timedelta(days=1) payload['foo'] = 'baz' token = jwt.encode(payload, PRIVATE_KEY, algorithm='RS256') token_payload = token.rsplit('.', 1)[0] token_sig = token.rsplit('.', 1)[-1] invalid_token = token_payload + '.' + token_sig.replace("a", "A") # Payload copied payload["exp"] = datetime_to_epoch(payload["exp"]) assert hmac_token_backend.decode(invalid_token, verify=False) == payload
def test_decode_hmac_with_invalid_sig_no_verify(): payload['exp'] = aware_utcnow() + timedelta(days=1) token_1 = jwt.encode(payload, SECRET, algorithm='HS256') payload['foo'] = 'baz' token_2 = jwt.encode(payload, SECRET, algorithm='HS256') # Payload copied payload["exp"] = datetime_to_epoch(payload["exp"]) token_2_payload = token_2.rsplit('.', 1)[0] token_1_sig = token_1.rsplit('.', 1)[-1] invalid_token = token_2_payload + '.' + token_1_sig assert hmac_token_backend.decode(invalid_token, verify=False) == payload
def test_init_bad_sig_token_given(): # Test backend rejects encoded token (expired or bad signature) payload = {'foo': 'bar'} payload['exp'] = aware_utcnow() + timedelta(days=1) token_1 = jwt.encode(payload, api_settings.SIGNING_KEY, algorithm='HS256') payload['foo'] = 'baz' token_2 = jwt.encode(payload, api_settings.SIGNING_KEY, algorithm='HS256') token_2_payload = token_2.rsplit('.', 1)[0] token_1_sig = token_1.rsplit('.', 1)[-1] invalid_token = token_2_payload + '.' + token_1_sig with pytest.raises(TokenError): MyToken(invalid_token)
def test_flush_expired_tokens_should_delete_any_expired_tokens(): user = f.UserFactory( username='******', password='******', ) # Make some tokens that won't expire soon not_expired_1 = RefreshToken.for_user(user) not_expired_2 = RefreshToken.for_user(user) not_expired_3 = RefreshToken() # Denylist fresh tokens not_expired_2.denylist() not_expired_3.denylist() # Make tokens with fake exp time that will expire soon fake_now = aware_utcnow() - api_settings.REFRESH_TOKEN_LIFETIME with patch('taiga.auth.tokens.aware_utcnow') as fake_aware_utcnow: fake_aware_utcnow.return_value = fake_now expired_1 = RefreshToken.for_user(user) expired_2 = RefreshToken() # Denylist expired tokens expired_1.denylist() expired_2.denylist() # Make another token that won't expire soon not_expired_4 = RefreshToken.for_user(user) # Should be certain number of outstanding tokens and denylisted # tokens assert OutstandingToken.objects.count() == 6 assert DenylistedToken.objects.count() == 4 call_command('flushexpiredtokens') # Expired outstanding *and* denylisted tokens should be gone assert OutstandingToken.objects.count() == 4 assert DenylistedToken.objects.count() == 2 assert ([i.jti for i in OutstandingToken.objects.order_by('id')] == [ not_expired_1['jti'], not_expired_2['jti'], not_expired_3['jti'], not_expired_4['jti'] ]) assert ([i.token.jti for i in DenylistedToken.objects.order_by('id') ] == [not_expired_2['jti'], not_expired_3['jti']])
def handle(self, *args, **kwargs): OutstandingToken.objects.filter( expires_at__lte=aware_utcnow()).delete()