diff --git a/native/cpp/CommonCpp/grpc/grpc_client/src/lib.rs b/native/cpp/CommonCpp/grpc/grpc_client/src/lib.rs --- a/native/cpp/CommonCpp/grpc/grpc_client/src/lib.rs +++ b/native/cpp/CommonCpp/grpc/grpc_client/src/lib.rs @@ -94,6 +94,69 @@ }) .await } + + #[instrument(skip(self))] + async fn register_user( + &mut self, + user_id: String, + device_id: String, + username: String, + password: String, + user_public_key: String, + ) -> Result { + // Create a RegistrationRequest channel and use ReceiverStream to turn the + // MPSC receiver into a Stream for outbound messages + let (tx, rx) = mpsc::channel(1); + let stream = ReceiverStream::new(rx); + let request = Request::new(stream); + + // `response` is the Stream for inbound messages + let mut response = self + .identity_client + .register_user(request) + .await? + .into_inner(); + + // Start PAKE registration on client and send initial registration request + // to Identity service + let mut client_rng = OsRng; + let (registration_request, client_registration) = pake_registration_start( + &mut client_rng, + user_id, + &password, + device_id, + username, + user_public_key, + )?; + if let Err(e) = tx.send(registration_request).await { + error!("Response was dropped: {}", e); + return Err(Status::aborted("Dropped response")); + } + + // Handle responses from Identity service sequentially, making sure we get + // messages in the correct order + + // Finish PAKE registration and begin PAKE login; send the final + // registration request and initial login request together to reduce the + // number of trips + let message = response.message().await?; + let client_login = handle_registration_response( + message, + &mut client_rng, + client_registration, + &password, + tx.clone(), + ) + .await?; + + // Finish PAKE login; send final login request to Identity service + let message = response.message().await?; + handle_credential_response(message, client_login, tx).await?; + + // Return access token + let message = response.message().await?; + handle_token_response(message) + } } fn pake_registration_start( @@ -103,7 +166,7 @@ device_id: String, username: String, user_public_key: String, -) -> Result<(RegistrationRequest, Option>), Status> { +) -> Result<(RegistrationRequest, ClientRegistration), Status> { let client_registration_start_result = ClientRegistration::::start(rng, password.as_bytes()).map_err( |e| { @@ -125,7 +188,7 @@ }, )), }, - Some(client_registration_start_result.state), + client_registration_start_result.state, )) }