Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F32562107
D12889.1767333067.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D12889.1767333067.diff
View Options
diff --git a/services/identity/src/database/device_list.rs b/services/identity/src/database/device_list.rs
--- a/services/identity/src/database/device_list.rs
+++ b/services/identity/src/database/device_list.rs
@@ -241,6 +241,20 @@
}
}
+impl From<HashMap<String, PlatformDetails>>
+ for protos::auth::UserDevicesPlatformDetails
+{
+ fn from(devices_map: HashMap<String, PlatformDetails>) -> Self {
+ let devices_platform_details = devices_map
+ .into_iter()
+ .map(|(device_id, platform_details)| (device_id, platform_details.into()))
+ .collect();
+ Self {
+ devices_platform_details,
+ }
+ }
+}
+
// helper structs for converting to/from attribute values for sort key (a.k.a itemID)
pub struct DeviceIDAttribute(pub String);
struct DeviceListKeyAttribute(DateTime<Utc>);
@@ -333,37 +347,7 @@
.and_then(Prekey::try_from)?;
let login_time: DateTime<Utc> = attrs.take_attr(ATTR_LOGIN_TIME)?;
-
- // New schema contains PlatformDetails attribute while legacy schema
- // contains "deviceType" and "codeVersion" top-level attributes
- let platform_details = match attrs
- .take_attr::<Option<PlatformDetails>>(ATTR_PLATFORM_DETAILS)?
- {
- Some(platform_details) => platform_details,
- None => {
- let raw_device_type: String = attrs.take_attr(OLD_ATTR_DEVICE_TYPE)?;
- let device_type = DeviceType::from_str_name(&raw_device_type)
- .ok_or_else(|| {
- DBItemError::new(
- OLD_ATTR_DEVICE_TYPE.to_string(),
- raw_device_type.into(),
- DBItemAttributeError::InvalidValue,
- )
- })?;
- let code_version = attrs
- .remove(OLD_ATTR_CODE_VERSION)
- .and_then(|attr| attr.as_n().ok().cloned())
- .and_then(|val| val.parse::<u64>().ok())
- .unwrap_or_default();
-
- PlatformDetails {
- device_type,
- code_version,
- state_version: None,
- major_desktop_version: None,
- }
- }
- };
+ let platform_details = take_platform_details(&mut attrs)?;
Ok(Self {
user_id,
@@ -1153,6 +1137,66 @@
Ok(device_lists)
}
+ /// Gets [`PlatformDetails`] for multiple users.
+ /// Takes iterable collection of tuples `(UserID, DeviceID)`.
+ /// Returns nested map: `Map<UserID, Map<DeviceID, PlatformDetails>>`.
+ #[tracing::instrument(skip_all)]
+ pub async fn get_devices_platform_details(
+ &self,
+ user_device_ids: impl IntoIterator<Item = (String, String)>,
+ ) -> Result<HashMap<String, HashMap<String, PlatformDetails>>, Error> {
+ let primary_keys = user_device_ids
+ .into_iter()
+ .map(|(user_id, device_id)| {
+ AttributeMap::from([
+ (
+ devices_table::ATTR_USER_ID.to_string(),
+ AttributeValue::S(user_id),
+ ),
+ (
+ devices_table::ATTR_ITEM_ID.to_string(),
+ DeviceIDAttribute(device_id).into(),
+ ),
+ ])
+ })
+ .collect::<Vec<_>>();
+ let projection_expression = Some(
+ [
+ devices_table::ATTR_USER_ID,
+ devices_table::ATTR_ITEM_ID,
+ devices_table::ATTR_PLATFORM_DETAILS,
+ // we need these for legacy devices without ATTR_PLATFORM_DETAILS
+ devices_table::OLD_ATTR_DEVICE_TYPE,
+ devices_table::OLD_ATTR_CODE_VERSION,
+ ]
+ .join(", "),
+ );
+
+ let fetched_results = comm_lib::database::batch_operations::batch_get(
+ &self.client,
+ devices_table::NAME,
+ primary_keys,
+ projection_expression,
+ Default::default(),
+ )
+ .await?;
+
+ let mut users_devices_platform_details = HashMap::new();
+ for mut item in fetched_results {
+ let user_id: String = item.take_attr(devices_table::ATTR_USER_ID)?;
+ let device_id: DeviceIDAttribute =
+ item.remove(devices_table::ATTR_ITEM_ID).try_into()?;
+ let platform_details = take_platform_details(&mut item)?;
+
+ let user_devices = users_devices_platform_details
+ .entry(user_id)
+ .or_insert_with(HashMap::new);
+ user_devices.insert(device_id.into_inner(), platform_details);
+ }
+
+ Ok(users_devices_platform_details)
+ }
+
/// Adds device data to devices table. If the device already exists, its
/// data is overwritten. This does not update the device list; the device ID
/// should already be present in the device list.
@@ -1800,6 +1844,44 @@
.consistent_read(true)
}
+fn take_platform_details(
+ device_attrs: &mut AttributeMap,
+) -> Result<PlatformDetails, DBItemError> {
+ let platform_details_attr: Option<PlatformDetails> =
+ device_attrs.take_attr::<Option<PlatformDetails>>(ATTR_PLATFORM_DETAILS)?;
+
+ // New schema contains PlatformDetails attribute while legacy schema
+ // contains "deviceType" and "codeVersion" top-level attributes
+ let platform_details = match platform_details_attr {
+ Some(platform_details) => platform_details,
+ None => {
+ let raw_device_type: String =
+ device_attrs.take_attr(OLD_ATTR_DEVICE_TYPE)?;
+ let device_type = DeviceType::from_str_name(&raw_device_type)
+ .ok_or_else(|| {
+ DBItemError::new(
+ OLD_ATTR_DEVICE_TYPE.to_string(),
+ raw_device_type.into(),
+ DBItemAttributeError::InvalidValue,
+ )
+ })?;
+ let code_version = device_attrs
+ .remove(OLD_ATTR_CODE_VERSION)
+ .and_then(|attr| attr.as_n().ok().cloned())
+ .and_then(|val| val.parse::<u64>().ok())
+ .unwrap_or_default();
+
+ PlatformDetails {
+ device_type,
+ code_version,
+ state_version: None,
+ major_desktop_version: None,
+ }
+ }
+ };
+ Ok(platform_details)
+}
+
/// [`transact_update_devicelist()`] closure result
struct UpdateOperationInfo {
/// (optional) transactional DDB operation to be performed
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Jan 2, 5:51 AM (1 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5878448
Default Alt Text
D12889.1767333067.diff (5 KB)
Attached To
Mode
D12889: [identity] Add function to batch-get platform details
Attached
Detach File
Event Timeline
Log In to Comment