2018-06-27 16:11:32 +03:00
|
|
|
module Hasura.RQL.DDL.Permission
|
|
|
|
( CreatePerm
|
2018-12-13 10:26:15 +03:00
|
|
|
, runCreatePerm
|
2018-06-27 16:11:32 +03:00
|
|
|
, PermDef(..)
|
|
|
|
|
|
|
|
, InsPerm(..)
|
|
|
|
, InsPermDef
|
|
|
|
, CreateInsPerm
|
|
|
|
, buildInsPermInfo
|
|
|
|
|
|
|
|
, SelPerm(..)
|
|
|
|
, SelPermDef
|
|
|
|
, CreateSelPerm
|
|
|
|
, buildSelPermInfo
|
|
|
|
|
|
|
|
, UpdPerm(..)
|
|
|
|
, UpdPermDef
|
|
|
|
, CreateUpdPerm
|
|
|
|
, buildUpdPermInfo
|
|
|
|
|
|
|
|
, DelPerm(..)
|
|
|
|
, DelPermDef
|
|
|
|
, CreateDelPerm
|
|
|
|
, buildDelPermInfo
|
|
|
|
|
|
|
|
, IsPerm(..)
|
2018-12-13 10:26:15 +03:00
|
|
|
|
|
|
|
, DropPerm
|
|
|
|
, runDropPerm
|
2020-12-08 17:22:31 +03:00
|
|
|
, dropPermissionInMetadata
|
2018-12-13 10:26:15 +03:00
|
|
|
|
|
|
|
, SetPermComment(..)
|
|
|
|
, runSetPermComment
|
2019-08-17 00:35:22 +03:00
|
|
|
|
|
|
|
, fetchPermDef
|
2018-06-27 16:11:32 +03:00
|
|
|
) where
|
|
|
|
|
2020-08-27 19:36:39 +03:00
|
|
|
import Hasura.Prelude
|
|
|
|
|
2020-10-27 16:53:49 +03:00
|
|
|
import qualified Data.HashMap.Strict as HM
|
2020-12-08 17:22:31 +03:00
|
|
|
import qualified Data.HashMap.Strict.InsOrd as OMap
|
2020-10-27 16:53:49 +03:00
|
|
|
import qualified Data.HashSet as HS
|
|
|
|
import qualified Database.PG.Query as Q
|
|
|
|
|
|
|
|
import Data.Aeson
|
|
|
|
import Data.Aeson.Casing
|
|
|
|
import Data.Aeson.TH
|
2020-10-21 19:35:06 +03:00
|
|
|
import Data.Text.Extended
|
2020-10-27 16:53:49 +03:00
|
|
|
|
|
|
|
import Hasura.Backends.Postgres.SQL.Types
|
2019-03-18 19:22:21 +03:00
|
|
|
import Hasura.EncJSON
|
2018-06-27 16:11:32 +03:00
|
|
|
import Hasura.RQL.DDL.Permission.Internal
|
2019-10-18 11:29:47 +03:00
|
|
|
import Hasura.RQL.DML.Internal hiding (askPermInfo)
|
2018-12-15 19:10:29 +03:00
|
|
|
import Hasura.RQL.Types
|
2020-12-01 18:50:18 +03:00
|
|
|
import Hasura.SQL.Types
|
2020-10-21 19:35:06 +03:00
|
|
|
import Hasura.Session
|
2018-06-27 16:11:32 +03:00
|
|
|
|
|
|
|
|
|
|
|
|
2020-04-24 12:10:53 +03:00
|
|
|
{- Note [Backend only permissions]
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
As of writing this note, Hasura permission system is meant to be used by the
|
|
|
|
frontend. After introducing "Actions", the webhook handlers now can make GraphQL
|
|
|
|
mutations to the server with some backend logic. These mutations shouldn't be
|
|
|
|
exposed to frontend for any user since they'll bypass the business logic.
|
|
|
|
|
|
|
|
For example:-
|
|
|
|
|
|
|
|
We've a table named "user" and it has a "email" column. We need to validate the
|
|
|
|
email address. So we define an action "create_user" and it expects the same inputs
|
|
|
|
as "insert_user" mutation (generated by Hasura). Now, a role has permission for both
|
|
|
|
actions and insert operation on the table. If the insert permission is not marked
|
|
|
|
as "backend_only: true" then it visible to the frontend client along with "creat_user".
|
|
|
|
|
|
|
|
Backend only permissions adds an additional privilege to Hasura generated operations.
|
|
|
|
Those are accessable only if the request is made with `x-hasura-admin-secret`
|
|
|
|
(if authorization is configured), `x-hasura-use-backend-only-permissions`
|
|
|
|
(value must be set to "true"), `x-hasura-role` to identify the role and other
|
|
|
|
required session variables.
|
|
|
|
|
|
|
|
backend_only `x-hasura-admin-secret` `x-hasura-use-backend-only-permissions` Result
|
|
|
|
------------ --------------------- ------------------------------------- ------
|
|
|
|
FALSE ANY ANY Mutation is always visible
|
|
|
|
TRUE FALSE ANY Mutation is always hidden
|
|
|
|
TRUE TRUE (OR NOT-SET) FALSE Mutation is hidden
|
|
|
|
TRUE TRUE (OR NOT-SET) TRUE Mutation is shown
|
|
|
|
-}
|
|
|
|
|
2020-11-02 14:50:40 +03:00
|
|
|
type CreateInsPerm b = CreatePerm (InsPerm b)
|
2018-06-27 16:11:32 +03:00
|
|
|
|
2019-02-11 15:45:30 +03:00
|
|
|
procSetObj
|
|
|
|
:: (QErrM m)
|
2019-12-15 19:07:08 +03:00
|
|
|
=> QualifiedTable
|
2020-10-22 23:42:27 +03:00
|
|
|
-> FieldInfoMap (FieldInfo 'Postgres)
|
2019-12-15 19:07:08 +03:00
|
|
|
-> Maybe (ColumnValues Value)
|
2020-10-22 23:42:27 +03:00
|
|
|
-> m (PreSetColsPartial 'Postgres, [Text], [SchemaDependency])
|
2019-12-15 19:07:08 +03:00
|
|
|
procSetObj tn fieldInfoMap mObj = do
|
2019-08-17 00:35:22 +03:00
|
|
|
(setColTups, deps) <- withPathK "set" $
|
|
|
|
fmap unzip $ forM (HM.toList setObj) $ \(pgCol, val) -> do
|
2019-02-11 15:45:30 +03:00
|
|
|
ty <- askPGType fieldInfoMap pgCol $
|
|
|
|
"column " <> pgCol <<> " not found in table " <>> tn
|
2020-12-01 18:50:18 +03:00
|
|
|
sqlExp <- valueParser (CollectableTypeScalar ty) val
|
2019-08-17 00:35:22 +03:00
|
|
|
let dep = mkColDep (getDepReason sqlExp) tn pgCol
|
|
|
|
return ((pgCol, sqlExp), dep)
|
|
|
|
return (HM.fromList setColTups, depHeaders, deps)
|
2019-02-11 15:45:30 +03:00
|
|
|
where
|
|
|
|
setObj = fromMaybe mempty mObj
|
|
|
|
depHeaders = getDepHeadersFromVal $ Object $
|
|
|
|
HM.fromList $ map (first getPGColTxt) $ HM.toList setObj
|
|
|
|
|
2019-08-17 00:35:22 +03:00
|
|
|
getDepReason = bool DRSessionVariable DROnType . isStaticValue
|
|
|
|
|
2020-11-12 12:25:48 +03:00
|
|
|
class (ToJSON a) => IsPerm a where
|
|
|
|
|
|
|
|
permAccessor
|
|
|
|
:: PermAccessor 'Postgres (PermInfo a)
|
|
|
|
|
|
|
|
buildPermInfo
|
|
|
|
:: (QErrM m, TableCoreInfoRM m)
|
|
|
|
=> QualifiedTable
|
|
|
|
-> FieldInfoMap (FieldInfo 'Postgres)
|
|
|
|
-> PermDef a
|
|
|
|
-> m (WithDeps (PermInfo a))
|
|
|
|
|
|
|
|
getPermAcc1
|
|
|
|
:: PermDef a -> PermAccessor 'Postgres (PermInfo a)
|
|
|
|
getPermAcc1 _ = permAccessor
|
|
|
|
|
|
|
|
getPermAcc2
|
|
|
|
:: DropPerm a -> PermAccessor 'Postgres (PermInfo a)
|
|
|
|
getPermAcc2 _ = permAccessor
|
|
|
|
|
2020-12-08 17:22:31 +03:00
|
|
|
addPermToMetadata
|
|
|
|
:: PermDef a -> TableMetadata -> TableMetadata
|
2020-11-12 12:25:48 +03:00
|
|
|
|
|
|
|
runCreatePerm
|
2020-12-08 17:22:31 +03:00
|
|
|
:: (UserInfoM m, CacheRWM m, IsPerm a, MonadError QErr m, MetadataM m)
|
2020-11-12 12:25:48 +03:00
|
|
|
=> CreatePerm a -> m EncJSON
|
|
|
|
runCreatePerm (WithTable tn pd) = do
|
|
|
|
let pt = permAccToType $ getPermAcc1 pd
|
2020-12-08 17:22:31 +03:00
|
|
|
role = _pdRole pd
|
|
|
|
metadataObject = MOTableObj tn $ MTOPerm role pt
|
|
|
|
buildSchemaCacheFor metadataObject
|
|
|
|
$ MetadataModifier
|
|
|
|
$ metaTables.ix tn %~ addPermToMetadata pd
|
2020-11-12 12:25:48 +03:00
|
|
|
pure successMsg
|
|
|
|
|
|
|
|
runDropPerm
|
2020-12-08 17:22:31 +03:00
|
|
|
:: (IsPerm a, UserInfoM m, CacheRWM m, MonadTx m, MetadataM m)
|
2020-11-12 12:25:48 +03:00
|
|
|
=> DropPerm a -> m EncJSON
|
2020-12-08 17:22:31 +03:00
|
|
|
runDropPerm dp@(DropPerm table role) = do
|
|
|
|
tabInfo <- askTabInfo table
|
|
|
|
let permType = permAccToType $ getPermAcc2 dp
|
|
|
|
askPermInfo tabInfo role $ getPermAcc2 dp
|
|
|
|
withNewInconsistentObjsCheck
|
|
|
|
$ buildSchemaCache
|
|
|
|
$ MetadataModifier
|
|
|
|
$ metaTables.ix table %~ dropPermissionInMetadata role permType
|
2020-11-12 12:25:48 +03:00
|
|
|
return successMsg
|
|
|
|
|
2020-12-08 17:22:31 +03:00
|
|
|
dropPermissionInMetadata
|
|
|
|
:: RoleName -> PermType -> TableMetadata -> TableMetadata
|
|
|
|
dropPermissionInMetadata rn = \case
|
|
|
|
PTInsert -> tmInsertPermissions %~ OMap.delete rn
|
|
|
|
PTSelect -> tmSelectPermissions %~ OMap.delete rn
|
|
|
|
PTDelete -> tmDeletePermissions %~ OMap.delete rn
|
|
|
|
PTUpdate -> tmUpdatePermissions %~ OMap.delete rn
|
|
|
|
|
2018-06-27 16:11:32 +03:00
|
|
|
buildInsPermInfo
|
2019-11-20 21:21:30 +03:00
|
|
|
:: (QErrM m, TableCoreInfoRM m)
|
2019-12-15 19:07:08 +03:00
|
|
|
=> QualifiedTable
|
2020-10-22 23:42:27 +03:00
|
|
|
-> FieldInfoMap (FieldInfo 'Postgres)
|
2020-11-02 14:50:40 +03:00
|
|
|
-> PermDef (InsPerm 'Postgres)
|
2020-10-22 23:42:27 +03:00
|
|
|
-> m (WithDeps (InsPermInfo 'Postgres))
|
2020-04-24 12:10:53 +03:00
|
|
|
buildInsPermInfo tn fieldInfoMap (PermDef _rn (InsPerm checkCond set mCols mBackendOnly) _) =
|
2019-04-17 12:48:41 +03:00
|
|
|
withPathK "permission" $ do
|
2020-02-13 10:38:49 +03:00
|
|
|
(be, beDeps) <- withPathK "check" $ procBoolExp tn fieldInfoMap checkCond
|
2019-12-15 19:07:08 +03:00
|
|
|
(setColsSQL, setHdrs, setColDeps) <- procSetObj tn fieldInfoMap set
|
|
|
|
void $ withPathK "columns" $ indexedForM insCols $ \col ->
|
|
|
|
askPGType fieldInfoMap col ""
|
2020-02-13 10:38:49 +03:00
|
|
|
let fltrHeaders = getDependentHeaders checkCond
|
2019-12-15 19:07:08 +03:00
|
|
|
reqHdrs = fltrHeaders `union` setHdrs
|
|
|
|
insColDeps = map (mkColDep DRUntyped tn) insCols
|
|
|
|
deps = mkParentDep tn : beDeps ++ setColDeps ++ insColDeps
|
|
|
|
insColsWithoutPresets = insCols \\ HM.keys setColsSQL
|
2020-04-24 12:10:53 +03:00
|
|
|
return (InsPermInfo (HS.fromList insColsWithoutPresets) be setColsSQL backendOnly reqHdrs, deps)
|
2018-06-27 16:11:32 +03:00
|
|
|
where
|
2020-10-28 19:40:33 +03:00
|
|
|
backendOnly = Just True == mBackendOnly
|
2019-09-19 07:47:36 +03:00
|
|
|
allCols = map pgiColumn $ getCols fieldInfoMap
|
2020-10-28 19:40:33 +03:00
|
|
|
insCols = maybe allCols (convColSpec fieldInfoMap) mCols
|
2018-06-27 16:11:32 +03:00
|
|
|
|
2020-10-22 23:42:27 +03:00
|
|
|
-- TODO this is a dirty hack, hardcoding permissions to postgres. When
|
|
|
|
-- implementing support for other backends, the type family 'PermInfo' probably
|
|
|
|
-- needs to be refactored.
|
2020-11-02 14:50:40 +03:00
|
|
|
type instance PermInfo (InsPerm b) = InsPermInfo b
|
2018-06-27 16:11:32 +03:00
|
|
|
|
2020-11-02 14:50:40 +03:00
|
|
|
instance IsPerm (InsPerm 'Postgres) where
|
2018-06-27 16:11:32 +03:00
|
|
|
permAccessor = PAInsert
|
|
|
|
buildPermInfo = buildInsPermInfo
|
|
|
|
|
2020-12-08 17:22:31 +03:00
|
|
|
addPermToMetadata permDef =
|
|
|
|
tmInsertPermissions %~ OMap.insert (_pdRole permDef) permDef
|
|
|
|
|
2018-06-27 16:11:32 +03:00
|
|
|
buildSelPermInfo
|
2019-11-20 21:21:30 +03:00
|
|
|
:: (QErrM m, TableCoreInfoRM m)
|
2019-12-15 19:07:08 +03:00
|
|
|
=> QualifiedTable
|
2020-10-22 23:42:27 +03:00
|
|
|
-> FieldInfoMap (FieldInfo 'Postgres)
|
2020-11-02 14:50:40 +03:00
|
|
|
-> SelPerm 'Postgres
|
2020-10-22 23:42:27 +03:00
|
|
|
-> m (WithDeps (SelPermInfo 'Postgres))
|
2019-12-15 19:07:08 +03:00
|
|
|
buildSelPermInfo tn fieldInfoMap sp = withPathK "permission" $ do
|
2018-06-27 16:11:32 +03:00
|
|
|
let pgCols = convColSpec fieldInfoMap $ spColumns sp
|
|
|
|
|
|
|
|
(be, beDeps) <- withPathK "filter" $
|
2018-11-16 15:40:23 +03:00
|
|
|
procBoolExp tn fieldInfoMap $ spFilter sp
|
2018-06-27 16:11:32 +03:00
|
|
|
|
|
|
|
-- check if the columns exist
|
|
|
|
void $ withPathK "columns" $ indexedForM pgCols $ \pgCol ->
|
|
|
|
askPGType fieldInfoMap pgCol autoInferredErr
|
|
|
|
|
2019-10-18 11:29:47 +03:00
|
|
|
-- validate computed fields
|
2019-11-07 17:39:48 +03:00
|
|
|
scalarComputedFields <-
|
|
|
|
withPathK "computed_fields" $ indexedForM computedFields $ \fieldName -> do
|
|
|
|
computedFieldInfo <- askComputedFieldInfo fieldInfoMap fieldName
|
|
|
|
case _cfiReturnType computedFieldInfo of
|
|
|
|
CFRScalar _ -> pure fieldName
|
|
|
|
CFRSetofTable returnTable -> throw400 NotSupported $
|
|
|
|
"select permissions on computed field " <> fieldName
|
|
|
|
<<> " are auto-derived from the permissions on its returning table "
|
|
|
|
<> returnTable <<> " and cannot be specified manually"
|
2019-10-18 11:29:47 +03:00
|
|
|
|
2019-08-17 00:35:22 +03:00
|
|
|
let deps = mkParentDep tn : beDeps ++ map (mkColDep DRUntyped tn) pgCols
|
2019-11-07 17:39:48 +03:00
|
|
|
++ map (mkComputedFieldDep DRUntyped tn) scalarComputedFields
|
2018-06-27 16:11:32 +03:00
|
|
|
depHeaders = getDependentHeaders $ spFilter sp
|
2018-08-06 15:15:08 +03:00
|
|
|
mLimit = spLimit sp
|
|
|
|
|
|
|
|
withPathK "limit" $ mapM_ onlyPositiveInt mLimit
|
2018-06-27 16:11:32 +03:00
|
|
|
|
2019-10-18 11:29:47 +03:00
|
|
|
return ( SelPermInfo (HS.fromList pgCols) (HS.fromList computedFields)
|
2020-06-25 06:33:37 +03:00
|
|
|
be mLimit allowAgg depHeaders
|
2019-10-18 11:29:47 +03:00
|
|
|
, deps
|
|
|
|
)
|
2018-06-27 16:11:32 +03:00
|
|
|
where
|
2019-10-18 11:29:47 +03:00
|
|
|
allowAgg = spAllowAggregations sp
|
|
|
|
computedFields = spComputedFields sp
|
2018-06-27 16:11:32 +03:00
|
|
|
autoInferredErr = "permissions for relationships are automatically inferred"
|
|
|
|
|
2020-11-02 14:50:40 +03:00
|
|
|
type CreateSelPerm b = CreatePerm (SelPerm b)
|
2018-06-27 16:11:32 +03:00
|
|
|
|
2020-10-22 23:42:27 +03:00
|
|
|
-- TODO see TODO for PermInfo above.
|
2020-11-02 14:50:40 +03:00
|
|
|
type instance PermInfo (SelPerm b) = SelPermInfo b
|
2018-06-27 16:11:32 +03:00
|
|
|
|
2020-11-02 14:50:40 +03:00
|
|
|
instance IsPerm (SelPerm 'Postgres) where
|
2018-06-27 16:11:32 +03:00
|
|
|
permAccessor = PASelect
|
2019-12-15 19:07:08 +03:00
|
|
|
buildPermInfo tn fieldInfoMap (PermDef _ a _) =
|
|
|
|
buildSelPermInfo tn fieldInfoMap a
|
2018-06-27 16:11:32 +03:00
|
|
|
|
2020-12-08 17:22:31 +03:00
|
|
|
addPermToMetadata permDef =
|
|
|
|
tmSelectPermissions %~ OMap.insert (_pdRole permDef) permDef
|
|
|
|
|
2020-11-02 14:50:40 +03:00
|
|
|
type CreateUpdPerm b = CreatePerm (UpdPerm b)
|
2018-06-27 16:11:32 +03:00
|
|
|
|
|
|
|
buildUpdPermInfo
|
2019-11-20 21:21:30 +03:00
|
|
|
:: (QErrM m, TableCoreInfoRM m)
|
2019-12-15 19:07:08 +03:00
|
|
|
=> QualifiedTable
|
2020-10-22 23:42:27 +03:00
|
|
|
-> FieldInfoMap (FieldInfo 'Postgres)
|
2020-11-02 14:50:40 +03:00
|
|
|
-> UpdPerm 'Postgres
|
2020-10-22 23:42:27 +03:00
|
|
|
-> m (WithDeps (UpdPermInfo 'Postgres))
|
2020-02-13 10:38:49 +03:00
|
|
|
buildUpdPermInfo tn fieldInfoMap (UpdPerm colSpec set fltr check) = do
|
2018-06-27 16:11:32 +03:00
|
|
|
(be, beDeps) <- withPathK "filter" $
|
2018-11-16 15:40:23 +03:00
|
|
|
procBoolExp tn fieldInfoMap fltr
|
2020-04-24 12:10:53 +03:00
|
|
|
|
2020-02-13 10:38:49 +03:00
|
|
|
checkExpr <- traverse (withPathK "check" . procBoolExp tn fieldInfoMap) check
|
2018-06-27 16:11:32 +03:00
|
|
|
|
2019-12-15 19:07:08 +03:00
|
|
|
(setColsSQL, setHeaders, setColDeps) <- procSetObj tn fieldInfoMap set
|
2019-02-11 15:45:30 +03:00
|
|
|
|
2018-06-27 16:11:32 +03:00
|
|
|
-- check if the columns exist
|
2019-06-21 14:04:21 +03:00
|
|
|
void $ withPathK "columns" $ indexedForM updCols $ \updCol ->
|
2018-06-27 16:11:32 +03:00
|
|
|
askPGType fieldInfoMap updCol relInUpdErr
|
|
|
|
|
2019-08-17 00:35:22 +03:00
|
|
|
let updColDeps = map (mkColDep DRUntyped tn) updCols
|
2020-02-13 10:38:49 +03:00
|
|
|
deps = mkParentDep tn : beDeps ++ maybe [] snd checkExpr ++ updColDeps ++ setColDeps
|
2018-06-27 16:11:32 +03:00
|
|
|
depHeaders = getDependentHeaders fltr
|
2019-02-11 15:45:30 +03:00
|
|
|
reqHeaders = depHeaders `union` setHeaders
|
|
|
|
updColsWithoutPreSets = updCols \\ HM.keys setColsSQL
|
2018-06-27 16:11:32 +03:00
|
|
|
|
2020-02-13 10:38:49 +03:00
|
|
|
return (UpdPermInfo (HS.fromList updColsWithoutPreSets) tn be (fst <$> checkExpr) setColsSQL reqHeaders, deps)
|
2018-06-27 16:11:32 +03:00
|
|
|
|
|
|
|
where
|
|
|
|
updCols = convColSpec fieldInfoMap colSpec
|
|
|
|
relInUpdErr = "relationships can't be used in update"
|
|
|
|
|
2020-10-22 23:42:27 +03:00
|
|
|
-- TODO see TODO for PermInfo above
|
2020-11-02 14:50:40 +03:00
|
|
|
type instance PermInfo (UpdPerm b) = UpdPermInfo b
|
2018-06-27 16:11:32 +03:00
|
|
|
|
2020-11-02 14:50:40 +03:00
|
|
|
instance IsPerm (UpdPerm 'Postgres) where
|
2018-06-27 16:11:32 +03:00
|
|
|
permAccessor = PAUpdate
|
2019-12-15 19:07:08 +03:00
|
|
|
buildPermInfo tn fieldInfoMap (PermDef _ a _) =
|
|
|
|
buildUpdPermInfo tn fieldInfoMap a
|
2018-06-27 16:11:32 +03:00
|
|
|
|
2020-12-08 17:22:31 +03:00
|
|
|
addPermToMetadata permDef =
|
|
|
|
tmUpdatePermissions %~ OMap.insert (_pdRole permDef) permDef
|
|
|
|
|
2020-11-02 14:50:40 +03:00
|
|
|
type CreateDelPerm b = CreatePerm (DelPerm b)
|
2018-06-27 16:11:32 +03:00
|
|
|
|
|
|
|
buildDelPermInfo
|
2019-11-20 21:21:30 +03:00
|
|
|
:: (QErrM m, TableCoreInfoRM m)
|
2019-12-15 19:07:08 +03:00
|
|
|
=> QualifiedTable
|
2020-10-22 23:42:27 +03:00
|
|
|
-> FieldInfoMap (FieldInfo 'Postgres)
|
2020-11-02 14:50:40 +03:00
|
|
|
-> DelPerm 'Postgres
|
2020-10-22 23:42:27 +03:00
|
|
|
-> m (WithDeps (DelPermInfo 'Postgres))
|
2019-12-15 19:07:08 +03:00
|
|
|
buildDelPermInfo tn fieldInfoMap (DelPerm fltr) = do
|
2018-06-27 16:11:32 +03:00
|
|
|
(be, beDeps) <- withPathK "filter" $
|
2018-11-16 15:40:23 +03:00
|
|
|
procBoolExp tn fieldInfoMap fltr
|
2018-06-27 16:11:32 +03:00
|
|
|
let deps = mkParentDep tn : beDeps
|
|
|
|
depHeaders = getDependentHeaders fltr
|
2018-11-16 15:40:23 +03:00
|
|
|
return (DelPermInfo tn be depHeaders, deps)
|
2018-06-27 16:11:32 +03:00
|
|
|
|
2020-10-22 23:42:27 +03:00
|
|
|
-- TODO see TODO for PermInfo above
|
2020-11-02 14:50:40 +03:00
|
|
|
type instance PermInfo (DelPerm b) = DelPermInfo b
|
2018-06-27 16:11:32 +03:00
|
|
|
|
2020-11-02 14:50:40 +03:00
|
|
|
instance IsPerm (DelPerm 'Postgres) where
|
2018-06-27 16:11:32 +03:00
|
|
|
permAccessor = PADelete
|
2019-12-15 19:07:08 +03:00
|
|
|
buildPermInfo tn fieldInfoMap (PermDef _ a _) =
|
|
|
|
buildDelPermInfo tn fieldInfoMap a
|
2018-06-27 16:11:32 +03:00
|
|
|
|
2020-12-08 17:22:31 +03:00
|
|
|
addPermToMetadata permDef =
|
|
|
|
tmDeletePermissions %~ OMap.insert (_pdRole permDef) permDef
|
|
|
|
|
2018-06-27 16:11:32 +03:00
|
|
|
data SetPermComment
|
|
|
|
= SetPermComment
|
|
|
|
{ apTable :: !QualifiedTable
|
|
|
|
, apRole :: !RoleName
|
|
|
|
, apPermission :: !PermType
|
2020-10-27 16:53:49 +03:00
|
|
|
, apComment :: !(Maybe Text)
|
2020-11-26 16:57:03 +03:00
|
|
|
} deriving (Show, Eq)
|
2018-06-27 16:11:32 +03:00
|
|
|
|
|
|
|
$(deriveJSON (aesonDrop 2 snakeCase) ''SetPermComment)
|
|
|
|
|
2018-12-13 10:26:15 +03:00
|
|
|
setPermCommentP1 :: (UserInfoM m, QErrM m, CacheRM m) => SetPermComment -> m ()
|
2018-06-27 16:11:32 +03:00
|
|
|
setPermCommentP1 (SetPermComment qt rn pt _) = do
|
|
|
|
tabInfo <- askTabInfo qt
|
|
|
|
action tabInfo
|
|
|
|
where
|
|
|
|
action tabInfo = case pt of
|
|
|
|
PTInsert -> assertPermDefined rn PAInsert tabInfo
|
|
|
|
PTSelect -> assertPermDefined rn PASelect tabInfo
|
|
|
|
PTUpdate -> assertPermDefined rn PAUpdate tabInfo
|
|
|
|
PTDelete -> assertPermDefined rn PADelete tabInfo
|
|
|
|
|
2019-03-18 19:22:21 +03:00
|
|
|
setPermCommentP2 :: (QErrM m, MonadTx m) => SetPermComment -> m EncJSON
|
2018-06-27 16:11:32 +03:00
|
|
|
setPermCommentP2 apc = do
|
|
|
|
liftTx $ setPermCommentTx apc
|
|
|
|
return successMsg
|
|
|
|
|
2018-12-13 10:26:15 +03:00
|
|
|
runSetPermComment
|
|
|
|
:: (QErrM m, CacheRM m, MonadTx m, UserInfoM m)
|
2019-03-18 19:22:21 +03:00
|
|
|
=> SetPermComment -> m EncJSON
|
2018-12-13 10:26:15 +03:00
|
|
|
runSetPermComment defn = do
|
|
|
|
setPermCommentP1 defn
|
|
|
|
setPermCommentP2 defn
|
2018-06-27 16:11:32 +03:00
|
|
|
|
|
|
|
setPermCommentTx
|
|
|
|
:: SetPermComment
|
|
|
|
-> Q.TxE QErr ()
|
2019-01-25 06:31:54 +03:00
|
|
|
setPermCommentTx (SetPermComment (QualifiedObject sn tn) rn pt comment) =
|
2018-06-27 16:11:32 +03:00
|
|
|
Q.unitQE defaultTxErrorHandler [Q.sql|
|
|
|
|
UPDATE hdb_catalog.hdb_permission
|
|
|
|
SET comment = $1
|
|
|
|
WHERE table_schema = $2
|
|
|
|
AND table_name = $3
|
|
|
|
AND role_name = $4
|
|
|
|
AND perm_type = $5
|
|
|
|
|] (comment, sn, tn, rn, permTypeToCode pt) True
|
|
|
|
|
2019-08-17 00:35:22 +03:00
|
|
|
fetchPermDef
|
|
|
|
:: QualifiedTable
|
|
|
|
-> RoleName
|
|
|
|
-> PermType
|
2020-10-27 16:53:49 +03:00
|
|
|
-> Q.TxE QErr (Value, Maybe Text)
|
2019-08-17 00:35:22 +03:00
|
|
|
fetchPermDef (QualifiedObject sn tn) rn pt =
|
2020-10-28 19:40:33 +03:00
|
|
|
first Q.getAltJ . Q.getRow <$> Q.withQE defaultTxErrorHandler
|
2019-08-17 00:35:22 +03:00
|
|
|
[Q.sql|
|
|
|
|
SELECT perm_def::json, comment
|
|
|
|
FROM hdb_catalog.hdb_permission
|
|
|
|
WHERE table_schema = $1
|
|
|
|
AND table_name = $2
|
|
|
|
AND role_name = $3
|
|
|
|
AND perm_type = $4
|
|
|
|
|] (sn, tn, rn, permTypeToCode pt) True
|