def test_jwt_required(app): url = "/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") # Access and fresh access should be able to access this for token in (access_token, fresh_access_token): response = test_client.get(url, headers=make_headers(token)) assert response.status_code == 200 assert response.get_json() == {"foo": "bar"} # Test accessing jwt_required with no jwt in the request response = test_client.get(url, headers=None) assert response.status_code == 401 assert response.get_json() == {"msg": "Missing Authorization Header"} # Test refresh token access to jwt_required 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" }
def test_jwt_required(app): url = '/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') # Access and fresh access should be able to access this for token in (access_token, fresh_access_token): response = test_client.get(url, headers=make_headers(token)) json_data = json.loads(response.get_data(as_text=True)) assert response.status_code == 200 assert json_data == {'foo': 'bar'} # Test accessing jwt_required with no jwt in the request 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'} # Test refresh token access to jwt_required 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 can access this endpoint'}
def test_refresh_jwt_required(app): url = '/refresh_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') 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 == 422 assert json_data == {'msg': 'Only refresh tokens can access this endpoint'} response = test_client.get(url, headers=make_headers(access_token)) json_data = json.loads(response.get_data(as_text=True)) assert response.status_code == 422 assert json_data == {'msg': 'Only refresh tokens can access this endpoint'} 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 == 200 assert json_data == {'foo': 'bar'}
def test_jwt_optional(app): url = '/optional_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) expired_token = create_access_token( 'username', expires_delta=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': 'baz'} response = test_client.get(url, headers=make_headers(access_token)) json_data = json.loads(response.get_data(as_text=True)) assert response.status_code == 200 assert json_data == {'foo': 'baz'} 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 can access this endpoint'} response = test_client.get(url, headers=None) 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(expired_token)) json_data = json.loads(response.get_data(as_text=True)) assert response.status_code == 401 assert json_data == {'msg': 'Token has expired'}
def test_jwt_optional(app, delta_func): url = "/optional_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") expired_token = create_access_token( identity="username", expires_delta=delta_func(minutes=-1)) response = test_client.get(url, headers=make_headers(fresh_access_token)) assert response.status_code == 200 assert response.get_json() == {"foo": "baz"} response = test_client.get(url, headers=make_headers(access_token)) assert response.status_code == 200 assert response.get_json() == {"foo": "baz"} response = test_client.get(url, headers=make_headers(refresh_token)) assert response.status_code == 422 assert response.get_json() == {"msg": "Only access tokens are allowed"} response = test_client.get(url, headers=None) assert response.status_code == 200 assert response.get_json() == {"foo": "bar"} response = test_client.get(url, headers=make_headers(expired_token)) assert response.status_code == 401 assert response.get_json() == {"msg": "Token has expired"}
async def test_jwt_invalid_issuer(app): url = "/protected" test_client = app.test_client() # No issuer claim expected or provided - OK access_token = await encode_token(app, {"identity": "me"}) response = await test_client.get(url, headers=make_headers(access_token)) assert response.status_code == 200 # Issuer claim expected and not provided - not OK app.config["JWT_DECODE_ISSUER"] = "my_issuer" access_token = await encode_token(app, {"identity": "me"}) response = await test_client.get(url, headers=make_headers(access_token)) assert response.status_code == 422 assert await response.get_json() == { "msg": 'Token is missing the "iss" claim' } # Issuer claim still expected and wrong one provided - not OK access_token = await encode_token(app, { "iss": "different_issuer", "identity": "me" }) response = await test_client.get(url, headers=make_headers(access_token)) assert response.status_code == 422 assert await response.get_json() == {"msg": "Invalid issuer"}
def test_jwt_optional(app): url = '/optional_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') expired_token = create_access_token( identity='username', expires_delta=timedelta(minutes=-1)) response = test_client.get(url, headers=make_headers(fresh_access_token)) assert response.status_code == 200 assert response.get_json() == {'foo': 'baz'} response = test_client.get(url, headers=make_headers(access_token)) assert response.status_code == 200 assert response.get_json() == {'foo': 'baz'} response = test_client.get(url, headers=make_headers(refresh_token)) assert response.status_code == 422 assert response.get_json() == {'msg': 'Only access tokens are allowed'} response = test_client.get(url, headers=None) assert response.status_code == 200 assert response.get_json() == {'foo': 'bar'} response = test_client.get(url, headers=make_headers(expired_token)) assert response.status_code == 401 assert response.get_json() == {'msg': 'Token has expired'}
async def test_refresh_jwt_required(app): url = "/refresh_protected" test_client = app.test_client() async with app.test_request_context("/protected"): access_token = create_access_token("username") fresh_access_token = create_access_token("username", fresh=True) refresh_token = create_refresh_token("username") response = await test_client.get(url, headers=make_headers(fresh_access_token)) assert response.status_code == 422 assert await response.get_json() == { "msg": "Only refresh tokens are allowed" } response = await test_client.get(url, headers=make_headers(access_token)) assert response.status_code == 422 assert await response.get_json() == { "msg": "Only refresh tokens are allowed" } response = await test_client.get(url, headers=None) assert response.status_code == 401 assert await response.get_json() == {"msg": "Missing Authorization Header"} response = await test_client.get(url, headers=make_headers(refresh_token)) assert response.status_code == 200 assert await response.get_json() == {"foo": "bar"}
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_override_jwt_location(app): app.config["JWT_TOKEN_LOCATION"] = ["cookies"] @app.route("/protected_other") @jwt_required(locations="headers") def protected_other(): return jsonify(foo="bar") @app.route("/protected_invalid") @jwt_required(locations="INVALID_LOCATION") def protected_invalid(): return jsonify(foo="bar") test_client = app.test_client() with app.test_request_context(): access_token = create_access_token("username") url = "/protected_other" response = test_client.get(url, headers=make_headers(access_token)) assert response.get_json() == {"foo": "bar"} assert response.status_code == 200 url = "/protected" response = test_client.get(url, headers=make_headers(access_token)) assert response.status_code == 401 assert response.get_json() == { "msg": 'Missing cookie "access_token_cookie"' } url = "/protected_invalid" response = test_client.get(url, headers=make_headers(access_token)) assert response.status_code == 500
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_last_action_is_refreshed(self, app, client, user_factory): """With every authenticated API request, the last_action column is refreshed.""" user = user_factory.get() client.get("/whoami", headers=make_headers("GET", user)) last_action_old = user.last_action client.get("/whoami", headers=make_headers("GET", user)) last_action_new = user.last_action assert last_action_old < last_action_new
def test_no_user_lookup_loader_specified(app, url): 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 "@jwt.user_lookup_loader" in response.get_json()["error"]
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
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_jwt_missing_claims(app): url = '/protected' test_client = app.test_client() token = encode_token(app, {'foo': 'bar'}) response = test_client.get(url, headers=make_headers(token)) assert response.status_code == 422 assert response.get_json() == {'msg': 'Missing claim: identity'}
def test_malformed_token(app): url = '/protected' test_client = app.test_client() access_token = 'foobarbaz' response = test_client.get(url, headers=make_headers(access_token)) assert response.status_code == 422 assert response.get_json() == {'msg': 'Not enough segments'}
def test_malformed_token(app): url = "/protected" test_client = app.test_client() access_token = "foobarbaz" response = test_client.get(url, headers=make_headers(access_token)) assert response.status_code == 422 assert response.get_json() == {"msg": "Not enough segments"}
def test_jwt_missing_claims(app): url = "/protected" test_client = app.test_client() token = encode_token(app, {"foo": "bar"}) response = test_client.get(url, headers=make_headers(token)) assert response.status_code == 422 assert response.get_json() == {"msg": "Missing claim: sub"}
def test_user_claims_in_access_token_specified_at_creation(app): with app.test_request_context(): access_token = create_access_token('username', user_claims={'foo': 'bar'}) 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
async def test_jwt_header_in_access_token_specified_at_creation(app): 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_no_blacklist_callback_method_provided(app): app.config['JWT_BLACKLIST_TOKEN_CHECKS'] = ['access'] 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.status_code == 500
def test_same_auth_token(self, app, client, user_factory): """Can log in and get back the same auth token if there's already a valid one.""" user = user_factory.get() client.post("/auth/login", headers=make_headers('POST'), data=json.dumps({ "email": user.email, "password": "******" })) current_token = user.current_auth_token client.post("/auth/login", headers=make_headers('POST'), data=json.dumps({ "email": user.email, "password": "******" })) db.session.refresh(user) assert current_token == user.current_auth_token
def test_no_blacklist_callback_method_provided(app): app.config['JWT_BLACKLIST_TOKEN_CHECKS'] = ['access'] with app.test_request_context(): access_token = create_access_token('username') with pytest.raises(RuntimeError): test_client = app.test_client() test_client.get('/protected', headers=make_headers(access_token))
def test_jwt_missing_claims(app): url = '/protected' test_client = app.test_client() token = encode_token(app, {'foo': 'bar'}) response = test_client.get(url, headers=make_headers(token)) json_data = json.loads(response.get_data(as_text=True)) assert response.status_code == 422 assert json_data == {'msg': 'Missing claim: jti'}
def test_invalid_jwt(app): url = '/protected' jwtM = get_jwt_manager(app) test_client = app.test_client() invalid_token = "aaaaa.bbbbb.ccccc" # Test default response response = test_client.get(url, headers=make_headers(invalid_token)) assert response.status_code == 422 assert response.get_json() == {'msg': 'Invalid header padding'} # Test custom response @jwtM.invalid_token_loader def custom_response(err_str): return jsonify(msg='foobar'), 201 response = test_client.get(url, headers=make_headers(invalid_token)) assert response.status_code == 201 assert response.get_json() == {'msg': 'foobar'}
def test_jwt_header_in_refresh_token_specified_at_creation(app): with app.test_request_context(): refresh_token = create_refresh_token('username', headers={'foo': 'bar'}) test_client = app.test_client() response = test_client.get('/protected2', headers=make_headers(refresh_token)) assert response.get_json().get("foo") == "bar" assert response.status_code == 200
def test_user_claim_in_refresh_token_specified_at_creation(app): app.config['JWT_CLAIMS_IN_REFRESH_TOKEN'] = True with app.test_request_context(): refresh_token = create_refresh_token('username', user_claims={'foo': 'bar'}) 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
def test_last_action_can_get_too_old(self, app, client, user_factory): """An error is thrown if using an old auth token.""" user = user_factory.get() headers = make_headers("GET", user) with freeze_time(datetime.utcnow() + app.config['AUTH_TOKEN_TIMEOUT'] + timedelta(days=1)): resp = client.get("/whoami", headers=headers) assert resp.status_code == codes.UNAUTHORIZED assert resp.json[ 'message'] == "Auth token too old, please log in again."
async def test_no_blacklist_callback_method_provided(app): app.config["JWT_BLACKLIST_TOKEN_CHECKS"] = ["access"] async with app.test_request_context("/protected"): access_token = create_access_token("username") test_client = app.test_client() response = await test_client.get("/protected", headers=make_headers(access_token)) assert response.status_code == 500