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)
async def test_jwt_required(app): url = "/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") # Access and fresh access should be able to access this for token in (access_token, fresh_access_token): response = await test_client.get(url, headers=make_headers(token)) assert response.status_code == 200 assert await response.get_json() == {"foo": "bar"} # Test accessing jwt_required with no jwt in the request response = await test_client.get(url, headers=None) assert response.status_code == 401 assert await response.get_json() == {"msg": "Missing Authorization Header"} # Test refresh token access to jwt_required response = await test_client.get(url, headers=make_headers(refresh_token)) assert response.status_code == 422 assert await response.get_json() == { "msg": "Only access tokens are allowed" }
async def test_jwt_optional(app, delta_func): url = "/optional_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") expired_token = create_access_token( identity="username", expires_delta=delta_func(minutes=-1)) response = await test_client.get(url, headers=make_headers(fresh_access_token)) assert response.status_code == 200 assert await response.get_json() == {"foo": "baz"} response = await test_client.get(url, headers=make_headers(access_token)) assert response.status_code == 200 assert await response.get_json() == {"foo": "baz"} response = await test_client.get(url, headers=make_headers(refresh_token)) assert response.status_code == 422 assert await response.get_json() == { "msg": "Only access tokens are allowed" } response = await test_client.get(url, headers=None) assert response.status_code == 200 assert await response.get_json() == {"foo": "bar"} response = await test_client.get(url, headers=make_headers(expired_token)) assert response.status_code == 401 assert await 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"}
async def test_custom_body_key(app): app.config["JWT_JSON_KEY"] = "Foo" app.config["JWT_REFRESH_JSON_KEY"] = "Bar" test_client = app.test_client() async with app.test_request_context("/protected"): access_token = create_access_token("username") refresh_token = create_refresh_token("username") # Ensure 'default' keys no longer work data = {"access_token": access_token} response = await test_client.post("/protected", json=data) assert response.status_code == 401 assert await response.get_json() == { "msg": 'Missing "Foo" key in json data.' } data = {"refresh_token": refresh_token} response = await test_client.post("/refresh", json=data) assert response.status_code == 401 assert await response.get_json() == { "msg": 'Missing "Bar" key in json data.' } # Ensure new keys do work data = {"Foo": access_token} response = await test_client.post("/protected", json=data) assert response.status_code == 200 assert await response.get_json() == {"foo": "bar"} data = {"Bar": refresh_token} response = await test_client.post("/refresh", json=data) assert response.status_code == 200 assert await response.get_json() == {"foo": "bar"}
async def test_never_expire_token(app): async with app.test_request_context("/protected"): access_token = create_access_token("username", expires_delta=False) refresh_token = create_refresh_token("username", expires_delta=False) for token in (access_token, refresh_token): decoded = decode_token(token) assert "exp" not in decoded
async def post(cls): get_user_details = await request.get_json() try: user = login_schema.load(get_user_details) except ValidationError as err: return err.messages, 400 get_user_from_db = await UserModel.find_user_by_email( get_user_details['email']) if get_user_from_db and psw.check_password_hash( get_user_from_db.password, user['password']): confirmation = get_user_from_db.recent_confirmation if confirmation and confirmation.confirmed: access_token = create_access_token( identity=get_user_from_db.email, fresh=True) refresh_token = create_refresh_token(get_user_from_db.email) return { "Access_Token": access_token, "Refresh_Token": refresh_token }, 200 return { "message": NOT_ACTIVATED.format(get_user_from_db.email) }, 400 return {"message": INCORRECT_EMAIL_OR_PASSWORD}, 400
async def test_jwt_headers(app): jwt_header = {"foo": "bar"} async with app.test_request_context("/protected"): access_token = create_access_token("username", headers=jwt_header) refresh_token = create_refresh_token("username", headers=jwt_header) assert get_unverified_jwt_headers(access_token)["foo"] == "bar" assert get_unverified_jwt_headers(refresh_token)["foo"] == "bar"
async def test_jwt_header_in_refresh_token_specified_at_creation(app): async with app.test_request_context("/protected"): refresh_token = create_refresh_token("username", headers={"foo": "bar"}) 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
async def test_allow_expired_token(app, delta_func): async with app.test_request_context("/protected"): delta = delta_func(minutes=-5) access_token = create_access_token("username", expires_delta=delta) refresh_token = create_refresh_token("username", expires_delta=delta) for token in (access_token, refresh_token): decoded = decode_token(token, allow_expired=True) assert decoded["identity"] == "username" assert "exp" in decoded
async def test_expired_token(app, delta_func): async with app.test_request_context("/protected"): delta = delta_func(minutes=-5) access_token = create_access_token("username", expires_delta=delta) refresh_token = create_refresh_token("username", expires_delta=delta) with pytest.raises(ExpiredSignatureError): decode_token(access_token) with pytest.raises(ExpiredSignatureError): decode_token(refresh_token)
async def login(): username = (await request.get_json()).get("username", None) password = (await request.get_json()).get("password", None) if username != "test" or password != "test": return {"msg": "Bad username or password"}, 401 ret = { "access_token": create_access_token(identity=username), "refresh_token": create_refresh_token(identity=username), } return ret, 200
async def test_user_claim_in_refresh_token_specified_at_creation(app): app.config["JWT_CLAIMS_IN_REFRESH_TOKEN"] = True async with app.test_request_context("/protected"): refresh_token = create_refresh_token("username", user_claims={"foo": "bar"}) test_client = app.test_client() response = await test_client.get("/protected2", headers=make_headers(refresh_token)) assert await response.get_json() == {"foo": "bar"} assert response.status_code == 200
async def test_fresh_jwt_required(app): jwtM = get_jwt_manager(app) url = "/fresh_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") 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 = await test_client.get(url, headers=make_headers(fresh_access_token)) assert response.status_code == 200 assert await response.get_json() == {"foo": "bar"} response = await test_client.get(url, headers=make_headers(access_token)) assert response.status_code == 401 assert await response.get_json() == {"msg": "Fresh token required"} response = await test_client.get( url, headers=make_headers(fresh_timed_access_token)) assert response.status_code == 200 assert await response.get_json() == {"foo": "bar"} response = await test_client.get( url, headers=make_headers(stale_timed_access_token)) assert response.status_code == 401 assert await response.get_json() == {"msg": "Fresh token required"} 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 == 422 assert await response.get_json() == { "msg": "Only access tokens are allowed" } # Test with custom response @jwtM.needs_fresh_token_loader def custom_response(): return jsonify(msg="foobar"), 201 response = await test_client.get(url, headers=make_headers(access_token)) assert response.status_code == 201 assert await response.get_json() == {"msg": "foobar"}
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
async def login(): username = (await request.get_json()).get("username", None) password = (await request.get_json()).get("password", None) if username != "test" or password != "test": return {"login": False}, 401 # Create the tokens we will be sending back to the user access_token = create_access_token(identity=username) refresh_token = create_refresh_token(identity=username) # Set the JWT cookies in the response resp = {"login": True} set_access_cookies(resp, access_token) set_refresh_cookies(resp, refresh_token) return resp, 200
async def login(): username = (await request.get_json()).get("username", None) password = (await request.get_json()).get("password", None) if username != "test" or password != "test": return {"msg": "Bad username or password"}, 401 # create_access_token supports an optional 'fresh' argument, # which marks the token as fresh or non-fresh accordingly. # As we just verified their username and password, we are # going to mark the token as fresh here. ret = { "access_token": create_access_token(identity=username, fresh=True), "refresh_token": create_refresh_token(identity=username), } return ret, 200
async 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"} 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() == {"foo": "bar"} assert response.status_code == 200
async def test_defaults(app): test_client = app.test_client() async with app.test_request_context("/protected"): access_token = create_access_token("username") refresh_token = create_refresh_token("username") data = {"access_token": access_token} response = await test_client.post("/protected", json=data) assert response.status_code == 200 assert await response.get_json() == {"foo": "bar"} data = {"refresh_token": refresh_token} response = await test_client.post("/refresh", json=data) assert response.status_code == 200 assert await response.get_json() == {"foo": "bar"}
async def test_blacklisted_refresh_token(app, blacklist_type): jwt = get_jwt_manager(app) app.config["JWT_BLACKLIST_TOKEN_CHECKS"] = blacklist_type @jwt.token_in_blacklist_loader def check_blacklisted(decrypted_token): return True async with app.test_request_context("/protected"): refresh_token = create_refresh_token("username") test_client = app.test_client() response = await test_client.get("/refresh_protected", headers=make_headers(refresh_token)) assert await response.get_json() == {"msg": "Token has been revoked"} assert response.status_code == 401
async def test_content_type(app): test_client = app.test_client() async with app.test_request_context("/protected"): access_token = create_access_token("username") refresh_token = create_refresh_token("username") data = {"access_token": access_token} response = await test_client.post("/protected", data=data) expected_json = {"msg": "Invalid content-type. Must be application/json."} assert response.status_code == 401 assert await response.get_json() == expected_json data = {"refresh_token": refresh_token} response = await test_client.post("/refresh", data=data) expected_json = {"msg": "Invalid content-type. Must be application/json."} assert response.status_code == 401 assert await response.get_json() == expected_json
async def login(): username = (await request.get_json()).get("username", None) password = (await request.get_json()).get("password", None) if username != "test" or password != "test": return {"msg": "Bad username or password"}, 401 # Create our JWTs access_token = create_access_token(identity=username) refresh_token = create_refresh_token(identity=username) # Store the tokens in redis with a status of not currently revoked. We # can use the `get_jti()` method to get the unique identifier string for # each token. We can also set an expires time on these tokens in redis, # so they will get automatically removed after they expire. We will set # everything to be automatically removed shortly after the token expires access_jti = get_jti(encoded_token=access_token) refresh_jti = get_jti(encoded_token=refresh_token) revoked_store.set(access_jti, "false", ACCESS_EXPIRES * 1.2) revoked_store.set(refresh_jti, "false", REFRESH_EXPIRES * 1.2) ret = {"access_token": access_token, "refresh_token": refresh_token} return ret, 201
async 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 async with app.test_request_context("/protected"): access_token = create_access_token("username") refresh_token = create_refresh_token("username") app.config["JWT_BLACKLIST_TOKEN_CHECKS"] = ["access"] response = await test_client.get("/refresh_protected", headers=make_headers(refresh_token)) assert await response.get_json() == {"foo": "bar"} assert response.status_code == 200 app.config["JWT_BLACKLIST_TOKEN_CHECKS"] = ["refresh"] response = await test_client.get("/protected", headers=make_headers(access_token)) assert await response.get_json() == {"foo": "bar"} assert response.status_code == 200
async def refresh_token(): resp = jsonify(login=True) refresh_token = create_refresh_token("username") set_refresh_cookies(resp, refresh_token) return resp