Changeset View
Changeset View
Standalone View
Standalone View
services/identity/src/client_service.rs
Show All 17 Lines | client_service::client_proto::{ | ||||
UpdateUserPasswordStartResponse, UploadOneTimeKeysRequest, | UpdateUserPasswordStartResponse, UploadOneTimeKeysRequest, | ||||
VerifyUserAccessTokenRequest, VerifyUserAccessTokenResponse, | VerifyUserAccessTokenRequest, VerifyUserAccessTokenResponse, | ||||
WalletLoginRequest, WalletLoginResponse, | WalletLoginRequest, WalletLoginResponse, | ||||
}, | }, | ||||
config::CONFIG, | config::CONFIG, | ||||
database::{DatabaseClient, Error as DBError, KeyPayload}, | database::{DatabaseClient, Error as DBError, KeyPayload}, | ||||
id::generate_uuid, | id::generate_uuid, | ||||
nonce::generate_nonce_data, | nonce::generate_nonce_data, | ||||
token::AccessTokenData, | |||||
}; | }; | ||||
use aws_sdk_dynamodb::Error as DynamoDBError; | use aws_sdk_dynamodb::Error as DynamoDBError; | ||||
pub use client_proto::identity_client_service_server::{ | pub use client_proto::identity_client_service_server::{ | ||||
IdentityClientService, IdentityClientServiceServer, | IdentityClientService, IdentityClientServiceServer, | ||||
}; | }; | ||||
use moka::future::Cache; | use moka::future::Cache; | ||||
use rand::rngs::OsRng; | use rand::rngs::OsRng; | ||||
use tonic::Response; | use tonic::Response; | ||||
use tracing::error; | use tracing::error; | ||||
#[derive(Clone)] | #[derive(Clone)] | ||||
pub enum WorkflowInProgress { | pub enum WorkflowInProgress { | ||||
Registration(UserRegistrationInfo), | Registration(UserRegistrationInfo), | ||||
} | } | ||||
#[derive(Clone)] | #[derive(Clone)] | ||||
pub struct UserRegistrationInfo { | pub struct UserRegistrationInfo { | ||||
username: String, | pub username: String, | ||||
device_id_key: String, | pub device_id_key: String, | ||||
key_payload: String, | pub key_payload: String, | ||||
key_payload_signature: String, | pub key_payload_signature: String, | ||||
identity_prekey: String, | pub identity_prekey: String, | ||||
identity_prekey_signature: String, | pub identity_prekey_signature: String, | ||||
identity_onetime_keys: Vec<String>, | pub identity_onetime_keys: Vec<String>, | ||||
notif_prekey: String, | pub notif_prekey: String, | ||||
notif_prekey_signature: String, | pub notif_prekey_signature: String, | ||||
notif_onetime_keys: Vec<String>, | pub notif_onetime_keys: Vec<String>, | ||||
} | } | ||||
#[derive(derive_more::Constructor)] | #[derive(derive_more::Constructor)] | ||||
pub struct ClientService { | pub struct ClientService { | ||||
client: DatabaseClient, | client: DatabaseClient, | ||||
cache: Cache<String, WorkflowInProgress>, | cache: Cache<String, WorkflowInProgress>, | ||||
} | } | ||||
▲ Show 20 Lines • Show All 78 Lines • ▼ Show 20 Lines | if let client_proto::RegistrationStartRequest { | ||||
Ok(Response::new(response)) | Ok(Response::new(response)) | ||||
} else { | } else { | ||||
Err(tonic::Status::invalid_argument("unexpected message data")) | Err(tonic::Status::invalid_argument("unexpected message data")) | ||||
} | } | ||||
} | } | ||||
async fn register_password_user_finish( | async fn register_password_user_finish( | ||||
&self, | &self, | ||||
_request: tonic::Request<RegistrationFinishRequest>, | request: tonic::Request<RegistrationFinishRequest>, | ||||
) -> Result<tonic::Response<RegistrationFinishResponse>, tonic::Status> { | ) -> Result<tonic::Response<RegistrationFinishResponse>, tonic::Status> { | ||||
unimplemented!(); | let message = request.into_inner(); | ||||
if let Some(WorkflowInProgress::Registration(state)) = | |||||
self.cache.get(&message.session_id) | |||||
{ | |||||
self.cache.invalidate(&message.session_id).await; | |||||
let server_registration = comm_opaque2::server::Registration::new(); | |||||
let password_file = server_registration | |||||
.finish(&message.opaque_registration_upload) | |||||
.map_err(comm_opaque2::grpc::protocol_error_to_grpc_status)?; | |||||
let device_id = state.device_id_key.clone(); | |||||
let user_id = self | |||||
.client | |||||
.add_user_to_users_table(state, password_file) | |||||
.await | |||||
.map_err(handle_db_error)?; | |||||
// Create access token | |||||
let token = AccessTokenData::new( | |||||
message.session_id, | |||||
device_id, | |||||
crate::token::AuthType::Password, | |||||
&mut OsRng, | |||||
); | |||||
let access_token = token.access_token.clone(); | |||||
self | |||||
.client | |||||
.put_access_token_data(token) | |||||
.await | |||||
.map_err(handle_db_error)?; | |||||
let response = RegistrationFinishResponse { | |||||
user_id, | |||||
access_token, | |||||
}; | |||||
Ok(Response::new(response)) | |||||
} else { | |||||
Err(tonic::Status::not_found("session not found")) | |||||
} | |||||
} | } | ||||
async fn update_user_password_start( | async fn update_user_password_start( | ||||
&self, | &self, | ||||
_request: tonic::Request<UpdateUserPasswordStartRequest>, | _request: tonic::Request<UpdateUserPasswordStartRequest>, | ||||
) -> Result<tonic::Response<UpdateUserPasswordStartResponse>, tonic::Status> | ) -> Result<tonic::Response<UpdateUserPasswordStartResponse>, tonic::Status> | ||||
{ | { | ||||
unimplemented!(); | unimplemented!(); | ||||
▲ Show 20 Lines • Show All 113 Lines • Show Last 20 Lines |