Skip to content

Commit bfe7c5f

Browse files
committed
WPB-19713: Implement channels and channelsCount in user-groups endpoints
1 parent f1c803e commit bfe7c5f

File tree

8 files changed

+109
-6
lines changed

8 files changed

+109
-6
lines changed

changelog.d/2-features/WPB-19713

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Implement `channels` and `channelsCount` in `user-groups` endpoints.

libs/wire-api/src/Wire/API/Routes/Internal/Galley.hs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,16 @@ type InternalAPIBase =
158158
'[JSON]
159159
(Respond 200 "Clients" ClientList)
160160
)
161+
:<|> Named
162+
"get-user-groups-conversation-list"
163+
( Summary "Get user-group conversations list"
164+
:> ZLocalUser
165+
:> "user-groups"
166+
:> Capture "gid" UserGroupId
167+
:> "conversations"
168+
:> ReqBody '[Servant.JSON] GetPaginatedConversationIds
169+
:> Post '[Servant.JSON] ConvIdsPage
170+
)
161171
:<|> Named
162172
"guard-legalhold-policy-conflicts"
163173
( "guard-legalhold-policy-conflicts"

libs/wire-api/src/Wire/API/Routes/Public/Brig.hs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ type UserGroupAPI =
314314
)
315315
:<|> Named
316316
"get-user-group"
317-
( Summary "[STUB] (channels in response not implemented)"
317+
( Summary "Fetch a group accessible from the logged-in user"
318318
:> From 'V10
319319
:> ZLocalUser
320320
:> CanThrow 'UserGroupNotFound
@@ -331,7 +331,7 @@ type UserGroupAPI =
331331
)
332332
:<|> Named
333333
"get-user-groups"
334-
( Summary "[STUB] (channelsCount not implemented)"
334+
( Summary "Fetch groups accessible from the logged-in user"
335335
:> From 'V10
336336
:> ZLocalUser
337337
:> "user-groups"
@@ -342,6 +342,7 @@ type UserGroupAPI =
342342
:> QueryParam' '[Optional, Strict, LastSeenNameDesc] "last_seen_name" UserGroupName
343343
:> QueryParam' '[Optional, Strict, LastSeenCreatedAtDesc] "last_seen_created_at" UTCTimeMillis
344344
:> QueryParam' '[Optional, Strict, LastSeenIdDesc] "last_seen_id" UserGroupId
345+
:> QueryFlag "include_channels"
345346
:> QueryFlag "include_member_count"
346347
:> Get '[JSON] UserGroupPage
347348
)

libs/wire-subsystems/src/Wire/GalleyAPIAccess.hs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import Imports
2727
import Network.Wai.Utilities.Error qualified as Wai
2828
import Polysemy
2929
import Wire.API.Conversation
30+
import Wire.API.Conversation qualified as Public
3031
import Wire.API.Routes.Internal.Brig.EJPD (EJPDConvInfo)
3132
import Wire.API.Routes.Internal.Galley.TeamsIntra qualified as Team
3233
import Wire.API.Team
@@ -144,5 +145,10 @@ data GalleyAPIAccess m a where
144145
UserId ->
145146
GalleyAPIAccess m [EJPDConvInfo]
146147
GetTeamAdmins :: TeamId -> GalleyAPIAccess m Team.TeamMemberList
148+
GetUserGroupConversations ::
149+
Local UserId ->
150+
UserGroupId ->
151+
Public.GetPaginatedConversationIds ->
152+
GalleyAPIAccess m Public.ConvIdsPage
147153

148154
makeSem ''GalleyAPIAccess

libs/wire-subsystems/src/Wire/GalleyAPIAccess/Rpc.hs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import Servant.API (toHeader)
4141
import System.Logger.Message
4242
import Util.Options
4343
import Wire.API.Conversation hiding (Member)
44+
import Wire.API.Conversation qualified as Public
4445
import Wire.API.Routes.Internal.Brig.EJPD (EJPDConvInfo)
4546
import Wire.API.Routes.Internal.Galley.TeamsIntra qualified as Team
4647
import Wire.API.Routes.Version
@@ -96,6 +97,7 @@ interpretGalleyAPIAccessToRpc disabledVersions galleyEndpoint =
9697
UnblockConversation lusr mconn qcnv -> unblockConversation v lusr mconn qcnv
9798
GetEJPDConvInfo uid -> getEJPDConvInfo uid
9899
GetTeamAdmins tid -> getTeamAdmins tid
100+
GetUserGroupConversations lusr ugid page -> getUserGroupConversations lusr ugid page
99101

100102
getUserLegalholdStatus ::
101103
( Member TinyLog r,
@@ -680,3 +682,25 @@ getEJPDConvInfo uid = do
680682
getReq =
681683
method GET
682684
. paths ["i", "user", toByteString' uid, "all-conversations"]
685+
686+
getUserGroupConversations ::
687+
( Member (Error ParseException) r,
688+
Member Rpc r,
689+
Member (Input Endpoint) r,
690+
Member TinyLog r
691+
) =>
692+
Local UserId ->
693+
UserGroupId ->
694+
Public.GetPaginatedConversationIds ->
695+
Sem r Public.ConvIdsPage
696+
getUserGroupConversations lusr ugid page = do
697+
debug $ remote "galley" . msg (val "Get user group conversation")
698+
galleyRequest req >>= decodeBodyOrThrow "galley"
699+
where
700+
req =
701+
method POST
702+
. zUser (tUnqualified lusr)
703+
. paths ["i", "user-groups", toByteString' ugid, "conversations"]
704+
. header "Content-Type" "application/json"
705+
. lbytes (encode page)
706+
. expect2xx

services/brig/brig.cabal

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,8 @@ library
314314
, uri-bytestring >=0.2
315315
, utf8-string
316316
, uuid >=1.3.5
317+
, vector >=0.13.2.0
318+
, vector-builder >=0.3.8.6
317319
, wai >=3.0
318320
, wai-extra >=3.0
319321
, wai-middleware-gunzip >=0.0.2

services/brig/src/Brig/API/Public.hs

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ import Data.Qualified
8585
import Data.Range
8686
import Data.Schema ()
8787
import Data.Text.Encoding qualified as Text
88+
import Data.Vector (Vector)
89+
import Data.Vector qualified as Vector
8890
import Data.ZAuth.CryptoSign (CryptoSign)
8991
import Data.ZAuth.Token qualified as ZAuth
9092
import FileEmbedLzma
@@ -103,6 +105,8 @@ import Servant.OpenApi.Internal.Orphans ()
103105
import Servant.Swagger.UI
104106
import System.Logger.Class qualified as Log
105107
import Util.Logging (logFunction, logHandle, logTeam, logUser)
108+
import VectorBuilder.Builder qualified as VB
109+
import VectorBuilder.Vector qualified as VB
106110
import Wire.API.App
107111
import Wire.API.Connection qualified as Public
108112
import Wire.API.EnterpriseLogin
@@ -123,6 +127,7 @@ import Wire.API.Routes.Internal.Cargohold qualified as CargoholdInternalAPI
123127
import Wire.API.Routes.Internal.Galley qualified as GalleyInternalAPI
124128
import Wire.API.Routes.Internal.Gundeck qualified as GundeckInternalAPI
125129
import Wire.API.Routes.Internal.Spar qualified as SparInternalAPI
130+
import Wire.API.Routes.MultiTablePaging (GetMultiTablePageRequest (GetMultiTablePageRequest))
126131
import Wire.API.Routes.MultiTablePaging qualified as Public
127132
import Wire.API.Routes.Named (Named (Named))
128133
import Wire.API.Routes.Public.Brig
@@ -173,7 +178,7 @@ import Wire.EnterpriseLoginSubsystem qualified as EnterpriseLogin
173178
import Wire.Error
174179
import Wire.Events (Events)
175180
import Wire.FederationConfigStore (FederationConfigStore)
176-
import Wire.GalleyAPIAccess (GalleyAPIAccess)
181+
import Wire.GalleyAPIAccess (GalleyAPIAccess, getUserGroupConversations)
177182
import Wire.GalleyAPIAccess qualified as GalleyAPIAccess
178183
import Wire.HashPassword (HashPassword)
179184
import Wire.IndexedUserStore (IndexedUserStore)
@@ -1676,7 +1681,18 @@ createUserGroup :: (_) => Local UserId -> NewUserGroup -> Handler r UserGroup
16761681
createUserGroup lusr newUserGroup = lift . liftSem $ UserGroup.createGroup (tUnqualified lusr) newUserGroup
16771682

16781683
getUserGroup :: (_) => Local UserId -> UserGroupId -> Bool -> Handler r (Maybe UserGroup)
1679-
getUserGroup lusr ugid _ = lift . liftSem $ UserGroup.getGroup (tUnqualified lusr) ugid
1684+
getUserGroup lusr ugid includeChannels =
1685+
lift . liftSem $ do
1686+
mUserGroup <- UserGroup.getGroup (tUnqualified lusr) ugid
1687+
if includeChannels
1688+
then forM mUserGroup $ \userGroup -> do
1689+
fetchedChannels <- fetchChannels lusr userGroup.id_
1690+
pure
1691+
userGroup
1692+
{ channels = Identity $ Just fetchedChannels,
1693+
channelsCount = Just $ Vector.length fetchedChannels
1694+
}
1695+
else pure mUserGroup
16801696

16811697
getUserGroups ::
16821698
(_) =>
@@ -1689,9 +1705,29 @@ getUserGroups ::
16891705
Maybe UTCTimeMillis ->
16901706
Maybe UserGroupId ->
16911707
Bool ->
1708+
Bool ->
16921709
Handler r UserGroupPage
1693-
getUserGroups lusr q sortByKeys sortOrder pSize mLastName mLastCreatedAt mLastId includeMemberCount =
1694-
lift . liftSem $ UserGroup.getGroups (tUnqualified lusr) q sortByKeys sortOrder pSize mLastName mLastCreatedAt mLastId includeMemberCount
1710+
getUserGroups lusr q sortByKeys sortOrder pSize mLastName mLastCreatedAt mLastId includeChannels includeMemberCount =
1711+
lift . liftSem $ do
1712+
userGroups <- UserGroup.getGroups (tUnqualified lusr) q sortByKeys sortOrder pSize mLastName mLastCreatedAt mLastId includeMemberCount
1713+
if includeChannels
1714+
then fmap UserGroupPage $ forM userGroups.page $ \userGroup -> do
1715+
fetchedChannels <- fetchChannels lusr userGroup.id_
1716+
pure
1717+
userGroup
1718+
{ channelsCount = Just $ Vector.length fetchedChannels
1719+
}
1720+
else pure userGroups
1721+
1722+
fetchChannels :: (_) => Local UserId -> UserGroupId -> Sem r (Vector (Qualified ConvId))
1723+
fetchChannels luser ugid = do
1724+
let mkRequest = getUserGroupConversations luser ugid . GetMultiTablePageRequest (toRange $ Proxy @1000)
1725+
go acc page = do
1726+
if page.mtpHasMore
1727+
then go (page.mtpResults : acc) =<< mkRequest (Just page.mtpPagingState)
1728+
else pure $ VB.build $ foldMap VB.foldable $ reverse (page.mtpResults : acc)
1729+
page <- mkRequest Nothing
1730+
go [] page
16951731

16961732
updateUserGroup :: (_) => Local UserId -> UserGroupId -> UserGroupUpdate -> (Handler r) ()
16971733
updateUserGroup lusr gid gupd = lift . liftSem $ UserGroup.updateGroup (tUnqualified lusr) gid gupd

services/galley/src/Galley/API/Internal.hs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ import Servant
7575
import System.Logger.Class hiding (Path, name)
7676
import System.Logger.Class qualified as Log
7777
import Wire.API.Conversation hiding (Member)
78+
import Wire.API.Conversation qualified as Public
7879
import Wire.API.Conversation.Action
7980
import Wire.API.Error
8081
import Wire.API.Error.Galley
@@ -113,6 +114,7 @@ internalAPI =
113114
<@> mkNamedAPI @"delete-user" rmUser
114115
<@> mkNamedAPI @"connect" Create.createConnectConversation
115116
<@> mkNamedAPI @"get-conversation-clients" iGetMLSClientListForConv
117+
<@> mkNamedAPI @"get-user-groups-conversation-list" getUserGroupsConversations
116118
<@> mkNamedAPI @"guard-legalhold-policy-conflicts" guardLegalholdPolicyConflictsH
117119
<@> legalholdWhitelistedTeamsAPI
118120
<@> iTeamsAPI
@@ -511,3 +513,24 @@ iGetMLSClientListForConv ::
511513
iGetMLSClientListForConv gid = do
512514
cm <- E.lookupMLSClients gid
513515
pure $ ClientList (concatMap (Map.keys . snd) (Map.assocs cm))
516+
517+
-- | Get the conversations list for a given user-group
518+
getUserGroupsConversations ::
519+
-- forall p r.
520+
-- ( p ~ CassandraPaging,
521+
-- ( Member ConversationStore r,
522+
-- Member (Error InternalError) r,
523+
-- Member (Input Env) r,
524+
-- Member (ListItems p ConvId) r,
525+
-- Member (ListItems p (Remote ConvId)) r,
526+
-- Member P.TinyLog r,
527+
-- Member TeamCollaboratorsSubsystem r
528+
-- )
529+
-- ) =>
530+
Local UserId ->
531+
UserGroupId ->
532+
Public.GetPaginatedConversationIds ->
533+
Sem r Public.ConvIdsPage
534+
getUserGroupsConversations _lusr _gid MTP.GetMultiTablePageRequest {} = do
535+
-- Blocked by 17126 get inspired by @"list-conversation-ids"
536+
undefined

0 commit comments

Comments
 (0)