Skip to content

Commit 3e7b662

Browse files
committed
feat: do not allow non-members to modify member list
1 parent 6057b40 commit 3e7b662

File tree

2 files changed

+93
-55
lines changed

2 files changed

+93
-55
lines changed

Diff for: src/chat.rs

+36
Original file line numberDiff line numberDiff line change
@@ -7860,4 +7860,40 @@ mod tests {
78607860

78617861
Ok(())
78627862
}
7863+
7864+
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
7865+
async fn non_member_cannot_modify_member_list() -> Result<()> {
7866+
let mut tcm = TestContextManager::new();
7867+
7868+
let alice = &tcm.alice().await;
7869+
let bob = &tcm.bob().await;
7870+
7871+
let bob_addr = bob.get_config(Config::Addr).await?.unwrap();
7872+
let alice_bob_contact_id = Contact::create(alice, "Bob", &bob_addr).await?;
7873+
7874+
let alice_chat_id =
7875+
create_group_chat(alice, ProtectionStatus::Unprotected, "Group chat").await?;
7876+
add_contact_to_chat(alice, alice_chat_id, alice_bob_contact_id).await?;
7877+
let alice_sent_msg = alice
7878+
.send_text(alice_chat_id, "Hi! I created a group.")
7879+
.await;
7880+
let bob_received_msg = bob.recv_msg(&alice_sent_msg).await;
7881+
let bob_chat_id = bob_received_msg.get_chat_id();
7882+
bob_chat_id.accept(bob).await?;
7883+
7884+
let bob_fiona_contact_id = Contact::create(bob, "Fiona", "[email protected]").await?;
7885+
7886+
// Alice removes Bob and Bob adds Fiona at the same time.
7887+
remove_contact_from_chat(alice, alice_chat_id, alice_bob_contact_id).await?;
7888+
add_contact_to_chat(bob, bob_chat_id, bob_fiona_contact_id).await?;
7889+
7890+
let bob_sent_add_msg = bob.pop_sent_msg().await;
7891+
7892+
// Alice ignores Bob's message because Bob is not a member.
7893+
assert_eq!(get_chat_contacts(alice, alice_chat_id).await?.len(), 1);
7894+
alice.recv_msg(&bob_sent_add_msg).await;
7895+
assert_eq!(get_chat_contacts(alice, alice_chat_id).await?.len(), 1);
7896+
7897+
Ok(())
7898+
}
78637899
}

Diff for: src/receive_imf.rs

+57-55
Original file line numberDiff line numberDiff line change
@@ -2329,65 +2329,67 @@ async fn apply_group_changes(
23292329
let mut added_ids = HashSet::<ContactId>::new();
23302330
let mut removed_ids = HashSet::<ContactId>::new();
23312331

2332-
if let Some(ref chat_group_member_timestamps) = mime_parser.chat_group_member_timestamps() {
2333-
send_event_chat_modified |= update_chats_contacts_timestamps(
2334-
context,
2335-
chat_id,
2336-
Some(from_id),
2337-
to_ids,
2338-
past_ids,
2339-
chat_group_member_timestamps,
2340-
)
2341-
.await?;
2342-
let new_chat_contacts = HashSet::<ContactId>::from_iter(
2343-
chat::get_chat_contacts(context, chat_id)
2344-
.await?
2345-
.iter()
2346-
.copied(),
2347-
);
2348-
added_ids = new_chat_contacts
2349-
.difference(&chat_contacts)
2350-
.copied()
2351-
.collect();
2352-
removed_ids = chat_contacts
2353-
.difference(&new_chat_contacts)
2354-
.copied()
2355-
.collect();
2356-
} else if is_from_in_chat {
2357-
let mut new_members = HashSet::from_iter(to_ids.iter().copied());
2358-
new_members.insert(ContactId::SELF);
2359-
if !from_id.is_special() {
2360-
new_members.insert(from_id);
2361-
}
2362-
2363-
if !self_added {
2364-
if mime_parser.get_header(HeaderDef::ChatVersion).is_none() {
2365-
// Allow non-Delta Chat MUAs to add members.
2366-
added_ids = new_members.difference(&chat_contacts).copied().collect();
2367-
}
2368-
2369-
if let Some(added_id) = added_id {
2370-
added_ids.insert(added_id);
2371-
}
2372-
new_members.clone_from(&chat_contacts);
2373-
// Don't delete any members locally, but instead add absent ones to provide group
2374-
// membership consistency for all members:
2375-
new_members.extend(added_ids.clone());
2376-
}
2377-
if let Some(removed_id) = removed_id {
2378-
new_members.remove(&removed_id);
2379-
}
2380-
2381-
if new_members != chat_contacts {
2382-
chat::update_chat_contacts_table(
2332+
if is_from_in_chat {
2333+
if let Some(ref chat_group_member_timestamps) = mime_parser.chat_group_member_timestamps() {
2334+
send_event_chat_modified |= update_chats_contacts_timestamps(
23832335
context,
2384-
mime_parser.timestamp_sent,
23852336
chat_id,
2386-
&new_members,
2337+
Some(from_id),
2338+
to_ids,
2339+
past_ids,
2340+
chat_group_member_timestamps,
23872341
)
23882342
.await?;
2389-
chat_contacts = new_members;
2390-
send_event_chat_modified = true;
2343+
let new_chat_contacts = HashSet::<ContactId>::from_iter(
2344+
chat::get_chat_contacts(context, chat_id)
2345+
.await?
2346+
.iter()
2347+
.copied(),
2348+
);
2349+
added_ids = new_chat_contacts
2350+
.difference(&chat_contacts)
2351+
.copied()
2352+
.collect();
2353+
removed_ids = chat_contacts
2354+
.difference(&new_chat_contacts)
2355+
.copied()
2356+
.collect();
2357+
} else {
2358+
let mut new_members = HashSet::from_iter(to_ids.iter().copied());
2359+
new_members.insert(ContactId::SELF);
2360+
if !from_id.is_special() {
2361+
new_members.insert(from_id);
2362+
}
2363+
2364+
if !self_added {
2365+
if mime_parser.get_header(HeaderDef::ChatVersion).is_none() {
2366+
// Allow non-Delta Chat MUAs to add members.
2367+
added_ids = new_members.difference(&chat_contacts).copied().collect();
2368+
}
2369+
2370+
if let Some(added_id) = added_id {
2371+
added_ids.insert(added_id);
2372+
}
2373+
new_members.clone_from(&chat_contacts);
2374+
// Don't delete any members locally, but instead add absent ones to provide group
2375+
// membership consistency for all members:
2376+
new_members.extend(added_ids.clone());
2377+
}
2378+
if let Some(removed_id) = removed_id {
2379+
new_members.remove(&removed_id);
2380+
}
2381+
2382+
if new_members != chat_contacts {
2383+
chat::update_chat_contacts_table(
2384+
context,
2385+
mime_parser.timestamp_sent,
2386+
chat_id,
2387+
&new_members,
2388+
)
2389+
.await?;
2390+
chat_contacts = new_members;
2391+
send_event_chat_modified = true;
2392+
}
23912393
}
23922394
}
23932395

0 commit comments

Comments
 (0)