From 16dac48f0c50fa4536b454895069a9721a56852d Mon Sep 17 00:00:00 2001 From: Tom Harding Date: Fri, 3 Mar 2023 16:44:44 +0000 Subject: [PATCH] chore(server): Factor out logical model metadata existence check PR-URL: https://github.com/hasura/graphql-engine-mono/pull/8187 GitOrigin-RevId: c18b593c8dec68b655af369e83756c37a36f53f1 --- .../Test/API/Metadata/LogicalModelsSpec.hs | 33 ++++++++++++-- server/src-lib/Hasura/LogicalModel/API.hs | 45 +++++++++---------- 2 files changed, 51 insertions(+), 27 deletions(-) diff --git a/server/lib/api-tests/src/Test/API/Metadata/LogicalModelsSpec.hs b/server/lib/api-tests/src/Test/API/Metadata/LogicalModelsSpec.hs index 96e46d5427c..e5b2adfc79d 100644 --- a/server/lib/api-tests/src/Test/API/Metadata/LogicalModelsSpec.hs +++ b/server/lib/api-tests/src/Test/API/Metadata/LogicalModelsSpec.hs @@ -433,7 +433,7 @@ tests opts = do ) [yaml| code: not-found - error: "Logical model 'some_logical_model' not found in source 'postgres'." + error: "Logical model \"some_logical_model\" not found in source \"postgres\"." path: "$.args" |] @@ -589,7 +589,32 @@ tests opts = do type: integer |] - describe "Permissions" do + it "Fails to adds a select permission to a nonexisting source" $ \testEnv -> do + shouldReturnYaml + opts + ( GraphqlEngine.postMetadataWithStatus + 400 + testEnv + [yaml| + type: bulk + args: + - type: pg_create_logical_model_select_permission + args: + source: made_up_source + root_field_name: made_up_logical_model + role: "test" + permission: + columns: + - divided + filter: {} + |] + ) + [yaml| + code: not-found + error: "Source \"made_up_source\" not found." + path: "$.args[0].args" + |] + it "Fails to adds a select permission to a nonexisting logical model" $ \testEnv -> do shouldReturnYaml opts @@ -611,8 +636,8 @@ tests opts = do |] ) [yaml| - code: not-exists - error: "Logical model \"made_up_logical_model\" does not exist in source: postgres" + code: "not-found" + error: "Logical model \"made_up_logical_model\" not found in source \"postgres\"." path: "$.args[0].args" |] diff --git a/server/src-lib/Hasura/LogicalModel/API.hs b/server/src-lib/Hasura/LogicalModel/API.hs index 721ef7b88be..bd94ca2c16d 100644 --- a/server/src-lib/Hasura/LogicalModel/API.hs +++ b/server/src-lib/Hasura/LogicalModel/API.hs @@ -40,7 +40,6 @@ import Hasura.SQL.AnyBackend qualified as AB import Hasura.SQL.Backend import Hasura.Server.Init.FeatureFlag as FF import Hasura.Server.Types (HasServerConfigCtx (..), ServerConfigCtx (..)) -import Language.GraphQL.Draft.Syntax (unName) -- | Default implementation of the 'track_logical_model' request payload. data TrackLogicalModel (b :: BackendType) = TrackLogicalModel @@ -236,16 +235,7 @@ runUntrackLogicalModel :: m EncJSON runUntrackLogicalModel q = do throwIfFeatureDisabled - - -- Check source exists - sourceMetadata <- - maybe (throw400 NotFound $ "Source " <> sourceNameToText source <> " not found.") pure - . preview (metaSources . ix source . toSourceMetadata @b) - =<< getMetadata - - -- Check the logical model exists - unless (any ((== fieldName) . _lmmRootFieldName) $ _smLogicalModels sourceMetadata) do - throw400 NotFound $ "Logical model '" <> unName (getLogicalModelName fieldName) <> "' not found in source '" <> sourceNameToText source <> "'." + assertLogicalModelExists @b source fieldName let metadataObj = MOSourceObjId source $ @@ -261,7 +251,7 @@ runUntrackLogicalModel q = do fieldName = utlmRootFieldName q dropLogicalModelInMetadata :: forall b. BackendMetadata b => SourceName -> LogicalModelName -> MetadataModifier -dropLogicalModelInMetadata source rootFieldName = +dropLogicalModelInMetadata source rootFieldName = do MetadataModifier $ metaSources . ix source . toSourceMetadata @b . smLogicalModels %~ OMap.delete rootFieldName @@ -303,17 +293,7 @@ runCreateSelectLogicalModelPermission :: m EncJSON runCreateSelectLogicalModelPermission CreateLogicalModelPermission {..} = do throwIfFeatureDisabled - - metadata <- getMetadata - - let existingLogicalModel :: Traversal' Metadata (LogicalModelMetadata b) - existingLogicalModel = metaSources . ix clmpSource . toSourceMetadata . smLogicalModels @b . ix clmpRootFieldName - - unless (has existingLogicalModel metadata) do - throw400 NotExists $ - "Logical model " - <> clmpRootFieldName <<> " does not exist in source: " - <> sourceNameToText clmpSource + assertLogicalModelExists @b clmpSource clmpRootFieldName let metadataObj :: MetadataObjId metadataObj = @@ -327,3 +307,22 @@ runCreateSelectLogicalModelPermission CreateLogicalModelPermission {..} = do %~ OMap.insert (_pdRole clmpInfo) clmpInfo pure successMsg + +-- | Check whether a logical model with the given root field name exists for +-- the given source. +assertLogicalModelExists :: forall b m. (Backend b, MetadataM m, MonadError QErr m) => SourceName -> LogicalModelName -> m () +assertLogicalModelExists sourceName rootFieldName = do + metadata <- getMetadata + + let sourceMetadataTraversal :: Traversal' Metadata (SourceMetadata b) + sourceMetadataTraversal = metaSources . ix sourceName . toSourceMetadata @b + + sourceMetadata <- + preview sourceMetadataTraversal metadata + `onNothing` throw400 NotFound ("Source " <> sourceName <<> " not found.") + + let desiredLogicalModel :: Traversal' (SourceMetadata b) (LogicalModelMetadata b) + desiredLogicalModel = smLogicalModels . ix rootFieldName + + unless (has desiredLogicalModel sourceMetadata) do + throw400 NotFound ("Logical model " <> rootFieldName <<> " not found in source " <> sourceName <<> ".")