diff --git a/services/identity/src/database.rs b/services/identity/src/database.rs --- a/services/identity/src/database.rs +++ b/services/identity/src/database.rs @@ -413,6 +413,30 @@ .await .map_err(|e| Error::AwsSdk(e.into())) } + + pub async fn get_users(&self) -> Result, Error> { + let scan_output = self + .client + .scan() + .table_name(USERS_TABLE) + .projection_expression(USERS_TABLE_PARTITION_KEY) + .send() + .await + .map_err(|e| Error::AwsSdk(e.into()))?; + + let mut result = Vec::new(); + if let Some(attributes) = scan_output.items { + for mut attribute in attributes { + let id = parse_string_attribute( + USERS_TABLE_PARTITION_KEY, + attribute.remove(USERS_TABLE_PARTITION_KEY), + ) + .map_err(Error::Attribute)?; + result.push(id); + } + } + Ok(result) + } } #[derive( diff --git a/services/identity/src/service.rs b/services/identity/src/service.rs --- a/services/identity/src/service.rs +++ b/services/identity/src/service.rs @@ -40,9 +40,10 @@ registration_request::Data::PakeRegistrationRequestAndUserId, registration_request::Data::PakeRegistrationUploadAndCredentialRequest, registration_response::Data::PakeLoginResponse as PakeRegistrationLoginResponse, - registration_response::Data::PakeRegistrationResponse, GetUserIdRequest, - GetUserIdResponse, GetUserPublicKeyRequest, GetUserPublicKeyResponse, - LoginRequest, LoginResponse, PakeLoginRequest as PakeLoginRequestStruct, + registration_response::Data::PakeRegistrationResponse, CompareUsersRequest, + CompareUsersResponse, GetUserIdRequest, GetUserIdResponse, + GetUserPublicKeyRequest, GetUserPublicKeyResponse, LoginRequest, + LoginResponse, PakeLoginRequest as PakeLoginRequestStruct, PakeLoginResponse as PakeLoginResponseStruct, RegistrationRequest, RegistrationResponse, VerifyUserTokenRequest, VerifyUserTokenResponse, WalletLoginRequest as WalletLoginRequestStruct, @@ -231,6 +232,26 @@ let response = Response::new(GetUserPublicKeyResponse { public_key }); Ok(response) } + + #[instrument(skip(self))] + async fn compare_users( + &self, + request: Request, + ) -> Result, Status> { + let message = request.into_inner(); + let mysql_users = message.users; + let ddb_users = match self.client.get_users().await { + Ok(user_list) => user_list, + Err(e) => return Err(handle_db_error(e)), + }; + let mut response = Vec::new(); + for user in ddb_users { + if !mysql_users.contains(&user) { + response.push(user) + } + } + Ok(Response::new(CompareUsersResponse { users: response })) + } } async fn put_token_helper( diff --git a/shared/protos/identity.proto b/shared/protos/identity.proto --- a/shared/protos/identity.proto +++ b/shared/protos/identity.proto @@ -18,6 +18,9 @@ // and device ID rpc GetUserPublicKey(GetUserPublicKeyRequest) returns (GetUserPublicKeyResponse) {} + // Called by Ashoat's keyserver with a list of user IDs in MySQL and returns + // any user IDs that are in DynamoDB but not in the supplied list + rpc CompareUsers(CompareUsersRequest) returns (CompareUsersResponse) {} } // Helper types @@ -153,3 +156,13 @@ message GetUserPublicKeyResponse { string publicKey = 1; } + +// CompareUsers + +message CompareUsersRequest { + repeated string users = 1; +} + +message CompareUsersResponse { + repeated string users = 1; +}