Changeset View
Changeset View
Standalone View
Standalone View
native/native_rust_library/src/lib.rs
use crate::ffi::string_callback; | use crate::ffi::string_callback; | ||||
use crate::identity::Empty; | 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 lazy_static::lazy_static; | ||||
use serde::Serialize; | |||||
use std::sync::Arc; | use std::sync::Arc; | ||||
use tokio::runtime::{Builder, Runtime}; | use tokio::runtime::{Builder, Runtime}; | ||||
use tonic::{transport::Channel, Status}; | use tonic::{transport::Channel, Status}; | ||||
use tracing::instrument; | use tracing::instrument; | ||||
mod crypto_tools; | mod crypto_tools; | ||||
mod identity_client; | mod identity_client; | ||||
mod identity { | mod identity { | ||||
tonic::include_proto!("identity.client"); | tonic::include_proto!("identity.client"); | ||||
} | } | ||||
use crypto_tools::generate_device_id; | use crypto_tools::generate_device_id; | ||||
use identity::identity_client_service_client::IdentityClientServiceClient; | use identity::identity_client_service_client::IdentityClientServiceClient; | ||||
use identity::{ | |||||
DeviceKeyUpload, IdentityKeyInfo, PreKey, RegistrationFinishRequest, | |||||
RegistrationStartRequest, | |||||
}; | |||||
lazy_static! { | lazy_static! { | ||||
pub static ref RUNTIME: Arc<Runtime> = Arc::new( | pub static ref RUNTIME: Arc<Runtime> = Arc::new( | ||||
Builder::new_multi_thread() | Builder::new_multi_thread() | ||||
.worker_threads(1) | .worker_threads(1) | ||||
.max_blocking_threads(1) | .max_blocking_threads(1) | ||||
.enable_all() | .enable_all() | ||||
.build() | .build() | ||||
Show All 12 Lines | mod ffi { | ||||
extern "Rust" { | extern "Rust" { | ||||
// Identity Service Client | // Identity Service Client | ||||
type IdentityClient; | type IdentityClient; | ||||
#[cxx_name = "identityInitializeClient"] | #[cxx_name = "identityInitializeClient"] | ||||
fn initialize_identity_client(addr: String) -> Box<IdentityClient>; | fn initialize_identity_client(addr: String) -> Box<IdentityClient>; | ||||
#[cxx_name = "identityRegisterUserBlocking"] | #[cxx_name = "registerUser"] | ||||
fn identity_register_user_blocking( | fn register_user( | ||||
client: Box<IdentityClient>, | |||||
username: String, | username: String, | ||||
password: String, | password: String, | ||||
key_payload: String, | key_payload: String, | ||||
key_payload_signature: String, | key_payload_signature: String, | ||||
identity_prekey: String, | content_prekey: String, | ||||
identity_prekey_signature: String, | content_prekey_signature: String, | ||||
notif_prekey: String, | notif_prekey: String, | ||||
notif_prekey_signature: String, | notif_prekey_signature: String, | ||||
identity_onetime_keys: Vec<String>, | content_onetime_keys: Vec<String>, | ||||
notif_onetime_keys: Vec<String>, | notif_onetime_keys: Vec<String>, | ||||
) -> Result<String>; | promise_id: u32, | ||||
); | |||||
#[cxx_name = "identityLoginUserPakeBlocking"] | #[cxx_name = "identityLoginUserPakeBlocking"] | ||||
fn identity_login_user_pake_blocking( | fn identity_login_user_pake_blocking( | ||||
client: Box<IdentityClient>, | client: Box<IdentityClient>, | ||||
username: String, | username: String, | ||||
password: String, | password: String, | ||||
key_payload: String, | key_payload: String, | ||||
key_payload_signature: String, | key_payload_signature: String, | ||||
▲ Show 20 Lines • Show All 74 Lines • ▼ Show 20 Lines | fn initialize_identity_client(addr: String) -> Box<IdentityClient> { | ||||
Box::new(IdentityClient { | Box::new(IdentityClient { | ||||
identity_client: RUNTIME | identity_client: RUNTIME | ||||
.block_on(IdentityClientServiceClient::connect(addr)) | .block_on(IdentityClientServiceClient::connect(addr)) | ||||
.unwrap(), | .unwrap(), | ||||
}) | }) | ||||
} | } | ||||
#[instrument] | #[instrument] | ||||
fn identity_register_user_blocking( | fn register_user( | ||||
client: Box<IdentityClient>, | |||||
username: String, | username: String, | ||||
password: String, | password: String, | ||||
key_payload: String, | key_payload: String, | ||||
key_payload_signature: String, | key_payload_signature: String, | ||||
identity_prekey: String, | content_prekey: String, | ||||
identity_prekey_signature: String, | content_prekey_signature: String, | ||||
notif_prekey: String, | notif_prekey: String, | ||||
notif_prekey_signature: String, | notif_prekey_signature: String, | ||||
identity_onetime_keys: Vec<String>, | content_onetime_keys: Vec<String>, | ||||
notif_onetime_keys: Vec<String>, | notif_onetime_keys: Vec<String>, | ||||
) -> Result<String, Status> { | promise_id: u32, | ||||
RUNTIME.block_on(identity_client::register_user( | ) { | ||||
client, | RUNTIME.spawn(async move { | ||||
let register_user_info = RegisterUserInfo { | |||||
username, | username, | ||||
password, | password, | ||||
key_payload, | key_payload, | ||||
key_payload_signature, | key_payload_signature, | ||||
identity_prekey, | content_prekey, | ||||
identity_prekey_signature, | content_prekey_signature, | ||||
notif_prekey, | notif_prekey, | ||||
notif_prekey_signature, | notif_prekey_signature, | ||||
identity_onetime_keys, | content_onetime_keys, | ||||
notif_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<String>, | |||||
notif_onetime_keys: Vec<String>, | |||||
} | |||||
#[derive(Serialize)] | |||||
struct UserIDAndDeviceAccessToken { | |||||
user_id: String, | |||||
access_token: String, | |||||
} | |||||
async fn register_user_helper( | |||||
register_user_info: RegisterUserInfo, | |||||
) -> Result<String, Error> { | |||||
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] | #[instrument] | ||||
fn identity_login_user_pake_blocking( | fn identity_login_user_pake_blocking( | ||||
client: Box<IdentityClient>, | client: Box<IdentityClient>, | ||||
username: String, | username: String, | ||||
password: String, | password: String, | ||||
key_payload: String, | key_payload: String, | ||||
▲ Show 20 Lines • Show All 52 Lines • ▼ Show 20 Lines | |||||
#[derive( | #[derive( | ||||
Debug, derive_more::Display, derive_more::From, derive_more::Error, | Debug, derive_more::Display, derive_more::From, derive_more::Error, | ||||
)] | )] | ||||
pub enum Error { | pub enum Error { | ||||
#[display(...)] | #[display(...)] | ||||
TonicGRPC(Status), | TonicGRPC(Status), | ||||
#[display(...)] | #[display(...)] | ||||
TonicTransport(tonic::transport::Error), | TonicTransport(tonic::transport::Error), | ||||
#[display(...)] | |||||
SerdeJson(serde_json::Error), | |||||
} | } |