Skip to content

Commit 330fb02

Browse files
committed
test: add test_securejoin_after_contact_resetup test
This test reproduces a bug preventing joining the group with a QR code if the group already has a contact with inconsistent key state, which means both Autocrypt and verified key exist, but don't match. This can happen when an invite QR code created by this contact is scanned as scanning an invite code creates unprotected group with the inviter for info messages. If securejoin process never finishes because the inviter is offline, group remains in this unprotected state with added inviter. Normally the group becomes verified when a "Member added" (vg-member-added) message is received in the chat. However, current code checks that all members of the chat are verified (have a green checkmark, use verified key in 1:1 chat) before marking the group as verified and fails otherwise.
1 parent 1447ab8 commit 330fb02

File tree

1 file changed

+72
-0
lines changed

1 file changed

+72
-0
lines changed

deltachat-rpc-client/tests/test_securejoin.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import logging
22

3+
import pytest
34
from deltachat_rpc_client import Chat, SpecialContactId
45

56

@@ -477,3 +478,74 @@ def test_gossip_verification(acfactory) -> None:
477478
# Securejoin propagates verification.
478479
carol_contact_alice_snapshot = carol_contact_alice.get_snapshot()
479480
assert carol_contact_alice_snapshot.is_verified
481+
482+
483+
@pytest.mark.xfail()
484+
def test_securejoin_after_contact_resetup(acfactory) -> None:
485+
"""
486+
Regression test for a bug that prevented joining verified group with a QR code
487+
if the group is already created and contains
488+
a contact with inconsistent (Autocrypt and verified keys exist but don't match) key state.
489+
"""
490+
ac1, ac2, ac3 = acfactory.get_online_accounts(3)
491+
492+
# ac3 creates protected group with ac1.
493+
ac3_chat = ac3.create_group("Verified group", protect=True)
494+
495+
# ac1 joins ac3 group.
496+
ac3_qr_code, _svg = ac3_chat.get_qr_code()
497+
ac1.secure_join(ac3_qr_code)
498+
ac1.wait_for_securejoin_joiner_success()
499+
500+
# ac1 waits for member added message and creates a QR code.
501+
snapshot = ac1.get_message_by_id(ac1.wait_for_incoming_msg_event().msg_id).get_snapshot()
502+
ac1_qr_code, _svg = snapshot.chat.get_qr_code()
503+
504+
# ac2 verifies ac1
505+
qr_code, _svg = ac1.get_qr_code()
506+
ac2.secure_join(qr_code)
507+
ac2.wait_for_securejoin_joiner_success()
508+
509+
# ac1 is verified for ac2.
510+
ac2_contact_ac1 = ac2.create_contact(ac1.get_config("addr"), "")
511+
assert ac2_contact_ac1.get_snapshot().is_verified
512+
513+
# ac1 resetups the account.
514+
ac1 = acfactory.resetup_account(ac1)
515+
516+
# ac1 sends a message to ac2.
517+
ac1_contact_ac2 = ac1.create_contact(ac2.get_config("addr"), "")
518+
ac1_chat_ac2 = ac1_contact_ac2.create_chat()
519+
ac1_chat_ac2.send_text("Hello!")
520+
521+
# ac2 receives a message.
522+
snapshot = ac2.get_message_by_id(ac2.wait_for_incoming_msg_event().msg_id).get_snapshot()
523+
assert snapshot.text == "Hello!"
524+
525+
# ac1 is no longer verified for ac2 as new Autocrypt key is not the same as old verified key.
526+
assert not ac2_contact_ac1.get_snapshot().is_verified
527+
528+
# ac1 goes offline.
529+
ac1.remove()
530+
531+
# Scanning a QR code results in creating an unprotected group with an inviter.
532+
# In this case inviter is ac1 which has an inconsistent key state.
533+
# Normally inviter becomes verified as a result of Securejoin protocol
534+
# and then the group chat becomes verified when "Member added" is received,
535+
# but in this case ac1 is offline and this Securejoin process will never finish.
536+
logging.info("ac2 scans ac1 QR code, this is not expected to finish")
537+
ac2.secure_join(ac1_qr_code)
538+
539+
logging.info("ac2 scans ac3 QR code")
540+
ac2.secure_join(ac3_qr_code)
541+
542+
logging.info("ac2 waits for joiner success")
543+
ac2.wait_for_securejoin_joiner_success()
544+
545+
# Wait for member added.
546+
logging.info("ac2 waits for member added message")
547+
snapshot = ac2.get_message_by_id(ac2.wait_for_incoming_msg_event().msg_id).get_snapshot()
548+
assert snapshot.is_info
549+
550+
# ac1 is still "not verified" for ac2 due to inconsistent state.
551+
assert not ac2_contact_ac1.get_snapshot().is_verified

0 commit comments

Comments
 (0)