diff --git a/deltachat-rpc-client/tests/test_securejoin.py b/deltachat-rpc-client/tests/test_securejoin.py index e50be9a7f..17440b49d 100644 --- a/deltachat-rpc-client/tests/test_securejoin.py +++ b/deltachat-rpc-client/tests/test_securejoin.py @@ -152,7 +152,8 @@ def test_qr_readreceipt(acfactory) -> None: assert not bob.get_chat_by_contact(bob_contact_charlie) -def test_verified_group_recovery(acfactory, rpc) -> None: +def test_verified_group_recovery(acfactory) -> None: + """Tests verified group recovery by reverifying a member and sending a message in a group.""" ac1, ac2, ac3 = acfactory.get_online_accounts(3) logging.info("ac1 creates verified group") @@ -194,60 +195,38 @@ def test_verified_group_recovery(acfactory, rpc) -> None: assert len(ac3_chat.get_contacts()) == 3 ac3_chat.send_text("Hi!") - msg_id = ac2.wait_for_incoming_msg_event().msg_id - message = ac2.get_message_by_id(msg_id) - snapshot = message.get_snapshot() - logging.info("Received message %s", snapshot.text) + snapshot = ac1.get_message_by_id(ac1.wait_for_incoming_msg_event().msg_id).get_snapshot() assert snapshot.text == "Hi!" - # ac1 contact cannot be verified by ac2 because ac3 did not gossip ac1 key in the "Hi!" message. - ac1_contact = ac2.get_contact_by_addr(ac1.get_config("addr")) - assert not ac1_contact.get_snapshot().is_verified - - ac3_contact_id_ac1 = rpc.lookup_contact_id_by_addr(ac3.id, ac1.get_config("addr")) - ac3_chat.remove_contact(ac3_contact_id_ac1) - ac3_chat.add_contact(ac3_contact_id_ac1) - msg_id = ac2.wait_for_incoming_msg_event().msg_id message = ac2.get_message_by_id(msg_id) snapshot = message.get_snapshot() - logging.info("ac2 got event message: %s", snapshot.text) - assert "removed" in snapshot.text - - event = ac2.wait_for_incoming_msg_event() - msg_id = event.msg_id - chat_id = event.chat_id - message = ac2.get_message_by_id(msg_id) - snapshot = message.get_snapshot() - logging.info("ac2 got event message: %s", snapshot.text) - assert "added" in snapshot.text + assert snapshot.text == "Hi!" + # ac1 contact is verified for ac2 because ac3 gossiped ac1 key in the "Hi!" message. + ac1_contact = ac2.get_contact_by_addr(ac1.get_config("addr")) assert ac1_contact.get_snapshot().is_verified - chat = Chat(ac2, chat_id) - chat.send_text("Works again!") + # ac2 can write messages to the group. + snapshot.chat.send_text("Works again!") - msg_id = ac3.wait_for_incoming_msg_event().msg_id - message = ac3.get_message_by_id(msg_id) - snapshot = message.get_snapshot() + snapshot = ac3.get_message_by_id(ac3.wait_for_incoming_msg_event().msg_id).get_snapshot() assert snapshot.text == "Works again!" - ac1.wait_for_incoming_msg_event() # Hi! - ac1.wait_for_incoming_msg_event() # Member removed - ac1.wait_for_incoming_msg_event() # Member added snapshot = ac1.get_message_by_id(ac1.wait_for_incoming_msg_event().msg_id).get_snapshot() assert snapshot.text == "Works again!" - # ac2 is now verified by ac3 for ac1 - ac1_contact_ac3 = ac1.get_contact_by_addr(ac3.get_config("addr")) - assert ac1_contact_ac2.get_snapshot().verifier_id == ac1_contact_ac3.id - ac1_chat_messages = snapshot.chat.get_messages() ac2_addr = ac2.get_config("addr") assert ac1_chat_messages[-2].get_snapshot().text == f"Changed setup for {ac2_addr}" + # ac2 is now verified by ac3 for ac1 + ac1_contact_ac3 = ac1.get_contact_by_addr(ac3.get_config("addr")) + assert ac1_contact_ac2.get_snapshot().verifier_id == ac1_contact_ac3.id + def test_verified_group_member_added_recovery(acfactory) -> None: + """Tests verified group recovery by reverifiying than removing and adding a member back.""" ac1, ac2, ac3 = acfactory.get_online_accounts(3) logging.info("ac1 creates verified group") diff --git a/src/contact.rs b/src/contact.rs index 151159145..84b9f9ada 100644 --- a/src/contact.rs +++ b/src/contact.rs @@ -149,6 +149,22 @@ impl ContactId { .await?; Ok(()) } + + /// Reset gossip timestamp in all chats with this contact. + pub(crate) async fn regossip_keys(&self, context: &Context) -> Result<()> { + context + .sql + .execute( + "UPDATE chats + SET gossiped_timestamp=0 + WHERE EXISTS (SELECT 1 FROM chats_contacts + WHERE chats_contacts.chat_id=chats.id + AND chats_contacts.contact_id=?)", + (self,), + ) + .await?; + Ok(()) + } } impl fmt::Display for ContactId { diff --git a/src/securejoin.rs b/src/securejoin.rs index ff352e38f..3beeaae2a 100644 --- a/src/securejoin.rs +++ b/src/securejoin.rs @@ -426,6 +426,7 @@ pub(crate) async fn handle_securejoin_handshake( .await?; return Ok(HandshakeMessage::Ignore); } + contact_id.regossip_keys(context).await?; Contact::scaleup_origin_by_id(context, contact_id, Origin::SecurejoinInvited).await?; info!(context, "Auth verified.",); context.emit_event(EventType::ContactsChanged(Some(contact_id)));