@@ -27,6 +27,7 @@ import Control.Arrow
27
27
import Control.Comonad
28
28
import Control.Lens (preview , to )
29
29
import Data.Id
30
+ import Data.Json.Util
30
31
import Data.List.NonEmpty (NonEmpty , nonEmpty )
31
32
import qualified Data.Map as Map
32
33
import Data.Qualified
@@ -42,6 +43,7 @@ import qualified Galley.Data.Conversation.Types as Data
42
43
import Galley.Effects
43
44
import Galley.Effects.BrigAccess
44
45
import Galley.Effects.ConversationStore
46
+ import Galley.Effects.FederatorAccess
45
47
import Galley.Effects.MemberStore
46
48
import Galley.Options
47
49
import Galley.Types
@@ -55,6 +57,8 @@ import Wire.API.Conversation.Protocol
55
57
import Wire.API.Conversation.Role
56
58
import Wire.API.Error
57
59
import Wire.API.Error.Galley
60
+ import Wire.API.Federation.API
61
+ import Wire.API.Federation.API.Galley
58
62
import Wire.API.Federation.Error
59
63
import Wire.API.MLS.CipherSuite
60
64
import Wire.API.MLS.Commit
@@ -65,7 +69,8 @@ import Wire.API.MLS.Proposal
65
69
import Wire.API.MLS.Serialisation
66
70
67
71
type MLSMessageStaticErrors =
68
- '[ ErrorS 'ConvNotFound,
72
+ '[ ErrorS 'ConvAccessDenied,
73
+ ErrorS 'ConvNotFound,
69
74
ErrorS 'MLSUnsupportedMessage,
70
75
ErrorS 'MLSStaleMessage,
71
76
ErrorS 'MLSProposalNotFound,
@@ -93,6 +98,7 @@ postMLSMessage ::
93
98
( HasProposalEffects r ,
94
99
Members
95
100
'[ Error FederationError ,
101
+ ErrorS 'ConvAccessDenied,
96
102
ErrorS 'ConvNotFound,
97
103
ErrorS 'MLSUnsupportedMessage,
98
104
ErrorS 'MLSStaleMessage,
@@ -108,17 +114,42 @@ postMLSMessage ::
108
114
RawMLS SomeMessage ->
109
115
Sem r [LocalConversationUpdate ]
110
116
postMLSMessage loc qusr con smsg = case rmValue smsg of
111
- SomeMessage tag msg -> do
112
- -- fetch conversation
117
+ SomeMessage _ msg -> do
118
+ -- fetch conversation ID
113
119
qcnv <- getConversationIdByGroupId (msgGroupId msg) >>= noteS @ 'ConvNotFound
114
- lcnv <- ensureLocal loc qcnv -- FUTUREWORK: allow remote conversations
120
+ foldQualified
121
+ loc
122
+ (postMLSMessageToLocalConv qusr con smsg)
123
+ (postMLSMessageToRemoteConv loc qusr con smsg)
124
+ qcnv
125
+
126
+ postMLSMessageToLocalConv ::
127
+ ( HasProposalEffects r ,
128
+ Members
129
+ '[ Error FederationError ,
130
+ ErrorS 'ConvNotFound,
131
+ ErrorS 'MLSUnsupportedMessage,
132
+ ErrorS 'MLSStaleMessage,
133
+ ErrorS 'MLSProposalNotFound,
134
+ ErrorS 'MissingLegalholdConsent,
135
+ TinyLog
136
+ ]
137
+ r
138
+ ) =>
139
+ Qualified UserId ->
140
+ Maybe ConnId ->
141
+ RawMLS SomeMessage ->
142
+ Local ConvId ->
143
+ Sem r [LocalConversationUpdate ]
144
+ postMLSMessageToLocalConv qusr con smsg lcnv = case rmValue smsg of
145
+ SomeMessage tag msg -> do
115
146
conv <- getConversation (tUnqualified lcnv) >>= noteS @ 'ConvNotFound
116
147
117
148
-- validate message
118
149
events <- case tag of
119
150
SMLSPlainText -> case msgTBS (msgPayload msg) of
120
151
CommitMessage c ->
121
- processCommit qusr con (qualifyAs loc conv) (msgEpoch msg) c
152
+ processCommit qusr con (qualifyAs lcnv conv) (msgEpoch msg) c
122
153
ApplicationMessage _ -> throwS @ 'MLSUnsupportedMessage
123
154
ProposalMessage _ -> pure mempty -- FUTUREWORK: handle proposals
124
155
SMLSCipherText -> case toMLSEnum' (msgContentType (msgPayload msg)) of
@@ -128,10 +159,42 @@ postMLSMessage loc qusr con smsg = case rmValue smsg of
128
159
Left _ -> throwS @ 'MLSUnsupportedMessage
129
160
130
161
-- forward message
131
- propagateMessage loc qusr conv con (rmRaw smsg)
162
+ propagateMessage lcnv qusr conv con (rmRaw smsg)
132
163
133
164
pure events
134
165
166
+ postMLSMessageToRemoteConv ::
167
+ ( Members MLSMessageStaticErrors r ,
168
+ Members '[Error FederationError , TinyLog ] r ,
169
+ HasProposalEffects r
170
+ ) =>
171
+ Local x ->
172
+ Qualified UserId ->
173
+ Maybe ConnId ->
174
+ RawMLS SomeMessage ->
175
+ Remote ConvId ->
176
+ Sem r [LocalConversationUpdate ]
177
+ postMLSMessageToRemoteConv loc qusr con smsg rcnv = do
178
+ -- only local users can send messages to remote conversations
179
+ lusr <- foldQualified loc pure (\ _ -> throwS @ 'ConvAccessDenied) qusr
180
+ resp <-
181
+ runFederated rcnv $
182
+ fedClient @ 'Galley @ " send-mls-message" $
183
+ MessageSendRequest
184
+ { msrConvId = tUnqualified rcnv,
185
+ msrSender = tUnqualified lusr,
186
+ msrRawMessage = Base64ByteString (rmRaw smsg)
187
+ }
188
+ updates <- case resp of
189
+ MLSMessageResponseError e -> rethrowErrors @ MLSMessageStaticErrors e
190
+ MLSMessageResponseProtocolError e -> throw (mlsProtocolError e)
191
+ MLSMessageResponseProposalFailure e -> throw (MLSProposalFailure e)
192
+ MLSMessageResponseUpdates updates -> pure updates
193
+
194
+ for updates $ \ update -> do
195
+ e <- notifyRemoteConversationAction loc (qualifyAs rcnv update) con
196
+ pure (LocalConversationUpdate e update)
197
+
135
198
type HasProposalEffects r =
136
199
( Member BrigAccess r ,
137
200
Member ConversationStore r ,
0 commit comments