def test_custom_encode_decode_key_callbacks(app, default_access_token): jwtM = get_jwt_manager(app) app.config["JWT_SECRET_KEY"] = "foobarbaz" @jwtM.encode_key_loader def get_encode_key_1(identity): assert identity == "username" return "different secret" with pytest.raises(InvalidSignatureError): with app.test_request_context(): token = create_access_token("username") decode_token(token) with pytest.raises(InvalidSignatureError): with app.test_request_context(): token = create_refresh_token("username") decode_token(token) @jwtM.decode_key_loader def get_decode_key_1(jwt_header, jwt_data): assert jwt_header["alg"] == "HS256" assert jwt_data["sub"] == "username" return "different secret" with app.test_request_context(): token = create_access_token("username") decode_token(token) token = create_refresh_token("username") decode_token(token)
async def test_token_from_complex_object(app): class TestObject: def __init__(self, username): self.username = username jwt = get_jwt_manager(app) @jwt.user_claims_loader def add_claims(test_obj): return {"username": test_obj.username} @jwt.user_identity_loader def add_claims(test_obj): return test_obj.username async with app.test_request_context("/protected"): access_token = create_access_token(TestObject("username")) # Make sure the changes appear in the token decoded_token = decode_token(access_token) assert decoded_token["identity"] == "username" assert decoded_token["user_claims"] == {"username": "******"} test_client = app.test_client() response = await test_client.get("/protected", headers=make_headers(access_token)) assert await response.get_json() == {"username": "******"} assert response.status_code == 200
async def test_custom_encode_decode_key_callbacks(app, default_access_token): jwtM = get_jwt_manager(app) app.config["JWT_SECRET_KEY"] = "foobarbaz" @jwtM.encode_key_loader def get_encode_key_1(identity): assert identity == "username" return "different secret" with pytest.raises(InvalidSignatureError): async with app.test_request_context("/protected"): token = create_access_token("username") decode_token(token) with pytest.raises(InvalidSignatureError): async with app.test_request_context("/protected"): token = create_refresh_token("username") decode_token(token) @jwtM.decode_key_loader def get_decode_key_1(claims, headers): assert claims["identity"] == "username" return "different secret" async with app.test_request_context("/protected"): token = create_access_token("username") decode_token(token) token = create_refresh_token("username") decode_token(token)
def test_token_from_complex_object(app): class TestObject: def __init__(self, username): self.username = username jwt = get_jwt_manager(app) @jwt.user_claims_loader def add_claims(test_obj): return {'username': test_obj.username} @jwt.user_identity_loader def add_claims(test_obj): return test_obj.username with app.test_request_context(): access_token = create_access_token(TestObject('username')) # Make sure the changes appear in the token decoded_token = decode_token(access_token) assert decoded_token['identity'] == 'username' assert decoded_token['user_claims'] == {'username': '******'} test_client = app.test_client() response = test_client.get('/protected', headers=make_headers(access_token)) assert response.get_json() == {'username': '******'} assert response.status_code == 200
def test_revoked_token_of_different_type(app): jwt = get_jwt_manager(app) test_client = app.test_client() @jwt.token_in_blacklist_loader def check_blacklisted(decrypted_token): return True with app.test_request_context(): access_token = create_access_token('username') refresh_token = create_refresh_token('username') app.config['JWT_BLACKLIST_TOKEN_CHECKS'] = ['access'] response = test_client.get('/refresh_protected', headers=make_headers(refresh_token)) json_data = json.loads(response.get_data(as_text=True)) assert json_data == {'foo': 'bar'} assert response.status_code == 200 app.config['JWT_BLACKLIST_TOKEN_CHECKS'] = ['refresh'] response = test_client.get('/protected', headers=make_headers(access_token)) json_data = json.loads(response.get_data(as_text=True)) assert json_data == {'foo': 'bar'} assert response.status_code == 200
def test_jwt_invalid_audience(app): url = '/protected' jwtM = get_jwt_manager(app) test_client = app.test_client() # No audience claim expected or provided - OK access_token = encode_token(app, {'identity': 'me'}) response = test_client.get(url, headers=make_headers(access_token)) assert response.status_code == 200 # Audience claim expected and not provided - not OK app.config['JWT_DECODE_AUDIENCE'] = 'my_audience' access_token = encode_token(app, {'identity': 'me'}) response = test_client.get(url, headers=make_headers(access_token)) assert response.status_code == 422 assert response.get_json() == {'msg': 'Token is missing the "aud" claim'} # Audience claim still expected and wrong one provided - not OK access_token = encode_token(app, { 'aud': 'different_audience', 'identity': 'me' }) response = test_client.get(url, headers=make_headers(access_token)) assert response.status_code == 422 assert response.get_json() == {'msg': 'Invalid audience'}
def test_missing_query_paramater(app): test_client = app.test_client() jwtM = get_jwt_manager(app) with app.test_request_context(): access_token = create_access_token('username') # Insure no query paramaters doesn't give a response response = test_client.get('/protected') assert response.status_code == 401 assert response.get_json() == {'msg': 'Missing "jwt" query paramater'} # Insure headers don't work access_headers = {'Authorization': 'Bearer {}'.format(access_token)} response = test_client.get('/protected', headers=access_headers) assert response.status_code == 401 assert response.get_json() == {'msg': 'Missing "jwt" query paramater'} # Test custom response works @jwtM.unauthorized_loader def custom_response(err_str): return jsonify(foo='bar'), 201 response = test_client.get('/protected') assert response.status_code == 201 assert response.get_json() == {'foo': "bar"}
def test_custom_encode_decode_key_callbacks(app, default_access_token): jwtM = get_jwt_manager(app) app.config['JWT_SECRET_KEY'] = 'foobarbaz' @jwtM.encode_key_loader def get_encode_key_1(identity): assert identity == 'username' return 'different secret' with pytest.raises(InvalidSignatureError): with app.test_request_context(): token = create_access_token('username') decode_token(token) with pytest.raises(InvalidSignatureError): with app.test_request_context(): token = create_refresh_token('username') decode_token(token) @jwtM.decode_key_loader def get_decode_key_1(claims, headers): assert claims['identity'] == 'username' return 'different secret' with app.test_request_context(): token = create_access_token('username') decode_token(token) token = create_refresh_token('username') decode_token(token)
def test_missing_query_paramater(app): test_client = app.test_client() jwtM = get_jwt_manager(app) with app.test_request_context(): access_token = create_access_token("username") # Insure no query paramaters doesn't give a response response = test_client.get("/protected") assert response.status_code == 401 assert response.get_json() == {"msg": "Missing 'jwt' query paramater"} # Insure headers don't work access_headers = {"Authorization": "Bearer {}".format(access_token)} response = test_client.get("/protected", headers=access_headers) assert response.status_code == 401 assert response.get_json() == {"msg": "Missing 'jwt' query paramater"} # Test custom response works @jwtM.unauthorized_loader def custom_response(err_str): return jsonify(foo="bar"), 201 response = test_client.get("/protected") assert response.status_code == 201 assert response.get_json() == {"foo": "bar"}
async def test_header_without_jwt(app): jwtM = get_jwt_manager(app) test_client = app.test_client() access_headers = {"Authorization": "Bearer "} response = await test_client.get("/protected", headers=access_headers) assert response.status_code == 422 assert await response.get_json() == { "msg": "Bad Authorization header. Expected value 'Bearer <JWT>'" }
def test_header_without_jwt(app): jwtM = get_jwt_manager(app) test_client = app.test_client() access_headers = {'Authorization': 'Bearer '} response = test_client.get('/protected', headers=access_headers) assert response.status_code == 422 assert response.get_json() == { 'msg': "Bad Authorization header. Expected value 'Bearer <JWT>'" }
async def test_non_serializable_user_claims(app): jwt = get_jwt_manager(app) @jwt.additional_headers_loader def add_jwt_headers(identity): return app with pytest.raises(TypeError): async with app.test_request_context("/protected"): create_access_token("username")
def test_non_serializable_user_claims(app): jwt = get_jwt_manager(app) @jwt.user_claims_loader def add_claims(identity): return app with pytest.raises(TypeError): with app.test_request_context(): create_access_token('username')
def test_fresh_jwt_required(app): jwtM = get_jwt_manager(app) url = '/fresh_protected' test_client = app.test_client() with app.test_request_context(): access_token = create_access_token('username') fresh_access_token = create_access_token('username', fresh=True) fresh_timed_access_token = create_access_token( 'username', fresh=timedelta(minutes=5)) stale_timed_access_token = create_access_token( 'username', fresh=timedelta(minutes=-1)) refresh_token = create_refresh_token('username') response = test_client.get(url, headers=make_headers(fresh_access_token)) json_data = json.loads(response.get_data(as_text=True)) assert response.status_code == 200 assert json_data == {'foo': 'bar'} response = test_client.get(url, headers=make_headers(access_token)) json_data = json.loads(response.get_data(as_text=True)) assert response.status_code == 401 assert json_data == {'msg': 'Fresh token required'} response = test_client.get(url, headers=make_headers(fresh_timed_access_token)) json_data = json.loads(response.get_data(as_text=True)) assert response.status_code == 200 assert json_data == {'foo': 'bar'} response = test_client.get(url, headers=make_headers(stale_timed_access_token)) json_data = json.loads(response.get_data(as_text=True)) assert response.status_code == 401 assert json_data == {'msg': 'Fresh token required'} response = test_client.get(url, headers=None) json_data = json.loads(response.get_data(as_text=True)) assert response.status_code == 401 assert json_data == {'msg': 'Missing Authorization Header'} response = test_client.get(url, headers=make_headers(refresh_token)) json_data = json.loads(response.get_data(as_text=True)) assert response.status_code == 422 assert json_data == {'msg': 'Only access tokens are allowed'} # Test with custom response @jwtM.needs_fresh_token_loader def custom_response(): return jsonify(msg='foobar'), 201 response = test_client.get(url, headers=make_headers(access_token)) json_data = json.loads(response.get_data(as_text=True)) assert response.status_code == 201 assert json_data == {'msg': 'foobar'}
def test_fresh_jwt_required(app): jwtM = get_jwt_manager(app) url = "/fresh_protected" test_client = app.test_client() with app.test_request_context(): access_token = create_access_token("username") fresh_access_token = create_access_token("username", fresh=True) refresh_token = create_refresh_token("username") fresh_timed_access_token = create_access_token( identity="username", fresh=timedelta(minutes=5)) stale_timed_access_token = create_access_token( identity="username", fresh=timedelta(minutes=-1)) response = test_client.get(url, headers=make_headers(fresh_access_token)) assert response.status_code == 200 assert response.get_json() == {"foo": "bar"} response = test_client.get(url, headers=make_headers(access_token)) assert response.status_code == 401 assert response.get_json() == {"msg": "Fresh token required"} response = test_client.get(url, headers=make_headers(fresh_timed_access_token)) assert response.status_code == 200 assert response.get_json() == {"foo": "bar"} response = test_client.get(url, headers=make_headers(stale_timed_access_token)) assert response.status_code == 401 assert response.get_json() == {"msg": "Fresh token required"} response = test_client.get(url, headers=None) assert response.status_code == 401 assert response.get_json() == {"msg": "Missing Authorization Header"} response = test_client.get(url, headers=make_headers(refresh_token)) assert response.status_code == 422 assert response.get_json() == { "msg": "Only non-refresh tokens are allowed" } # Test with custom response @jwtM.needs_fresh_token_loader def custom_response(jwt_header, jwt_data): assert jwt_header["alg"] == "HS256" assert jwt_data["sub"] == "username" return jsonify(msg="foobar"), 201 response = test_client.get(url, headers=make_headers(access_token)) assert response.status_code == 201 assert response.get_json() == {"msg": "foobar"}
def test_load_valid_user(app, url): jwt = get_jwt_manager(app) @jwt.user_lookup_loader def user_lookup_callback(_jwt_header, jwt_data): return {"username": jwt_data["sub"]} test_client = app.test_client() with app.test_request_context(): access_token = create_access_token("username") response = test_client.get(url, headers=make_headers(access_token)) assert response.status_code == 200 assert response.get_json() == {"foo": "username"}
def test_unsuccessful_claims_validation(app, url): jwt = get_jwt_manager(app) @jwt.claims_verification_loader def user_load_callback(user_claims): return False test_client = app.test_client() with app.test_request_context(): access_token = create_access_token('username', fresh=True) response = test_client.get(url, headers=make_headers(access_token)) assert response.get_json() == {'msg': 'User claims verification failed'} assert response.status_code == 400
async def test_load_valid_user(app, url): jwt = get_jwt_manager(app) @jwt.user_loader_callback_loader def user_load_callback(identity): return {"username": identity} test_client = app.test_client() async with app.test_request_context("/protected"): access_token = create_access_token("username") response = await test_client.get(url, headers=make_headers(access_token)) assert response.status_code == 200 assert await response.get_json() == {"foo": "username"}
async def test_jwt_header_in_access_token_specified_at_creation_override(app): jwt = get_jwt_manager(app) @jwt.additional_headers_loader def add_jwt_headers(identity): return {"ping": "pong"} async with app.test_request_context("/protected"): access_token = create_access_token("username", headers={"foo": "bar"}) test_client = app.test_client() response = await test_client.get("/protected", headers=make_headers(access_token)) assert (await response.get_json()).get("foo") == "bar" assert response.status_code == 200
def test_load_invalid_user(app, url): jwt = get_jwt_manager(app) @jwt.user_lookup_loader def user_lookup_callback(_jwt_header, jwt_data): return None test_client = app.test_client() with app.test_request_context(): access_token = create_access_token("username") response = test_client.get(url, headers=make_headers(access_token)) assert response.status_code == 401 assert response.get_json() == {"msg": "Error loading the user username"}
async def test_jwt_headers_in_refresh_token(app): jwt = get_jwt_manager(app) @jwt.additional_headers_loader def add_jwt_headers(identity): return {"foo": "bar"} async with app.test_request_context("/protected"): refresh_token = create_refresh_token("username") test_client = app.test_client() response = await test_client.get("/protected2", headers=make_headers(refresh_token)) assert (await response.get_json()).get("foo") == "bar" assert response.status_code == 200
def test_user_claim_in_access_token(app): jwt = get_jwt_manager(app) @jwt.user_claims_loader def add_claims(identity): return {'foo': 'bar'} with app.test_request_context(): access_token = create_access_token('username') test_client = app.test_client() response = test_client.get('/protected', headers=make_headers(access_token)) assert response.get_json() == {'foo': 'bar'} assert response.status_code == 200
def test_load_valid_user(app, url): jwt = get_jwt_manager(app) @jwt.user_loader_callback_loader def user_load_callback(identity): return {'username': identity} test_client = app.test_client() with app.test_request_context(): access_token = create_access_token('username') response = test_client.get(url, headers=make_headers(access_token)) assert response.status_code == 200 assert response.get_json() == {'foo': 'username'}
def test_load_invalid_user(app, url): jwt = get_jwt_manager(app) @jwt.user_loader_callback_loader def user_load_callback(identity): return None test_client = app.test_client() with app.test_request_context(): access_token = create_access_token('username') response = test_client.get(url, headers=make_headers(access_token)) json_data = json.loads(response.get_data(as_text=True)) assert response.status_code == 401 assert json_data == {'msg': "Error loading the user username"}
def test_user_claim_not_in_refresh_token(app): jwt = get_jwt_manager(app) @jwt.user_claims_loader def add_claims(identity, extra_info_for_claims={}): return {'foo': 'bar'} with app.test_request_context(): refresh_token = create_refresh_token('username') test_client = app.test_client() response = test_client.get('/protected2', headers=make_headers(refresh_token)) assert response.get_json() == {} assert response.status_code == 200
def test_no_user_claims(app, user_loader_return): jwtM = get_jwt_manager(app) @jwtM.user_claims_loader def empty_user_loader_return(identity, extra_info_for_claims={}): return user_loader_return # Identity should not be in the actual token, but should be in the data # returned via the decode_token call with app.test_request_context(): token = create_access_token('username') pure_decoded = jwt.decode(token, config.decode_key, algorithms=[config.algorithm]) assert config.user_claims_key not in pure_decoded extension_decoded = decode_token(token) assert config.user_claims_key in extension_decoded
def test_custom_token_loader(app): jwtM = get_jwt_manager(app) app.config['JWT_SECRET_KEY'] = 'foobarbaz' @jwtM.post_decode_token_loader def token_loader(token): token["new_field"] = "hello" return token with app.test_request_context(): token = create_access_token('username') token = decode_token(token) assert "new_field" in token assert token["new_field"] == "hello"
def test_claims_overload_refresh(app): jwt = get_jwt_manager(app) custom_claim = "my custom claim" @jwt.pre_encode_refresh_token_loader def pre_encode(data): data["cust"] = "before claim" return data with app.test_request_context(): refresh_token = create_refresh_token('username', claims_overload_payload={"cust": custom_claim}) decoded_token = decode_token(refresh_token) assert decoded_token['cust'] == custom_claim
def test_pre_encode_refresh_token_loader(app): jwt = get_jwt_manager(app) custom_claim = "my custom" @jwt.pre_encode_refresh_token_loader def pre_encode(data): data["cust"] = custom_claim return data with app.test_request_context(): refresh_token = create_refresh_token('username') decoded_token = decode_token(refresh_token) assert decoded_token['cust'] == custom_claim
def test_user_claim_in_refresh_token(app): app.config['JWT_CLAIMS_IN_REFRESH_TOKEN'] = True jwt = get_jwt_manager(app) @jwt.user_claims_loader def add_claims(identity): return {'foo': 'bar'} with app.test_request_context(): refresh_token = create_refresh_token('username') test_client = app.test_client() response = test_client.get('/protected2', headers=make_headers(refresh_token)) assert response.get_json() == {'foo': 'bar'} assert response.status_code == 200