graphql-engine/server/src-lib/Hasura/RQL/DDL/InheritedRoles.hs
Tom Harding 1698f9dd91 Extract RoleName from Hasura.Session, move it into Hasura.RQL.Types.Roles
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/8856
Co-authored-by: Daniel Harvey <4729125+danieljharvey@users.noreply.github.com>
GitOrigin-RevId: 38ad67de9b3d765c4eb50943dd52b8fc32317540
2023-04-24 08:51:58 +00:00

74 lines
2.7 KiB
Haskell

module Hasura.RQL.DDL.InheritedRoles
( runAddInheritedRole,
runDropInheritedRole,
dropInheritedRoleInMetadata,
resolveInheritedRole,
)
where
import Data.HashMap.Strict.InsOrd qualified as OMap
import Data.HashSet qualified as Set
import Data.Sequence qualified as Seq
import Data.Text.Extended
import Hasura.Base.Error
import Hasura.EncJSON
import Hasura.Prelude
import Hasura.RQL.Types.Common
import Hasura.RQL.Types.Metadata
import Hasura.RQL.Types.Metadata.Object
import Hasura.RQL.Types.Roles
import Hasura.RQL.Types.SchemaCache
import Hasura.RQL.Types.SchemaCache.Build
runAddInheritedRole ::
( MonadError QErr m,
CacheRWM m,
MetadataM m
) =>
InheritedRole ->
m EncJSON
runAddInheritedRole addInheritedRoleQ@(Role inheritedRoleName (ParentRoles parentRoles)) = do
when (inheritedRoleName `elem` parentRoles) $
throw400 InvalidParams "an inherited role name cannot be in the role combination"
buildSchemaCacheFor (MOInheritedRole inheritedRoleName) $
MetadataModifier $
metaInheritedRoles %~ OMap.insert inheritedRoleName addInheritedRoleQ
pure successMsg
dropInheritedRoleInMetadata :: RoleName -> MetadataModifier
dropInheritedRoleInMetadata roleName =
MetadataModifier $ metaInheritedRoles %~ OMap.delete roleName
runDropInheritedRole ::
(MonadError QErr m, CacheRWM m, MetadataM m) =>
DropInheritedRole ->
m EncJSON
runDropInheritedRole (DropInheritedRole roleName) = do
inheritedRolesMetadata <- _metaInheritedRoles <$> getMetadata
unless (roleName `OMap.member` inheritedRolesMetadata) $
throw400 NotExists $
roleName <<> " inherited role doesn't exist"
buildSchemaCacheFor (MOInheritedRole roleName) (dropInheritedRoleInMetadata roleName)
pure successMsg
-- | `resolveInheritedRole` resolves an inherited role by checking if
-- all the parent roles of an inherited role exists and report
-- the dependencies of the inherited role which will be the list
-- of the parent roles
resolveInheritedRole ::
MonadError QErr m =>
HashSet RoleName ->
InheritedRole ->
m (Role, Seq SchemaDependency)
resolveInheritedRole allRoles (Role roleName (ParentRoles parentRoles)) = do
let missingParentRoles = Set.filter (`notElem` allRoles) parentRoles
unless (Set.null missingParentRoles) $
let errMessage roles =
"the following parent role(s) are not found: "
<> roles
<> " which are required to construct the inherited role: " <>> roleName
in throw400 NotExists $ errMessage $ commaSeparated $ Set.map roleNameToTxt missingParentRoles
let schemaDependencies =
fmap (\parentRole -> SchemaDependency (SORole parentRole) DRParentRole) (Seq.fromList (toList parentRoles))
pure $ (Role roleName $ ParentRoles parentRoles, schemaDependencies)