Skip to content

Commit 5699ebd

Browse files
committed
List groups in UserGroupSubsystem.
1 parent deb9377 commit 5699ebd

File tree

1 file changed

+69
-5
lines changed

1 file changed

+69
-5
lines changed

libs/wire-subsystems/src/Wire/UserGroupSubsystem/Interpreter.hs

Lines changed: 69 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1+
{-# LANGUAGE RecordWildCards #-}
2+
13
module Wire.UserGroupSubsystem.Interpreter where
24

35
import Control.Error (MaybeT (..))
46
import Control.Lens ((^.))
57
import Data.Default
68
import Data.Id
7-
import Data.Json.Util (ToJSONObject (toJSONObject))
9+
import Data.Json.Util
810
import Data.Qualified (Local, Qualified (qUnqualified), qualifyAs, tUnqualified)
911
import Data.Set qualified as Set
12+
import Data.Text qualified as T
1013
import Imports
1114
import Polysemy
1215
import Polysemy.Error
@@ -49,6 +52,7 @@ data UserGroupSubsystemError
4952
= UserGroupNotATeamAdmin
5053
| UserGroupMemberIsNotInTheSameTeam
5154
| UserGroupNotFound
55+
| UserGroupInvalidQueryParams Text
5256
deriving (Show, Eq)
5357

5458
userGroupSubsystemErrorToHttpError :: UserGroupSubsystemError -> HttpError
@@ -57,6 +61,7 @@ userGroupSubsystemErrorToHttpError =
5761
UserGroupNotATeamAdmin -> errorToWai @E.UserGroupNotATeamAdmin
5862
UserGroupMemberIsNotInTheSameTeam -> errorToWai @E.UserGroupMemberIsNotInTheSameTeam
5963
UserGroupNotFound -> errorToWai @E.UserGroupNotFound
64+
UserGroupInvalidQueryParams msg -> _ msg
6065

6166
createUserGroupImpl ::
6267
( Member UserSubsystem r,
@@ -134,24 +139,83 @@ getUserGroupImpl ::
134139
Sem r (Maybe UserGroup)
135140
getUserGroupImpl getter gid = runMaybeT $ do
136141
team <- MaybeT $ getUserTeam getter
137-
getterCanSeeAll <- do
138-
creatorTeamMember <- MaybeT $ getTeamMember getter team
139-
pure . isAdminOrOwner $ creatorTeamMember ^. permissions
142+
getterCanSeeAll <- mkGetterCanSeeAll getter team
140143
userGroup <- MaybeT $ Store.getUserGroup team gid
141144
if getterCanSeeAll || getter `elem` (toList userGroup.members)
142145
then pure userGroup
143146
else MaybeT $ pure Nothing
144147

148+
mkGetterCanSeeAll ::
149+
forall r.
150+
(Member GalleyAPIAccess r) =>
151+
UserId ->
152+
TeamId ->
153+
MaybeT (Sem r) Bool
154+
mkGetterCanSeeAll getter team = do
155+
creatorTeamMember <- MaybeT $ getTeamMember getter team
156+
pure . isAdminOrOwner $ creatorTeamMember ^. permissions
157+
145158
getUserGroupsImpl ::
146159
forall r.
160+
( Member UserSubsystem r,
161+
Member Store.UserGroupStore r,
162+
Member GalleyAPIAccess r,
163+
Member (Error UserGroupSubsystemError) r
164+
) =>
147165
UserId ->
148166
Maybe Text ->
149167
Maybe SortBy ->
150168
Maybe SortOrder ->
151169
Maybe PageSize ->
152170
Maybe PaginationState ->
153171
Sem r (PaginationResult UserGroup)
154-
getUserGroupsImpl = undefined
172+
getUserGroupsImpl getter q sortByKeys' sortOrder' pSize pState = do
173+
team :: TeamId <- getUserTeam getter >>= ifNothing UserGroupNotATeamAdmin {- sic! -}
174+
getterCanSeeAll :: Bool <- fromMaybe False <$> runMaybeT (mkGetterCanSeeAll getter team)
175+
unless (getterCanSeeAll) $ throw UserGroupNotATeamAdmin
176+
checkPaginationState `mapM_` pState
177+
details <- either (throw . UserGroupInvalidQueryParams) pure (mkQueryDetails team)
178+
page :: [UserGroup] <- Store.getUserGroups details
179+
pure (PaginationResult page (newPaginationState page))
180+
where
181+
ifNothing :: UserGroupSubsystemError -> Maybe a -> Sem r a
182+
ifNothing e = maybe (throw e) pure
183+
184+
-- TODO: try to push most of this to Wire.API.Pagination
185+
186+
checkPaginationState :: PaginationState -> Sem r ()
187+
checkPaginationState st = do
188+
let badState = throw . UserGroupInvalidQueryParams . (<> " mismatch")
189+
forM_ q $ \x -> unless (st.searchString == x) (badState "searchString")
190+
forM_ sortByKeys' $ \x -> unless (st.sortByKeys == x) (badState "sortBy")
191+
forM_ sortOrder' $ \x -> unless (st.sortOrder == x) (badState "sortOrder")
192+
forM_ pSize $ \x -> unless (st.pageSize == x) (badState "pageSize")
193+
194+
newPaginationState :: [UserGroup] -> PaginationState
195+
newPaginationState ugs = case pState of
196+
Just oldState -> oldState {lastRowSent = lastRowSent}
197+
Nothing -> PaginationState {..}
198+
where
199+
searchString :: Text = fromMaybe "" q
200+
sortByKeys :: SortBy = fromMaybe (SortBy ["created_at", "name"]) sortByKeys'
201+
sortOrder :: SortOrder = fromMaybe def sortOrder'
202+
pageSize :: PageSize = fromMaybe def pSize
203+
lastRowSent :: (Text, UTCTimeMillis) = let l = last ugs in (userGroupNameToText l.name, l.createdAt)
204+
205+
mkQueryDetails :: TeamId -> Either Text Store.ListUserGroupsQuery
206+
mkQueryDetails team = do
207+
let lastRowSent = (.lastRowSent) <$> pState
208+
sortDescending = maybe True (== Desc) sortOrder'
209+
pageSize = pageSizeToInt $ fromMaybe def pSize
210+
sortByName <- case sortByKeys' of
211+
Nothing -> pure False
212+
Just (SortBy ["name"]) -> pure True
213+
Just (SortBy ["name", "created_at"]) -> pure True
214+
Just (SortBy ["created_at"]) -> pure False
215+
Just (SortBy ["created_at", "name"]) -> pure False
216+
Just (SortBy bad) ->
217+
Left $ "invalid sort keys (allowed: name,created_at); received: " <> T.intercalate "," bad <> ")"
218+
pure Store.ListUserGroupsQuery {..}
155219

156220
updateGroupImpl ::
157221
( Member UserSubsystem r,

0 commit comments

Comments
 (0)