Skip to content

Commit 5168b99

Browse files
author
Antoine Leblanc
committed
[skip ci] add column permission propagation
1 parent f5d3172 commit 5168b99

File tree

1 file changed

+45
-46
lines changed
  • server/src-lib/Hasura/GraphQL/Schema

1 file changed

+45
-46
lines changed

server/src-lib/Hasura/GraphQL/Schema/Select.hs

+45-46
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module Hasura.GraphQL.Schema.Select where
33
import Hasura.Prelude
44

55
import qualified Data.HashMap.Strict as Map
6+
import qualified Data.HashSet as Set
67
import qualified Language.GraphQL.Draft.Syntax as G
78

89
import qualified Hasura.GraphQL.Parser as P
@@ -19,10 +20,11 @@ import Hasura.SQL.Value
1920

2021

2122

22-
type SelectExp = RQL.AnnSimpleSelG UnpreparedValue
23-
type TableArgs = RQL.TableArgsG UnpreparedValue
24-
type TablePerms = RQL.TablePermG UnpreparedValue
25-
23+
type SelectExp = RQL.AnnSimpleSelG UnpreparedValue
24+
type TableArgs = RQL.TableArgsG UnpreparedValue
25+
type TablePerms = RQL.TablePermG UnpreparedValue
26+
type AnnotatedFields = RQL.AnnFldsG UnpreparedValue
27+
type AnnotatedField = RQL.AnnFldG UnpreparedValue
2628

2729

2830
queryExp
@@ -32,54 +34,59 @@ queryExp
3234
-> m (Parser 'Output n (HashMap G.Name SelectExp))
3335
queryExp allTables stringifyNum = do
3436
selectExpParsers <- for (toList allTables) $ \tableName -> do
35-
tablePermissions <- tablePerms tableName
36-
for tablePermissions $ \perms ->
37-
selectExp tableName perms stringifyNum
37+
selPerms <- tableSelectPermissions tableName
38+
for selPerms $ \perms -> selectExp tableName perms stringifyNum
3839
let queryFieldsParser = fmap (Map.fromList . catMaybes) $ sequenceA $ catMaybes selectExpParsers
3940
pure $ P.selectionSet $$(G.litName "Query") Nothing queryFieldsParser
4041

41-
42-
43-
4442
selectExp
4543
:: forall m n. (MonadSchema n m, MonadError QErr m)
4644
=> QualifiedTable
47-
-> TablePerms
45+
-> SelPermInfo
4846
-> Bool
4947
-> m (FieldsParser 'Output n (Maybe (G.Name, SelectExp)))
50-
selectExp table tablePermissions stringifyNum = do
48+
selectExp table selectPermissions stringifyNum = do
5149
name <- qualifiedObjectToName table
5250
tableArgsParser <- tableArgs table
53-
selectionSetParser <- tableSelectionSet table
51+
selectionSetParser <- tableSelectionSet table selectPermissions
5452
return $ P.selection name Nothing tableArgsParser selectionSetParser <&> fmap
5553
\(aliasName, tableArgs, tableFields) -> (aliasName, RQL.AnnSelG
5654
{ RQL._asnFields = tableFields
5755
, RQL._asnFrom = RQL.FromTable table
58-
, RQL._asnPerm = tablePermissions
56+
, RQL._asnPerm = tablePermissions selectPermissions
5957
, RQL._asnArgs = tableArgs
6058
, RQL._asnStrfyNum = stringifyNum
6159
})
6260

63-
64-
tablePerms
61+
tableSelectPermissions
6562
:: forall m n. (MonadSchema n m)
6663
=> QualifiedTable
67-
-> m (Maybe TablePerms)
68-
tablePerms table = do
64+
-> m (Maybe SelPermInfo)
65+
tableSelectPermissions table = do
6966
roleName <- askRoleName
7067
tableInfo <- _tiRolePermInfoMap <$> askTableInfo table
71-
return $ do
72-
rolePermissions <- Map.lookup roleName tableInfo
73-
selectPermissions <- _permSel rolePermissions
74-
return $ RQL.TablePerm
75-
{ RQL._tpFilter = fmapAnnBoolExp toUnpreparedValue $ spiFilter selectPermissions
76-
, RQL._tpLimit = spiLimit selectPermissions
77-
}
68+
return $ _permSel =<< Map.lookup roleName tableInfo
69+
70+
tablePermissions :: SelPermInfo -> TablePerms
71+
tablePermissions selectPermissions =
72+
RQL.TablePerm { RQL._tpFilter = fmapAnnBoolExp toUnpreparedValue $ spiFilter selectPermissions
73+
, RQL._tpLimit = spiLimit selectPermissions
74+
}
7875
where
7976
toUnpreparedValue (PSESessVar pftype var) = P.UVSessionVar pftype var
80-
toUnpreparedValue (PSESQLExp exp) = P.UVLiteral exp
77+
toUnpreparedValue (PSESQLExp sqlExp) = P.UVLiteral sqlExp
8178

8279

80+
-- | Corresponds to an object type for table argumuments:
81+
--
82+
-- FIXME: is that the correct name?
83+
-- > type table_arguments {
84+
-- > distinct_on: [card_types_select_column!]
85+
-- > limit: Int
86+
-- > offset: Int
87+
-- > order_by: [card_types_order_by!]
88+
-- > where: card_types_bool_exp
89+
-- > }
8390
tableArgs
8491
:: forall m n. (MonadSchema n m, MonadError QErr m)
8592
=> QualifiedTable
@@ -95,25 +102,12 @@ tableArgs table = do
95102
, RQL._taOrderBy = Nothing -- TODO
96103
, RQL._taLimit = fromIntegral <$> limit
97104
, RQL._taOffset = txtEncoder . PGValInteger <$> offset
98-
, RQL._taDistCols = Nothing
105+
, RQL._taDistCols = Nothing -- TODO
99106
}
100107
where limitName = $$(G.litName "limit")
101108
offsetName = $$(G.litName "offset")
102109
whereName = $$(G.litName "where")
103110

104-
-- SELit . Text.pack . show <$>
105-
{-
106-
distinct_on: [card_types_select_column!]
107-
limit: Intoffset: Int
108-
order_by: [card_types_order_by!]
109-
where: card_types_bool_exp
110-
-}
111-
112-
113-
type AnnotatedFields = RQL.AnnFldsG UnpreparedValue
114-
type AnnotatedField = RQL.AnnFldG UnpreparedValue
115-
116-
117111

118112
-- | Corresponds to an object type for a table:
119113
--
@@ -125,12 +119,14 @@ type AnnotatedField = RQL.AnnFldG UnpreparedValue
125119
tableSelectionSet
126120
:: (MonadSchema n m, MonadError QErr m)
127121
=> QualifiedTable
122+
-> SelPermInfo
128123
-> m (Parser 'Output n AnnotatedFields)
129-
tableSelectionSet = P.memoize 'tableSelectionSet \tableName -> do
124+
tableSelectionSet tableName selectPermissions = memoizeOn 'tableSelectionSet tableName $ do
130125
tableInfo <- _tiCoreInfo <$> askTableInfo tableName
131126
name <- qualifiedObjectToName $ _tciName tableInfo
132-
-- FIXME: permissions!
133-
fields <- catMaybes <$> traverse fieldSelection (Map.elems $ _tciFieldInfoMap tableInfo)
127+
fields <- fmap catMaybes $ traverse (fieldSelection selectPermissions)
128+
$ Map.elems
129+
$ _tciFieldInfoMap tableInfo
134130
pure $ P.selectionSet name (_tciDescription tableInfo) $ catMaybes <$> sequenceA fields
135131

136132
-- | A field for a table. Returns 'Nothing' if the field’s name is not a valid
@@ -139,14 +135,17 @@ tableSelectionSet = P.memoize 'tableSelectionSet \tableName -> do
139135
-- > field_name(arg_name: arg_type, ...): field_type
140136
fieldSelection
141137
:: (MonadSchema n m, MonadError QErr m)
142-
=> FieldInfo
138+
=> SelPermInfo
139+
-> FieldInfo
143140
-> m (Maybe (FieldsParser 'Output n (Maybe (FieldName, AnnotatedField))))
144-
fieldSelection fieldInfo = for (fieldInfoGraphQLName fieldInfo) \fieldName ->
141+
fieldSelection selectPermissions fieldInfo = for (fieldInfoGraphQLName fieldInfo) \fieldName ->
145142
aliasToFieldName <$> case fieldInfo of
146143
FIColumn columnInfo -> do
147144
let annotated = RQL.mkAnnColField columnInfo Nothing -- FIXME: support ColOp
148145
field <- P.column (pgiType columnInfo) (G.Nullability $ pgiIsNullable columnInfo)
149-
pure $ fmap (, annotated) <$> P.selection_ fieldName fieldDescription field
146+
pure $ if Set.member (pgiColumn columnInfo) $ spiCols selectPermissions
147+
then fmap (, annotated) <$> P.selection_ fieldName fieldDescription field
148+
else pure Nothing
150149
FIRelationship relationshipInfo -> undefined -- TODO: implement
151150
FIComputedField computedFieldInfo -> undefined -- TODO: implement
152151
where

0 commit comments

Comments
 (0)