diff --git a/CHANGELOG.md b/CHANGELOG.md index 942d5c08b..e4fd0d6c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - #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 +- #1435, Add request.method and request.path GUCs - @steve-chavez ### Fixed diff --git a/src/PostgREST/ApiRequest.hs b/src/PostgREST/ApiRequest.hs index 9515f187e..a5ed551cd 100644 --- a/src/PostgREST/ApiRequest.hs +++ b/src/PostgREST/ApiRequest.hs @@ -94,6 +94,8 @@ data ApiRequest = ApiRequest { , iJWT :: Text -- ^ JSON Web Token , iHeaders :: [(Text, Text)] -- ^ HTTP request headers , iCookies :: [(Text, Text)] -- ^ Request Cookies + , iPath :: ByteString -- ^ Raw request path + , iMethod :: ByteString -- ^ Raw request method } -- | Examines HTTP request and translates it into user intent. @@ -133,6 +135,8 @@ userApiRequest schema rootSpec req reqBody , iJWT = tokenStr , iHeaders = [ (toS $ CI.foldedCase k, toS v) | (k,v) <- hdrs, k /= hCookie] , iCookies = maybe [] parseCookiesText $ lookupHeader "Cookie" + , iPath = rawPathInfo req + , iMethod = method } where -- queryString with '+' converted to ' '(space) diff --git a/src/PostgREST/Middleware.hs b/src/PostgREST/Middleware.hs index bcb864050..89dc46493 100644 --- a/src/PostgREST/Middleware.hs +++ b/src/PostgREST/Middleware.hs @@ -38,10 +38,12 @@ runWithClaims conf eClaims app req = JWTInvalid JWTExpired -> return . errorResponseFor . JwtTokenInvalid $ "JWT expired" JWTInvalid e -> return . errorResponseFor . JwtTokenInvalid . show $ e JWTClaims claims -> do - H.sql $ toS . mconcat $ setSearchPathSql : setRoleSql ++ claimsSql ++ headersSql ++ cookiesSql ++ appSettingsSql + H.sql $ toS . mconcat $ setSearchPathSql : setRoleSql ++ claimsSql ++ [methodSql, pathSql] ++ headersSql ++ cookiesSql ++ appSettingsSql mapM_ H.sql customReqCheck app req where + methodSql = setLocalQuery mempty ("request.method", toS $ iMethod req) + pathSql = setLocalQuery mempty ("request.path", toS $ iPath req) headersSql = setLocalQuery "request.header." <$> iHeaders req cookiesSql = setLocalQuery "request.cookie." <$> iCookies req claimsSql = setLocalQuery "request.jwt.claim." <$> [(c,unquoted v) | (c,v) <- M.toList claimsWithRole] diff --git a/test/Feature/RpcSpec.hs b/test/Feature/RpcSpec.hs index e04e5ab35..0fdb5aec1 100644 --- a/test/Feature/RpcSpec.hs +++ b/test/Feature/RpcSpec.hs @@ -557,7 +557,7 @@ spec actualPgVersion = { matchStatus = 200 , matchHeaders = [ matchContentTypeJson ] } - it "allows getting the Authorization value" $ + it "gets the Authorization value" $ request methodPost "/rpc/get_guc_value" [authHeaderJWT "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoicG9zdGdyZXN0X3Rlc3RfYXV0aG9yIn0.Xod-F15qsGL0WhdOCr2j3DdKuTw9QJERVgoFD3vGaWA"] [json| {"name":"request.header.authorization"} |] `shouldRespondWith` @@ -565,6 +565,22 @@ spec actualPgVersion = { matchStatus = 200 , matchHeaders = [] } + it "gets the http method" $ + request methodPost "/rpc/get_guc_value" [] + [json| {"name":"request.method"} |] + `shouldRespondWith` + [str|"POST"|] + { matchStatus = 200 + , matchHeaders = [] + } + it "gets the http path" $ + request methodPost "/rpc/get_guc_value" [] + [json| {"name":"request.path"} |] + `shouldRespondWith` + [str|"/rpc/get_guc_value"|] + { matchStatus = 200 + , matchHeaders = [] + } context "binary output" $ do context "Proc that returns scalar" $ do