mirror of
https://github.com/chatmail/core.git
synced 2026-05-25 01:36:31 +03:00
feat: do not allow non-members to modify member list
This commit is contained in:
36
src/chat.rs
36
src/chat.rs
@@ -7860,4 +7860,40 @@ mod tests {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
|
async fn non_member_cannot_modify_member_list() -> Result<()> {
|
||||||
|
let mut tcm = TestContextManager::new();
|
||||||
|
|
||||||
|
let alice = &tcm.alice().await;
|
||||||
|
let bob = &tcm.bob().await;
|
||||||
|
|
||||||
|
let bob_addr = bob.get_config(Config::Addr).await?.unwrap();
|
||||||
|
let alice_bob_contact_id = Contact::create(alice, "Bob", &bob_addr).await?;
|
||||||
|
|
||||||
|
let alice_chat_id =
|
||||||
|
create_group_chat(alice, ProtectionStatus::Unprotected, "Group chat").await?;
|
||||||
|
add_contact_to_chat(alice, alice_chat_id, alice_bob_contact_id).await?;
|
||||||
|
let alice_sent_msg = alice
|
||||||
|
.send_text(alice_chat_id, "Hi! I created a group.")
|
||||||
|
.await;
|
||||||
|
let bob_received_msg = bob.recv_msg(&alice_sent_msg).await;
|
||||||
|
let bob_chat_id = bob_received_msg.get_chat_id();
|
||||||
|
bob_chat_id.accept(bob).await?;
|
||||||
|
|
||||||
|
let bob_fiona_contact_id = Contact::create(bob, "Fiona", "fiona@example.net").await?;
|
||||||
|
|
||||||
|
// Alice removes Bob and Bob adds Fiona at the same time.
|
||||||
|
remove_contact_from_chat(alice, alice_chat_id, alice_bob_contact_id).await?;
|
||||||
|
add_contact_to_chat(bob, bob_chat_id, bob_fiona_contact_id).await?;
|
||||||
|
|
||||||
|
let bob_sent_add_msg = bob.pop_sent_msg().await;
|
||||||
|
|
||||||
|
// Alice ignores Bob's message because Bob is not a member.
|
||||||
|
assert_eq!(get_chat_contacts(alice, alice_chat_id).await?.len(), 1);
|
||||||
|
alice.recv_msg(&bob_sent_add_msg).await;
|
||||||
|
assert_eq!(get_chat_contacts(alice, alice_chat_id).await?.len(), 1);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2329,65 +2329,67 @@ async fn apply_group_changes(
|
|||||||
let mut added_ids = HashSet::<ContactId>::new();
|
let mut added_ids = HashSet::<ContactId>::new();
|
||||||
let mut removed_ids = HashSet::<ContactId>::new();
|
let mut removed_ids = HashSet::<ContactId>::new();
|
||||||
|
|
||||||
if let Some(ref chat_group_member_timestamps) = mime_parser.chat_group_member_timestamps() {
|
if is_from_in_chat {
|
||||||
send_event_chat_modified |= update_chats_contacts_timestamps(
|
if let Some(ref chat_group_member_timestamps) = mime_parser.chat_group_member_timestamps() {
|
||||||
context,
|
send_event_chat_modified |= update_chats_contacts_timestamps(
|
||||||
chat_id,
|
|
||||||
Some(from_id),
|
|
||||||
to_ids,
|
|
||||||
past_ids,
|
|
||||||
chat_group_member_timestamps,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
let new_chat_contacts = HashSet::<ContactId>::from_iter(
|
|
||||||
chat::get_chat_contacts(context, chat_id)
|
|
||||||
.await?
|
|
||||||
.iter()
|
|
||||||
.copied(),
|
|
||||||
);
|
|
||||||
added_ids = new_chat_contacts
|
|
||||||
.difference(&chat_contacts)
|
|
||||||
.copied()
|
|
||||||
.collect();
|
|
||||||
removed_ids = chat_contacts
|
|
||||||
.difference(&new_chat_contacts)
|
|
||||||
.copied()
|
|
||||||
.collect();
|
|
||||||
} else if is_from_in_chat {
|
|
||||||
let mut new_members = HashSet::from_iter(to_ids.iter().copied());
|
|
||||||
new_members.insert(ContactId::SELF);
|
|
||||||
if !from_id.is_special() {
|
|
||||||
new_members.insert(from_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
if !self_added {
|
|
||||||
if mime_parser.get_header(HeaderDef::ChatVersion).is_none() {
|
|
||||||
// Allow non-Delta Chat MUAs to add members.
|
|
||||||
added_ids = new_members.difference(&chat_contacts).copied().collect();
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(added_id) = added_id {
|
|
||||||
added_ids.insert(added_id);
|
|
||||||
}
|
|
||||||
new_members.clone_from(&chat_contacts);
|
|
||||||
// Don't delete any members locally, but instead add absent ones to provide group
|
|
||||||
// membership consistency for all members:
|
|
||||||
new_members.extend(added_ids.clone());
|
|
||||||
}
|
|
||||||
if let Some(removed_id) = removed_id {
|
|
||||||
new_members.remove(&removed_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
if new_members != chat_contacts {
|
|
||||||
chat::update_chat_contacts_table(
|
|
||||||
context,
|
context,
|
||||||
mime_parser.timestamp_sent,
|
|
||||||
chat_id,
|
chat_id,
|
||||||
&new_members,
|
Some(from_id),
|
||||||
|
to_ids,
|
||||||
|
past_ids,
|
||||||
|
chat_group_member_timestamps,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
chat_contacts = new_members;
|
let new_chat_contacts = HashSet::<ContactId>::from_iter(
|
||||||
send_event_chat_modified = true;
|
chat::get_chat_contacts(context, chat_id)
|
||||||
|
.await?
|
||||||
|
.iter()
|
||||||
|
.copied(),
|
||||||
|
);
|
||||||
|
added_ids = new_chat_contacts
|
||||||
|
.difference(&chat_contacts)
|
||||||
|
.copied()
|
||||||
|
.collect();
|
||||||
|
removed_ids = chat_contacts
|
||||||
|
.difference(&new_chat_contacts)
|
||||||
|
.copied()
|
||||||
|
.collect();
|
||||||
|
} else {
|
||||||
|
let mut new_members = HashSet::from_iter(to_ids.iter().copied());
|
||||||
|
new_members.insert(ContactId::SELF);
|
||||||
|
if !from_id.is_special() {
|
||||||
|
new_members.insert(from_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if !self_added {
|
||||||
|
if mime_parser.get_header(HeaderDef::ChatVersion).is_none() {
|
||||||
|
// Allow non-Delta Chat MUAs to add members.
|
||||||
|
added_ids = new_members.difference(&chat_contacts).copied().collect();
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(added_id) = added_id {
|
||||||
|
added_ids.insert(added_id);
|
||||||
|
}
|
||||||
|
new_members.clone_from(&chat_contacts);
|
||||||
|
// Don't delete any members locally, but instead add absent ones to provide group
|
||||||
|
// membership consistency for all members:
|
||||||
|
new_members.extend(added_ids.clone());
|
||||||
|
}
|
||||||
|
if let Some(removed_id) = removed_id {
|
||||||
|
new_members.remove(&removed_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if new_members != chat_contacts {
|
||||||
|
chat::update_chat_contacts_table(
|
||||||
|
context,
|
||||||
|
mime_parser.timestamp_sent,
|
||||||
|
chat_id,
|
||||||
|
&new_members,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
chat_contacts = new_members;
|
||||||
|
send_event_chat_modified = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user