From b20e1150a59793c43356daf9dcebdec3ea78e015 Mon Sep 17 00:00:00 2001 From: steve-chavez Date: Tue, 14 Jan 2020 14:38:05 -0500 Subject: [PATCH] Add GUC for accessing the Authorization header --- CHANGELOG.md | 1 + src/PostgREST/ApiRequest.hs | 2 +- test/Feature/QuerySpec.hs | 52 -------------------------------- test/Feature/RpcSpec.hs | 60 +++++++++++++++++++++++++++++++++++++ 4 files changed, 62 insertions(+), 53 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a7130c0ea..942d5c08b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - #1378, Add support for `Prefer: count=planned` and `Prefer: count=estimated` on GET /table - @steve-chavez - #1327, Add support for optional query parameter `on_conflict` to upsert with specified keys for POST - @ykst - #1430, Allow specifying the foreign key constraint name(`/source?select=fk_constraint(*)`) to disambiguate an embedding - @steve-chavez +- #1168, Allow access to the Authorization header through the request.header.authorization GUC - @steve-chavez ### Fixed diff --git a/src/PostgREST/ApiRequest.hs b/src/PostgREST/ApiRequest.hs index f8d909cb4..9515f187e 100644 --- a/src/PostgREST/ApiRequest.hs +++ b/src/PostgREST/ApiRequest.hs @@ -131,7 +131,7 @@ userApiRequest schema rootSpec req reqBody . map (join (***) toS . second (fromMaybe BS.empty)) $ qString , iJWT = tokenStr - , iHeaders = [ (toS $ CI.foldedCase k, toS v) | (k,v) <- hdrs, k /= hAuthorization, k /= hCookie] + , iHeaders = [ (toS $ CI.foldedCase k, toS v) | (k,v) <- hdrs, k /= hCookie] , iCookies = maybe [] parseCookiesText $ lookupHeader "Cookie" } where diff --git a/test/Feature/QuerySpec.hs b/test/Feature/QuerySpec.hs index 229cfb917..a5c7ba23a 100644 --- a/test/Feature/QuerySpec.hs +++ b/test/Feature/QuerySpec.hs @@ -768,58 +768,6 @@ spec actualPgVersion = do , matchHeaders = ["Content-Type" <:> "application/octet-stream; charset=utf-8"] } - describe "HTTP request env vars" $ do - it "custom header is set" $ - request methodPost "/rpc/get_guc_value" - [("Custom-Header", "test")] - [json| { "name": "request.header.custom-header" } |] - `shouldRespondWith` - [str|"test"|] - { matchStatus = 200 - , matchHeaders = [ matchContentTypeJson ] - } - it "standard header is set" $ - request methodPost "/rpc/get_guc_value" - [("Origin", "http://example.com")] - [json| { "name": "request.header.origin" } |] - `shouldRespondWith` - [str|"http://example.com"|] - { matchStatus = 200 - , matchHeaders = [ matchContentTypeJson ] - } - it "current role is available as GUC claim" $ - request methodPost "/rpc/get_guc_value" [] - [json| { "name": "request.jwt.claim.role" } |] - `shouldRespondWith` - [str|"postgrest_test_anonymous"|] - { matchStatus = 200 - , matchHeaders = [ matchContentTypeJson ] - } - it "single cookie ends up as claims" $ - request methodPost "/rpc/get_guc_value" [("Cookie","acookie=cookievalue")] - [json| {"name":"request.cookie.acookie"} |] - `shouldRespondWith` - [str|"cookievalue"|] - { matchStatus = 200 - , matchHeaders = [] - } - it "multiple cookies ends up as claims" $ - request methodPost "/rpc/get_guc_value" [("Cookie","acookie=cookievalue;secondcookie=anothervalue")] - [json| {"name":"request.cookie.secondcookie"} |] - `shouldRespondWith` - [str|"anothervalue"|] - { matchStatus = 200 - , matchHeaders = [] - } - it "app settings available" $ - request methodPost "/rpc/get_guc_value" [] - [json| { "name": "app.settings.app_host" } |] - `shouldRespondWith` - [str|"localhost"|] - { matchStatus = 200 - , matchHeaders = [ matchContentTypeJson ] - } - describe "values with quotes in IN and NOT IN" $ do it "succeeds when only quoted values are present" $ do get "/w_or_wo_comma_names?name=in.(\"Hebdon, John\")" `shouldRespondWith` diff --git a/test/Feature/RpcSpec.hs b/test/Feature/RpcSpec.hs index a4c0c61a1..e04e5ab35 100644 --- a/test/Feature/RpcSpec.hs +++ b/test/Feature/RpcSpec.hs @@ -506,6 +506,66 @@ spec actualPgVersion = {"id":4,"name":"OSX"}] |] { matchHeaders = [matchContentTypeJson] } + context "HTTP request env vars" $ do + it "custom header is set" $ + request methodPost "/rpc/get_guc_value" + [("Custom-Header", "test")] + [json| { "name": "request.header.custom-header" } |] + `shouldRespondWith` + [str|"test"|] + { matchStatus = 200 + , matchHeaders = [ matchContentTypeJson ] + } + it "standard header is set" $ + request methodPost "/rpc/get_guc_value" + [("Origin", "http://example.com")] + [json| { "name": "request.header.origin" } |] + `shouldRespondWith` + [str|"http://example.com"|] + { matchStatus = 200 + , matchHeaders = [ matchContentTypeJson ] + } + it "current role is available as GUC claim" $ + request methodPost "/rpc/get_guc_value" [] + [json| { "name": "request.jwt.claim.role" } |] + `shouldRespondWith` + [str|"postgrest_test_anonymous"|] + { matchStatus = 200 + , matchHeaders = [ matchContentTypeJson ] + } + it "single cookie ends up as claims" $ + request methodPost "/rpc/get_guc_value" [("Cookie","acookie=cookievalue")] + [json| {"name":"request.cookie.acookie"} |] + `shouldRespondWith` + [str|"cookievalue"|] + { matchStatus = 200 + , matchHeaders = [] + } + it "multiple cookies ends up as claims" $ + request methodPost "/rpc/get_guc_value" [("Cookie","acookie=cookievalue;secondcookie=anothervalue")] + [json| {"name":"request.cookie.secondcookie"} |] + `shouldRespondWith` + [str|"anothervalue"|] + { matchStatus = 200 + , matchHeaders = [] + } + it "app settings available" $ + request methodPost "/rpc/get_guc_value" [] + [json| { "name": "app.settings.app_host" } |] + `shouldRespondWith` + [str|"localhost"|] + { matchStatus = 200 + , matchHeaders = [ matchContentTypeJson ] + } + it "allows getting the Authorization value" $ + request methodPost "/rpc/get_guc_value" [authHeaderJWT "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoicG9zdGdyZXN0X3Rlc3RfYXV0aG9yIn0.Xod-F15qsGL0WhdOCr2j3DdKuTw9QJERVgoFD3vGaWA"] + [json| {"name":"request.header.authorization"} |] + `shouldRespondWith` + [str|"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoicG9zdGdyZXN0X3Rlc3RfYXV0aG9yIn0.Xod-F15qsGL0WhdOCr2j3DdKuTw9QJERVgoFD3vGaWA"|] + { matchStatus = 200 + , matchHeaders = [] + } + context "binary output" $ do context "Proc that returns scalar" $ do it "can query without selecting column" $