When changing self addr, transfer private key to new addr (#3351)

fix #3267
This commit is contained in:
Hocuri
2022-05-23 19:25:53 +02:00
committed by GitHub
parent c762834e05
commit b7af53c7d9
3 changed files with 128 additions and 39 deletions

View File

@@ -8,7 +8,7 @@ use crate::blob::BlobObject;
use crate::constants::DC_VERSION_STR;
use crate::contact::addr_cmp;
use crate::context::Context;
use crate::dc_tools::{dc_get_abs_path, improve_single_line_input};
use crate::dc_tools::{dc_get_abs_path, improve_single_line_input, EmailAddress};
use crate::events::EventType;
use crate::mimefactory::RECOMMENDED_FILE_SIZE;
use crate::provider::{get_provider_by_id, Provider};
@@ -355,6 +355,8 @@ impl Context {
///
/// This should only be used by test code and during configure.
pub(crate) async fn set_primary_self_addr(&self, primary_new: &str) -> Result<()> {
let old_addr = self.get_config(Config::ConfiguredAddr).await?;
// add old primary address (if exists) to secondary addresses
let mut secondary_addrs = self.get_all_self_addrs().await?;
// never store a primary address also as a secondary
@@ -368,6 +370,17 @@ impl Context {
self.set_config(Config::ConfiguredAddr, Some(primary_new))
.await?;
if let Some(old_addr) = old_addr {
let old_addr = EmailAddress::new(&old_addr)?;
let old_keypair = crate::key::load_keypair(self, &old_addr).await?;
if let Some(mut old_keypair) = old_keypair {
old_keypair.addr = EmailAddress::new(primary_new)?;
crate::key::store_self_keypair(self, &old_keypair, crate::key::KeyPairUse::Default)
.await?;
}
}
Ok(())
}
@@ -419,7 +432,9 @@ mod tests {
use std::string::ToString;
use crate::constants;
use crate::dc_receive_imf::dc_receive_imf;
use crate::test_utils::TestContext;
use crate::test_utils::TestContextManager;
use num_traits::FromPrimitive;
#[test]
@@ -499,14 +514,14 @@ mod tests {
assert_eq!(alice.get_all_self_addrs().await?, vec!["Alice@Example.Org"]);
// Test adding a new (primary) self address
// The address is trimmed during by `LoginParam::from_database()`,
// The address is trimmed during configure by `LoginParam::from_database()`,
// so `set_primary_self_addr()` doesn't have to trim it.
alice.set_primary_self_addr(" Alice@alice.com ").await?;
assert!(alice.is_self_addr(" aliCe@example.org").await?);
alice.set_primary_self_addr("Alice@alice.com").await?;
assert!(alice.is_self_addr("aliCe@example.org").await?);
assert!(alice.is_self_addr("alice@alice.com").await?);
assert_eq!(
alice.get_all_self_addrs().await?,
vec![" Alice@alice.com ", "Alice@Example.Org"]
vec!["Alice@alice.com", "Alice@Example.Org"]
);
// Check that the entry is not duplicated
@@ -537,4 +552,68 @@ mod tests {
Ok(())
}
#[async_std::test]
async fn test_change_primary_self_addr() -> Result<()> {
let mut tcm = TestContextManager::new().await;
let alice = tcm.alice().await;
let bob = tcm.bob().await;
// Alice sends a message to Bob
let alice_bob_chat = alice.create_chat(&bob).await;
let sent = alice.send_text(alice_bob_chat.id, "Hi").await;
let bob_msg = bob.recv_msg(&sent).await;
bob_msg.chat_id.accept(&bob).await?;
assert_eq!(bob_msg.text.unwrap(), "Hi");
// Alice changes her self address and reconfigures
// (ensure_secret_key_exists() is called during configure)
alice
.set_primary_self_addr("alice@someotherdomain.xyz")
.await?;
crate::e2ee::ensure_secret_key_exists(&alice).await?;
assert_eq!(
alice.get_primary_self_addr().await?,
"alice@someotherdomain.xyz"
);
// Bob sends a message to Alice, encrypting to her previous key
let sent = bob.send_text(bob_msg.chat_id, "hi back").await;
// Alice set up message forwarding so that she still receives
// the message with her new address
let alice_msg = alice.recv_msg(&sent).await;
assert_eq!(alice_msg.text, Some("hi back".to_string()));
assert_eq!(alice_msg.get_showpadlock(), true);
assert_eq!(alice_msg.chat_id, alice_bob_chat.id);
// Even if Bob sends a message to Alice without In-Reply-To,
// it's still assigned to the 1:1 chat with Bob and not to
// a group (without secondary addresses, an ad-hoc group
// would be created)
dc_receive_imf(
&alice,
b"From: bob@example.net
To: alice@example.org
Chat-Version: 1.0
Message-ID: <456@example.com>
Message w/out In-Reply-To
",
false,
)
.await?;
let alice_msg = alice.get_last_msg().await;
assert_eq!(
alice_msg.text,
Some("Message w/out In-Reply-To".to_string())
);
assert_eq!(alice_msg.get_showpadlock(), false);
assert_eq!(alice_msg.chat_id, alice_bob_chat.id);
Ok(())
}
}