async def test_bad_token_type(app, default_access_token): default_access_token["type"] = "banana" bad_type_token = await encode_token(app, default_access_token) with pytest.raises(JWTDecodeError): async with app.test_request_context("/protected"): decode_token(bad_type_token)
async def test_missing_claims(app, default_access_token, missing_claims): del default_access_token[missing_claims] missing_jwt_token = await encode_token(app, default_access_token) with pytest.raises(JWTDecodeError): async with app.test_request_context("/protected"): decode_token(missing_jwt_token, csrf_value="abcd")
async def test_invalid_aud(app, default_access_token, token_aud): app.config["JWT_DECODE_AUDIENCE"] = "foo" default_access_token["aud"] = token_aud invalid_token = await encode_token(app, default_access_token) with pytest.raises(InvalidAudienceError): async with app.test_request_context("/protected"): decode_token(invalid_token)
async def test_mismatch_iss(app, default_access_token): app.config["JWT_ENCODE_ISSUER"] = "foobar" app.config["JWT_DECODE_ISSUER"] = "baz" with pytest.raises(InvalidIssuerError): async with app.test_request_context("/protected"): invalid_token = create_access_token("username") decode_token(invalid_token)
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 test_invalid_decode_iss(app, default_access_token): app.config["JWT_DECODE_ISSUER"] = "baz" default_access_token["iss"] = "foobar" invalid_token = await encode_token(app, default_access_token) with pytest.raises(InvalidIssuerError): async with app.test_request_context("/protected"): decode_token(invalid_token)
async def test_nbf_token_in_future(app, patch_datetime_now): with pytest.raises(ImmatureSignatureError): async with app.test_request_context("/protected"): access_token = create_access_token("username") decode_token(access_token) async with app.test_request_context("/protected"): app.config["JWT_DECODE_LEEWAY"] = 30 access_token = create_access_token("username") decode_token(access_token)
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_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 test_encode_iss(app, default_access_token): app.config["JWT_ENCODE_ISSUER"] = "foobar" async with app.test_request_context("/protected"): access_token = create_access_token("username") decoded = decode_token(access_token) assert decoded["iss"] == "foobar"
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_alternate_identity_claim(app, default_access_token): app.config["JWT_IDENTITY_CLAIM"] = "sub" # Insure decoding fails if the claim isn't there token = await encode_token(app, default_access_token) with pytest.raises(JWTDecodeError): async with app.test_request_context("/protected"): decode_token(token) # Insure the claim exists in the decoded jwt del default_access_token["identity"] default_access_token["sub"] = "username" token = await encode_token(app, default_access_token) async with app.test_request_context("/protected"): decoded = decode_token(token) assert "sub" in decoded assert "identity" not in decoded
async def test_valid_aud(app, default_access_token, token_aud): app.config["JWT_DECODE_AUDIENCE"] = ["foo", "bar"] default_access_token["aud"] = token_aud valid_token = await encode_token(app, default_access_token) async with app.test_request_context("/protected"): decoded = decode_token(valid_token) assert decoded["aud"] == token_aud
async def test_legacy_decode_key_callback(app, default_access_token): jwtM = get_jwt_manager(app) app.config["JWT_SECRET_KEY"] = "foobarbaz" # test decode key callback with one argument (backwards compatibility) with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") @jwtM.decode_key_loader def get_decode_key_legacy(claims): return "foobarbaz" async with app.test_request_context("/protected"): token = await encode_token(app, default_access_token) decode_token(token) assert len(w) == 1 assert issubclass(w[-1].category, DeprecationWarning)
async def test_valid_decode_iss(app, default_access_token): app.config["JWT_DECODE_ISSUER"] = "foobar" default_access_token["iss"] = "foobar" valid_token = await encode_token(app, default_access_token) async with app.test_request_context("/protected"): decoded = decode_token(valid_token) assert decoded["iss"] == "foobar"
async def ws(room_id: str): room = None for existing in rooms: if existing.id == room_id: room = existing break else: room = await Room.from_id(room_id) if room is None: return {"status": 404, "error": "Invalid room ID."}, 404 rooms.append(room) local_socket = websocket._get_current_object() cookie_string = local_socket.headers.get("Cookie", "") cookie = SimpleCookie() cookie.load(cookie_string) cookies = {} for key, morsel in cookie.items(): cookies[key] = morsel.value user_info = None try: decoded = decode_token(cookies["access_token_cookie"]) except Exception: user_info = { "identity": str(uuid.uuid4()), "name": "Guest" } else: name = decoded["user_claims"]["name"] identity = decoded["identity"] user_info = { "identity": identity, "name": name } local_socket.user_info = user_info await room.add_socket(local_socket) await local_socket.send(json.dumps({ "components": await room.get_components(), "info": await room.get_info(), "user_info": user_info })) try: while True: data = await local_socket.receive() resp = await generate_response(local_socket, room, data) if resp and resp.get("result"): await local_socket.send(json.dumps(resp)) except asyncio.CancelledError: # Client disconnected await room.remove_socket(local_socket) raise
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_default_decode_token_values(app, default_access_token): del default_access_token["type"] del default_access_token["jti"] del default_access_token["fresh"] token = await encode_token(app, default_access_token) async with app.test_request_context("/protected"): decoded = decode_token(token) assert decoded["type"] == "access" assert decoded["jti"] is None assert decoded["fresh"] is False
async def test_no_user_claims(app, user_loader_return): jwtM = get_jwt_manager(app) @jwtM.user_claims_loader def empty_user_loader_return(identity): return user_loader_return # Identity should not be in the actual token, but should be in the data # returned via the decode_token call async with app.test_request_context("/protected"): 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
async def mouse_move(socket, room: Room, token, x: int, y: int): identity = None if isinstance(token, dict): identity = token["identity"] name = token["name"] else: try: decoded = decode_token(str.encode(token)) except Exception as e: name = "Guest" identity = "guest" else: name = decoded["user_claims"]["name"] identity = decoded["identity"] await room.broadcast_except_sender(socket, { "method": "mouse_move", "params": [identity, name, x, y] })
async def test_user_claims_with_different_name(app): jwt = get_jwt_manager(app) app.config["JWT_USER_CLAIMS"] = "banana" @jwt.user_claims_loader def add_claims(identity): return {"foo": "bar"} async with app.test_request_context("/protected"): access_token = create_access_token("username") # Make sure the name is actually different in the token decoded_token = decode_token(access_token) assert decoded_token["banana"] == {"foo": "bar"} # Make sure the correct data is returned to us from the full call test_client = app.test_client() 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 test_malformed_token(app): invalid_token = "foobarbaz" with pytest.raises(DecodeError): async with app.test_request_context("/protected"): decode_token(invalid_token)
async def test_route(): token = create_access_token("username", expires_delta=timedelta(minutes=-1)) decode_token(token) return jsonify(msg="baz"), 200