diff --git a/CHANGELOG.md b/CHANGELOG.md index cc9704165..6717f72a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## Unreleased +### Fixed + +- Fix jwt error returning HTTP status `400` for invalid role by @taimoorzaeem in #3601 + ## [13.0.0] - 2025-05-08 ### Added diff --git a/src/PostgREST/Error.hs b/src/PostgREST/Error.hs index 9335032c4..8724982cd 100644 --- a/src/PostgREST/Error.hs +++ b/src/PostgREST/Error.hs @@ -595,6 +595,10 @@ pgErrorStatus authed (SQL.SessionUsageError (SQL.QueryError _ _ (SQL.ResultError if BS.isSuffixOf "requires a WHERE clause" m then HTTP.status400 -- special case for pg-safeupdate, which we consider as client error else HTTP.status500 -- generic function or view server error, e.g. "more than one row returned by a subquery used as an expression" + "22023" -> -- invalid_parameter_value. Catch nonexistent role error, see https://github.com/PostgREST/postgrest/issues/3601 + if BS.isPrefixOf "role" m && BS.isSuffixOf "does not exist" m + then HTTP.status401 -- role in jwt does not exist + else HTTP.status400 '2':'5':_ -> HTTP.status500 -- invalid tx state '2':'8':_ -> HTTP.status403 -- invalid auth specification '2':'D':_ -> HTTP.status500 -- invalid tx termination diff --git a/test/io/fixtures.yaml b/test/io/fixtures.yaml index ab8d051ab..e0e8f04c5 100644 --- a/test/io/fixtures.yaml +++ b/test/io/fixtures.yaml @@ -212,7 +212,7 @@ jwtaudroleclaims: - key: '.aud[1]' # succeeds the aud claims check, but fail when hits the db data: aud: [postgrest_test_author, postgrest_test_invalid] - expected_status: 400 + expected_status: 401 invalidroleclaimkeys: - 'role.other' diff --git a/test/io/test_io.py b/test/io/test_io.py index 0d8caaeac..1a7eb8f70 100644 --- a/test/io/test_io.py +++ b/test/io/test_io.py @@ -96,8 +96,7 @@ def test_jwt_errors(defaultenv): headers = jwtauthheader({"role": "not_existing"}, SECRET) response = postgrest.session.get("/", headers=headers) - # TODO: Should this return 401? - assert response.status_code == 400 + assert response.status_code == 401 assert response.json()["message"] == 'role "not_existing" does not exist' # -31 seconds, because we allow clock skew of 30 seconds