Page MenuHomePhabricator

D14088.id46227.diff
No OneTemporary

D14088.id46227.diff

diff --git a/services/identity/src/device_list.rs b/services/identity/src/device_list.rs
--- a/services/identity/src/device_list.rs
+++ b/services/identity/src/device_list.rs
@@ -382,6 +382,27 @@
is_added != is_removed
}
+ pub fn new_flow_migration_validator(
+ previous_device_list: &[&str],
+ new_device_list: &[&str],
+ calling_device_id: &str,
+ ) -> bool {
+ // primary device must be changed
+ if !primary_device_changed(previous_device_list, new_device_list) {
+ return false;
+ }
+
+ // new primary must be the calling device
+ if new_device_list.first() != Some(&calling_device_id) {
+ return false;
+ }
+
+ // no device added or removed, just reorder
+ let previous_set: HashSet<_> = previous_device_list.iter().collect();
+ let new_set: HashSet<_> = new_device_list.iter().collect();
+ previous_set == new_set
+ }
+
#[cfg(test)]
mod tests {
use super::*;
diff --git a/services/identity/src/grpc_services/authenticated.rs b/services/identity/src/grpc_services/authenticated.rs
--- a/services/identity/src/grpc_services/authenticated.rs
+++ b/services/identity/src/grpc_services/authenticated.rs
@@ -920,13 +920,58 @@
)
.await?;
+ let is_new_flow_user = self
+ .db_client
+ .get_user_login_flow(&user_id)
+ .await?
+ .is_new_flows();
+
let new_list = SignedDeviceList::try_from(request.into_inner())?;
let update = DeviceListUpdate::try_from(new_list)?;
- let validator =
- crate::device_list::validation::update_device_list_rpc_validator;
+
+ let validator = if is_new_flow_user {
+ // regular device list update
+ Some(crate::device_list::validation::update_device_list_rpc_validator)
+ } else {
+ // new flow migration
+ let Some(current_device_list) =
+ self.db_client.get_current_device_list(&user_id).await?
+ else {
+ tracing::warn!("User {} does not have valid device list. New flow migration impossible.", redact_sensitive_data(&user_id));
+ return Err(tonic::Status::aborted(
+ tonic_status_messages::DEVICE_LIST_ERROR,
+ ));
+ };
+
+ let calling_device_id = &device_id;
+ let previous_device_ids: Vec<&str> = current_device_list
+ .device_ids
+ .iter()
+ .map(AsRef::as_ref)
+ .collect();
+ let new_device_ids: Vec<&str> =
+ update.devices.iter().map(AsRef::as_ref).collect();
+
+ let is_valid =
+ crate::device_list::validation::new_flow_migration_validator(
+ &previous_device_ids,
+ &new_device_ids,
+ calling_device_id,
+ );
+ if !is_valid {
+ return Err(
+ crate::error::Error::DeviceList(
+ crate::error::DeviceListError::InvalidDeviceListUpdate,
+ )
+ .into(),
+ );
+ }
+ // we've already validated it, no further validator required
+ None
+ };
self
.db_client
- .apply_devicelist_update(&user_id, update, Some(validator), true)
+ .apply_devicelist_update(&user_id, update, validator, true)
.await?;
Ok(Response::new(Empty {}))

File Metadata

Mime Type
text/plain
Expires
Thu, Dec 12, 10:19 AM (3 h, 57 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2647808
Default Alt Text
D14088.id46227.diff (3 KB)

Event Timeline