Changeset View
Changeset View
Standalone View
Standalone View
services/identity/src/client_service.rs
Show All 24 Lines | use crate::{ | ||||
siwe::parse_and_verify_siwe_message, | siwe::parse_and_verify_siwe_message, | ||||
token::{AccessTokenData, AuthType}, | token::{AccessTokenData, AuthType}, | ||||
}; | }; | ||||
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 comm_opaque2::grpc::protocol_error_to_grpc_status; | use comm_opaque2::grpc::protocol_error_to_grpc_status; | ||||
use constant_time_eq::constant_time_eq; | |||||
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), | ||||
▲ Show 20 Lines • Show All 182 Lines • ▼ Show 20 Lines | ) -> Result<tonic::Response<UpdateUserPasswordStartResponse>, tonic::Status> | ||||
let access_token = self | let access_token = self | ||||
.client | .client | ||||
.get_access_token_data(message.user_id.clone(), message.device_id_key) | .get_access_token_data(message.user_id.clone(), message.device_id_key) | ||||
.await | .await | ||||
.map_err(handle_db_error)?; | .map_err(handle_db_error)?; | ||||
if let Some(token) = access_token { | if let Some(token) = access_token { | ||||
if !token.is_valid() || token.access_token != message.access_token { | if !token.is_valid() | ||||
|| !constant_time_eq( | |||||
token.access_token.as_bytes(), | |||||
message.access_token.as_bytes(), | |||||
) | |||||
{ | |||||
return Err(tonic::Status::permission_denied("bad token")); | return Err(tonic::Status::permission_denied("bad token")); | ||||
} | } | ||||
let server_registration = comm_opaque2::server::Registration::new(); | let server_registration = comm_opaque2::server::Registration::new(); | ||||
let server_message = server_registration | let server_message = server_registration | ||||
.start( | .start( | ||||
&CONFIG.server_setup, | &CONFIG.server_setup, | ||||
&message.opaque_registration_request, | &message.opaque_registration_request, | ||||
▲ Show 20 Lines • Show All 304 Lines • ▼ Show 20 Lines | ) -> Result<tonic::Response<Empty>, tonic::Status> { | ||||
let access_token = self | let access_token = self | ||||
.client | .client | ||||
.get_access_token_data(message.user_id.clone(), message.device_id_key) | .get_access_token_data(message.user_id.clone(), message.device_id_key) | ||||
.await | .await | ||||
.map_err(handle_db_error)?; | .map_err(handle_db_error)?; | ||||
if let Some(token) = access_token { | if let Some(token) = access_token { | ||||
if !token.is_valid() || token.access_token != message.access_token { | if !token.is_valid() | ||||
|| !constant_time_eq( | |||||
token.access_token.as_bytes(), | |||||
message.access_token.as_bytes(), | |||||
) | |||||
{ | |||||
return Err(tonic::Status::permission_denied("bad token")); | return Err(tonic::Status::permission_denied("bad token")); | ||||
} | } | ||||
self | self | ||||
.client | .client | ||||
.delete_user(message.user_id) | .delete_user(message.user_id) | ||||
.await | .await | ||||
.map_err(handle_db_error)?; | .map_err(handle_db_error)?; | ||||
▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | async fn refresh_user_pre_keys( | ||||
&self, | &self, | ||||
_request: tonic::Request<RefreshUserPreKeysRequest>, | _request: tonic::Request<RefreshUserPreKeysRequest>, | ||||
) -> Result<tonic::Response<Empty>, tonic::Status> { | ) -> Result<tonic::Response<Empty>, tonic::Status> { | ||||
unimplemented!(); | unimplemented!(); | ||||
} | } | ||||
async fn verify_user_access_token( | async fn verify_user_access_token( | ||||
&self, | &self, | ||||
_request: tonic::Request<VerifyUserAccessTokenRequest>, | request: tonic::Request<VerifyUserAccessTokenRequest>, | ||||
) -> Result<tonic::Response<VerifyUserAccessTokenResponse>, tonic::Status> { | ) -> Result<tonic::Response<VerifyUserAccessTokenResponse>, tonic::Status> { | ||||
unimplemented!(); | let message = request.into_inner(); | ||||
let token_valid = match self | |||||
.client | |||||
.get_access_token_data(message.user_id, message.signing_public_key) | |||||
.await | |||||
{ | |||||
Ok(Some(access_token_data)) => { | |||||
constant_time_eq( | |||||
access_token_data.access_token.as_bytes(), | |||||
message.access_token.as_bytes(), | |||||
) && access_token_data.is_valid() | |||||
} | |||||
Ok(None) => false, | |||||
Err(e) => return Err(handle_db_error(e)), | |||||
}; | |||||
let response = Response::new(VerifyUserAccessTokenResponse { token_valid }); | |||||
Ok(response) | |||||
} | } | ||||
} | } | ||||
pub fn handle_db_error(db_error: DBError) -> tonic::Status { | pub fn handle_db_error(db_error: DBError) -> tonic::Status { | ||||
match db_error { | match db_error { | ||||
DBError::AwsSdk(DynamoDBError::InternalServerError(_)) | DBError::AwsSdk(DynamoDBError::InternalServerError(_)) | ||||
| DBError::AwsSdk(DynamoDBError::ProvisionedThroughputExceededException( | | DBError::AwsSdk(DynamoDBError::ProvisionedThroughputExceededException( | ||||
_, | _, | ||||
Show All 10 Lines |