diff --git a/services/identity/src/service.rs b/services/identity/src/service.rs --- a/services/identity/src/service.rs +++ b/services/identity/src/service.rs @@ -1,19 +1,25 @@ use constant_time_eq::constant_time_eq; use futures_core::Stream; +use rand::{CryptoRng, Rng}; use rusoto_core::RusotoError; -use rusoto_dynamodb::GetItemError; +use rusoto_dynamodb::{GetItemError, PutItemError}; use std::pin::Pin; use tonic::{Request, Response, Status}; use tracing::{error, info, instrument}; use crate::database::DatabaseClient; +use crate::token::{AccessTokenData, AuthType}; use crate::{config::Config, database::Error}; pub use proto::identity_service_server::IdentityServiceServer; use proto::{ - identity_service_server::IdentityService, LoginRequest, LoginResponse, - RegistrationRequest, RegistrationResponse, VerifyUserTokenRequest, - VerifyUserTokenResponse, + identity_service_server::IdentityService, + login_response::Data::PakeLoginResponse, + login_response::Data::WalletLoginResponse, + pake_login_response::Data::AccessToken, LoginRequest, LoginResponse, + PakeLoginResponse as PakeLoginResponseStruct, RegistrationRequest, + RegistrationResponse, VerifyUserTokenRequest, VerifyUserTokenResponse, + WalletLoginResponse as WalletLoginResponseStruct, }; mod proto { @@ -89,3 +95,42 @@ Ok(response) } } + +async fn put_token_helper( + client: DatabaseClient, + auth_type: AuthType, + user_id: String, + device_id: String, + rng: &mut (impl Rng + CryptoRng), +) -> Result { + let access_token_data = + AccessTokenData::new(user_id, device_id, auth_type.clone(), rng); + match client + .put_access_token_data(access_token_data.clone()) + .await + { + Ok(_) => match auth_type { + AuthType::Wallet => Ok(LoginResponse { + data: Some(WalletLoginResponse(WalletLoginResponseStruct { + access_token: access_token_data.access_token, + })), + }), + AuthType::Password => Ok(LoginResponse { + data: Some(PakeLoginResponse(PakeLoginResponseStruct { + data: Some(AccessToken(access_token_data.access_token)), + })), + }), + }, + Err(Error::RusotoPut(RusotoError::Service( + PutItemError::ResourceNotFound(_), + ))) + | Err(Error::RusotoPut(RusotoError::Credentials(_))) => { + Err(Status::failed_precondition("internal error")) + } + Err(Error::RusotoPut(_)) => Err(Status::unavailable("please retry")), + Err(e) => { + error!("Encountered an unexpected error: {}", e); + Err(Status::failed_precondition("unexpected error")) + } + } +} diff --git a/services/identity/src/token.rs b/services/identity/src/token.rs --- a/services/identity/src/token.rs +++ b/services/identity/src/token.rs @@ -4,11 +4,13 @@ CryptoRng, Rng, }; +#[derive(Clone)] pub enum AuthType { Password, Wallet, } +#[derive(Clone)] pub struct AccessTokenData { pub user_id: String, pub device_id: String,