crypto: Allow a device to be updated.

master
Damir Jelić 2020-04-21 09:31:33 +02:00
parent b572381a8e
commit 63c0aa8771
2 changed files with 50 additions and 5 deletions

View File

@ -722,7 +722,6 @@ impl AsyncClient {
callback(response).await; callback(response).await;
// TODO query keys here.
// TODO send out to-device messages here // TODO send out to-device messages here
#[cfg(feature = "encryption")] #[cfg(feature = "encryption")]

View File

@ -13,6 +13,7 @@
// limitations under the License. // limitations under the License.
use std::collections::HashMap; use std::collections::HashMap;
use std::mem;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc; use std::sync::Arc;
@ -26,8 +27,6 @@ use crate::identifiers::{DeviceId, UserId};
pub struct Device { pub struct Device {
user_id: Arc<UserId>, user_id: Arc<UserId>,
device_id: Arc<DeviceId>, device_id: Arc<DeviceId>,
// TODO the algorithm and the keys might change, so we can't make them read
// only here. Perhaps dashmap and a rwlock on the algorithms.
algorithms: Arc<Vec<Algorithm>>, algorithms: Arc<Vec<Algorithm>>,
keys: Arc<HashMap<KeyAlgorithm, String>>, keys: Arc<HashMap<KeyAlgorithm, String>>,
display_name: Arc<Option<String>>, display_name: Arc<Option<String>>,
@ -115,6 +114,30 @@ impl Device {
pub fn algorithms(&self) -> &[Algorithm] { pub fn algorithms(&self) -> &[Algorithm] {
&self.algorithms &self.algorithms
} }
/// Update a device with a new device keys struct.
pub(crate) fn update_device(&mut self, device_keys: &DeviceKeys) {
let mut keys = HashMap::new();
for (key_id, key) in device_keys.keys.iter() {
let key_id = key_id.0;
keys.insert(key_id, key.clone());
}
let display_name = Arc::new(
device_keys
.unsigned
.as_ref()
.map(|d| d.device_display_name.clone()),
);
mem::replace(
&mut self.algorithms,
Arc::new(device_keys.algorithms.clone()),
);
mem::replace(&mut self.keys, Arc::new(keys));
mem::replace(&mut self.display_name, display_name);
}
} }
impl From<&DeviceKeys> for Device { impl From<&DeviceKeys> for Device {
@ -158,7 +181,7 @@ pub(crate) mod test {
use crate::crypto::device::{Device, TrustState}; use crate::crypto::device::{Device, TrustState};
use crate::identifiers::UserId; use crate::identifiers::UserId;
pub(crate) fn get_device() -> Device { fn device_keys() -> DeviceKeys {
let user_id = UserId::try_from("@alice:example.org").unwrap(); let user_id = UserId::try_from("@alice:example.org").unwrap();
let device_id = "DEVICEID"; let device_id = "DEVICEID";
@ -183,8 +206,11 @@ pub(crate) mod test {
} }
}); });
let device_keys: DeviceKeys = serde_json::from_value(device_keys).unwrap(); serde_json::from_value(device_keys).unwrap()
}
pub(crate) fn get_device() -> Device {
let device_keys = device_keys();
Device::from(&device_keys) Device::from(&device_keys)
} }
@ -212,4 +238,24 @@ pub(crate) mod test {
"nE6W2fCblxDcOFmeEtCHNl8/l8bXcu7GKyAswA4r3mM" "nE6W2fCblxDcOFmeEtCHNl8/l8bXcu7GKyAswA4r3mM"
); );
} }
#[test]
fn update_a_device() {
let mut device = get_device();
assert_eq!(
"Alice's mobile phone",
device.display_name().as_ref().unwrap()
);
let mut device_keys = device_keys();
device_keys.unsigned.as_mut().unwrap().device_display_name =
"Alice's work computer".to_owned();
device.update_device(&device_keys);
assert_eq!(
"Alice's work computer",
device.display_name().as_ref().unwrap()
);
}
} }