Page MenuHomePhabricator

D9527.id32290.diff
No OneTemporary

D9527.id32290.diff

diff --git a/services/identity/src/client_service.rs b/services/identity/src/client_service.rs
--- a/services/identity/src/client_service.rs
+++ b/services/identity/src/client_service.rs
@@ -32,7 +32,7 @@
DBDeviceTypeInt, DatabaseClient, DeviceType, KeyPayload,
};
use crate::error::Error as DBError;
-use crate::grpc_utils::DeviceInfoWithAuth;
+use crate::grpc_utils::{DeviceInfoWithAuth, DeviceKeyUploadActions};
use crate::id::generate_uuid;
use crate::nonce::generate_nonce_data;
use crate::reserved_users::{
@@ -105,18 +105,14 @@
let message = request.into_inner();
debug!("Received registration request for: {}", message.username);
- let username_taken = self
- .client
- .username_taken(message.username.clone())
- .await
- .map_err(handle_db_error)?;
+ self.check_username_taken(&message.username).await?;
let username_in_reserved_usernames_table = self
.client
.username_in_reserved_usernames_table(&message.username)
.await
.map_err(handle_db_error)?;
- if username_taken || username_in_reserved_usernames_table {
+ if username_in_reserved_usernames_table {
return Err(tonic::Status::already_exists("username already exists"));
}
@@ -126,73 +122,26 @@
return Err(tonic::Status::invalid_argument("username reserved"));
}
- if let client_proto::RegistrationStartRequest {
- opaque_registration_request: register_message,
- username,
- device_key_upload:
- Some(client_proto::DeviceKeyUpload {
- device_key_info:
- Some(client_proto::IdentityKeyInfo {
- payload,
- payload_signature,
- social_proof: _social_proof,
- }),
- content_upload:
- Some(client_proto::PreKey {
- pre_key: content_prekey,
- pre_key_signature: content_prekey_signature,
- }),
- notif_upload:
- Some(client_proto::PreKey {
- pre_key: notif_prekey,
- pre_key_signature: notif_prekey_signature,
- }),
- one_time_content_prekeys,
- one_time_notif_prekeys,
- device_type,
- }),
- } = message
- {
- let server_registration = comm_opaque2::server::Registration::new();
- let server_message = server_registration
- .start(&CONFIG.server_setup, &register_message, username.as_bytes())
- .map_err(protocol_error_to_grpc_status)?;
- let key_info = KeyPayload::from_str(&payload)
- .map_err(|_| tonic::Status::invalid_argument("malformed payload"))?;
- let registration_state = UserRegistrationInfo {
- username,
- flattened_device_key_upload: FlattenedDeviceKeyUpload {
- device_id_key: key_info.primary_identity_public_keys.ed25519,
- key_payload: payload,
- key_payload_signature: payload_signature,
- content_prekey,
- content_prekey_signature,
- content_one_time_keys: one_time_content_prekeys,
- notif_prekey,
- notif_prekey_signature,
- notif_one_time_keys: one_time_notif_prekeys,
- device_type: DeviceType::try_from(DBDeviceTypeInt(device_type))
- .map_err(handle_db_error)?,
- },
- user_id: None,
- };
- let session_id = generate_uuid();
- self
- .cache
- .insert(
- session_id.clone(),
- WorkflowInProgress::Registration(Box::new(registration_state)),
- )
- .await;
+ let registration_state = construct_user_registration_info(&message, None)?;
+ let server_registration = comm_opaque2::server::Registration::new();
+ let server_message = server_registration
+ .start(
+ &CONFIG.server_setup,
+ &message.opaque_registration_request,
+ message.username.as_bytes(),
+ )
+ .map_err(protocol_error_to_grpc_status)?;
+ let session_id = self
+ .insert_into_cache(WorkflowInProgress::Registration(Box::new(
+ registration_state,
+ )))
+ .await;
- let response = RegistrationStartResponse {
- session_id,
- opaque_registration_response: server_message,
- };
- Ok(Response::new(response))
- } else {
- Err(tonic::Status::invalid_argument("unexpected message data"))
- }
+ let response = RegistrationStartResponse {
+ session_id,
+ opaque_registration_response: server_message,
+ };
+ Ok(Response::new(response))
}
async fn register_reserved_password_user_start(
@@ -200,15 +149,7 @@
request: tonic::Request<ReservedRegistrationStartRequest>,
) -> Result<tonic::Response<RegistrationStartResponse>, tonic::Status> {
let message = request.into_inner();
- let username_taken = self
- .client
- .username_taken(message.username.clone())
- .await
- .map_err(handle_db_error)?;
-
- if username_taken {
- return Err(tonic::Status::already_exists("username already exists"));
- }
+ self.check_username_taken(&message.username).await?;
if CONFIG.reserved_usernames.contains(&message.username) {
return Err(tonic::Status::invalid_argument("username reserved"));
@@ -229,75 +170,28 @@
&message.keyserver_signature,
)?;
- if let client_proto::ReservedRegistrationStartRequest {
- opaque_registration_request: register_message,
- username,
- device_key_upload:
- Some(client_proto::DeviceKeyUpload {
- device_key_info:
- Some(client_proto::IdentityKeyInfo {
- payload,
- payload_signature,
- social_proof: _social_proof,
- }),
- content_upload:
- Some(client_proto::PreKey {
- pre_key: content_prekey,
- pre_key_signature: content_prekey_signature,
- }),
- notif_upload:
- Some(client_proto::PreKey {
- pre_key: notif_prekey,
- pre_key_signature: notif_prekey_signature,
- }),
- one_time_content_prekeys,
- one_time_notif_prekeys,
- device_type,
- }),
- ..
- } = message
- {
- let server_registration = comm_opaque2::server::Registration::new();
- let server_message = server_registration
- .start(&CONFIG.server_setup, &register_message, username.as_bytes())
- .map_err(protocol_error_to_grpc_status)?;
- let key_info = KeyPayload::from_str(&payload)
- .map_err(|_| tonic::Status::invalid_argument("malformed payload"))?;
- let registration_state = UserRegistrationInfo {
- username,
- flattened_device_key_upload: FlattenedDeviceKeyUpload {
- device_id_key: key_info.primary_identity_public_keys.ed25519,
- key_payload: payload,
- key_payload_signature: payload_signature,
- content_prekey,
- content_prekey_signature,
- content_one_time_keys: one_time_content_prekeys,
- notif_prekey,
- notif_prekey_signature,
- notif_one_time_keys: one_time_notif_prekeys,
- device_type: DeviceType::try_from(DBDeviceTypeInt(device_type))
- .map_err(handle_db_error)?,
- },
- user_id: Some(user_id),
- };
+ let registration_state =
+ construct_user_registration_info(&message, Some(user_id))?;
+ let server_registration = comm_opaque2::server::Registration::new();
+ let server_message = server_registration
+ .start(
+ &CONFIG.server_setup,
+ &message.opaque_registration_request,
+ message.username.as_bytes(),
+ )
+ .map_err(protocol_error_to_grpc_status)?;
- let session_id = generate_uuid();
- self
- .cache
- .insert(
- session_id.clone(),
- WorkflowInProgress::Registration(Box::new(registration_state)),
- )
- .await;
+ let session_id = self
+ .insert_into_cache(WorkflowInProgress::Registration(Box::new(
+ registration_state,
+ )))
+ .await;
- let response = RegistrationStartResponse {
- session_id,
- opaque_registration_response: server_message,
- };
- Ok(Response::new(response))
- } else {
- Err(tonic::Status::invalid_argument("unexpected message data"))
- }
+ let response = RegistrationStartResponse {
+ session_id,
+ opaque_registration_response: server_message,
+ };
+ Ok(Response::new(response))
}
async fn register_password_user_finish(
@@ -382,10 +276,8 @@
let update_state = UpdateState {
user_id: message.user_id,
};
- let session_id = generate_uuid();
- self
- .cache
- .insert(session_id.clone(), WorkflowInProgress::Update(update_state))
+ let session_id = self
+ .insert_into_cache(WorkflowInProgress::Update(update_state))
.await;
let response = UpdateUserPasswordStartResponse {
@@ -517,13 +409,8 @@
.map_err(handle_db_error)?,
},
};
- let session_id = generate_uuid();
- self
- .cache
- .insert(
- session_id.clone(),
- WorkflowInProgress::Login(Box::new(login_state)),
- )
+ let session_id = self
+ .insert_into_cache(WorkflowInProgress::Login(Box::new(login_state)))
.await;
let response = Response::new(OpaqueLoginStartResponse {
@@ -1026,6 +913,29 @@
}
}
+impl ClientService {
+ async fn check_username_taken(
+ &self,
+ username: &str,
+ ) -> Result<(), tonic::Status> {
+ let username_taken = self
+ .client
+ .username_taken(username.to_string())
+ .await
+ .map_err(handle_db_error)?;
+ if username_taken {
+ return Err(tonic::Status::already_exists("username already exists"));
+ }
+ Ok(())
+ }
+
+ async fn insert_into_cache(&self, workflow: WorkflowInProgress) -> String {
+ let session_id = generate_uuid();
+ self.cache.insert(session_id.clone(), workflow).await;
+ session_id
+ }
+}
+
pub fn handle_db_error(db_error: DBError) -> tonic::Status {
match db_error {
DBError::AwsSdk(DynamoDBError::InternalServerError(_))
@@ -1041,3 +951,31 @@
}
}
}
+
+fn construct_user_registration_info(
+ message: &impl DeviceKeyUploadActions,
+ user_id: Option<String>,
+) -> Result<UserRegistrationInfo, tonic::Status> {
+ let key_info = KeyPayload::from_str(&message.payload()?)
+ .map_err(|_| tonic::Status::invalid_argument("malformed payload"))?;
+
+ Ok(UserRegistrationInfo {
+ username: message.username(),
+ flattened_device_key_upload: FlattenedDeviceKeyUpload {
+ device_id_key: key_info.primary_identity_public_keys.ed25519,
+ key_payload: message.payload()?,
+ key_payload_signature: message.payload_signature()?,
+ content_prekey: message.content_prekey()?,
+ content_prekey_signature: message.content_prekey_signature()?,
+ content_one_time_keys: message.one_time_content_prekeys()?,
+ notif_prekey: message.notif_prekey()?,
+ notif_prekey_signature: message.notif_prekey_signature()?,
+ notif_one_time_keys: message.one_time_notif_prekeys()?,
+ device_type: DeviceType::try_from(DBDeviceTypeInt(
+ message.device_type()?,
+ ))
+ .map_err(handle_db_error)?,
+ },
+ user_id,
+ })
+}
diff --git a/services/identity/src/grpc_utils.rs b/services/identity/src/grpc_utils.rs
--- a/services/identity/src/grpc_utils.rs
+++ b/services/identity/src/grpc_utils.rs
@@ -5,7 +5,8 @@
use crate::{
client_service::client_proto::{
- IdentityKeyInfo, InboundKeyInfo, OutboundKeyInfo, PreKey,
+ DeviceKeyUpload, IdentityKeyInfo, InboundKeyInfo, OutboundKeyInfo, PreKey,
+ RegistrationStartRequest, ReservedRegistrationStartRequest,
},
constants::{
CONTENT_ONE_TIME_KEY, NOTIF_ONE_TIME_KEY,
@@ -127,3 +128,113 @@
pre_key_signature: extract_key(device_info, signature_attr)?,
})
}
+
+pub trait DeviceKeyUploadData {
+ fn device_key_upload(&self) -> Option<&DeviceKeyUpload>;
+ fn username(&self) -> &str;
+}
+
+impl DeviceKeyUploadData for RegistrationStartRequest {
+ fn device_key_upload(&self) -> Option<&DeviceKeyUpload> {
+ self.device_key_upload.as_ref()
+ }
+ fn username(&self) -> &str {
+ &self.username
+ }
+}
+
+impl DeviceKeyUploadData for ReservedRegistrationStartRequest {
+ fn device_key_upload(&self) -> Option<&DeviceKeyUpload> {
+ self.device_key_upload.as_ref()
+ }
+ fn username(&self) -> &str {
+ &self.username
+ }
+}
+
+pub trait DeviceKeyUploadActions {
+ fn username(&self) -> String;
+ fn payload(&self) -> Result<String, Status>;
+ fn payload_signature(&self) -> Result<String, Status>;
+ fn content_prekey(&self) -> Result<String, Status>;
+ fn content_prekey_signature(&self) -> Result<String, Status>;
+ fn notif_prekey(&self) -> Result<String, Status>;
+ fn notif_prekey_signature(&self) -> Result<String, Status>;
+ fn one_time_content_prekeys(&self) -> Result<Vec<String>, Status>;
+ fn one_time_notif_prekeys(&self) -> Result<Vec<String>, Status>;
+ fn device_type(&self) -> Result<i32, Status>;
+}
+
+impl<T: DeviceKeyUploadData> DeviceKeyUploadActions for T {
+ fn username(&self) -> String {
+ self.username().to_string()
+ }
+
+ fn payload(&self) -> Result<String, Status> {
+ self
+ .device_key_upload()
+ .and_then(|upload| upload.device_key_info.as_ref())
+ .map(|info| info.payload.clone())
+ .ok_or_else(|| Status::invalid_argument("unexpected message data"))
+ }
+
+ fn payload_signature(&self) -> Result<String, Status> {
+ self
+ .device_key_upload()
+ .and_then(|upload| upload.device_key_info.as_ref())
+ .map(|info| info.payload_signature.clone())
+ .ok_or_else(|| Status::invalid_argument("unexpected message data"))
+ }
+
+ fn content_prekey(&self) -> Result<String, Status> {
+ self
+ .device_key_upload()
+ .and_then(|upload| upload.content_upload.as_ref())
+ .map(|prekey| prekey.pre_key.clone())
+ .ok_or_else(|| Status::invalid_argument("unexpected message data"))
+ }
+
+ fn content_prekey_signature(&self) -> Result<String, Status> {
+ self
+ .device_key_upload()
+ .and_then(|upload| upload.content_upload.as_ref())
+ .map(|prekey| prekey.pre_key_signature.clone())
+ .ok_or_else(|| Status::invalid_argument("unexpected message data"))
+ }
+
+ fn notif_prekey(&self) -> Result<String, Status> {
+ self
+ .device_key_upload()
+ .and_then(|upload| upload.notif_upload.as_ref())
+ .map(|prekey| prekey.pre_key.clone())
+ .ok_or_else(|| Status::invalid_argument("unexpected message data"))
+ }
+
+ fn notif_prekey_signature(&self) -> Result<String, Status> {
+ self
+ .device_key_upload()
+ .and_then(|upload| upload.notif_upload.as_ref())
+ .map(|prekey| prekey.pre_key_signature.clone())
+ .ok_or_else(|| Status::invalid_argument("unexpected message data"))
+ }
+
+ fn one_time_content_prekeys(&self) -> Result<Vec<String>, Status> {
+ self
+ .device_key_upload()
+ .map(|upload| upload.one_time_content_prekeys.clone())
+ .ok_or_else(|| Status::invalid_argument("unexpected message data"))
+ }
+
+ fn one_time_notif_prekeys(&self) -> Result<Vec<String>, Status> {
+ self
+ .device_key_upload()
+ .map(|upload| upload.one_time_notif_prekeys.clone())
+ .ok_or_else(|| Status::invalid_argument("unexpected message data"))
+ }
+ fn device_type(&self) -> Result<i32, Status> {
+ self
+ .device_key_upload()
+ .map(|upload| upload.device_type)
+ .ok_or_else(|| Status::invalid_argument("unexpected message data"))
+ }
+}

File Metadata

Mime Type
text/plain
Expires
Mon, Dec 2, 6:33 PM (21 h, 44 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2607897
Default Alt Text
D9527.id32290.diff (15 KB)

Event Timeline