graphql-engine/server/src-lib/Data/HashMap/Strict/InsOrd/Extended.hs
Swann Moreau 8bd34b4a51 server, pro: add support for per-role allowlists
spec: https://github.com/hasura/graphql-engine-mono/pull/2278

Briefly:
- extend metadata so that allowlist entries get a new scope field
- update `add_collection_to_allowlist` to accept this new scope field,
  and adds `update_scope_of_collection_in_allowlist` to change the scope
- scope can be global or role-based; a collection is available for every
  role if it is global, and available to every listed role if it is role-based
- graphql-engine-oss is aware of role-based allowlist metadata; collections
  with non-global scope are treated as if they weren't in the allowlist

To run the tests:
- `cabal run graphql-engine-tests -- unit --match Allowlist`
- py-tests against pro:
  - launch `graphql-engine-pro` with `HASURA_GRAPHQL_ADMIN_SECRET` and `HASURA_GRAPHQL_ENABLE_ALLOWLIST`
  - `pytest test_allowlist_queries.py --hge-urls=... --pg-urls=... --hge-key=... --test-allowlist-queries --pro-tests`

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/2477
Co-authored-by: Anon Ray <616387+ecthiender@users.noreply.github.com>
Co-authored-by: Robert <132113+robx@users.noreply.github.com>
GitOrigin-RevId: 01f8026fbe59d8701e2de30986511a452fce1a99
2022-02-08 16:54:49 +00:00

57 lines
1.5 KiB
Haskell

module Data.HashMap.Strict.InsOrd.Extended
( module OMap,
groupTuples,
groupListWith,
partition,
alterF,
)
where
import Data.HashMap.Strict.InsOrd as OMap
import Data.Hashable (Hashable)
import Data.List qualified as L
import Data.Sequence.NonEmpty qualified as NE
import Prelude
groupTuples ::
(Eq k, Hashable k, Foldable t) =>
t (k, v) ->
OMap.InsOrdHashMap k (NE.NESeq v)
groupTuples =
L.foldl' groupFlds OMap.empty
where
groupFlds m (k, v) =
OMap.insertWith (flip (<>)) k (NE.singleton v) m
groupListWith ::
(Eq k, Hashable k, Foldable t, Functor t) =>
(v -> k) ->
t v ->
OMap.InsOrdHashMap k (NE.NESeq v)
groupListWith f l =
groupTuples $ fmap (\v -> (f v, v)) l
partition :: (Eq k, Hashable k) => (v -> Bool) -> OMap.InsOrdHashMap k v -> (OMap.InsOrdHashMap k v, OMap.InsOrdHashMap k v)
partition predicate =
OMap.foldlWithKey'
( \(left, right) key val ->
if (predicate val)
then (OMap.insert key val left, right)
else (left, OMap.insert key val right)
)
(mempty, mempty)
-- | Alter a hashmap using a function that can fail, in which case the entire operation fails.
-- (Maybe a version with the key also being passed to the function could be useful.)
alterF ::
(Functor f, Eq k, Hashable k) =>
(Maybe v -> f (Maybe v)) ->
k ->
InsOrdHashMap k v ->
f (InsOrdHashMap k v)
alterF f k m = alter' <$> f (OMap.lookup k m)
where
alter' = \case
Nothing -> OMap.delete k m
Just v -> OMap.insert k v m