Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F3527809
D11471.id38766.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
7 KB
Referenced Files
None
Subscribers
None
D11471.id38766.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
@@ -556,6 +556,58 @@
Ok(item.is_some())
}
+ pub async fn get_device_data(
+ &self,
+ user_id: impl Into<String>,
+ device_id: impl Into<String>,
+ ) -> Result<Option<DeviceRow>, Error> {
+ let GetItemOutput { item, .. } = self
+ .client
+ .get_item()
+ .table_name(devices_table::NAME)
+ .key(ATTR_USER_ID, AttributeValue::S(user_id.into()))
+ .key(ATTR_ITEM_ID, DeviceIDAttribute(device_id.into()).into())
+ .send()
+ .await
+ .map_err(|e| {
+ error!("Failed to fetch device data: {:?}", e);
+ Error::AwsSdk(e.into())
+ })?;
+
+ let Some(attrs) = item else {
+ return Ok(None);
+ };
+
+ let device_data = DeviceRow::try_from(attrs)?;
+ Ok(Some(device_data))
+ }
+
+ /// Fails if the device list is empty
+ pub async fn get_primary_device_data(
+ &self,
+ user_id: &str,
+ ) -> Result<DeviceRow, Error> {
+ let device_list = self.get_current_device_list(user_id).await?;
+ let Some(primary_device_id) = device_list
+ .as_ref()
+ .and_then(|list| list.device_ids.first())
+ else {
+ error!(user_id, "Device list is empty. Cannot fetch primary device");
+ return Err(Error::DeviceList(DeviceListError::DeviceNotFound));
+ };
+
+ self
+ .get_device_data(user_id, primary_device_id)
+ .await?
+ .ok_or_else(|| {
+ error!(
+ "Corrupt database. Missing primary device data for user {}",
+ user_id
+ );
+ Error::MissingItem
+ })
+ }
+
/// Required only for migration purposes (determining primary device)
pub async fn update_device_login_time(
&self,
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
@@ -187,29 +187,35 @@
let message = request.into_inner();
- let keyserver_info = self
- .db_client
- .get_keyserver_keys_for_user(&message.user_id)
- .await
- .map_err(handle_db_error)?
- .map(OutboundKeyInfo::from);
-
let identifier = self
.db_client
.get_user_identifier(&message.user_id)
.await
.map_err(handle_db_error)?
.ok_or_else(|| tonic::Status::not_found("user not found"))?;
-
let identity_info = IdentityInfo::try_from(identifier)?;
-
let identity = Some(Identity {
identity_info: Some(identity_info),
});
+ let keyserver_info = self
+ .db_client
+ .get_keyserver_keys_for_user(&message.user_id)
+ .await
+ .map_err(handle_db_error)?
+ .map(OutboundKeyInfo::from);
+
+ let primary_device_data = self
+ .db_client
+ .get_primary_device_data(&message.user_id)
+ .await
+ .map_err(handle_db_error)?;
+ let primary_device_keys = primary_device_data.device_key_info;
+
let response = Response::new(KeyserverKeysResponse {
keyserver_info,
identity,
+ primary_device_identity_info: Some(primary_device_keys.into()),
});
return Ok(response);
diff --git a/shared/protos/identity_auth.proto b/shared/protos/identity_auth.proto
--- a/shared/protos/identity_auth.proto
+++ b/shared/protos/identity_auth.proto
@@ -118,6 +118,7 @@
message KeyserverKeysResponse {
optional OutboundKeyInfo keyserver_info = 1;
Identity identity = 2;
+ identity.unauth.IdentityKeyInfo primary_device_identity_info = 3;
}
// GetOutboundKeysForUser
diff --git a/web/protobufs/identity-auth-structs.cjs b/web/protobufs/identity-auth-structs.cjs
--- a/web/protobufs/identity-auth-structs.cjs
+++ b/web/protobufs/identity-auth-structs.cjs
@@ -1639,7 +1639,8 @@
proto.identity.auth.KeyserverKeysResponse.toObject = function(includeInstance, msg) {
var f, obj = {
keyserverInfo: (f = msg.getKeyserverInfo()) && proto.identity.auth.OutboundKeyInfo.toObject(includeInstance, f),
- identity: (f = msg.getIdentity()) && proto.identity.auth.Identity.toObject(includeInstance, f)
+ identity: (f = msg.getIdentity()) && proto.identity.auth.Identity.toObject(includeInstance, f),
+ primaryDeviceIdentityInfo: (f = msg.getPrimaryDeviceIdentityInfo()) && identity_unauth_pb.IdentityKeyInfo.toObject(includeInstance, f)
};
if (includeInstance) {
@@ -1686,6 +1687,11 @@
reader.readMessage(value,proto.identity.auth.Identity.deserializeBinaryFromReader);
msg.setIdentity(value);
break;
+ case 3:
+ var value = new identity_unauth_pb.IdentityKeyInfo;
+ reader.readMessage(value,identity_unauth_pb.IdentityKeyInfo.deserializeBinaryFromReader);
+ msg.setPrimaryDeviceIdentityInfo(value);
+ break;
default:
reader.skipField();
break;
@@ -1731,6 +1737,14 @@
proto.identity.auth.Identity.serializeBinaryToWriter
);
}
+ f = message.getPrimaryDeviceIdentityInfo();
+ if (f != null) {
+ writer.writeMessage(
+ 3,
+ f,
+ identity_unauth_pb.IdentityKeyInfo.serializeBinaryToWriter
+ );
+ }
};
@@ -1808,6 +1822,43 @@
};
+/**
+ * optional identity.unauth.IdentityKeyInfo primary_device_identity_info = 3;
+ * @return {?proto.identity.unauth.IdentityKeyInfo}
+ */
+proto.identity.auth.KeyserverKeysResponse.prototype.getPrimaryDeviceIdentityInfo = function() {
+ return /** @type{?proto.identity.unauth.IdentityKeyInfo} */ (
+ jspb.Message.getWrapperField(this, identity_unauth_pb.IdentityKeyInfo, 3));
+};
+
+
+/**
+ * @param {?proto.identity.unauth.IdentityKeyInfo|undefined} value
+ * @return {!proto.identity.auth.KeyserverKeysResponse} returns this
+*/
+proto.identity.auth.KeyserverKeysResponse.prototype.setPrimaryDeviceIdentityInfo = function(value) {
+ return jspb.Message.setWrapperField(this, 3, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.identity.auth.KeyserverKeysResponse} returns this
+ */
+proto.identity.auth.KeyserverKeysResponse.prototype.clearPrimaryDeviceIdentityInfo = function() {
+ return this.setPrimaryDeviceIdentityInfo(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.identity.auth.KeyserverKeysResponse.prototype.hasPrimaryDeviceIdentityInfo = function() {
+ return jspb.Message.getField(this, 3) != null;
+};
+
+
diff --git a/web/protobufs/identity-auth-structs.cjs.flow b/web/protobufs/identity-auth-structs.cjs.flow
--- a/web/protobufs/identity-auth-structs.cjs.flow
+++ b/web/protobufs/identity-auth-structs.cjs.flow
@@ -156,6 +156,11 @@
hasIdentity(): boolean;
clearIdentity(): KeyserverKeysResponse;
+ getPrimaryDeviceIdentityInfo(): identityStructs.IdentityKeyInfo | void;
+ setPrimaryDeviceIdentityInfo(value?: identityStructs.IdentityKeyInfo): KeyserverKeysResponse;
+ hasPrimaryDeviceIdentityInfo(): boolean;
+ clearPrimaryDeviceIdentityInfo(): KeyserverKeysResponse;
+
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): KeyserverKeysResponseObject;
static toObject(includeInstance: boolean, msg: KeyserverKeysResponse): KeyserverKeysResponseObject;
@@ -167,6 +172,7 @@
export type KeyserverKeysResponseObject = {
keyserverInfo?: OutboundKeyInfoObject,
identity: ?IdentityObject,
+ primaryDeviceIdentityInfo: ?identityStructs.IdentityKeyInfoObject,
};
declare export class OutboundKeysForUserResponse extends Message {
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Dec 25, 6:50 AM (10 h, 38 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2701864
Default Alt Text
D11471.id38766.diff (7 KB)
Attached To
Mode
D11471: [protos][identity] Add primary device keys to GetKeyserverKeys response
Attached
Detach File
Event Timeline
Log In to Comment