diff --git a/CHANGELOG.md b/CHANGELOG.md index 60e7dd06a..1087bff91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Fixed - Fix OpenAPI broken docs link by @taimoorzaeem in #4080 +- Fix OpenAPI specification incorrectly exposing GET methods for volatile functions by @joelonsql in #4174 ## [13.0.4] - 2025-06-17 diff --git a/src/PostgREST/Response/OpenAPI.hs b/src/PostgREST/Response/OpenAPI.hs index fe40e3c0f..9ca526932 100644 --- a/src/PostgREST/Response/OpenAPI.hs +++ b/src/PostgREST/Response/OpenAPI.hs @@ -30,7 +30,8 @@ import PostgREST.SchemaCache.Identifiers (QualifiedIdentifier (..)) import PostgREST.SchemaCache.Relationship (Cardinality (..), Relationship (..), RelationshipsMap) -import PostgREST.SchemaCache.Routine (Routine (..), +import PostgREST.SchemaCache.Routine (FuncVolatility (..), + Routine (..), RoutineParam (..)) import PostgREST.SchemaCache.Table (Column (..), Table (..), TablesMap, @@ -355,9 +356,9 @@ makeProcPathItem pd = ("/rpc/" ++ toS (pdName pd), pe) & parameters .~ makeProcGetParams (pdParams pd) postOp = procOp & parameters .~ makeProcPostParams pd - pe = (mempty :: PathItem) - & get ?~ getOp - & post ?~ postOp + pe = case pdVolatility pd of + Volatile -> (mempty :: PathItem) & post ?~ postOp + _ -> (mempty :: PathItem) & get ?~ getOp & post ?~ postOp makeRootPathItem :: (FilePath, PathItem) makeRootPathItem = ("/", p) diff --git a/test/spec/Feature/OpenApi/OpenApiSpec.hs b/test/spec/Feature/OpenApi/OpenApiSpec.hs index fbe227a32..c035bbe7b 100644 --- a/test/spec/Feature/OpenApi/OpenApiSpec.hs +++ b/test/spec/Feature/OpenApi/OpenApiSpec.hs @@ -1058,6 +1058,33 @@ spec = describe "OpenAPI" $ do } |] + it "only includes POST method for volatile functions" $ do + r <- simpleBody <$> get "/" + let volatileGet = r ^? key "paths" . key "/rpc/reset_table" . key "get" + volatilePost = r ^? key "paths" . key "/rpc/reset_table" . key "post" + + liftIO $ do + volatileGet `shouldBe` Nothing + volatilePost `shouldNotBe` Nothing + + it "includes GET and POST methods for stable functions" $ do + r <- simpleBody <$> get "/" + let stableGet = r ^? key "paths" . key "/rpc/getallusers" . key "get" + stablePost = r ^? key "paths" . key "/rpc/getallusers" . key "post" + + liftIO $ do + stableGet `shouldNotBe` Nothing + stablePost `shouldNotBe` Nothing + + it "includes GET and POST methods for immutable functions" $ do + r <- simpleBody <$> get "/" + let immutableGet = r ^? key "paths" . key "/rpc/jwt_test" . key "get" + immutablePost = r ^? key "paths" . key "/rpc/jwt_test" . key "post" + + liftIO $ do + immutableGet `shouldNotBe` Nothing + immutablePost `shouldNotBe` Nothing + describe "Security" $ it "does not include security or security definitions by default" $ do r <- simpleBody <$> get "/"