Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F3295666
D11898.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
6 KB
Referenced Files
None
Subscribers
None
D11898.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
@@ -72,12 +72,17 @@
pub prekey_signature: String,
}
-/// A struct representing device list update request
-/// payload; issued by the primary device
-#[derive(derive_more::Constructor)]
+/// A struct representing device list update payload
+/// issued by the primary device.
+/// For the JSON payload, see [`crate::device_list::SignedDeviceList`]
pub struct DeviceListUpdate {
pub devices: Vec<String>,
pub timestamp: DateTime<Utc>,
+ /// Primary device signature. This is `None` for Identity-generated lists.
+ pub current_primary_signature: Option<String>,
+ /// Last primary device signature, in case the primary device has changed
+ /// since last device list update.
+ pub last_primary_signature: Option<String>,
}
impl DeviceRow {
@@ -925,6 +930,7 @@
let DeviceListUpdate {
devices: new_list,
timestamp,
+ ..
} = update;
self
.transact_update_devicelist(user_id, |current_list, _| {
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
@@ -10,22 +10,16 @@
grpc_services::protos::auth::UpdateDeviceListRequest,
};
-// raw device list that can be serialized to JSON (and then signed in the future)
+// serde helper for serializing/deserializing
+// device list JSON payload
#[derive(serde::Serialize, serde::Deserialize)]
-pub struct RawDeviceList {
+struct RawDeviceList {
devices: Vec<String>,
timestamp: i64,
}
-impl From<DeviceListRow> for RawDeviceList {
- fn from(row: DeviceListRow) -> Self {
- Self {
- devices: row.device_ids,
- timestamp: row.timestamp.timestamp_millis(),
- }
- }
-}
-
+/// Signed device list payload that is serializable to JSON.
+/// For the DDB payload, see [`DeviceListUpdate`]
#[derive(serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SignedDeviceList {
@@ -45,23 +39,6 @@
}
impl SignedDeviceList {
- /// Serialize (and sign in the future) a [`RawDeviceList`]
- pub fn try_from_raw(raw: RawDeviceList) -> Result<Self, tonic::Status> {
- let stringified_list = serde_json::to_string(&raw).map_err(|err| {
- error!(
- errorType = error_types::GRPC_SERVICES_LOG,
- "Failed to serialize raw device list: {}", err
- );
- tonic::Status::failed_precondition("unexpected error")
- })?;
-
- Ok(Self {
- raw_device_list: stringified_list,
- cur_primary_signature: None,
- last_primary_signature: None,
- })
- }
-
fn as_raw(&self) -> Result<RawDeviceList, tonic::Status> {
// The device list payload is sent as an escaped JSON payload.
// Escaped double quotes need to be trimmed before attempting to deserialize
@@ -84,6 +61,30 @@
}
}
+impl TryFrom<DeviceListRow> for SignedDeviceList {
+ type Error = tonic::Status;
+
+ fn try_from(row: DeviceListRow) -> Result<Self, Self::Error> {
+ let raw_list = RawDeviceList {
+ devices: row.device_ids,
+ timestamp: row.timestamp.timestamp_millis(),
+ };
+ let stringified_list = serde_json::to_string(&raw_list).map_err(|err| {
+ error!(
+ errorType = error_types::GRPC_SERVICES_LOG,
+ "Failed to serialize raw device list: {}", err
+ );
+ tonic::Status::failed_precondition("unexpected error")
+ })?;
+
+ Ok(Self {
+ raw_device_list: stringified_list,
+ cur_primary_signature: row.current_primary_signature,
+ last_primary_signature: row.last_primary_signature,
+ })
+ }
+}
+
impl TryFrom<UpdateDeviceListRequest> for SignedDeviceList {
type Error = tonic::Status;
fn try_from(request: UpdateDeviceListRequest) -> Result<Self, Self::Error> {
@@ -109,7 +110,12 @@
);
tonic::Status::invalid_argument("invalid timestamp")
})?;
- Ok(DeviceListUpdate::new(devices, timestamp))
+ Ok(DeviceListUpdate {
+ devices,
+ timestamp,
+ current_primary_signature: signed_list.cur_primary_signature,
+ last_primary_signature: signed_list.last_primary_signature,
+ })
}
}
@@ -349,14 +355,14 @@
#[test]
fn serialize_device_list_updates() {
let raw_updates = vec![
- RawDeviceList {
+ create_device_list_row(RawDeviceList {
devices: vec!["device1".into()],
timestamp: 111111111,
- },
- RawDeviceList {
+ }),
+ create_device_list_row(RawDeviceList {
devices: vec!["device1".into(), "device2".into()],
timestamp: 222222222,
- },
+ }),
];
let expected_raw_list1 = r#"{"devices":["device1"],"timestamp":111111111}"#;
@@ -365,7 +371,7 @@
let signed_updates = raw_updates
.into_iter()
- .map(SignedDeviceList::try_from_raw)
+ .map(SignedDeviceList::try_from)
.collect::<Result<Vec<_>, _>>()
.expect("signing device list updates failed");
@@ -439,4 +445,16 @@
"No provided timestamp should pass"
);
}
+
+ /// helper for mocking DB rows from raw device list payloads
+ fn create_device_list_row(raw_list: RawDeviceList) -> DeviceListRow {
+ DeviceListRow {
+ user_id: "".to_string(),
+ device_ids: raw_list.devices,
+ timestamp: DateTime::<Utc>::from_utc_timestamp_millis(raw_list.timestamp)
+ .unwrap(),
+ current_primary_signature: None,
+ last_primary_signature: None,
+ }
+ }
}
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
@@ -2,7 +2,7 @@
use crate::config::CONFIG;
use crate::database::DeviceListUpdate;
-use crate::device_list::{RawDeviceList, SignedDeviceList};
+use crate::device_list::SignedDeviceList;
use crate::{
client_service::{handle_db_error, UpdateState, WorkflowInProgress},
constants::{error_types, request_metadata},
@@ -461,8 +461,7 @@
let device_list_updates: Vec<SignedDeviceList> = db_result
.into_iter()
- .map(RawDeviceList::from)
- .map(SignedDeviceList::try_from_raw)
+ .map(SignedDeviceList::try_from)
.collect::<Result<Vec<_>, _>>()?;
let stringified_updates = device_list_updates
@@ -496,8 +495,7 @@
while let Some(task_result) = fetch_tasks.join_next().await {
match task_result {
Ok((user_id, Ok(Some(device_list_row)))) => {
- let raw_list = RawDeviceList::from(device_list_row);
- let signed_list = SignedDeviceList::try_from_raw(raw_list)?;
+ let signed_list = SignedDeviceList::try_from(device_list_row)?;
let serialized_list = signed_list.as_json_string()?;
device_lists.insert(user_id, serialized_list);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Nov 17, 10:36 PM (22 h, 18 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2532140
Default Alt Text
D11898.diff (6 KB)
Attached To
Mode
D11898: [identity] Refactor device list types
Attached
Detach File
Event Timeline
Log In to Comment