Skip to content

Commit 55b7418

Browse files
committed
wip
1 parent d376f36 commit 55b7418

File tree

7 files changed

+137
-162
lines changed

7 files changed

+137
-162
lines changed

libs/wire-api/src/Wire/API/Conversation.hs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ module Wire.API.Conversation
7171
ConversationMessageTimerUpdate (..),
7272
ConversationJoin (..),
7373
ConversationLeave (..),
74+
ConversationRemoveMembers (..),
7475
ConversationMemberUpdate (..),
7576
ConversationDelete (..),
7677

@@ -896,10 +897,25 @@ instance ToSchema ConversationLeave where
896897
schema =
897898
objectWithDocModifier
898899
"ConversationLeave"
899-
(description ?~ "The action of some users leaving a conversation")
900+
(description ?~ "The action of some users leaving a conversation on their own")
900901
$ ConversationLeave
901902
<$> clUsers .= field "users" (nonEmptyArray schema)
902903

904+
data ConversationRemoveMembers = ConversationRemoveMembers
905+
{ crmTargets :: NonEmpty (Qualified UserId)
906+
}
907+
deriving stock (Eq, Show, Generic)
908+
deriving (Arbitrary) via (GenericUniform ConversationRemoveMembers)
909+
deriving (FromJSON, ToJSON, S.ToSchema) via Schema ConversationRemoveMembers
910+
911+
instance ToSchema ConversationRemoveMembers where
912+
schema =
913+
objectWithDocModifier
914+
"ConversationRemoveMembers"
915+
(description ?~ "The action of some users being removed from a conversation")
916+
$ ConversationRemoveMembers
917+
<$> crmTargets .= field "targets" (nonEmptyArray schema)
918+
903919
data ConversationMemberUpdate = ConversationMemberUpdate
904920
{ cmuTarget :: Qualified UserId,
905921
cmuUpdate :: OtherMemberUpdate

libs/wire-api/src/Wire/API/Conversation/Action.hs

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@ module Wire.API.Conversation.Action
2323
SConversationActionTag (..),
2424
SomeConversationAction (..),
2525
conversationActionToEvent,
26-
conversationActionPermission
26+
conversationActionPermission,
2727
)
2828
where
2929

3030
import Data.Aeson (FromJSON (..), ToJSON (..), Value, object, withObject, (.:), (.=))
3131
import Data.Id
32-
import Data.Qualified ( Qualified )
32+
import Data.Qualified (Qualified)
3333
import Data.Schema (ToSchema, element, enum, schema, schemaParseJSON, schemaToJSON)
3434
import Data.Singletons (Sing, SomeSing (SomeSing), fromSing, toSing)
3535
import Data.Singletons.TH (genSingletons, sCases)
@@ -44,6 +44,7 @@ import Wire.API.Event.Conversation
4444
data ConversationActionTag
4545
= ConversationJoinTag
4646
| ConversationLeaveTag
47+
| ConversationRemoveMembersTag
4748
| ConversationMemberUpdateTag
4849
| ConversationDeleteTag
4950
| ConversationRenameTag
@@ -61,6 +62,7 @@ instance ToSchema ConversationActionTag where
6162
mconcat
6263
[ element "ConversationJoinTag" ConversationJoinTag,
6364
element "ConversationLeaveTag" ConversationLeaveTag,
65+
element "ConversationRemoveMembersTag" ConversationRemoveMembersTag,
6466
element "ConversationMemberUpdateTag" ConversationMemberUpdateTag,
6567
element "ConversationDeleteTag" ConversationDeleteTag,
6668
element "ConversationRenameTag" ConversationRenameTag,
@@ -86,6 +88,7 @@ type family ConversationAction (tag :: ConversationActionTag) :: * where
8688
ConversationAction 'ConversationMessageTimerUpdateTag = ConversationMessageTimerUpdate
8789
ConversationAction 'ConversationReceiptModeUpdateTag = ConversationReceiptModeUpdate
8890
ConversationAction 'ConversationAccessDataTag = ConversationAccessData
91+
ConversationAction 'ConversationRemoveMembersTag = ConversationRemoveMembers
8992

9093
data SomeConversationAction where
9194
SomeConversationAction :: Sing tag -> ConversationAction tag -> SomeConversationAction
@@ -98,14 +101,23 @@ instance Eq SomeConversationAction where
98101
(SomeConversationAction tag1 action1) == (SomeConversationAction tag2 action2) =
99102
case (tag1, tag2) of
100103
(SConversationJoinTag, SConversationJoinTag) -> action1 == action2
104+
(SConversationJoinTag, _) -> False
101105
(SConversationLeaveTag, SConversationLeaveTag) -> action1 == action2
106+
(SConversationLeaveTag, _) -> False
102107
(SConversationMemberUpdateTag, SConversationMemberUpdateTag) -> action1 == action2
108+
(SConversationMemberUpdateTag, _) -> False
103109
(SConversationDeleteTag, SConversationDeleteTag) -> action1 == action2
110+
(SConversationDeleteTag, _) -> False
104111
(SConversationRenameTag, SConversationRenameTag) -> action1 == action2
112+
(SConversationRenameTag, _) -> False
105113
(SConversationMessageTimerUpdateTag, SConversationMessageTimerUpdateTag) -> action1 == action2
114+
(SConversationMessageTimerUpdateTag, _) -> False
106115
(SConversationReceiptModeUpdateTag, SConversationReceiptModeUpdateTag) -> action1 == action2
116+
(SConversationReceiptModeUpdateTag, _) -> False
107117
(SConversationAccessDataTag, SConversationAccessDataTag) -> action1 == action2
108-
(_, _) -> False
118+
(SConversationAccessDataTag, _) -> False
119+
(SConversationRemoveMembersTag, SConversationRemoveMembersTag) -> action1 == action2
120+
(SConversationRemoveMembersTag, _) -> False
109121

110122
instance ToJSON SomeConversationAction where
111123
toJSON (SomeConversationAction sb action) =
@@ -131,6 +143,7 @@ instance Arbitrary SomeConversationAction where
131143
conversationActionPermission :: ConversationActionTag -> Action
132144
conversationActionPermission ConversationJoinTag = AddConversationMember
133145
conversationActionPermission ConversationLeaveTag = LeaveConversation
146+
conversationActionPermission ConversationRemoveMembersTag = RemoveConversationMember
134147
conversationActionPermission ConversationMemberUpdateTag = ModifyOtherConversationMember
135148
conversationActionPermission ConversationDeleteTag = DeleteConversation
136149
conversationActionPermission ConversationRenameTag = ModifyConversationName
@@ -153,9 +166,13 @@ conversationActionToEvent tag now quid qcnv action =
153166
in Event MemberJoin qcnv quid now $
154167
EdMembersJoin $ SimpleMembers (map (`SimpleMember` role) (toList newMembers))
155168
SConversationLeaveTag ->
156-
let ConversationLeave removedMembers = action
169+
let ConversationLeave leavingMembers = action
157170
in Event MemberLeave qcnv quid now $
158-
EdMembersLeave (QualifiedUserIdList (toList removedMembers))
171+
EdMembersLeave (QualifiedUserIdList (toList leavingMembers))
172+
SConversationRemoveMembersTag ->
173+
let ConversationRemoveMembers targets = action
174+
in Event MemberLeave qcnv quid now $
175+
EdMembersLeave (QualifiedUserIdList (toList targets))
159176
SConversationMemberUpdateTag ->
160177
let ConversationMemberUpdate target (OtherMemberUpdate role) = action
161178
update = MemberUpdateData target Nothing Nothing Nothing Nothing Nothing Nothing role

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

Lines changed: 19 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,11 @@ import Polysemy.Input
7979
import qualified Polysemy.TinyLog as P
8080
import qualified System.Logger as Log
8181
import Wire.API.Conversation hiding (Conversation, Member)
82-
import Wire.API.Conversation.Action hiding (conversationActionToEvent)
82+
import Wire.API.Conversation.Action
8383
import Wire.API.Conversation.Role
8484
import Wire.API.ErrorDescription
8585
import Wire.API.Event.Conversation hiding (Conversation)
86+
import Wire.API.Federation.API (Component (Galley), fedClient)
8687
import Wire.API.Federation.API.Galley
8788
import Wire.API.Federation.Error
8889
import Wire.API.Team.LegalHold
@@ -104,65 +105,6 @@ data NoChanges = NoChanges
104105
-- deriving (Arbitrary) via (GenericUniform ConversationAction)
105106
-- deriving (ToJSON, FromJSON) via (CustomEncoded ConversationAction)
106107

107-
-- conversationActionToEvent ::
108-
-- UTCTime ->
109-
-- Qualified UserId ->
110-
-- Qualified ConvId ->
111-
-- ConversationAction ->
112-
-- Event
113-
-- conversationActionToEvent now quid qcnv (ConversationActionAddMembers newMembers role) =
114-
-- Event MemberJoin qcnv quid now $
115-
-- EdMembersJoin $ SimpleMembers (map (`SimpleMember` role) (toList newMembers))
116-
-- conversationActionToEvent now quid qcnv (ConversationActionRemoveMembers removedMembers) =
117-
-- Event MemberLeave qcnv quid now $
118-
-- EdMembersLeave (QualifiedUserIdList (toList removedMembers))
119-
-- conversationActionToEvent now quid qcnv (ConversationActionRename rename) =
120-
-- Event ConvRename qcnv quid now (EdConvRename rename)
121-
-- conversationActionToEvent now quid qcnv (ConversationActionMessageTimerUpdate update) =
122-
-- Event ConvMessageTimerUpdate qcnv quid now (EdConvMessageTimerUpdate update)
123-
-- conversationActionToEvent now quid qcnv (ConversationActionReceiptModeUpdate update) =
124-
-- Event ConvReceiptModeUpdate qcnv quid now (EdConvReceiptModeUpdate update)
125-
-- conversationActionToEvent now quid qcnv (ConversationActionMemberUpdate target (OtherMemberUpdate role)) =
126-
-- let update = MemberUpdateData target Nothing Nothing Nothing Nothing Nothing Nothing role
127-
-- in Event MemberStateUpdate qcnv quid now (EdMemberUpdate update)
128-
-- conversationActionToEvent now quid qcnv (ConversationActionAccessUpdate update) =
129-
-- Event ConvAccessUpdate qcnv quid now (EdConvAccessUpdate update)
130-
-- conversationActionToEvent now quid qcnv ConversationActionDelete =
131-
-- Event ConvDelete qcnv quid now EdConvDelete
132-
133-
conversationActionToEvent ::
134-
forall tag.
135-
Sing tag ->
136-
UTCTime ->
137-
Qualified UserId ->
138-
Qualified ConvId ->
139-
ConversationAction tag ->
140-
Event
141-
conversationActionToEvent tag now quid qcnv action =
142-
case tag of
143-
SConversationJoinTag ->
144-
let ConversationJoin newMembers role = action
145-
in Event MemberJoin qcnv quid now $
146-
EdMembersJoin $ SimpleMembers (map (`SimpleMember` role) (toList newMembers))
147-
SConversationLeaveTag ->
148-
let ConversationLeave removedMembers = action
149-
in Event MemberLeave qcnv quid now $
150-
EdMembersLeave (QualifiedUserIdList (toList removedMembers))
151-
SConversationMemberUpdateTag ->
152-
let ConversationMemberUpdate target (OtherMemberUpdate role) = action
153-
update = MemberUpdateData target Nothing Nothing Nothing Nothing Nothing Nothing role
154-
in Event MemberStateUpdate qcnv quid now (EdMemberUpdate update)
155-
SConversationDeleteTag ->
156-
Event ConvDelete qcnv quid now EdConvDelete
157-
SConversationRenameTag ->
158-
Event ConvRename qcnv quid now $ EdConvRename action
159-
SConversationMessageTimerUpdateTag ->
160-
Event ConvMessageTimerUpdate qcnv quid now (EdConvMessageTimerUpdate action)
161-
SConversationReceiptModeUpdateTag ->
162-
Event ConvReceiptModeUpdate qcnv quid now (EdConvReceiptModeUpdate action)
163-
SConversationAccessDataTag ->
164-
Event ConvAccessUpdate qcnv quid now (EdConvAccessUpdate action)
165-
166108
type family HasConversationActionEffects (tag :: ConversationActionTag) r :: Constraint where
167109
HasConversationActionEffects 'ConversationJoinTag r =
168110
Members
@@ -187,6 +129,8 @@ type family HasConversationActionEffects (tag :: ConversationActionTag) r :: Con
187129
r
188130
HasConversationActionEffects 'ConversationLeaveTag r =
189131
(Members '[MemberStore, Error NoChanges] r)
132+
HasConversationActionEffects 'ConversationRemoveMembersTag r =
133+
(Members '[MemberStore, Error NoChanges] r)
190134
HasConversationActionEffects 'ConversationMemberUpdateTag r =
191135
(Members '[MemberStore, Error ConversationError] r)
192136
HasConversationActionEffects 'ConversationDeleteTag r =
@@ -288,6 +232,11 @@ performAction origUser lcnv cnv action =
288232
when (null presentVictims) noChanges
289233
E.deleteMembers (convId cnv) (toUserList lcnv presentVictims)
290234
pure (mempty, action) -- FUTUREWORK: should we return the filtered action here?
235+
SConversationRemoveMembersTag -> do
236+
let presentVictims = filter (isConvMember lcnv cnv) (toList (crmTargets action))
237+
when (null presentVictims) noChanges
238+
E.deleteMembers (convId cnv) (toUserList lcnv presentVictims)
239+
pure (mempty, action) -- FUTUREWORK: should we return the filtered action here?
291240
SConversationMemberUpdateTag -> do
292241
void $ ensureOtherMember lcnv (cmuTarget action) cnv
293242
E.setOtherMember lcnv (cmuTarget action) (cmuUpdate action)
@@ -315,31 +264,6 @@ performAction origUser lcnv cnv action =
315264
(bm, act) <- performConversationAccessData origUser lcnv cnv action
316265
pure (bm, act)
317266

318-
-- -- | An update to a conversation, including addition and removal of members.
319-
-- -- Used to send notifications to users and to remote backends.
320-
-- class IsConversationAction a where
321-
-- conversationAction :: a -> ConversationAction
322-
-- ensureAllowed ::
323-
-- (IsConvMember mem) =>
324-
-- Local x ->
325-
-- a ->
326-
-- Conversation ->
327-
-- mem ->
328-
-- Sem r ()
329-
-- ensureAllowed _ _ _ _ = pure ()
330-
331-
-- conversationActionPermission :: Action
332-
333-
-- conversationActionTag' :: ConversationActionTag
334-
-- performAction ::
335-
-- ( Members '[ConversationStore, Error NoChanges] r
336-
-- ) =>
337-
-- Qualified UserId ->
338-
-- Local ConvId ->
339-
-- Conversation ->
340-
-- a ->
341-
-- Sem r (BotsAndMembers, a)
342-
343267
performConversationJoin ::
344268
(HasConversationActionEffects 'ConversationJoinTag r) =>
345269
Qualified UserId ->
@@ -498,7 +422,7 @@ performConversationAccessData qusr lcnv conv action = do
498422
void . for_ (nonEmpty (bmQualifiedMembers lcnv toRemove)) $ \usersToRemove -> do
499423
let rAction = ConversationLeave usersToRemove
500424
void . runError @NoChanges $ performAction @'ConversationLeaveTag qusr lcnv conv rAction
501-
notifyConversationAction @'ConversationLeaveTag qusr Nothing lcnv bmToNotify rAction
425+
notifyConversationAction (sing @'ConversationLeaveTag) qusr Nothing lcnv bmToNotify rAction
502426
pure (mempty, action)
503427
where
504428
maybeRemoveBots :: Member BrigAccess r => BotsAndMembers -> Sem r BotsAndMembers
@@ -568,7 +492,8 @@ updateLocalConversationWithLocalUser lcnv lusr con action = do
568492
-- perform action
569493
(extraTargets, action') <- performAction @tag (qUntagged lusr) lcnv conv action
570494

571-
notifyConversationAction @tag
495+
notifyConversationAction
496+
(sing @tag)
572497
(qUntagged lusr)
573498
con
574499
lcnv
@@ -616,7 +541,8 @@ updateLocalConversationWithRemoteUser _tag lcnv rusr action = do
616541
remotesOtherDomain = remotes Set.\\ remotesUserDomain
617542

618543
void $
619-
notifyConversationAction @tag
544+
notifyConversationAction
545+
(sing @tag)
620546
(qUntagged rusr)
621547
Nothing
622548
lcnv
@@ -678,20 +604,20 @@ notifyConversationAction ::
678604
forall tag r.
679605
(SingI tag) =>
680606
Members '[FederatorAccess, ExternalAccess, GundeckAccess, Input UTCTime] r =>
607+
Sing tag ->
681608
Qualified UserId ->
682609
Maybe ConnId ->
683610
Local ConvId ->
684611
BotsAndMembers ->
685612
ConversationAction (tag :: ConversationActionTag) ->
686613
Sem r Event
687-
notifyConversationAction quid con lcnv targets action = do
614+
notifyConversationAction tag quid con lcnv targets action = do
688615
now <- input
689616
let e = conversationActionToEvent (sing @tag) now quid (qUntagged lcnv) action
690617

691-
-- TODO: uncomment this!
692-
-- E.runFederatedConcurrently_ (toList (bmRemotes targets)) $ \ruids ->
693-
-- fedClient @'Galley @"on-conversation-updated" $
694-
-- ConversationUpdate now quid (tUnqualified lcnv) (tUnqualified ruids) action
618+
E.runFederatedConcurrently_ (toList (bmRemotes targets)) $ \ruids ->
619+
fedClient @'Galley @"on-conversation-updated" $
620+
ConversationUpdate now quid (tUnqualified lcnv) (tUnqualified ruids) (SomeConversationAction tag action)
695621

696622
-- notify local participants and bots
697623
pushConversationEvent con e (qualifyAs lcnv (bmLocals targets)) (bmBots targets) $> e

0 commit comments

Comments
 (0)