fix: improve jwt errors
This commit is contained in:
committed by
Steve Chavez
parent
4819520e3a
commit
36b6a2c86b
+38
-9
@@ -92,7 +92,7 @@ def test_jwt_errors(defaultenv):
|
||||
headers = jwtauthheader({}, "other secret")
|
||||
response = postgrest.session.get("/", headers=headers)
|
||||
assert response.status_code == 401
|
||||
assert response.json()["message"] == "JWSError JWSInvalidSignature"
|
||||
assert response.json()["message"] == "No suitable key or wrong key type"
|
||||
|
||||
headers = jwtauthheader({"role": "not_existing"}, SECRET)
|
||||
response = postgrest.session.get("/", headers=headers)
|
||||
@@ -110,27 +110,30 @@ def test_jwt_errors(defaultenv):
|
||||
headers = jwtauthheader({"nbf": relativeSeconds(31)}, SECRET)
|
||||
response = postgrest.session.get("/", headers=headers)
|
||||
assert response.status_code == 401
|
||||
assert response.json()["message"] == "JWTNotYetValid"
|
||||
assert response.json()["message"] == "JWT not yet valid"
|
||||
|
||||
# 31 seconds, because we allow clock skew of 30 seconds
|
||||
headers = jwtauthheader({"iat": relativeSeconds(31)}, SECRET)
|
||||
response = postgrest.session.get("/", headers=headers)
|
||||
assert response.status_code == 401
|
||||
assert response.json()["message"] == "JWTIssuedAtFuture"
|
||||
assert response.json()["message"] == "JWT issued at future"
|
||||
|
||||
headers = jwtauthheader({"aud": "not set"}, SECRET)
|
||||
response = postgrest.session.get("/", headers=headers)
|
||||
assert response.status_code == 401
|
||||
assert response.json()["message"] == "JWTNotInAudience"
|
||||
assert response.json()["message"] == "JWT not in audience"
|
||||
|
||||
# partial token, no signature
|
||||
headers = authheader("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.bm90IGFuIG9iamVjdA")
|
||||
response = postgrest.session.get("/", headers=headers)
|
||||
assert response.status_code == 401
|
||||
assert (
|
||||
response.json()["message"]
|
||||
== "JWSError (CompactDecodeError Invalid number of parts: Expected 3 parts; got 2)"
|
||||
)
|
||||
assert response.json()["message"] == "Expected 3 parts in JWT; got 2"
|
||||
|
||||
# complete token but random characters
|
||||
headers = authheader("quifquirndsjagnrgniur.fonvoienqhhdj.iuqvnvhojah")
|
||||
response = postgrest.session.get("/", headers=headers)
|
||||
assert response.status_code == 401
|
||||
assert response.json()["message"] == "JWT cryptographic operation failed"
|
||||
|
||||
# token with algorithm "none"
|
||||
headers = authheader(
|
||||
@@ -138,7 +141,33 @@ def test_jwt_errors(defaultenv):
|
||||
)
|
||||
response = postgrest.session.get("/", headers=headers)
|
||||
assert response.status_code == 401
|
||||
assert response.json()["message"] == "JWSError JWSNoSignatures"
|
||||
assert response.json()["message"] == "Wrong or unsupported encoding algorithm"
|
||||
|
||||
env = {
|
||||
**defaultenv,
|
||||
"PGRST_SERVER_TIMING_ENABLED": "true",
|
||||
"PGRST_JWT_CACHE_MAX_LIFETIME": "86400",
|
||||
"PGRST_JWT_SECRET": SECRET,
|
||||
}
|
||||
|
||||
# for code coverage with cache enabled and server-timing enabled
|
||||
with run(env=env) as postgrest:
|
||||
response = postgrest.session.get("/authors_only")
|
||||
assert response.status_code == 401
|
||||
assert response.json()["message"] == "permission denied for table authors_only"
|
||||
|
||||
env = {
|
||||
**defaultenv,
|
||||
"PGRST_SERVER_TIMING_ENABLED": "false",
|
||||
"PGRST_JWT_CACHE_MAX_LIFETIME": "86400",
|
||||
"PGRST_JWT_SECRET": SECRET,
|
||||
}
|
||||
|
||||
# for code coverage with cache enabled and server-timing disabled
|
||||
with run(env=env) as postgrest:
|
||||
response = postgrest.session.get("/authors_only")
|
||||
assert response.status_code == 401
|
||||
assert response.json()["message"] == "permission denied for table authors_only"
|
||||
|
||||
|
||||
def test_fail_with_invalid_password(defaultenv):
|
||||
|
||||
@@ -85,10 +85,21 @@ spec = describe "authorization" $ do
|
||||
request methodGet "/authors_only" [auth] ""
|
||||
`shouldRespondWith` 200
|
||||
|
||||
it "fails when auth header is sent empty" $ do
|
||||
let auth = authHeaderJWT ""
|
||||
request methodGet "/authors_only" [auth] ""
|
||||
`shouldRespondWith` [json| {"message":"Empty JWT is sent in Authorization header","code":"PGRST301","hint":null,"details":null} |]
|
||||
{ matchStatus = 401
|
||||
, matchHeaders = [
|
||||
"WWW-Authenticate" <:>
|
||||
"Bearer error=\"invalid_token\", error_description=\"Empty JWT is sent in Authorization header\""
|
||||
]
|
||||
}
|
||||
|
||||
it "fails with an expired token" $ do
|
||||
let auth = authHeaderJWT "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0NDY2NzgxNDksInJvbGUiOiJwb3N0Z3Jlc3RfdGVzdF9hdXRob3IiLCJpZCI6Impkb2UifQ.f8__E6VQwYcDqwHmr9PG03uaZn8Zh1b0vbJ9DYS0AdM"
|
||||
request methodGet "/authors_only" [auth] ""
|
||||
`shouldRespondWith` [json| {"message":"JWT expired","code":"PGRST301","hint":null,"details":null} |]
|
||||
`shouldRespondWith` [json| {"message":"JWT expired","code":"PGRST303","hint":null,"details":null} |]
|
||||
{ matchStatus = 401
|
||||
, matchHeaders = [
|
||||
"WWW-Authenticate" <:>
|
||||
@@ -99,11 +110,11 @@ spec = describe "authorization" $ do
|
||||
it "hides tables from users with invalid JWT" $ do
|
||||
let auth = authHeaderJWT "ey9zdGdyZXN0X3Rlc3RfYXV0aG9yIiwiaWQiOiJqZG9lIn0.y4vZuu1dDdwAl0-S00MCRWRYMlJ5YAMSir6Es6WtWx0"
|
||||
request methodGet "/authors_only" [auth] ""
|
||||
`shouldRespondWith` [json| {"message":"JWSError (CompactDecodeError Invalid number of parts: Expected 3 parts; got 2)","code":"PGRST301","hint":null,"details":null} |]
|
||||
`shouldRespondWith` [json| {"message":"Expected 3 parts in JWT; got 2","code":"PGRST301","hint":null,"details":null} |]
|
||||
{ matchStatus = 401
|
||||
, matchHeaders = [
|
||||
"WWW-Authenticate" <:>
|
||||
"Bearer error=\"invalid_token\", error_description=\"JWSError (CompactDecodeError Invalid number of parts: Expected 3 parts; got 2)\""
|
||||
"Bearer error=\"invalid_token\", error_description=\"Expected 3 parts in JWT; got 2\""
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user