| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | use anyhow::Result; |
| |
|
| | use crate::chat::{self, Chat, ChatId}; |
| | use crate::contact::{Contact, ContactId}; |
| | use crate::message::Message; |
| | use crate::receive_imf::receive_imf; |
| | use crate::securejoin::get_securejoin_qr; |
| | use crate::test_utils::TestContext; |
| | use crate::test_utils::TestContextManager; |
| | use crate::test_utils::mark_as_verified; |
| |
|
| | #[tokio::test(flavor = "multi_thread", worker_threads = 2)] |
| | async fn test_change_primary_self_addr() -> Result<()> { |
| | let mut tcm = TestContextManager::new(); |
| | let alice = tcm.alice().await; |
| | let bob = tcm.bob().await; |
| |
|
| | tcm.send_recv_accept(&alice, &bob, "Hi").await; |
| | let bob_alice_chat = bob.create_chat(&alice).await; |
| |
|
| | tcm.change_addr(&alice, "alice@someotherdomain.xyz").await; |
| |
|
| | tcm.section("Bob sends a message to Alice, encrypting to her previous key"); |
| | let sent = bob.send_text(bob_alice_chat.id, "hi back").await; |
| |
|
| | |
| | |
| | let alice_msg = alice.recv_msg(&sent).await; |
| | assert_eq!(alice_msg.text, "hi back".to_string()); |
| | assert_eq!(alice_msg.get_showpadlock(), true); |
| | let alice_bob_chat = alice.create_chat(&bob).await; |
| | assert_eq!(alice_msg.chat_id, alice_bob_chat.id); |
| |
|
| | Ok(()) |
| | } |
| |
|
| | enum ChatForTransition { |
| | OneToOne, |
| | GroupChat, |
| | VerifiedGroup, |
| | } |
| | use ChatForTransition::*; |
| |
|
| | #[tokio::test(flavor = "multi_thread", worker_threads = 2)] |
| | async fn test_aeap_transition_0() { |
| | check_aeap_transition(OneToOne, false).await; |
| | } |
| | #[tokio::test(flavor = "multi_thread", worker_threads = 2)] |
| | async fn test_aeap_transition_1() { |
| | check_aeap_transition(GroupChat, false).await; |
| | } |
| | #[tokio::test(flavor = "multi_thread", worker_threads = 2)] |
| | async fn test_aeap_transition_0_verified() { |
| | check_aeap_transition(OneToOne, true).await; |
| | } |
| | #[tokio::test(flavor = "multi_thread", worker_threads = 2)] |
| | async fn test_aeap_transition_1_verified() { |
| | check_aeap_transition(GroupChat, true).await; |
| | } |
| | #[tokio::test(flavor = "multi_thread", worker_threads = 2)] |
| | async fn test_aeap_transition_2_verified() { |
| | check_aeap_transition(VerifiedGroup, true).await; |
| | } |
| |
|
| | |
| | |
| | |
| | async fn check_aeap_transition(chat_for_transition: ChatForTransition, verified: bool) { |
| | const ALICE_NEW_ADDR: &str = "alice2@example.net"; |
| |
|
| | let mut tcm = TestContextManager::new(); |
| | let alice = &tcm.alice().await; |
| | let bob = &tcm.bob().await; |
| |
|
| | tcm.send_recv_accept(alice, bob, "Hi").await; |
| | tcm.send_recv(bob, alice, "Hi back").await; |
| |
|
| | if verified { |
| | mark_as_verified(alice, bob).await; |
| | mark_as_verified(bob, alice).await; |
| | } |
| |
|
| | let mut groups = vec![ |
| | chat::create_group(bob, "Group 0").await.unwrap(), |
| | chat::create_group(bob, "Group 1").await.unwrap(), |
| | ]; |
| | if verified { |
| | groups.push(chat::create_group(bob, "Group 2").await.unwrap()); |
| | groups.push(chat::create_group(bob, "Group 3").await.unwrap()); |
| | } |
| |
|
| | let alice_contact = bob.add_or_lookup_contact_id(alice).await; |
| | for group in &groups { |
| | chat::add_contact_to_chat(bob, *group, alice_contact) |
| | .await |
| | .unwrap(); |
| | } |
| |
|
| | |
| | |
| | tcm.section("Promoting group 1"); |
| | let sent = bob.send_text(groups[1], "group created").await; |
| | let group1_alice = alice.recv_msg(&sent).await.chat_id; |
| |
|
| | let mut group3_alice = None; |
| | if verified { |
| | tcm.section("Promoting group 3"); |
| | let sent = bob.send_text(groups[3], "group created").await; |
| | group3_alice = Some(alice.recv_msg(&sent).await.chat_id); |
| | } |
| |
|
| | tcm.change_addr(alice, ALICE_NEW_ADDR).await; |
| |
|
| | tcm.section("Alice sends another message to Bob, this time from her new addr"); |
| | |
| | let chat_to_send = match chat_for_transition { |
| | OneToOne => alice.create_chat(bob).await.id, |
| | GroupChat => group1_alice, |
| | VerifiedGroup => group3_alice.expect("No verified group"), |
| | }; |
| | let sent = alice |
| | .send_text(chat_to_send, "Hello from my new addr!") |
| | .await; |
| | let recvd = bob.recv_msg(&sent).await; |
| | assert_eq!(recvd.text, "Hello from my new addr!"); |
| |
|
| | tcm.section("Check that the AEAP transition worked"); |
| | check_that_transition_worked(bob, &groups, alice_contact, ALICE_NEW_ADDR).await; |
| |
|
| | tcm.section("Test switching back"); |
| | tcm.change_addr(alice, "alice@example.org").await; |
| | let sent = alice |
| | .send_text(chat_to_send, "Hello from my old addr!") |
| | .await; |
| | let recvd = bob.recv_msg(&sent).await; |
| | assert_eq!(recvd.text, "Hello from my old addr!"); |
| |
|
| | check_that_transition_worked(bob, &groups, alice_contact, "alice@example.org").await; |
| | } |
| |
|
| | async fn check_that_transition_worked( |
| | bob: &TestContext, |
| | groups: &[ChatId], |
| | alice_contact_id: ContactId, |
| | alice_addr: &str, |
| | ) { |
| | for group in groups { |
| | let members = chat::get_chat_contacts(bob, *group).await.unwrap(); |
| | |
| | assert_eq!( |
| | members.len(), |
| | 2, |
| | "Group {} has members {:?}, but should have members {:?} and {:?}", |
| | group, |
| | &members, |
| | alice_contact_id, |
| | ContactId::SELF |
| | ); |
| | assert!( |
| | members.contains(&alice_contact_id), |
| | "Group {group} lacks {alice_contact_id}" |
| | ); |
| | assert!(members.contains(&ContactId::SELF)); |
| | } |
| |
|
| | |
| | let alice_contact = Contact::get_by_id(bob, alice_contact_id).await.unwrap(); |
| | assert_eq!(alice_contact.get_addr(), alice_addr); |
| | } |
| |
|
| | |
| | |
| | #[tokio::test(flavor = "multi_thread", worker_threads = 2)] |
| | async fn test_aeap_replay_attack() -> Result<()> { |
| | let mut tcm = TestContextManager::new(); |
| | let alice = tcm.alice().await; |
| | let bob = tcm.bob().await; |
| | let fiona = tcm.fiona().await; |
| |
|
| | tcm.send_recv_accept(&alice, &bob, "Hi").await; |
| | tcm.send_recv(&bob, &alice, "Hi back").await; |
| |
|
| | let group = chat::create_group(&bob, "Group 0").await?; |
| |
|
| | let bob_alice_contact = bob.add_or_lookup_contact_id(&alice).await; |
| | let bob_fiona_contact = bob.add_or_lookup_contact_id(&fiona).await; |
| | chat::add_contact_to_chat(&bob, group, bob_alice_contact).await?; |
| |
|
| | |
| | |
| | |
| | let chat = alice.create_chat(&bob).await; |
| | let sent = alice.send_text(chat.id, "whoop whoop").await; |
| |
|
| | |
| | let sent = sent |
| | .payload() |
| | .replace("From: <alice@example.org>", "From: <fiona@example.net>"); |
| | sent.find("From: <fiona@example.net>").unwrap(); |
| |
|
| | |
| | |
| | assert!(!sent.contains("addr=alice@example.org;")); |
| |
|
| | tcm.section("Fiona replaced the From addr and forwards the message to Bob"); |
| | receive_imf(&bob, sent.as_bytes(), false).await?.unwrap(); |
| |
|
| | |
| | assert!(chat::is_contact_in_chat(&bob, group, bob_alice_contact).await?); |
| | assert!(!chat::is_contact_in_chat(&bob, group, bob_fiona_contact).await?); |
| |
|
| | Ok(()) |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | #[tokio::test(flavor = "multi_thread", worker_threads = 2)] |
| | async fn test_write_to_alice_after_aeap() -> Result<()> { |
| | let mut tcm = TestContextManager::new(); |
| | let alice = &tcm.alice().await; |
| | let bob = &tcm.bob().await; |
| |
|
| | let alice_grp_id = chat::create_group(alice, "Group").await?; |
| | let qr = get_securejoin_qr(alice, Some(alice_grp_id)).await?; |
| | tcm.exec_securejoin_qr(bob, alice, &qr).await; |
| | let bob_alice_contact = bob.add_or_lookup_contact(alice).await; |
| | assert!(bob_alice_contact.is_verified(bob).await?); |
| | let bob_alice_chat = bob.create_chat(alice).await; |
| | let bob_unprotected_grp_id = bob.create_group_with_members("Group", &[alice]).await; |
| |
|
| | tcm.change_addr(alice, "alice@someotherdomain.xyz").await; |
| | let sent = alice.send_text(alice_grp_id, "Hello!").await; |
| | bob.recv_msg(&sent).await; |
| |
|
| | assert!(bob_alice_contact.is_verified(bob).await?); |
| | let bob_alice_chat = Chat::load_from_db(bob, bob_alice_chat.id).await?; |
| | let mut msg = Message::new_text("hi".to_string()); |
| | chat::send_msg(bob, bob_alice_chat.id, &mut msg).await?; |
| |
|
| | |
| | let sent = bob |
| | .send_text(bob_unprotected_grp_id, "Alice, how is your address change?") |
| | .await; |
| | let msg = Message::load_from_db(bob, sent.sender_msg_id).await?; |
| | assert!(msg.get_showpadlock()); |
| | Ok(()) |
| | } |
| |
|