diff --git a/native/native_rust_library/Cargo.lock b/native/native_rust_library/Cargo.lock --- a/native/native_rust_library/Cargo.lock +++ b/native/native_rust_library/Cargo.lock @@ -766,6 +766,8 @@ "prost", "rand", "regex", + "serde", + "serde_json", "tokio", "tokio-stream", "tonic", @@ -1062,6 +1064,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" +[[package]] +name = "ryu" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" + [[package]] name = "scratch" version = "1.0.2" @@ -1107,6 +1115,17 @@ "syn 1.0.99", ] +[[package]] +name = "serde_json" +version = "1.0.96" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" +dependencies = [ + "itoa", + "ryu", + "serde", +] + [[package]] name = "sha2" version = "0.10.6" diff --git a/native/native_rust_library/Cargo.toml b/native/native_rust_library/Cargo.toml --- a/native/native_rust_library/Cargo.toml +++ b/native/native_rust_library/Cargo.toml @@ -19,6 +19,8 @@ regex = "1.6" comm-opaque2 = {path = "../../shared/comm-opaque2"} derive_more = "0.99" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" [build-dependencies] cxx-build = "1.0" diff --git a/native/native_rust_library/src/identity_client.rs b/native/native_rust_library/src/identity_client.rs --- a/native/native_rust_library/src/identity_client.rs +++ b/native/native_rust_library/src/identity_client.rs @@ -2,22 +2,6 @@ use crate::IdentityClient; -pub async fn register_user( - mut _client: Box, - _username: String, - _password: String, - _key_payload: String, - _key_payload_signature: String, - _identity_prekey: String, - _identity_prekey_signature: String, - _notif_prekey: String, - _notif_prekey_signature: String, - _identity_onetime_keys: Vec, - _notif_onetime_keys: Vec, -) -> Result { - unimplemented!(); -} - // User could be logging in from new device, need to resend device information pub async fn login_user_pake( mut _client: Box, diff --git a/native/native_rust_library/src/lib.rs b/native/native_rust_library/src/lib.rs --- a/native/native_rust_library/src/lib.rs +++ b/native/native_rust_library/src/lib.rs @@ -1,6 +1,9 @@ use crate::ffi::string_callback; use crate::identity::Empty; +use comm_opaque2::client::Registration; +use comm_opaque2::grpc::opaque_error_to_grpc_status as handle_error; use lazy_static::lazy_static; +use serde::Serialize; use std::sync::Arc; use tokio::runtime::{Builder, Runtime}; use tonic::{transport::Channel, Status}; @@ -14,6 +17,10 @@ use crypto_tools::generate_device_id; use identity::identity_client_service_client::IdentityClientServiceClient; +use identity::{ + DeviceKeyUpload, IdentityKeyInfo, PreKey, RegistrationFinishRequest, + RegistrationStartRequest, +}; lazy_static! { pub static ref RUNTIME: Arc = Arc::new( @@ -42,20 +49,20 @@ #[cxx_name = "identityInitializeClient"] fn initialize_identity_client(addr: String) -> Box; - #[cxx_name = "identityRegisterUserBlocking"] - fn identity_register_user_blocking( - client: Box, + #[cxx_name = "registerUser"] + fn register_user( username: String, password: String, key_payload: String, key_payload_signature: String, - identity_prekey: String, - identity_prekey_signature: String, + content_prekey: String, + content_prekey_signature: String, notif_prekey: String, notif_prekey_signature: String, - identity_onetime_keys: Vec, + content_onetime_keys: Vec, notif_onetime_keys: Vec, - ) -> Result; + promise_id: u32, + ); #[cxx_name = "identityLoginUserPakeBlocking"] fn identity_login_user_pake_blocking( @@ -146,32 +153,112 @@ } #[instrument] -fn identity_register_user_blocking( - client: Box, +fn register_user( username: String, password: String, key_payload: String, key_payload_signature: String, - identity_prekey: String, - identity_prekey_signature: String, + content_prekey: String, + content_prekey_signature: String, notif_prekey: String, notif_prekey_signature: String, - identity_onetime_keys: Vec, + content_onetime_keys: Vec, + notif_onetime_keys: Vec, + promise_id: u32, +) { + RUNTIME.spawn(async move { + let register_user_info = RegisterUserInfo { + username, + password, + key_payload, + key_payload_signature, + content_prekey, + content_prekey_signature, + notif_prekey, + notif_prekey_signature, + content_onetime_keys, + notif_onetime_keys, + }; + let result = register_user_helper(register_user_info).await; + handle_string_result_as_callback(result, promise_id); + }); +} + +struct RegisterUserInfo { + username: String, + password: String, + key_payload: String, + key_payload_signature: String, + content_prekey: String, + content_prekey_signature: String, + notif_prekey: String, + notif_prekey_signature: String, + content_onetime_keys: Vec, notif_onetime_keys: Vec, -) -> Result { - RUNTIME.block_on(identity_client::register_user( - client, - username, - password, - key_payload, - key_payload_signature, - identity_prekey, - identity_prekey_signature, - notif_prekey, - notif_prekey_signature, - identity_onetime_keys, - notif_onetime_keys, - )) +} + +#[derive(Serialize)] +struct UserIDAndDeviceAccessToken { + user_id: String, + access_token: String, +} + +async fn register_user_helper( + register_user_info: RegisterUserInfo, +) -> Result { + let mut client_registration = Registration::new(); + let opaque_registration_request = client_registration + .start(®ister_user_info.password) + .map_err(handle_error)?; + let registration_start_request = RegistrationStartRequest { + opaque_registration_request, + username: register_user_info.username, + device_key_upload: Some(DeviceKeyUpload { + device_key_info: Some(IdentityKeyInfo { + payload: register_user_info.key_payload, + payload_signature: register_user_info.key_payload_signature, + social_proof: None, + }), + content_upload: Some(PreKey { + pre_key: register_user_info.content_prekey, + pre_key_signature: register_user_info.content_prekey_signature, + }), + notif_upload: Some(PreKey { + pre_key: register_user_info.notif_prekey, + pre_key_signature: register_user_info.notif_prekey_signature, + }), + onetime_content_prekeys: register_user_info.content_onetime_keys, + onetime_notif_prekeys: register_user_info.notif_onetime_keys, + }), + }; + + let mut identity_client = + IdentityClientServiceClient::connect("http://127.0.0.1:50054").await?; + let registration_start_response = identity_client + .register_password_user_start(registration_start_request) + .await? + .into_inner(); + + let opaque_registration_upload = client_registration + .finish( + ®ister_user_info.password, + ®istration_start_response.opaque_registration_response, + ) + .map_err(handle_error)?; + let registration_finish_request = RegistrationFinishRequest { + session_id: registration_start_response.session_id, + opaque_registration_upload, + }; + + let registration_finish_response = identity_client + .register_password_user_finish(registration_finish_request) + .await? + .into_inner(); + let user_id_and_access_token = UserIDAndDeviceAccessToken { + user_id: registration_finish_response.user_id, + access_token: registration_finish_response.access_token, + }; + Ok(serde_json::to_string(&user_id_and_access_token)?) } #[instrument] @@ -240,4 +327,6 @@ TonicGRPC(Status), #[display(...)] TonicTransport(tonic::transport::Error), + #[display(...)] + SerdeJson(serde_json::Error), }