Skip to content

Commit abe85c6

Browse files
Marko Dimjaševićpcapriotti
andauthored
[FS-873] Leaving MLS Conversations and Backend-side Removals (#2667)
* Allow leaving an MLS conversation via Wire API * Add failing test for user leaving * Move MLS clients to their own table * Refactor leave action: remove list of leavers * Update conversation object after removal * Fix integration tests * Implement a remote leaver test * Update federation golden tests * Split leave test into two * Make removing already-removed users a no-op * Add CHANGELOG entries Co-authored-by: Paolo Capriotti <[email protected]>
1 parent 869a9eb commit abe85c6

File tree

44 files changed

+961
-470
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+961
-470
lines changed

cassandra-schema.cql

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,6 @@ CREATE TABLE galley_test.member (
168168
conversation_role text,
169169
hidden boolean,
170170
hidden_ref text,
171-
mls_clients_keypackages set<frozen<tuple<text, blob>>>,
172171
otr_archived boolean,
173172
otr_archived_ref text,
174173
otr_muted boolean,
@@ -262,7 +261,6 @@ CREATE TABLE galley_test.member_remote_user (
262261
user_remote_domain text,
263262
user_remote_id uuid,
264263
conversation_role text,
265-
mls_clients_keypackages set<frozen<tuple<text, blob>>>,
266264
PRIMARY KEY (conv, user_remote_domain, user_remote_id)
267265
) WITH CLUSTERING ORDER BY (user_remote_domain ASC, user_remote_id ASC)
268266
AND bloom_filter_fp_chance = 0.1
@@ -365,15 +363,18 @@ CREATE TABLE galley_test.group_id_conv_id (
365363
AND read_repair_chance = 0.0
366364
AND speculative_retry = '99PERCENTILE';
367365

368-
CREATE TABLE galley_test.user (
369-
user uuid,
366+
CREATE TABLE galley_test.member_client (
370367
conv uuid,
371-
PRIMARY KEY (user, conv)
372-
) WITH CLUSTERING ORDER BY (conv ASC)
373-
AND bloom_filter_fp_chance = 0.1
368+
user_domain text,
369+
user uuid,
370+
client text,
371+
key_package_ref blob,
372+
PRIMARY KEY (conv, user_domain, user, client)
373+
) WITH CLUSTERING ORDER BY (user_domain ASC, user ASC, client ASC)
374+
AND bloom_filter_fp_chance = 0.01
374375
AND caching = {'keys': 'ALL', 'rows_per_partition': 'NONE'}
375376
AND comment = ''
376-
AND compaction = {'class': 'org.apache.cassandra.db.compaction.LeveledCompactionStrategy'}
377+
AND compaction = {'class': 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy', 'max_threshold': '32', 'min_threshold': '4'}
377378
AND compression = {'chunk_length_in_kb': '64', 'class': 'org.apache.cassandra.io.compress.LZ4Compressor'}
378379
AND crc_check_chance = 1.0
379380
AND dclocal_read_repair_chance = 0.1
@@ -565,6 +566,26 @@ CREATE TABLE galley_test.mls_proposal_refs (
565566
AND read_repair_chance = 0.0
566567
AND speculative_retry = '99PERCENTILE';
567568

569+
CREATE TABLE galley_test.user (
570+
user uuid,
571+
conv uuid,
572+
PRIMARY KEY (user, conv)
573+
) WITH CLUSTERING ORDER BY (conv ASC)
574+
AND bloom_filter_fp_chance = 0.1
575+
AND caching = {'keys': 'ALL', 'rows_per_partition': 'NONE'}
576+
AND comment = ''
577+
AND compaction = {'class': 'org.apache.cassandra.db.compaction.LeveledCompactionStrategy'}
578+
AND compression = {'chunk_length_in_kb': '64', 'class': 'org.apache.cassandra.io.compress.LZ4Compressor'}
579+
AND crc_check_chance = 1.0
580+
AND dclocal_read_repair_chance = 0.1
581+
AND default_time_to_live = 0
582+
AND gc_grace_seconds = 864000
583+
AND max_index_interval = 2048
584+
AND memtable_flush_period_in_ms = 0
585+
AND min_index_interval = 128
586+
AND read_repair_chance = 0.0
587+
AND speculative_retry = '99PERCENTILE';
588+
568589
CREATE KEYSPACE gundeck_test WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'} AND durable_writes = true;
569590

570591
CREATE TABLE gundeck_test.push (
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Leaving an MLS conversation is now possible using the regular endpoint `DELETE /conversations/{cnv_domain}/{cnv}/members/{usr_domain}/{usr}`. When a user leaves, the backend sends external remove proposals for all their clients in the corresponding MLS group.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Clients and key package refs in an MLS conversation are now stored in their own table.

libs/galley-types/src/Galley/Types/Conversations/Members.hs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,15 @@ where
3333
import Data.Domain
3434
import Data.Id as Id
3535
import Data.Qualified
36-
import qualified Data.Set as Set
3736
import Imports
3837
import Wire.API.Conversation
3938
import Wire.API.Conversation.Role (RoleName, roleNameWireAdmin)
40-
import Wire.API.MLS.KeyPackage
4139
import Wire.API.Provider.Service (ServiceRef)
4240

4341
-- | Internal (cassandra) representation of a remote conversation member.
4442
data RemoteMember = RemoteMember
4543
{ rmId :: Remote UserId,
46-
rmConvRoleName :: RoleName,
47-
rmMLSClients :: Set (ClientId, KeyPackageRef)
44+
rmConvRoleName :: RoleName
4845
}
4946
deriving stock (Show)
5047

@@ -64,8 +61,7 @@ data LocalMember = LocalMember
6461
{ lmId :: UserId,
6562
lmStatus :: MemberStatus,
6663
lmService :: Maybe ServiceRef,
67-
lmConvRoleName :: RoleName,
68-
lmMLSClients :: Set (ClientId, KeyPackageRef)
64+
lmConvRoleName :: RoleName
6965
}
7066
deriving stock (Show)
7167

@@ -78,8 +74,7 @@ newMemberWithRole (u, r) =
7874
{ lmId = u,
7975
lmService = Nothing,
8076
lmStatus = defMemberStatus,
81-
lmConvRoleName = r,
82-
lmMLSClients = Set.empty
77+
lmConvRoleName = r
8378
}
8479

8580
localMemberToOther :: Domain -> LocalMember -> OtherMember

libs/types-common/src/Data/Qualified.hs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ module Data.Qualified
4141
indexQualified,
4242
bucketQualified,
4343
bucketRemote,
44+
isLocal,
4445
deprecatedSchema,
4546
qualifiedSchema,
4647
qualifiedObjectSchema,
@@ -157,6 +158,9 @@ bucketRemote =
157158
. indexQualified
158159
. fmap qUntagged
159160

161+
isLocal :: Local x -> Qualified a -> Bool
162+
isLocal loc = foldQualified loc (const True) (const False)
163+
160164
----------------------------------------------------------------------
161165

162166
deprecatedSchema :: S.HasDescription doc (Maybe Text) => Text -> ValueSchema doc a -> ValueSchema doc a

libs/wire-api-federation/test/Test/Wire/API/Federation/Golden/ConversationUpdate.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,5 +72,5 @@ testObject_ConversationUpdate2 =
7272
cuConvId =
7373
Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000100000006")),
7474
cuAlreadyPresentUsers = [chad, dee],
75-
cuAction = SomeConversationAction (sing @'ConversationLeaveTag) (pure qAlice)
75+
cuAction = SomeConversationAction (sing @'ConversationLeaveTag) ()
7676
}

libs/wire-api-federation/test/golden/testObject_ConversationUpdate2.json

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,6 @@
11
{
22
"cuAction": {
3-
"action": {
4-
"users": [
5-
{
6-
"domain": "golden.example.com",
7-
"id": "00000000-0000-0000-0000-000100004007"
8-
}
9-
]
10-
},
3+
"action": {},
114
"tag": "ConversationLeaveTag"
125
},
136
"cuAlreadyPresentUsers": [
Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,49 @@
11
{
22
"Right": {
3-
"failed_to_send": {
3+
"deleted": {
44
"golden.example.com": {
5-
"00000000-0000-0000-0000-000200000008": [
6-
"0"
7-
],
8-
"00000000-0000-0000-0000-000100000007": [
5+
"00000000-0000-0000-0000-000100000005": [
96
"0",
107
"1"
8+
],
9+
"00000000-0000-0000-0000-000200000006": [
10+
"0"
1111
]
1212
}
1313
},
14-
"redundant": {
14+
"failed_to_send": {
1515
"golden.example.com": {
16-
"00000000-0000-0000-0000-000100000003": [
16+
"00000000-0000-0000-0000-000100000007": [
1717
"0",
1818
"1"
1919
],
20-
"00000000-0000-0000-0000-000200000004": [
20+
"00000000-0000-0000-0000-000200000008": [
2121
"0"
2222
]
2323
}
2424
},
25-
"time": "1864-04-12T12:22:43.673Z",
2625
"missing": {
2726
"golden.example.com": {
28-
"00000000-0000-0000-0000-000200000000": [
29-
"0"
30-
],
3127
"00000000-0000-0000-0000-000100000002": [
3228
"0",
3329
"1"
30+
],
31+
"00000000-0000-0000-0000-000200000000": [
32+
"0"
3433
]
3534
}
3635
},
37-
"deleted": {
36+
"redundant": {
3837
"golden.example.com": {
39-
"00000000-0000-0000-0000-000100000005": [
38+
"00000000-0000-0000-0000-000100000003": [
4039
"0",
4140
"1"
4241
],
43-
"00000000-0000-0000-0000-000200000006": [
42+
"00000000-0000-0000-0000-000200000004": [
4443
"0"
4544
]
4645
}
47-
}
46+
},
47+
"time": "1864-04-12T12:22:43.673Z"
4848
}
4949
}
Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,52 @@
11
{
22
"Left": {
3-
"tag": "MessageNotSentClientMissing",
43
"contents": {
5-
"failed_to_send": {
4+
"deleted": {
65
"golden.example.com": {
7-
"00000000-0000-0000-0000-000200000008": [
8-
"0"
9-
],
10-
"00000000-0000-0000-0000-000100000007": [
6+
"00000000-0000-0000-0000-000100000005": [
117
"0",
128
"1"
9+
],
10+
"00000000-0000-0000-0000-000200000006": [
11+
"0"
1312
]
1413
}
1514
},
16-
"redundant": {
15+
"failed_to_send": {
1716
"golden.example.com": {
18-
"00000000-0000-0000-0000-000100000003": [
17+
"00000000-0000-0000-0000-000100000007": [
1918
"0",
2019
"1"
2120
],
22-
"00000000-0000-0000-0000-000200000004": [
21+
"00000000-0000-0000-0000-000200000008": [
2322
"0"
2423
]
2524
}
2625
},
27-
"time": "1864-04-12T12:22:43.673Z",
2826
"missing": {
2927
"golden.example.com": {
30-
"00000000-0000-0000-0000-000200000000": [
31-
"0"
32-
],
3328
"00000000-0000-0000-0000-000100000002": [
3429
"0",
3530
"1"
31+
],
32+
"00000000-0000-0000-0000-000200000000": [
33+
"0"
3634
]
3735
}
3836
},
39-
"deleted": {
37+
"redundant": {
4038
"golden.example.com": {
41-
"00000000-0000-0000-0000-000100000005": [
39+
"00000000-0000-0000-0000-000100000003": [
4240
"0",
4341
"1"
4442
],
45-
"00000000-0000-0000-0000-000200000006": [
43+
"00000000-0000-0000-0000-000200000004": [
4644
"0"
4745
]
4846
}
49-
}
50-
}
47+
},
48+
"time": "1864-04-12T12:22:43.673Z"
49+
},
50+
"tag": "MessageNotSentClientMissing"
5151
}
5252
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"to": "1669240c-c510-43e0-bf1a-33378fa4ba55",
2+
"action": "RemoteConnect",
33
"from": "69f66843-6cf1-48fb-8c05-1cf58c23566a",
4-
"action": "RemoteConnect"
4+
"to": "1669240c-c510-43e0-bf1a-33378fa4ba55"
55
}

0 commit comments

Comments
 (0)