crypto: Store our own device we receive from the server
parent
7d851a10b5
commit
0598bdebc7
|
@ -938,11 +938,16 @@ mod test {
|
||||||
let user_id: Arc<UserId> = alice_id().into();
|
let user_id: Arc<UserId> = alice_id().into();
|
||||||
let account = ReadOnlyAccount::new(&user_id, &alice_device_id());
|
let account = ReadOnlyAccount::new(&user_id, &alice_device_id());
|
||||||
let device = ReadOnlyDevice::from_account(&account).await;
|
let device = ReadOnlyDevice::from_account(&account).await;
|
||||||
|
let another_device =
|
||||||
|
ReadOnlyDevice::from_account(&ReadOnlyAccount::new(&user_id, &alice2_device_id()))
|
||||||
|
.await;
|
||||||
|
|
||||||
let store: Arc<dyn CryptoStore> = Arc::new(MemoryStore::new());
|
let store: Arc<dyn CryptoStore> = Arc::new(MemoryStore::new());
|
||||||
let identity = Arc::new(Mutex::new(PrivateCrossSigningIdentity::empty(alice_id())));
|
let identity = Arc::new(Mutex::new(PrivateCrossSigningIdentity::empty(alice_id())));
|
||||||
let verification = VerificationMachine::new(account, identity.clone(), store.clone());
|
let verification = VerificationMachine::new(account, identity.clone(), store.clone());
|
||||||
|
|
||||||
let store = Store::new(user_id.clone(), identity, store, verification);
|
let store = Store::new(user_id.clone(), identity, store, verification);
|
||||||
store.save_devices(&[device]).await.unwrap();
|
store.save_devices(&[device, another_device]).await.unwrap();
|
||||||
let session_cache = GroupSessionCache::new(store.clone());
|
let session_cache = GroupSessionCache::new(store.clone());
|
||||||
|
|
||||||
GossipMachine::new(
|
GossipMachine::new(
|
||||||
|
@ -1136,7 +1141,7 @@ mod test {
|
||||||
let account = account();
|
let account = account();
|
||||||
|
|
||||||
let own_device =
|
let own_device =
|
||||||
machine.store.get_device(&alice_id(), &alice_device_id()).await.unwrap().unwrap();
|
machine.store.get_device(&alice_id(), &alice2_device_id()).await.unwrap().unwrap();
|
||||||
|
|
||||||
let (outbound, inbound) =
|
let (outbound, inbound) =
|
||||||
account.create_group_session_pair_with_defaults(&room_id()).await.unwrap();
|
account.create_group_session_pair_with_defaults(&room_id()).await.unwrap();
|
||||||
|
|
|
@ -137,18 +137,20 @@ impl IdentityManager {
|
||||||
user_id: UserId,
|
user_id: UserId,
|
||||||
device_map: BTreeMap<DeviceIdBox, DeviceKeys>,
|
device_map: BTreeMap<DeviceIdBox, DeviceKeys>,
|
||||||
) -> StoreResult<DeviceChanges> {
|
) -> StoreResult<DeviceChanges> {
|
||||||
|
let own_device_id = (&*own_device_id).to_owned();
|
||||||
|
|
||||||
let mut changes = DeviceChanges::default();
|
let mut changes = DeviceChanges::default();
|
||||||
|
|
||||||
let current_devices: HashSet<DeviceIdBox> = device_map.keys().cloned().collect();
|
let current_devices: HashSet<DeviceIdBox> = device_map.keys().cloned().collect();
|
||||||
|
|
||||||
let tasks = device_map.into_iter().filter_map(|(device_id, device_keys)| {
|
let tasks = device_map.into_iter().filter_map(|(device_id, device_keys)| {
|
||||||
// We don't need our own device in the device store.
|
if user_id != device_keys.user_id || device_id != device_keys.device_id {
|
||||||
if user_id == *own_user_id && *device_id == *own_device_id {
|
|
||||||
None
|
|
||||||
} else if user_id != device_keys.user_id || device_id != device_keys.device_id {
|
|
||||||
warn!(
|
warn!(
|
||||||
"Mismatch in device keys payload of device {}|{} from user {}|{}",
|
user_id = user_id.as_str(),
|
||||||
device_id, device_keys.device_id, user_id, device_keys.user_id
|
device_id = device_id.as_str(),
|
||||||
|
device_key_user = device_keys.user_id.as_str(),
|
||||||
|
device_key_device_id = device_keys.device_id.as_str(),
|
||||||
|
"Mismatch in the device keys payload",
|
||||||
);
|
);
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
|
@ -169,13 +171,14 @@ impl IdentityManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
let current_devices: HashSet<&DeviceIdBox> = current_devices.iter().collect();
|
let current_devices: HashSet<&DeviceIdBox> = current_devices.iter().collect();
|
||||||
let stored_devices = store.get_readonly_devices(&user_id).await?;
|
let stored_devices = store.get_readonly_devices_unfiltered(&user_id).await?;
|
||||||
let stored_devices_set: HashSet<&DeviceIdBox> = stored_devices.keys().collect();
|
let stored_devices_set: HashSet<&DeviceIdBox> = stored_devices.keys().collect();
|
||||||
|
|
||||||
let deleted_devices_set = stored_devices_set.difference(¤t_devices);
|
let deleted_devices_set = stored_devices_set.difference(¤t_devices);
|
||||||
|
|
||||||
for device_id in deleted_devices_set {
|
for device_id in deleted_devices_set {
|
||||||
if let Some(device) = stored_devices.get(*device_id) {
|
if user_id == *own_user_id && *device_id == &own_device_id {
|
||||||
|
warn!("Our own device has been deleted");
|
||||||
|
} else if let Some(device) = stored_devices.get(*device_id) {
|
||||||
device.mark_as_deleted();
|
device.mark_as_deleted();
|
||||||
changes.deleted.push(device.clone());
|
changes.deleted.push(device.clone());
|
||||||
}
|
}
|
||||||
|
|
|
@ -287,6 +287,11 @@ impl OlmMachine {
|
||||||
self.account.identity_keys()
|
self.account.identity_keys()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the display name of our own device
|
||||||
|
pub async fn dislpay_name(&self) -> StoreResult<Option<String>> {
|
||||||
|
self.store.device_display_name().await
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the outgoing requests that need to be sent out.
|
/// Get the outgoing requests that need to be sent out.
|
||||||
///
|
///
|
||||||
/// This returns a list of `OutGoingRequest`, those requests need to be sent
|
/// This returns a list of `OutGoingRequest`, those requests need to be sent
|
||||||
|
|
|
@ -162,19 +162,19 @@ impl Store {
|
||||||
Self { user_id, identity, inner: store, verification_machine }
|
Self { user_id, identity, inner: store, verification_machine }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn user_id(&self) -> &UserId {
|
||||||
|
&self.user_id
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn device_id(&self) -> &DeviceId {
|
||||||
|
self.verification_machine.own_device_id()
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub async fn reset_cross_signing_identity(&self) {
|
pub async fn reset_cross_signing_identity(&self) {
|
||||||
self.identity.lock().await.reset().await;
|
self.identity.lock().await.reset().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_readonly_device(
|
|
||||||
&self,
|
|
||||||
user_id: &UserId,
|
|
||||||
device_id: &DeviceId,
|
|
||||||
) -> Result<Option<ReadOnlyDevice>> {
|
|
||||||
self.inner.get_device(user_id, device_id).await
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn save_sessions(&self, sessions: &[Session]) -> Result<()> {
|
pub async fn save_sessions(&self, sessions: &[Session]) -> Result<()> {
|
||||||
let changes = Changes { sessions: sessions.to_vec(), ..Default::default() };
|
let changes = Changes { sessions: sessions.to_vec(), ..Default::default() };
|
||||||
|
|
||||||
|
@ -201,13 +201,58 @@ impl Store {
|
||||||
self.save_changes(changes).await
|
self.save_changes(changes).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the display name of our own device.
|
||||||
|
pub async fn device_display_name(&self) -> Result<Option<String>, CryptoStoreError> {
|
||||||
|
Ok(self
|
||||||
|
.inner
|
||||||
|
.get_device(self.user_id(), self.device_id())
|
||||||
|
.await?
|
||||||
|
.and_then(|d| d.display_name().to_owned()))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the read-only version of all the devices that the given user has.
|
||||||
|
///
|
||||||
|
/// *Note*: This doesn't return our own device.
|
||||||
|
pub async fn get_readonly_device(
|
||||||
|
&self,
|
||||||
|
user_id: &UserId,
|
||||||
|
device_id: &DeviceId,
|
||||||
|
) -> Result<Option<ReadOnlyDevice>> {
|
||||||
|
if user_id == self.user_id() && device_id == self.device_id() {
|
||||||
|
Ok(None)
|
||||||
|
} else {
|
||||||
|
self.inner.get_device(user_id, device_id).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the read-only version of all the devices that the given user has.
|
||||||
|
///
|
||||||
|
/// *Note*: This doesn't return our own device.
|
||||||
pub async fn get_readonly_devices(
|
pub async fn get_readonly_devices(
|
||||||
&self,
|
&self,
|
||||||
user_id: &UserId,
|
user_id: &UserId,
|
||||||
|
) -> Result<HashMap<DeviceIdBox, ReadOnlyDevice>> {
|
||||||
|
self.inner.get_user_devices(user_id).await.map(|mut d| {
|
||||||
|
if user_id == self.user_id() {
|
||||||
|
d.remove(self.device_id());
|
||||||
|
}
|
||||||
|
d
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the read-only version of all the devices that the given user has.
|
||||||
|
///
|
||||||
|
/// *Note*: This does also return our own device.
|
||||||
|
pub async fn get_readonly_devices_unfiltered(
|
||||||
|
&self,
|
||||||
|
user_id: &UserId,
|
||||||
) -> Result<HashMap<DeviceIdBox, ReadOnlyDevice>> {
|
) -> Result<HashMap<DeviceIdBox, ReadOnlyDevice>> {
|
||||||
self.inner.get_user_devices(user_id).await
|
self.inner.get_user_devices(user_id).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get a device for the given user with the given curve25519 key.
|
||||||
|
///
|
||||||
|
/// *Note*: This doesn't return our own device.
|
||||||
pub async fn get_device_from_curve_key(
|
pub async fn get_device_from_curve_key(
|
||||||
&self,
|
&self,
|
||||||
user_id: &UserId,
|
user_id: &UserId,
|
||||||
|
@ -221,7 +266,11 @@ impl Store {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_user_devices(&self, user_id: &UserId) -> Result<UserDevices> {
|
pub async fn get_user_devices(&self, user_id: &UserId) -> Result<UserDevices> {
|
||||||
let devices = self.inner.get_user_devices(user_id).await?;
|
let mut devices = self.inner.get_user_devices(user_id).await?;
|
||||||
|
|
||||||
|
if user_id == self.user_id() {
|
||||||
|
devices.remove(self.device_id());
|
||||||
|
}
|
||||||
|
|
||||||
let own_identity =
|
let own_identity =
|
||||||
self.inner.get_user_identity(&self.user_id).await?.map(|i| i.own().cloned()).flatten();
|
self.inner.get_user_identity(&self.user_id).await?.map(|i| i.own().cloned()).flatten();
|
||||||
|
|
Loading…
Reference in New Issue