mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-14 17:02:49 +03:00
chore(server): permissions for inline logical models
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/9835 GitOrigin-RevId: b36a4d5a8e0d4156a2d26803c7d046570f7afefa
This commit is contained in:
parent
5681b2edff
commit
78323ed1a1
@ -726,6 +726,7 @@ library
|
||||
, Hasura.GC
|
||||
|
||||
, Hasura.LogicalModelResolver.Codec
|
||||
, Hasura.LogicalModelResolver.Lenses
|
||||
, Hasura.LogicalModelResolver.Metadata
|
||||
, Hasura.LogicalModelResolver.Schema
|
||||
, Hasura.LogicalModelResolver.Types
|
||||
|
@ -82,7 +82,7 @@ import Hasura.GraphQL.Schema.Parser qualified as P
|
||||
import Hasura.GraphQL.Schema.Typename
|
||||
import Hasura.LogicalModel.Cache (LogicalModelInfo (_lmiPermissions))
|
||||
import Hasura.LogicalModel.Types (LogicalModelName)
|
||||
import Hasura.NativeQuery.Cache (NativeQueryCache, NativeQueryInfo)
|
||||
import Hasura.NativeQuery.Cache (NativeQueryCache, NativeQueryInfo (..))
|
||||
import Hasura.NativeQuery.Types (NativeQueryName)
|
||||
import Hasura.Prelude
|
||||
import Hasura.RQL.IR qualified as IR
|
||||
@ -348,7 +348,10 @@ getTableRoles bsi = AB.dispatchAnyBackend @Backend bsi go
|
||||
getLogicalModelRoles :: BackendSourceInfo -> [RoleName]
|
||||
getLogicalModelRoles bsi = AB.dispatchAnyBackend @Backend bsi go
|
||||
where
|
||||
go si = HashMap.keys . _lmiPermissions =<< HashMap.elems (_siLogicalModels si)
|
||||
go si =
|
||||
let namedLogicalModelRoles = HashMap.keys . _lmiPermissions =<< HashMap.elems (_siLogicalModels si)
|
||||
inlineLogicalModelRoles = HashMap.keys . _lmiPermissions . _nqiReturns =<< HashMap.elems (_siNativeQueries si)
|
||||
in namedLogicalModelRoles <> inlineLogicalModelRoles
|
||||
|
||||
askScalarTypeParsingContext ::
|
||||
forall b r m.
|
||||
|
@ -27,7 +27,10 @@ import Hasura.Base.Error
|
||||
import Hasura.EncJSON
|
||||
import Hasura.LogicalModel.Lenses (lmmSelectPermissions)
|
||||
import Hasura.LogicalModel.Metadata (LogicalModelMetadata (..))
|
||||
import Hasura.LogicalModel.Types (LogicalModelField, LogicalModelName, logicalModelFieldMapCodec)
|
||||
import Hasura.LogicalModel.Types (LogicalModelField, LogicalModelLocation (..), LogicalModelName, logicalModelFieldMapCodec)
|
||||
import Hasura.LogicalModelResolver.Lenses
|
||||
import Hasura.NativeQuery.API (assertNativeQueryExists)
|
||||
import Hasura.NativeQuery.Lenses (nqmReturns)
|
||||
import Hasura.Prelude
|
||||
import Hasura.RQL.Types.Backend (Backend (..))
|
||||
import Hasura.RQL.Types.BackendTag (backendPrefix, backendTag, reify)
|
||||
@ -230,12 +233,22 @@ execUntrackLogicalModel q metadata = do
|
||||
source = utlmSource q
|
||||
fieldName = utlmName q
|
||||
|
||||
-- type for the `type` field in permissions
|
||||
data LogicalModelSource
|
||||
= LMLogicalModel
|
||||
| LMNativeQuery
|
||||
|
||||
instance FromJSON LogicalModelSource where
|
||||
parseJSON (String "logical_model") = pure LMLogicalModel
|
||||
parseJSON (String "native_query") = pure LMNativeQuery
|
||||
parseJSON _ = fail "Expected string"
|
||||
|
||||
-- | A permission for logical models is tied to a specific name and
|
||||
-- source. This wrapper adds both of those things to the JSON object that
|
||||
-- describes the permission.
|
||||
data CreateLogicalModelPermission a (b :: BackendType) = CreateLogicalModelPermission
|
||||
{ clmpSource :: SourceName,
|
||||
clmpName :: LogicalModelName,
|
||||
clmpLocation :: LogicalModelLocation,
|
||||
clmpInfo :: PermDef b a
|
||||
}
|
||||
deriving stock (Generic)
|
||||
@ -246,7 +259,12 @@ instance
|
||||
where
|
||||
parseJSON = withObject "CreateLogicalModelPermission" \obj -> do
|
||||
clmpSource <- obj .:? "source" .!= defaultSource
|
||||
clmpName <- obj .: "name"
|
||||
lmType <- obj .:? "type" .!= LMLogicalModel
|
||||
|
||||
clmpLocation <- case lmType of
|
||||
LMLogicalModel -> LMLLogicalModel <$> obj .: "name"
|
||||
LMNativeQuery -> LMLNativeQuery <$> obj .: "name"
|
||||
|
||||
clmpInfo <- parseJSON (Object obj)
|
||||
|
||||
pure CreateLogicalModelPermission {..}
|
||||
@ -258,19 +276,38 @@ runCreateSelectLogicalModelPermission ::
|
||||
m EncJSON
|
||||
runCreateSelectLogicalModelPermission CreateLogicalModelPermission {..} = do
|
||||
metadata <- getMetadata
|
||||
assertLogicalModelExists @b clmpSource clmpName metadata
|
||||
|
||||
let metadataObj :: MetadataObjId
|
||||
metadataObj =
|
||||
MOSourceObjId clmpSource
|
||||
$ AB.mkAnyBackend
|
||||
$ SMOLogicalModel @b clmpName
|
||||
case clmpLocation of
|
||||
LMLNativeQuery nativeQueryName -> do
|
||||
assertNativeQueryExists @b clmpSource nativeQueryName metadata
|
||||
|
||||
buildSchemaCacheFor metadataObj
|
||||
$ MetadataModifier
|
||||
$ logicalModelMetadataSetter @b clmpSource clmpName
|
||||
. lmmSelectPermissions
|
||||
%~ InsOrdHashMap.insert (_pdRole clmpInfo) clmpInfo
|
||||
let metadataObj :: MetadataObjId
|
||||
metadataObj =
|
||||
MOSourceObjId clmpSource
|
||||
$ AB.mkAnyBackend
|
||||
$ SMONativeQuery @b nativeQueryName
|
||||
|
||||
buildSchemaCacheFor metadataObj
|
||||
$ MetadataModifier
|
||||
$ nativeQueryMetadataSetter @b clmpSource nativeQueryName
|
||||
. nqmReturns
|
||||
. _LMIInlineLogicalModel
|
||||
. ilmmSelectPermissions
|
||||
%~ InsOrdHashMap.insert (_pdRole clmpInfo) clmpInfo
|
||||
LMLLogicalModel logicalModelName -> do
|
||||
assertLogicalModelExists @b clmpSource logicalModelName metadata
|
||||
|
||||
let metadataObj :: MetadataObjId
|
||||
metadataObj =
|
||||
MOSourceObjId clmpSource
|
||||
$ AB.mkAnyBackend
|
||||
$ SMOLogicalModel @b logicalModelName
|
||||
|
||||
buildSchemaCacheFor metadataObj
|
||||
$ MetadataModifier
|
||||
$ logicalModelMetadataSetter @b clmpSource logicalModelName
|
||||
. lmmSelectPermissions
|
||||
%~ InsOrdHashMap.insert (_pdRole clmpInfo) clmpInfo
|
||||
|
||||
pure successMsg
|
||||
|
||||
@ -278,7 +315,7 @@ runCreateSelectLogicalModelPermission CreateLogicalModelPermission {..} = do
|
||||
-- the logical model, as well as the role whose permission we want to drop.
|
||||
data DropLogicalModelPermission (b :: BackendType) = DropLogicalModelPermission
|
||||
{ dlmpSource :: SourceName,
|
||||
dlmpName :: LogicalModelName,
|
||||
dlmpLocation :: LogicalModelLocation,
|
||||
dlmpRole :: RoleName
|
||||
}
|
||||
deriving stock (Generic)
|
||||
@ -286,7 +323,13 @@ data DropLogicalModelPermission (b :: BackendType) = DropLogicalModelPermission
|
||||
instance FromJSON (DropLogicalModelPermission b) where
|
||||
parseJSON = withObject "DropLogicalModelPermission" \obj -> do
|
||||
dlmpSource <- obj .:? "source" .!= defaultSource
|
||||
dlmpName <- obj .: "name"
|
||||
|
||||
lmType <- obj .:? "type" .!= LMLogicalModel
|
||||
|
||||
dlmpLocation <- case lmType of
|
||||
LMLogicalModel -> LMLLogicalModel <$> obj .: "name"
|
||||
LMNativeQuery -> LMLNativeQuery <$> obj .: "name"
|
||||
|
||||
dlmpRole <- obj .: "role"
|
||||
|
||||
pure DropLogicalModelPermission {..}
|
||||
@ -298,19 +341,37 @@ runDropSelectLogicalModelPermission ::
|
||||
m EncJSON
|
||||
runDropSelectLogicalModelPermission DropLogicalModelPermission {..} = do
|
||||
metadata <- getMetadata
|
||||
assertLogicalModelExists @b dlmpSource dlmpName metadata
|
||||
case dlmpLocation of
|
||||
LMLNativeQuery nativeQueryName -> do
|
||||
assertNativeQueryExists @b dlmpSource nativeQueryName metadata
|
||||
|
||||
let metadataObj :: MetadataObjId
|
||||
metadataObj =
|
||||
MOSourceObjId dlmpSource
|
||||
$ AB.mkAnyBackend
|
||||
$ SMOLogicalModel @b dlmpName
|
||||
let metadataObj :: MetadataObjId
|
||||
metadataObj =
|
||||
MOSourceObjId dlmpSource
|
||||
$ AB.mkAnyBackend
|
||||
$ SMONativeQuery @b nativeQueryName
|
||||
|
||||
buildSchemaCacheFor metadataObj
|
||||
$ MetadataModifier
|
||||
$ logicalModelMetadataSetter @b dlmpSource dlmpName
|
||||
. lmmSelectPermissions
|
||||
%~ InsOrdHashMap.delete dlmpRole
|
||||
buildSchemaCacheFor metadataObj
|
||||
$ MetadataModifier
|
||||
$ nativeQueryMetadataSetter @b dlmpSource nativeQueryName
|
||||
. nqmReturns
|
||||
. _LMIInlineLogicalModel
|
||||
. ilmmSelectPermissions
|
||||
%~ InsOrdHashMap.delete dlmpRole
|
||||
LMLLogicalModel logicalModelName -> do
|
||||
assertLogicalModelExists @b dlmpSource logicalModelName metadata
|
||||
|
||||
let metadataObj :: MetadataObjId
|
||||
metadataObj =
|
||||
MOSourceObjId dlmpSource
|
||||
$ AB.mkAnyBackend
|
||||
$ SMOLogicalModel @b logicalModelName
|
||||
|
||||
buildSchemaCacheFor metadataObj
|
||||
$ MetadataModifier
|
||||
$ logicalModelMetadataSetter @b dlmpSource logicalModelName
|
||||
. lmmSelectPermissions
|
||||
%~ InsOrdHashMap.delete dlmpRole
|
||||
|
||||
pure successMsg
|
||||
|
||||
|
@ -9,6 +9,7 @@ module Hasura.LogicalModel.Types
|
||||
LogicalModelTypeArray (..),
|
||||
LogicalModelTypeReference (..),
|
||||
logicalModelFieldMapCodec,
|
||||
LogicalModelLocation (..),
|
||||
)
|
||||
where
|
||||
|
||||
@ -19,8 +20,9 @@ import Autodocodec
|
||||
import Autodocodec qualified as AC
|
||||
import Data.Aeson (FromJSON (..), FromJSONKey, ToJSON (..), ToJSONKey, Value)
|
||||
import Data.HashMap.Strict.InsOrd qualified as InsOrdHashMap
|
||||
import Data.Text.Extended (ToTxt)
|
||||
import Data.Text.Extended (ToTxt (..))
|
||||
import Hasura.Metadata.DTO.Placeholder (placeholderCodecViaJSON)
|
||||
import Hasura.NativeQuery.Types (NativeQueryName)
|
||||
import Hasura.Prelude hiding (first)
|
||||
import Hasura.RQL.Types.Backend (Backend (..))
|
||||
import Hasura.RQL.Types.BackendTag (backendPrefix)
|
||||
@ -317,3 +319,14 @@ logicalModelFieldMapCodec =
|
||||
( fmap snd . InsOrdHashMap.toList
|
||||
)
|
||||
(AC.codec @[LogicalModelField b])
|
||||
|
||||
-- when we are talking about permissions, they might be attached directly to a
|
||||
-- Native Query or similar
|
||||
data LogicalModelLocation
|
||||
= LMLLogicalModel LogicalModelName
|
||||
| LMLNativeQuery NativeQueryName
|
||||
deriving (Eq, Ord, Show, Generic, Hashable)
|
||||
|
||||
instance ToTxt LogicalModelLocation where
|
||||
toTxt (LMLLogicalModel lmn) = toTxt lmn
|
||||
toTxt (LMLNativeQuery nqn) = toTxt nqn
|
||||
|
15
server/src-lib/Hasura/LogicalModelResolver/Lenses.hs
Normal file
15
server/src-lib/Hasura/LogicalModelResolver/Lenses.hs
Normal file
@ -0,0 +1,15 @@
|
||||
{-# LANGUAGE TemplateHaskell #-}
|
||||
|
||||
module Hasura.LogicalModelResolver.Lenses
|
||||
( ilmmFields,
|
||||
ilmmSelectPermissions,
|
||||
_LMIInlineLogicalModel,
|
||||
_LMILogicalModelName,
|
||||
)
|
||||
where
|
||||
|
||||
import Control.Lens (makeLenses, makePrisms)
|
||||
import Hasura.LogicalModelResolver.Metadata (InlineLogicalModelMetadata, LogicalModelIdentifier)
|
||||
|
||||
makeLenses ''InlineLogicalModelMetadata
|
||||
makePrisms ''LogicalModelIdentifier
|
@ -9,6 +9,7 @@ module Hasura.NativeQuery.API
|
||||
execTrackNativeQuery,
|
||||
execUntrackNativeQuery,
|
||||
dropNativeQueryInMetadata,
|
||||
assertNativeQueryExists,
|
||||
module Hasura.NativeQuery.Types,
|
||||
)
|
||||
where
|
||||
|
@ -10,12 +10,14 @@ module Hasura.NativeQuery.Metadata
|
||||
InterpolatedQuery (..),
|
||||
parseInterpolatedQuery,
|
||||
module Hasura.NativeQuery.Types,
|
||||
WithNativeQuery (..),
|
||||
)
|
||||
where
|
||||
|
||||
import Autodocodec
|
||||
import Autodocodec qualified as AC
|
||||
import Data.Aeson (FromJSON, ToJSON)
|
||||
import Data.Aeson (FromJSON (parseJSON), ToJSON, (.!=), (.:), (.:?))
|
||||
import Data.Aeson qualified as J
|
||||
import Data.HashMap.Strict.InsOrd.Autodocodec (sortedElemsCodec)
|
||||
import Data.Text.Extended qualified as T
|
||||
import Hasura.LogicalModelResolver.Metadata (LogicalModelIdentifier)
|
||||
@ -25,7 +27,7 @@ import Hasura.Prelude hiding (first)
|
||||
import Hasura.RQL.Types.Backend
|
||||
import Hasura.RQL.Types.BackendTag (backendPrefix)
|
||||
import Hasura.RQL.Types.BackendType
|
||||
import Hasura.RQL.Types.Common (RelName)
|
||||
import Hasura.RQL.Types.Common (RelName, SourceName, ToAesonPairs (toAesonPairs), defaultSource)
|
||||
import Hasura.RQL.Types.Relationships.Local (RelDef (..), RelManualNativeQueryConfig (..))
|
||||
|
||||
-- | copy pasta'd from Hasura.RQL.Types.Metadata.Common, forgive me Padre i did
|
||||
@ -94,3 +96,27 @@ deriving via
|
||||
(Autodocodec (NativeQueryMetadata b))
|
||||
instance
|
||||
(Backend b) => (ToJSON (NativeQueryMetadata b))
|
||||
|
||||
-- | A wrapper to tie something to a particular native query. Specifically, it
|
||||
-- assumes the underlying '_wlmInfo' is represented as an object, and adds two
|
||||
-- keys to that object: @source@ and @root_field_name@.
|
||||
data WithNativeQuery a = WithNativeQuery
|
||||
{ _wnqSource :: SourceName,
|
||||
_wnqName :: NativeQueryName,
|
||||
_wnqInfo :: a
|
||||
}
|
||||
deriving stock (Eq, Show)
|
||||
|
||||
-- | something to note here: if the `a` contains a `name` or `source` key then
|
||||
-- this won't work anymore.
|
||||
instance (FromJSON a) => FromJSON (WithNativeQuery a) where
|
||||
parseJSON = J.withObject "NativeQuery" \obj -> do
|
||||
_wnqSource <- obj .:? "source" .!= defaultSource
|
||||
_wnqName <- obj .: "name"
|
||||
_wnqInfo <- J.parseJSON (J.Object obj)
|
||||
|
||||
pure WithNativeQuery {..}
|
||||
|
||||
instance (ToAesonPairs a) => ToJSON (WithNativeQuery a) where
|
||||
toJSON (WithNativeQuery source name info) =
|
||||
J.object $ ("source", J.toJSON source) : ("name", J.toJSON name) : toAesonPairs info
|
||||
|
@ -44,8 +44,10 @@ import Hasura.Eventing.Backend (BackendEventTrigger (..))
|
||||
import Hasura.Function.API
|
||||
import Hasura.Logging qualified as HL
|
||||
import Hasura.LogicalModel.API
|
||||
import Hasura.LogicalModelResolver.Lenses (_LMIInlineLogicalModel)
|
||||
import Hasura.Metadata.Class
|
||||
import Hasura.NativeQuery.API
|
||||
import Hasura.NativeQuery.Lenses (nqmReturns)
|
||||
import Hasura.Prelude hiding (first)
|
||||
import Hasura.RQL.DDL.Action
|
||||
import Hasura.RQL.DDL.ApiLimit
|
||||
@ -723,16 +725,24 @@ purgeMetadataObj = \case
|
||||
$ nativeQueryMetadataSetter @b source nativeQueryName
|
||||
%~ case nativeQueryMetadataObjId of
|
||||
NQMORel rn _ -> dropNativeQueryRelationshipInMetadata rn
|
||||
NQMOReferencedLogicalModel _ -> id
|
||||
SMOStoredProcedure sp -> dropStoredProcedureInMetadata @b source sp
|
||||
SMOLogicalModel lm -> dropLogicalModelInMetadata @b source lm
|
||||
SMOLogicalModelObj logicalModelName logicalModelMetadataObjId ->
|
||||
SMOLogicalModelObj (LMLLogicalModel logicalModelName) logicalModelMetadataObjId ->
|
||||
MetadataModifier
|
||||
$ logicalModelMetadataSetter @b source logicalModelName
|
||||
%~ case logicalModelMetadataObjId of
|
||||
LMMOPerm roleName permType ->
|
||||
dropLogicalModelPermissionInMetadata roleName permType
|
||||
LMMOReferencedLogicalModel _ -> id
|
||||
SMOLogicalModelObj (LMLNativeQuery nativeQueryName) logicalModelMetadataObjId ->
|
||||
MetadataModifier
|
||||
$ nativeQueryMetadataSetter @b source nativeQueryName
|
||||
. nqmReturns
|
||||
. _LMIInlineLogicalModel
|
||||
%~ case logicalModelMetadataObjId of
|
||||
LMMOPerm roleName permType ->
|
||||
dropInlineLogicalModelPermissionInMetadata roleName permType
|
||||
LMMOReferencedLogicalModel _ -> id
|
||||
SMOTableObj qt tableObj ->
|
||||
MetadataModifier
|
||||
$ tableMetadataSetter @b source qt
|
||||
|
@ -44,7 +44,7 @@ import Data.Text.Extended
|
||||
import Hasura.Base.Error
|
||||
import Hasura.EncJSON
|
||||
import Hasura.LogicalModel.Common (logicalModelFieldsToFieldInfo)
|
||||
import Hasura.LogicalModel.Types (LogicalModelField (..), LogicalModelName)
|
||||
import Hasura.LogicalModel.Types (LogicalModelField (..), LogicalModelLocation)
|
||||
import Hasura.Prelude
|
||||
import Hasura.RQL.DDL.Permission.Internal
|
||||
import Hasura.RQL.IR.BoolExp
|
||||
@ -264,12 +264,12 @@ buildLogicalModelPermInfo ::
|
||||
Has (ScalarTypeParsingContext b) r
|
||||
) =>
|
||||
SourceName ->
|
||||
LogicalModelName ->
|
||||
LogicalModelLocation ->
|
||||
InsOrdHashMap.InsOrdHashMap (Column b) (LogicalModelField b) ->
|
||||
PermDefPermission b perm ->
|
||||
m (WithDeps (PermInfo perm b))
|
||||
buildLogicalModelPermInfo sourceName logicalModelName fieldInfoMap = \case
|
||||
SelPerm' p -> buildLogicalModelSelPermInfo sourceName logicalModelName fieldInfoMap p
|
||||
buildLogicalModelPermInfo sourceName logicalModelLocation fieldInfoMap = \case
|
||||
SelPerm' p -> buildLogicalModelSelPermInfo sourceName logicalModelLocation fieldInfoMap p
|
||||
InsPerm' _ -> error "Not implemented yet"
|
||||
UpdPerm' _ -> error "Not implemented yet"
|
||||
DelPerm' _ -> error "Not implemented yet"
|
||||
@ -464,11 +464,11 @@ buildLogicalModelSelPermInfo ::
|
||||
Has (ScalarTypeParsingContext b) r
|
||||
) =>
|
||||
SourceName ->
|
||||
LogicalModelName ->
|
||||
LogicalModelLocation ->
|
||||
InsOrdHashMap.InsOrdHashMap (Column b) (LogicalModelField b) ->
|
||||
SelPerm b ->
|
||||
m (WithDeps (SelPermInfo b))
|
||||
buildLogicalModelSelPermInfo source logicalModelName logicalModelFieldMap sp = withPathK "permission" do
|
||||
buildLogicalModelSelPermInfo source logicalModelLocation logicalModelFieldMap sp = withPathK "permission" do
|
||||
let columns :: [Column b]
|
||||
columns = interpColSpec (lmfName <$> InsOrdHashMap.elems logicalModelFieldMap) (spColumns sp)
|
||||
|
||||
@ -477,7 +477,7 @@ buildLogicalModelSelPermInfo source logicalModelName logicalModelFieldMap sp = w
|
||||
-- filter out the non-scalars.
|
||||
(spiFilter, boolExpDeps) <-
|
||||
withPathK "filter"
|
||||
$ procLogicalModelBoolExp source logicalModelName (logicalModelFieldsToFieldInfo logicalModelFieldMap) (spFilter sp)
|
||||
$ procLogicalModelBoolExp source logicalModelLocation (logicalModelFieldsToFieldInfo logicalModelFieldMap) (spFilter sp)
|
||||
|
||||
let -- What parts of the metadata are interesting when computing the
|
||||
-- permissions? These dependencies bubble all the way up to
|
||||
@ -486,9 +486,9 @@ buildLogicalModelSelPermInfo source logicalModelName logicalModelFieldMap sp = w
|
||||
deps :: Seq SchemaDependency
|
||||
deps =
|
||||
mconcat
|
||||
[ Seq.singleton (mkLogicalModelParentDep @b source logicalModelName),
|
||||
[ Seq.singleton (mkLogicalModelParentDep @b source logicalModelLocation),
|
||||
boolExpDeps,
|
||||
fmap (mkLogicalModelColDep @b DRUntyped source logicalModelName)
|
||||
fmap (mkLogicalModelColDep @b DRUntyped source logicalModelLocation)
|
||||
$ Seq.fromList columns
|
||||
]
|
||||
|
||||
|
@ -24,7 +24,7 @@ import Data.Sequence qualified as Seq
|
||||
import Data.Text qualified as T
|
||||
import Data.Text.Extended
|
||||
import Hasura.Base.Error
|
||||
import Hasura.LogicalModel.Types (LogicalModelName)
|
||||
import Hasura.LogicalModel.Types (LogicalModelLocation)
|
||||
import Hasura.Prelude
|
||||
import Hasura.RQL.IR.BoolExp
|
||||
import Hasura.RQL.Types.Backend
|
||||
@ -124,11 +124,11 @@ procLogicalModelBoolExp ::
|
||||
Has (ScalarTypeParsingContext b) r
|
||||
) =>
|
||||
SourceName ->
|
||||
LogicalModelName ->
|
||||
LogicalModelLocation ->
|
||||
FieldInfoMap (FieldInfo b) ->
|
||||
BoolExp b ->
|
||||
m (AnnBoolExpPartialSQL b, Seq SchemaDependency)
|
||||
procLogicalModelBoolExp source lmn fieldInfoMap be = do
|
||||
procLogicalModelBoolExp source logicalModelLocation fieldInfoMap be = do
|
||||
let -- The parser for the "right hand side" of operations. We use @rhsParser@
|
||||
-- as the name here for ease of grepping, though it's maybe a bit vague.
|
||||
-- More specifically, if we think of an operation that combines a field
|
||||
@ -147,7 +147,7 @@ procLogicalModelBoolExp source lmn fieldInfoMap be = do
|
||||
-- this boolean expression? This dependency system is explained more
|
||||
-- thoroughly in the 'buildLogicalModelSelPermInfo' inline comments.
|
||||
deps :: [SchemaDependency]
|
||||
deps = getLogicalModelBoolExpDeps source lmn abe
|
||||
deps = getLogicalModelBoolExpDeps source logicalModelLocation abe
|
||||
|
||||
return (abe, Seq.fromList deps)
|
||||
|
||||
|
@ -50,7 +50,7 @@ import Hasura.Incremental qualified as Inc
|
||||
import Hasura.Logging
|
||||
import Hasura.LogicalModel.Cache (LogicalModelCache, LogicalModelInfo (..))
|
||||
import Hasura.LogicalModel.Metadata (LogicalModelMetadata (..))
|
||||
import Hasura.LogicalModel.Types (LogicalModelField (..), LogicalModelName (..), LogicalModelType (..), LogicalModelTypeArray (..), LogicalModelTypeReference (..))
|
||||
import Hasura.LogicalModel.Types (LogicalModelField (..), LogicalModelLocation (..), LogicalModelName (..), LogicalModelType (..), LogicalModelTypeArray (..), LogicalModelTypeReference (..))
|
||||
import Hasura.LogicalModelResolver.Metadata (InlineLogicalModelMetadata (..), LogicalModelIdentifier (..))
|
||||
import Hasura.Metadata.Class
|
||||
import Hasura.NativeQuery.Cache (NativeQueryCache, NativeQueryInfo (..))
|
||||
@ -906,6 +906,24 @@ buildSchemaCacheRule logger env mSchemaRegistryContext = proc (MetadataWithResou
|
||||
getLogicalModelTypeDependencies ltmaArray
|
||||
LogicalModelTypeReference (LogicalModelTypeReferenceC lmtrr _) -> S.singleton lmtrr
|
||||
|
||||
let logicalModelDepObjects metadataJSON rootLogicalModelLocation logicalModelName =
|
||||
let metadataObject =
|
||||
MetadataObject
|
||||
( MOSourceObjId sourceName
|
||||
$ AB.mkAnyBackend
|
||||
$ SMOLogicalModelObj @b rootLogicalModelLocation
|
||||
$ LMMOReferencedLogicalModel logicalModelName
|
||||
)
|
||||
metadataJSON
|
||||
|
||||
sourceObject :: SchemaObjId
|
||||
sourceObject =
|
||||
SOSourceObj sourceName
|
||||
$ AB.mkAnyBackend
|
||||
$ SOILogicalModelObj @b rootLogicalModelLocation
|
||||
$ LMOReferencedLogicalModel logicalModelName
|
||||
in (metadataObject, sourceObject)
|
||||
|
||||
logicalModelCacheMaybes <-
|
||||
interpretWriter
|
||||
-< for
|
||||
@ -913,32 +931,17 @@ buildSchemaCacheRule logger env mSchemaRegistryContext = proc (MetadataWithResou
|
||||
\lmm@LogicalModelMetadata {..} ->
|
||||
withRecordInconsistencyM (mkLogicalModelMetadataObject lmm) $ do
|
||||
logicalModelPermissions <-
|
||||
flip runReaderT sourceConfig $ buildLogicalModelPermissions sourceName tableCoreInfos _lmmName _lmmFields _lmmSelectPermissions orderedRoles
|
||||
|
||||
let recordDependency logicalModelName = do
|
||||
let metadataObject =
|
||||
MetadataObject
|
||||
( MOSourceObjId sourceName
|
||||
$ AB.mkAnyBackend
|
||||
$ SMOLogicalModelObj @b _lmmName
|
||||
$ LMMOReferencedLogicalModel logicalModelName
|
||||
)
|
||||
( toJSON lmm
|
||||
)
|
||||
|
||||
sourceObject :: SchemaObjId
|
||||
sourceObject =
|
||||
SOSourceObj sourceName
|
||||
$ AB.mkAnyBackend
|
||||
$ SOILogicalModelObj @b _lmmName
|
||||
$ LMOReferencedLogicalModel logicalModelName
|
||||
flip runReaderT sourceConfig
|
||||
$ buildLogicalModelPermissions sourceName tableCoreInfos (LMLLogicalModel _lmmName) _lmmFields _lmmSelectPermissions orderedRoles
|
||||
|
||||
let recordDep (metadataObject, sourceObject) =
|
||||
recordDependenciesM metadataObject sourceObject
|
||||
$ Seq.singleton (SchemaDependency sourceObject DRReferencedLogicalModel)
|
||||
|
||||
-- record a dependency with each Logical Model our types
|
||||
-- reference
|
||||
mapM_ recordDependency (concatMap (S.toList . getLogicalModelTypeDependencies . lmfType) _lmmFields)
|
||||
-- record a dependency with each Logical Model our types reference
|
||||
mapM_
|
||||
(recordDep . logicalModelDepObjects (toJSON lmm) (LMLLogicalModel _lmmName))
|
||||
(concatMap (S.toList . getLogicalModelTypeDependencies . lmfType) _lmmFields)
|
||||
|
||||
pure
|
||||
LogicalModelInfo
|
||||
@ -995,38 +998,21 @@ buildSchemaCacheRule logger env mSchemaRegistryContext = proc (MetadataWithResou
|
||||
(HashMap.lookup logicalModelName logicalModelsCache)
|
||||
(throw400 InvalidConfiguration ("The logical model " <> toTxt logicalModelName <> " could not be found"))
|
||||
LMIInlineLogicalModel (InlineLogicalModelMetadata {_ilmmFields, _ilmmSelectPermissions}) -> do
|
||||
let logicalModelName = LogicalModelName (getNativeQueryName _nqmRootFieldName)
|
||||
|
||||
recordDependency innerLogicalModelName = do
|
||||
let nqMetadataObject =
|
||||
MetadataObject
|
||||
( MOSourceObjId sourceName
|
||||
$ AB.mkAnyBackend
|
||||
$ SMONativeQueryObj @b _nqmRootFieldName
|
||||
$ NQMOReferencedLogicalModel innerLogicalModelName
|
||||
)
|
||||
( toJSON preValidationNativeQuery
|
||||
)
|
||||
|
||||
nqSourceObject :: SchemaObjId
|
||||
nqSourceObject =
|
||||
SOSourceObj sourceName
|
||||
$ AB.mkAnyBackend
|
||||
$ SOINativeQueryObj @b _nqmRootFieldName
|
||||
$ NQOReferencedLogicalModel innerLogicalModelName
|
||||
|
||||
recordDependenciesM nqMetadataObject nqSourceObject
|
||||
$ Seq.singleton (SchemaDependency nqSourceObject DRReferencedLogicalModel)
|
||||
|
||||
logicalModelPermissions <-
|
||||
flip runReaderT sourceConfig $ buildLogicalModelPermissions sourceName tableCoreInfos logicalModelName _ilmmFields _ilmmSelectPermissions orderedRoles
|
||||
flip runReaderT sourceConfig $ buildLogicalModelPermissions sourceName tableCoreInfos (LMLNativeQuery _nqmRootFieldName) _ilmmFields _ilmmSelectPermissions orderedRoles
|
||||
|
||||
let recordDep (metadataObject', sourceObject) =
|
||||
recordDependenciesM metadataObject' sourceObject
|
||||
$ Seq.singleton (SchemaDependency sourceObject DRReferencedLogicalModel)
|
||||
|
||||
-- record a dependency with each Logical Model our types reference
|
||||
mapM_ recordDependency (concatMap (S.toList . getLogicalModelTypeDependencies . lmfType) _ilmmFields)
|
||||
mapM_
|
||||
(recordDep . logicalModelDepObjects (toJSON preValidationNativeQuery) (LMLNativeQuery _nqmRootFieldName))
|
||||
(concatMap (S.toList . getLogicalModelTypeDependencies . lmfType) _ilmmFields)
|
||||
|
||||
pure
|
||||
$ LogicalModelInfo
|
||||
{ _lmiName = logicalModelName,
|
||||
{ _lmiName = LogicalModelName (getNativeQueryName _nqmRootFieldName),
|
||||
_lmiFields = _ilmmFields,
|
||||
_lmiDescription = _nqmDescription,
|
||||
_lmiPermissions = logicalModelPermissions
|
||||
|
@ -53,7 +53,7 @@ import Data.Sequence qualified as Seq
|
||||
import Data.Text.Extended
|
||||
import Hasura.Base.Error
|
||||
import Hasura.Incremental qualified as Inc
|
||||
import Hasura.LogicalModel.Types (LogicalModelName)
|
||||
import Hasura.LogicalModel.Types (LogicalModelLocation (..), LogicalModelName)
|
||||
import Hasura.Prelude
|
||||
import Hasura.RQL.DDL.Schema.Cache.Config
|
||||
import Hasura.RQL.DDL.SchemaRegistry (SchemaRegistryAction)
|
||||
@ -389,5 +389,6 @@ buildInfoMapPreservingMetadataM extractKey mkMetadataObject buildInfo =
|
||||
addTableContext :: (Backend b) => TableName b -> Text -> Text
|
||||
addTableContext tableName e = "in table " <> tableName <<> ": " <> e
|
||||
|
||||
addLogicalModelContext :: LogicalModelName -> Text -> Text
|
||||
addLogicalModelContext logicalModelName e = "in logical model " <> logicalModelName <<> ": " <> e
|
||||
addLogicalModelContext :: LogicalModelLocation -> Text -> Text
|
||||
addLogicalModelContext (LMLLogicalModel logicalModelName) e = "in logical model " <> logicalModelName <<> ": " <> e
|
||||
addLogicalModelContext (LMLNativeQuery nativeQueryName) e = "in logical model for native query" <> nativeQueryName <<> ": " <> e
|
||||
|
@ -16,6 +16,7 @@ import Hasura.Base.Error
|
||||
import Hasura.Function.Lenses (fiPermissions)
|
||||
import Hasura.LogicalModel.Cache (LogicalModelInfo (..))
|
||||
import Hasura.LogicalModel.Lenses (lmiPermissions)
|
||||
import Hasura.LogicalModel.Types (LogicalModelLocation (..))
|
||||
import Hasura.NativeQuery.Cache (NativeQueryInfo (_nqiReturns))
|
||||
import Hasura.NativeQuery.Lenses (nqiRelationships)
|
||||
import Hasura.Prelude
|
||||
@ -173,8 +174,13 @@ pruneDanglingDependents cache =
|
||||
`onNothing` Left ("function " <> functionName <<> " is not tracked")
|
||||
SOILogicalModel logicalModelName ->
|
||||
void $ resolveLogicalModel sourceInfo logicalModelName
|
||||
SOILogicalModelObj logicalModelName logicalModelObjId -> do
|
||||
logicalModel <- resolveLogicalModel sourceInfo logicalModelName
|
||||
SOILogicalModelObj logicalModelLocation logicalModelObjId -> do
|
||||
(logicalModelDesc, logicalModel) <- case logicalModelLocation of
|
||||
LMLLogicalModel logicalModelName ->
|
||||
(,) ("logical model " <>> logicalModelName) <$> resolveLogicalModel sourceInfo logicalModelName
|
||||
LMLNativeQuery nativeQueryName ->
|
||||
(,) ("logical model for native query " <>> nativeQueryName)
|
||||
<$> resolveLogicalModelInNativeQuery sourceInfo nativeQueryName
|
||||
case logicalModelObjId of
|
||||
LMOReferencedLogicalModel inner ->
|
||||
void $ resolveLogicalModel sourceInfo inner
|
||||
@ -186,13 +192,13 @@ pruneDanglingDependents cache =
|
||||
$ Left
|
||||
$ "no "
|
||||
<> permTypeToCode permType
|
||||
<> " permission defined on logical model "
|
||||
<> logicalModelName
|
||||
<> " permission defined on "
|
||||
<> logicalModelDesc
|
||||
<<> " for role "
|
||||
<>> roleName
|
||||
LMOCol column ->
|
||||
unless (InsOrdHashMap.member column (_lmiFields logicalModel)) do
|
||||
Left ("Could not find column " <> column <<> " in logical model " <>> logicalModelName)
|
||||
Left ("Could not find column " <> column <<> " in " <>> logicalModelDesc)
|
||||
SOINativeQuery nativeQueryName -> do
|
||||
void $ resolveNativeQuery sourceInfo nativeQueryName
|
||||
SOINativeQueryObj nativeQueryName nativeQueryObjId -> do
|
||||
@ -202,8 +208,6 @@ pruneDanglingDependents cache =
|
||||
unless (InsOrdHashMap.member colName (_lmiFields (_nqiReturns nativeQueryInfo)))
|
||||
$ Left
|
||||
("native query " <> nativeQueryName <<> " has no field named " <>> colName)
|
||||
NQOReferencedLogicalModel inner ->
|
||||
void $ resolveLogicalModel sourceInfo inner
|
||||
SOIStoredProcedure storedProcedureName -> do
|
||||
void $ resolveStoredProcedure sourceInfo storedProcedureName
|
||||
SOIStoredProcedureObj storedProcedureName storedProcedureObjId -> do
|
||||
@ -278,6 +282,9 @@ pruneDanglingDependents cache =
|
||||
HashMap.lookup logicalModelName (_siLogicalModels sourceInfo)
|
||||
`onNothing` Left ("logical model " <> logicalModelName <<> " is not tracked")
|
||||
|
||||
resolveLogicalModelInNativeQuery sourceInfo nativeQueryName =
|
||||
resolveNativeQuery sourceInfo nativeQueryName <&> \nq -> _nqiReturns nq
|
||||
|
||||
columnToFieldName :: forall b. (Backend b) => TableInfo b -> Column b -> FieldName
|
||||
columnToFieldName _ = fromCol @b
|
||||
|
||||
@ -349,18 +356,18 @@ deleteMetadataObject = \case
|
||||
SMONativeQueryObj nativeQueryName nativeQueryObjId ->
|
||||
siNativeQueries . ix nativeQueryName %~ case nativeQueryObjId of
|
||||
NQMORel name _ -> nqiRelationships %~ InsOrdHashMap.delete name
|
||||
NQMOReferencedLogicalModel _ -> id
|
||||
SMOStoredProcedure name -> siStoredProcedures %~ HashMap.delete name
|
||||
SMOLogicalModel name ->
|
||||
-- TODO: if I'm inconsistent, delete everything that depends on me
|
||||
siLogicalModels %~ HashMap.delete name
|
||||
SMOLogicalModelObj logicalModelName logicalModelObjectId ->
|
||||
SMOLogicalModelObj (LMLLogicalModel logicalModelName) logicalModelObjectId ->
|
||||
siLogicalModels . ix logicalModelName %~ case logicalModelObjectId of
|
||||
LMMOPerm roleName PTSelect -> lmiPermissions . ix roleName . permSel .~ Nothing
|
||||
LMMOPerm roleName PTInsert -> lmiPermissions . ix roleName . permIns .~ Nothing
|
||||
LMMOPerm roleName PTUpdate -> lmiPermissions . ix roleName . permUpd .~ Nothing
|
||||
LMMOPerm roleName PTDelete -> lmiPermissions . ix roleName . permDel .~ Nothing
|
||||
LMMOReferencedLogicalModel _ -> id
|
||||
SMOLogicalModelObj (LMLNativeQuery _nativeQueryName) _logicalModelObjectId -> error "copy above pls"
|
||||
SMOTableObj tableName tableObjectId ->
|
||||
siTables . ix tableName %~ case tableObjectId of
|
||||
MTORel name _ -> tiCoreInfo . tciFieldInfoMap %~ HashMap.delete (fromRel name)
|
||||
|
@ -9,7 +9,7 @@ module Hasura.RQL.DDL.Schema.Cache.Permission
|
||||
)
|
||||
where
|
||||
|
||||
import Data.Aeson
|
||||
import Data.Aeson (ToJSON (..))
|
||||
import Data.Environment qualified as Env
|
||||
import Data.Graph qualified as G
|
||||
import Data.Has
|
||||
@ -19,7 +19,8 @@ import Data.Sequence qualified as Seq
|
||||
import Data.Text.Extended
|
||||
import Hasura.Base.Error
|
||||
import Hasura.LogicalModel.Metadata (WithLogicalModel (..))
|
||||
import Hasura.LogicalModel.Types (LogicalModelField (..), LogicalModelName)
|
||||
import Hasura.LogicalModel.Types (LogicalModelField (..), LogicalModelLocation (..))
|
||||
import Hasura.NativeQuery.Metadata (WithNativeQuery (..))
|
||||
import Hasura.Prelude
|
||||
import Hasura.RQL.DDL.Permission
|
||||
import Hasura.RQL.DDL.Schema.Cache.Common
|
||||
@ -303,12 +304,12 @@ buildLogicalModelPermissions ::
|
||||
) =>
|
||||
SourceName ->
|
||||
TableCoreCache b ->
|
||||
LogicalModelName ->
|
||||
LogicalModelLocation ->
|
||||
InsOrdHashMap (Column b) (LogicalModelField b) ->
|
||||
InsOrdHashMap RoleName (SelPermDef b) ->
|
||||
OrderedRoles ->
|
||||
m (RolePermInfoMap b)
|
||||
buildLogicalModelPermissions sourceName tableCache logicalModelName logicalModelFields selectPermissions orderedRoles = do
|
||||
buildLogicalModelPermissions sourceName tableCache logicalModelLocation logicalModelFields selectPermissions orderedRoles = do
|
||||
let combineRolePermissions :: RolePermInfoMap b -> Role -> m (RolePermInfoMap b)
|
||||
combineRolePermissions acc (Role roleName (ParentRoles parentRoles)) = do
|
||||
-- This error will ideally never be thrown, but if it's thrown then
|
||||
@ -348,59 +349,88 @@ buildLogicalModelPermissions sourceName tableCache logicalModelName logicalModel
|
||||
|
||||
-- At the moment, we only support select permissions for logical models
|
||||
metadataRolePermissions <-
|
||||
for (InsOrdHashMap.toHashMap selectPermissions) \selectPermission -> do
|
||||
let role :: RoleName
|
||||
role = _pdRole selectPermission
|
||||
|
||||
-- An identifier for the object on we're going to need to depend to
|
||||
-- generate this permission.
|
||||
sourceObjId :: MetadataObjId
|
||||
sourceObjId =
|
||||
MOSourceObjId sourceName
|
||||
$ AB.mkAnyBackend
|
||||
$ SMOLogicalModelObj @b logicalModelName
|
||||
$ LMMOPerm role PTSelect
|
||||
|
||||
-- The object we're going to use to track the dependency and any
|
||||
-- potential cache inconsistencies.
|
||||
metadataObject :: MetadataObject
|
||||
metadataObject =
|
||||
MetadataObject sourceObjId
|
||||
$ toJSON
|
||||
WithLogicalModel
|
||||
{ _wlmSource = sourceName,
|
||||
_wlmName = logicalModelName,
|
||||
_wlmInfo = selectPermission
|
||||
}
|
||||
|
||||
-- An identifier for this permission within the metadata structure.
|
||||
schemaObject :: SchemaObjId
|
||||
schemaObject =
|
||||
SOSourceObj sourceName
|
||||
$ AB.mkAnyBackend
|
||||
$ SOILogicalModelObj @b logicalModelName
|
||||
$ LMOPerm role PTSelect
|
||||
|
||||
modifyError :: ExceptT QErr m a -> ExceptT QErr m a
|
||||
modifyError = modifyErr \err ->
|
||||
addLogicalModelContext logicalModelName
|
||||
$ "in permission for role "
|
||||
<> role
|
||||
<<> ": "
|
||||
<> err
|
||||
|
||||
select <- withRecordInconsistencyM metadataObject $ modifyError do
|
||||
when (role == adminRoleName)
|
||||
$ throw400 ConstraintViolation "cannot define permission for admin role"
|
||||
|
||||
(permissionInformation, dependencies) <-
|
||||
flip runTableCoreCacheRT tableCache
|
||||
$ buildLogicalModelPermInfo sourceName logicalModelName logicalModelFields
|
||||
$ _pdPermission selectPermission
|
||||
|
||||
recordDependenciesM metadataObject schemaObject dependencies
|
||||
pure permissionInformation
|
||||
|
||||
pure (RolePermInfo Nothing select Nothing Nothing)
|
||||
for
|
||||
(InsOrdHashMap.toHashMap selectPermissions)
|
||||
(buildLogicalModelSelectPermission sourceName tableCache logicalModelLocation logicalModelFields)
|
||||
|
||||
foldlM combineRolePermissions metadataRolePermissions (_unOrderedRoles orderedRoles)
|
||||
|
||||
buildLogicalModelSelectPermission ::
|
||||
forall b m r.
|
||||
( MonadError QErr m,
|
||||
MonadWriter (Seq CollectItem) m,
|
||||
BackendMetadata b,
|
||||
GetAggregationPredicatesDeps b,
|
||||
MonadReader r m,
|
||||
Has (ScalarTypeParsingContext b) r
|
||||
) =>
|
||||
SourceName ->
|
||||
TableCoreCache b ->
|
||||
LogicalModelLocation ->
|
||||
InsOrdHashMap (Column b) (LogicalModelField b) ->
|
||||
SelPermDef b ->
|
||||
m (RolePermInfo b)
|
||||
buildLogicalModelSelectPermission sourceName tableCache logicalModelLocation logicalModelFields selectPermission = do
|
||||
let role :: RoleName
|
||||
role = _pdRole selectPermission
|
||||
|
||||
-- An identifier for the object on we're going to need to depend to
|
||||
-- generate this permission.
|
||||
sourceObjId :: MetadataObjId
|
||||
sourceObjId =
|
||||
MOSourceObjId sourceName
|
||||
$ AB.mkAnyBackend
|
||||
$ SMOLogicalModelObj @b logicalModelLocation
|
||||
$ LMMOPerm role PTSelect
|
||||
|
||||
-- The object we're going to use to track the dependency and any
|
||||
-- potential cache inconsistencies.
|
||||
-- we'll need to add one for each location a Logical Model can live in future (a Stored Procedure, etc)
|
||||
metadataObject :: MetadataObject
|
||||
metadataObject = case logicalModelLocation of
|
||||
LMLLogicalModel logicalModelName ->
|
||||
MetadataObject sourceObjId
|
||||
$ toJSON
|
||||
WithLogicalModel
|
||||
{ _wlmSource = sourceName,
|
||||
_wlmName = logicalModelName,
|
||||
_wlmInfo = selectPermission
|
||||
}
|
||||
LMLNativeQuery nativeQueryName ->
|
||||
MetadataObject sourceObjId
|
||||
$ toJSON
|
||||
WithNativeQuery
|
||||
{ _wnqSource = sourceName,
|
||||
_wnqName = nativeQueryName,
|
||||
_wnqInfo = selectPermission
|
||||
}
|
||||
|
||||
-- An identifier for this permission within the metadata structure.
|
||||
schemaObject :: SchemaObjId
|
||||
schemaObject =
|
||||
SOSourceObj sourceName
|
||||
$ AB.mkAnyBackend
|
||||
$ SOILogicalModelObj @b logicalModelLocation
|
||||
$ LMOPerm role PTSelect
|
||||
|
||||
modifyError :: ExceptT QErr m a -> ExceptT QErr m a
|
||||
modifyError = modifyErr \err ->
|
||||
addLogicalModelContext logicalModelLocation
|
||||
$ "in permission for role "
|
||||
<> role
|
||||
<<> ": "
|
||||
<> err
|
||||
|
||||
select <- withRecordInconsistencyM metadataObject $ modifyError do
|
||||
when (role == adminRoleName)
|
||||
$ throw400 ConstraintViolation "cannot define permission for admin role"
|
||||
|
||||
(permissionInformation, dependencies) <-
|
||||
flip runTableCoreCacheRT tableCache
|
||||
$ buildLogicalModelPermInfo sourceName logicalModelLocation logicalModelFields
|
||||
$ _pdPermission selectPermission
|
||||
|
||||
recordDependenciesM metadataObject schemaObject dependencies
|
||||
pure permissionInformation
|
||||
|
||||
pure (RolePermInfo Nothing select Nothing Nothing)
|
||||
|
@ -13,6 +13,7 @@ module Hasura.RQL.Types.Metadata
|
||||
dropFunctionInMetadata,
|
||||
dropPermissionInMetadata,
|
||||
dropLogicalModelPermissionInMetadata,
|
||||
dropInlineLogicalModelPermissionInMetadata,
|
||||
dropRelationshipInMetadata,
|
||||
dropNativeQueryRelationshipInMetadata,
|
||||
dropRemoteRelationshipInMetadata,
|
||||
@ -61,6 +62,8 @@ import Hasura.Function.Metadata (FunctionMetadata (..))
|
||||
import Hasura.Incremental qualified as Inc
|
||||
import Hasura.LogicalModel.Lenses (lmmSelectPermissions)
|
||||
import Hasura.LogicalModel.Metadata (LogicalModelMetadata, LogicalModelName)
|
||||
import Hasura.LogicalModelResolver.Lenses (ilmmSelectPermissions)
|
||||
import Hasura.LogicalModelResolver.Metadata (InlineLogicalModelMetadata (..))
|
||||
import Hasura.Metadata.DTO.MetadataV3 (MetadataV3 (..))
|
||||
import Hasura.NativeQuery.Lenses (nqmArrayRelationships)
|
||||
import Hasura.NativeQuery.Metadata (NativeQueryMetadata, NativeQueryName)
|
||||
@ -436,6 +439,14 @@ dropLogicalModelPermissionInMetadata rn = \case
|
||||
PTDelete -> error "Not implemented yet"
|
||||
PTUpdate -> error "Not implemented yet"
|
||||
|
||||
dropInlineLogicalModelPermissionInMetadata ::
|
||||
RoleName -> PermType -> InlineLogicalModelMetadata b -> InlineLogicalModelMetadata b
|
||||
dropInlineLogicalModelPermissionInMetadata rn = \case
|
||||
PTSelect -> ilmmSelectPermissions %~ InsOrdHashMap.delete rn
|
||||
PTInsert -> error "Not implemented yet"
|
||||
PTDelete -> error "Not implemented yet"
|
||||
PTUpdate -> error "Not implemented yet"
|
||||
|
||||
dropComputedFieldInMetadata ::
|
||||
ComputedFieldName -> TableMetadata b -> TableMetadata b
|
||||
dropComputedFieldInMetadata name =
|
||||
|
@ -84,7 +84,6 @@ instance Hashable LogicalModelMetadataObjId
|
||||
-- | the native query should probably also link to its logical model
|
||||
data NativeQueryMetadataObjId
|
||||
= NQMORel RelName RelType
|
||||
| NQMOReferencedLogicalModel LogicalModelName
|
||||
deriving (Show, Eq, Ord, Generic)
|
||||
|
||||
instance Hashable NativeQueryMetadataObjId
|
||||
@ -98,7 +97,7 @@ data SourceMetadataObjId b
|
||||
| SMONativeQueryObj NativeQueryName NativeQueryMetadataObjId
|
||||
| SMOStoredProcedure (FunctionName b)
|
||||
| SMOLogicalModel LogicalModelName
|
||||
| SMOLogicalModelObj LogicalModelName LogicalModelMetadataObjId
|
||||
| SMOLogicalModelObj LogicalModelLocation LogicalModelMetadataObjId
|
||||
deriving (Generic)
|
||||
|
||||
deriving instance (Backend b) => Show (SourceMetadataObjId b)
|
||||
@ -162,7 +161,6 @@ moiTypeName = \case
|
||||
SMONativeQuery _ -> "native_query"
|
||||
SMONativeQueryObj _ nativeQueryObjId -> case nativeQueryObjId of
|
||||
NQMORel _ relType -> relTypeToTxt relType <> "_relation"
|
||||
NQMOReferencedLogicalModel name -> "inner_logical_model_" <> toTxt name
|
||||
SMOStoredProcedure _ -> "stored_procedure"
|
||||
SMOLogicalModel _ -> "logical_model"
|
||||
SMOLogicalModelObj _ logicalModelObjectId -> case logicalModelObjectId of
|
||||
@ -223,10 +221,9 @@ moiName objectId =
|
||||
SMONativeQueryObj nativeQueryName nativeQueryObjId ->
|
||||
case nativeQueryObjId of
|
||||
NQMORel name _ -> toTxt name <> " in " <> toTxt nativeQueryName
|
||||
NQMOReferencedLogicalModel name -> toTxt name <> " in " <> toTxt nativeQueryName
|
||||
SMOStoredProcedure name -> toTxt name <> " in source " <> toTxt source
|
||||
SMOLogicalModel name -> toTxt name <> " in source " <> toTxt source
|
||||
SMOLogicalModelObj logicalModelName logicalModelObjectId -> do
|
||||
SMOLogicalModelObj (LMLLogicalModel logicalModelName) logicalModelObjectId -> do
|
||||
let objectName :: Text
|
||||
objectName = case logicalModelObjectId of
|
||||
LMMOPerm name _ -> toTxt name
|
||||
@ -238,6 +235,19 @@ moiName objectId =
|
||||
$ AB.mkAnyBackend
|
||||
$ SMOLogicalModel @b logicalModelName
|
||||
|
||||
objectName <> " in " <> moiName sourceObjectId
|
||||
SMOLogicalModelObj (LMLNativeQuery nativeQueryName) logicalModelObjectId -> do
|
||||
let objectName :: Text
|
||||
objectName = case logicalModelObjectId of
|
||||
LMMOPerm name _ -> toTxt name
|
||||
LMMOReferencedLogicalModel name -> toTxt name
|
||||
|
||||
sourceObjectId :: MetadataObjId
|
||||
sourceObjectId =
|
||||
MOSourceObjId source
|
||||
$ AB.mkAnyBackend
|
||||
$ SMONativeQuery @b nativeQueryName
|
||||
|
||||
objectName <> " in " <> moiName sourceObjectId
|
||||
SMOTableObj tableName tableObjectId ->
|
||||
let tableObjectName = case tableObjectId of
|
||||
|
@ -125,7 +125,7 @@ import Hasura.Backends.Postgres.Connection qualified as Postgres
|
||||
import Hasura.Base.Error
|
||||
import Hasura.Function.Cache
|
||||
import Hasura.GraphQL.Context (GQLContext, RoleContext)
|
||||
import Hasura.LogicalModel.Types (LogicalModelName)
|
||||
import Hasura.LogicalModel.Types (LogicalModelLocation (..))
|
||||
import Hasura.Prelude
|
||||
import Hasura.RQL.IR.BoolExp
|
||||
import Hasura.RQL.Types.Action
|
||||
@ -200,14 +200,20 @@ mkLogicalModelParentDep ::
|
||||
forall b.
|
||||
(Backend b) =>
|
||||
SourceName ->
|
||||
LogicalModelName ->
|
||||
LogicalModelLocation ->
|
||||
SchemaDependency
|
||||
mkLogicalModelParentDep source logicalModelName = do
|
||||
mkLogicalModelParentDep source logicalModelLocation = do
|
||||
let sourceObject :: SchemaObjId
|
||||
sourceObject =
|
||||
SOSourceObj source
|
||||
$ AB.mkAnyBackend @b
|
||||
$ SOILogicalModel logicalModelName
|
||||
case logicalModelLocation of
|
||||
LMLLogicalModel logicalModelName ->
|
||||
SOSourceObj source
|
||||
$ AB.mkAnyBackend @b
|
||||
$ SOILogicalModel logicalModelName
|
||||
LMLNativeQuery nativeQueryName ->
|
||||
SOSourceObj source
|
||||
$ AB.mkAnyBackend @b
|
||||
$ SOINativeQuery nativeQueryName
|
||||
|
||||
SchemaDependency sourceObject DRTable
|
||||
|
||||
@ -232,15 +238,15 @@ mkLogicalModelColDep ::
|
||||
(Backend b) =>
|
||||
DependencyReason ->
|
||||
SourceName ->
|
||||
LogicalModelName ->
|
||||
LogicalModelLocation ->
|
||||
Column b ->
|
||||
SchemaDependency
|
||||
mkLogicalModelColDep reason source logicalModelName column = do
|
||||
mkLogicalModelColDep reason source logicalModelLocation column = do
|
||||
let sourceObject :: SchemaObjId
|
||||
sourceObject =
|
||||
SOSourceObj source
|
||||
$ AB.mkAnyBackend
|
||||
$ SOILogicalModelObj @b logicalModelName
|
||||
$ SOILogicalModelObj @b logicalModelLocation
|
||||
$ LMOCol @b column
|
||||
|
||||
SchemaDependency sourceObject reason
|
||||
@ -753,14 +759,14 @@ getLogicalModelBoolExpDeps ::
|
||||
forall b.
|
||||
(GetAggregationPredicatesDeps b) =>
|
||||
SourceName ->
|
||||
LogicalModelName ->
|
||||
LogicalModelLocation ->
|
||||
AnnBoolExpPartialSQL b ->
|
||||
[SchemaDependency]
|
||||
getLogicalModelBoolExpDeps source logicalModelName = \case
|
||||
BoolAnd exps -> concatMap (getLogicalModelBoolExpDeps source logicalModelName) exps
|
||||
BoolOr exps -> concatMap (getLogicalModelBoolExpDeps source logicalModelName) exps
|
||||
BoolNot e -> getLogicalModelBoolExpDeps source logicalModelName e
|
||||
BoolField fld -> getLogicalModelColExpDeps source logicalModelName fld
|
||||
getLogicalModelBoolExpDeps source logicalModelLocation = \case
|
||||
BoolAnd exps -> concatMap (getLogicalModelBoolExpDeps source logicalModelLocation) exps
|
||||
BoolOr exps -> concatMap (getLogicalModelBoolExpDeps source logicalModelLocation) exps
|
||||
BoolNot e -> getLogicalModelBoolExpDeps source logicalModelLocation e
|
||||
BoolField fld -> getLogicalModelColExpDeps source logicalModelLocation fld
|
||||
BoolExists (GExists refqt whereExp) -> do
|
||||
let table :: SchemaObjId
|
||||
table = SOSourceObj source $ AB.mkAnyBackend $ SOITable @b refqt
|
||||
@ -776,10 +782,10 @@ getLogicalModelColExpDeps ::
|
||||
forall b.
|
||||
(GetAggregationPredicatesDeps b) =>
|
||||
SourceName ->
|
||||
LogicalModelName ->
|
||||
LogicalModelLocation ->
|
||||
AnnBoolExpFld b (PartialSQLExp b) ->
|
||||
[SchemaDependency]
|
||||
getLogicalModelColExpDeps source logicalModelName = \case
|
||||
getLogicalModelColExpDeps source logicalModelLocation = \case
|
||||
AVRelationship {} -> []
|
||||
AVComputedField _ -> []
|
||||
AVAggregationPredicates _ -> []
|
||||
@ -793,9 +799,9 @@ getLogicalModelColExpDeps source logicalModelName = \case
|
||||
colDepReason = bool DRSessionVariable DROnType (any hasStaticExp opExps)
|
||||
|
||||
colDep :: SchemaDependency
|
||||
colDep = mkLogicalModelColDep @b colDepReason source logicalModelName columnName
|
||||
colDep = mkLogicalModelColDep @b colDepReason source logicalModelLocation columnName
|
||||
|
||||
colDep : getLogicalModelOpExpDeps source logicalModelName opExps
|
||||
colDep : getLogicalModelOpExpDeps source logicalModelLocation opExps
|
||||
|
||||
-- | Discover the schema dependencies of an @AnnBoolExpPartialSQL@.
|
||||
getBoolExpDeps ::
|
||||
@ -904,12 +910,12 @@ getLogicalModelOpExpDeps ::
|
||||
forall b.
|
||||
(Backend b) =>
|
||||
SourceName ->
|
||||
LogicalModelName ->
|
||||
LogicalModelLocation ->
|
||||
[OpExpG b (PartialSQLExp b)] ->
|
||||
[SchemaDependency]
|
||||
getLogicalModelOpExpDeps source logicalModelName operatorExpressions = do
|
||||
getLogicalModelOpExpDeps source logicalModelLocation operatorExpressions = do
|
||||
RootOrCurrentColumn _ column <- mapMaybe opExpDepCol operatorExpressions
|
||||
pure (mkLogicalModelColDep @b DROnType source logicalModelName column)
|
||||
pure (mkLogicalModelColDep @b DROnType source logicalModelLocation column)
|
||||
|
||||
-- | Asking for a table's fields info without explicit @'SourceName' argument.
|
||||
-- The source name is implicitly inferred from @'SourceM' via @'TableCoreInfoRM'.
|
||||
|
@ -29,7 +29,7 @@ import Data.Text qualified as T
|
||||
import Data.Text.Extended
|
||||
import Data.Text.NonEmpty
|
||||
import Hasura.Base.Error
|
||||
import Hasura.LogicalModel.Types (LogicalModelName)
|
||||
import Hasura.LogicalModel.Types (LogicalModelLocation, LogicalModelName)
|
||||
import Hasura.NativeQuery.Types (NativeQueryName)
|
||||
import Hasura.Prelude
|
||||
import Hasura.RQL.IR.BoolExp (PartialSQLExp)
|
||||
@ -79,7 +79,6 @@ instance (Backend b) => Hashable (LogicalModelObjId b)
|
||||
-- that the two columns that join an array relationship actually exist.
|
||||
data NativeQueryObjId (b :: BackendType)
|
||||
= NQOCol (Column b)
|
||||
| NQOReferencedLogicalModel LogicalModelName
|
||||
deriving (Generic)
|
||||
|
||||
deriving instance (Backend b) => Eq (NativeQueryObjId b)
|
||||
@ -107,7 +106,7 @@ data SourceObjId (b :: BackendType)
|
||||
| SOIStoredProcedure (FunctionName b)
|
||||
| SOIStoredProcedureObj (FunctionName b) (StoredProcedureObjId b)
|
||||
| SOILogicalModel LogicalModelName
|
||||
| SOILogicalModelObj LogicalModelName (LogicalModelObjId b)
|
||||
| SOILogicalModelObj LogicalModelLocation (LogicalModelObjId b)
|
||||
deriving (Eq, Generic)
|
||||
|
||||
instance (Backend b) => Hashable (SourceObjId b)
|
||||
@ -139,8 +138,6 @@ reportSchemaObj = \case
|
||||
SOINativeQuery nqn -> "native query " <> toTxt nqn
|
||||
SOINativeQueryObj nqn (NQOCol cn) ->
|
||||
"column " <> toTxt nqn <> "." <> toTxt cn
|
||||
SOINativeQueryObj nqn (NQOReferencedLogicalModel inner) ->
|
||||
"inner logical model " <> toTxt nqn <> "." <> toTxt inner
|
||||
SOIStoredProcedure spn -> "stored procedure " <> toTxt spn
|
||||
SOIStoredProcedureObj spn (SPOCol cn) ->
|
||||
"column " <> toTxt spn <> "." <> toTxt cn
|
||||
|
Loading…
Reference in New Issue
Block a user