Page MenuHomePhabricator

D11898.diff
No OneTemporary

D11898.diff

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

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)

Event Timeline