Page MenuHomePhabricator

D9930.id33408.diff
No OneTemporary

D9930.id33408.diff

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,15 +1,17 @@
use crate::ffi::{string_callback, void_callback};
use comm_opaque2::client::{Login, Registration};
use comm_opaque2::grpc::opaque_error_to_grpc_status as handle_error;
-use grpc_clients::identity::get_unauthenticated_client;
+use grpc_clients::identity::protos::authenticated::{
+ UpdateUserPasswordFinishRequest, UpdateUserPasswordStartRequest,
+};
use grpc_clients::identity::protos::client::{
outbound_keys_for_user_request::Identifier, DeleteUserRequest,
DeviceKeyUpload, DeviceType, Empty, IdentityKeyInfo,
OpaqueLoginFinishRequest, OpaqueLoginStartRequest, OutboundKeyInfo,
OutboundKeysForUserRequest, PreKey, RegistrationFinishRequest,
- RegistrationStartRequest, UpdateUserPasswordFinishRequest,
- UpdateUserPasswordStartRequest, WalletLoginRequest,
+ RegistrationStartRequest, WalletLoginRequest,
};
+use grpc_clients::identity::{get_auth_client, get_unauthenticated_client};
use lazy_static::lazy_static;
use serde::Serialize;
use std::sync::Arc;
@@ -525,12 +527,12 @@
.map_err(handle_error)?;
let update_password_start_request = UpdateUserPasswordStartRequest {
opaque_registration_request,
- access_token: update_password_info.access_token,
- user_id: update_password_info.user_id,
- device_id_key: update_password_info.device_id,
};
- let mut identity_client = get_unauthenticated_client(
+ let mut identity_client = get_auth_client(
"http://127.0.0.1:50054",
+ update_password_info.user_id,
+ update_password_info.device_id,
+ update_password_info.access_token,
CODE_VERSION,
DEVICE_TYPE.as_str_name().to_lowercase(),
)
diff --git a/services/identity/src/client_service.rs b/services/identity/src/client_service.rs
--- a/services/identity/src/client_service.rs
+++ b/services/identity/src/client_service.rs
@@ -22,10 +22,8 @@
RegistrationFinishRequest, RegistrationFinishResponse,
RegistrationStartRequest, RegistrationStartResponse,
RemoveReservedUsernameRequest, ReservedRegistrationStartRequest,
- ReservedWalletLoginRequest, UpdateUserPasswordFinishRequest,
- UpdateUserPasswordStartRequest, UpdateUserPasswordStartResponse,
- VerifyUserAccessTokenRequest, VerifyUserAccessTokenResponse,
- WalletLoginRequest, WalletLoginResponse,
+ ReservedWalletLoginRequest, VerifyUserAccessTokenRequest,
+ VerifyUserAccessTokenResponse, WalletLoginRequest, WalletLoginResponse,
};
use crate::config::CONFIG;
use crate::database::{
@@ -252,80 +250,6 @@
}
}
- async fn update_user_password_start(
- &self,
- request: tonic::Request<UpdateUserPasswordStartRequest>,
- ) -> Result<tonic::Response<UpdateUserPasswordStartResponse>, tonic::Status>
- {
- let message = request.into_inner();
-
- let token_is_valid = self
- .client
- .verify_access_token(
- message.user_id.clone(),
- message.device_id_key,
- message.access_token,
- )
- .await
- .map_err(handle_db_error)?;
-
- if !token_is_valid {
- return Err(tonic::Status::permission_denied("bad token"));
- }
-
- let server_registration = comm_opaque2::server::Registration::new();
- let server_message = server_registration
- .start(
- &CONFIG.server_setup,
- &message.opaque_registration_request,
- message.user_id.as_bytes(),
- )
- .map_err(protocol_error_to_grpc_status)?;
-
- let update_state = UpdateState {
- user_id: message.user_id,
- };
- let session_id = self
- .cache
- .insert_with_uuid_key(WorkflowInProgress::Update(update_state))
- .await;
-
- let response = UpdateUserPasswordStartResponse {
- session_id,
- opaque_registration_response: server_message,
- };
- Ok(Response::new(response))
- }
-
- async fn update_user_password_finish(
- &self,
- request: tonic::Request<UpdateUserPasswordFinishRequest>,
- ) -> Result<tonic::Response<Empty>, tonic::Status> {
- let message = request.into_inner();
-
- if let Some(WorkflowInProgress::Update(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(protocol_error_to_grpc_status)?;
-
- self
- .client
- .update_user_password(state.user_id, password_file)
- .await
- .map_err(handle_db_error)?;
-
- let response = Empty {};
- Ok(Response::new(response))
- } else {
- Err(tonic::Status::not_found("session not found"))
- }
- }
-
async fn login_password_user_start(
&self,
request: tonic::Request<OpaqueLoginStartRequest>,
diff --git a/services/identity/src/grpc_services/authenticated.rs b/services/identity/src/grpc_services/authenticated.rs
--- a/services/identity/src/grpc_services/authenticated.rs
+++ b/services/identity/src/grpc_services/authenticated.rs
@@ -1,7 +1,15 @@
+use crate::config::CONFIG;
use crate::{
- client_service::handle_db_error, constants::request_metadata,
- database::DatabaseClient, grpc_services::shared::get_value, token::AuthType,
+ client_service::{
+ handle_db_error, CacheExt, UpdateState, WorkflowInProgress,
+ },
+ constants::request_metadata,
+ database::DatabaseClient,
+ grpc_services::shared::get_value,
+ token::AuthType,
};
+use comm_opaque2::grpc::protocol_error_to_grpc_status;
+use moka::future::Cache;
use tonic::{Request, Response, Status};
// This must be named client, because generated code from the authenticated
@@ -25,6 +33,7 @@
#[derive(derive_more::Constructor)]
pub struct AuthenticatedService {
db_client: DatabaseClient,
+ cache: Cache<String, WorkflowInProgress>,
}
fn get_auth_info(req: &Request<()>) -> Option<(String, String, String)> {
@@ -194,4 +203,65 @@
Ok(Response::new(FindUserIdResponse { user_id }))
}
+
+ async fn update_user_password_start(
+ &self,
+ request: tonic::Request<auth_proto::UpdateUserPasswordStartRequest>,
+ ) -> Result<
+ tonic::Response<auth_proto::UpdateUserPasswordStartResponse>,
+ tonic::Status,
+ > {
+ let (user_id, _) = get_user_and_device_id(&request)?;
+ let message = request.into_inner();
+
+ let server_registration = comm_opaque2::server::Registration::new();
+ let server_message = server_registration
+ .start(
+ &CONFIG.server_setup,
+ &message.opaque_registration_request,
+ user_id.as_bytes(),
+ )
+ .map_err(protocol_error_to_grpc_status)?;
+
+ let update_state = UpdateState { user_id };
+ let session_id = self
+ .cache
+ .insert_with_uuid_key(WorkflowInProgress::Update(update_state))
+ .await;
+
+ let response = auth_proto::UpdateUserPasswordStartResponse {
+ session_id,
+ opaque_registration_response: server_message,
+ };
+ Ok(Response::new(response))
+ }
+
+ async fn update_user_password_finish(
+ &self,
+ request: tonic::Request<auth_proto::UpdateUserPasswordFinishRequest>,
+ ) -> Result<tonic::Response<Empty>, tonic::Status> {
+ let message = request.into_inner();
+
+ let Some(WorkflowInProgress::Update(state)) =
+ self.cache.get(&message.session_id)
+ else {
+ return Err(tonic::Status::not_found("session not found"));
+ };
+
+ 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(protocol_error_to_grpc_status)?;
+
+ self
+ .db_client
+ .update_user_password(state.user_id, password_file)
+ .await
+ .map_err(handle_db_error)?;
+
+ let response = Empty {};
+ Ok(Response::new(response))
+ }
}
diff --git a/services/identity/src/main.rs b/services/identity/src/main.rs
--- a/services/identity/src/main.rs
+++ b/services/identity/src/main.rs
@@ -80,13 +80,13 @@
.time_to_live(Duration::from_secs(10))
.build();
let inner_client_service =
- ClientService::new(database_client.clone(), workflow_cache);
+ ClientService::new(database_client.clone(), workflow_cache.clone());
let client_service = IdentityClientServiceServer::with_interceptor(
inner_client_service,
grpc_services::shared::version_interceptor,
);
let inner_auth_service =
- AuthenticatedService::new(database_client.clone());
+ AuthenticatedService::new(database_client.clone(), workflow_cache);
let auth_service =
AuthServer::with_interceptor(inner_auth_service, move |req| {
grpc_services::authenticated::auth_interceptor(req, &database_client)
diff --git a/shared/protos/identity_authenticated.proto b/shared/protos/identity_authenticated.proto
--- a/shared/protos/identity_authenticated.proto
+++ b/shared/protos/identity_authenticated.proto
@@ -19,6 +19,12 @@
rpc RefreshUserPreKeys(RefreshUserPreKeysRequest)
returns (identity.client.Empty) {}
+ // Called by user to update password and receive new access token
+ rpc UpdateUserPasswordStart(UpdateUserPasswordStartRequest) returns
+ (UpdateUserPasswordStartResponse) {}
+ rpc UpdateUserPasswordFinish(UpdateUserPasswordFinishRequest) returns
+ (identity.client.Empty) {}
+
// Called by clients to get required keys for opening a connection
// to a user's keyserver
rpc GetKeyserverKeys(OutboundKeysForUserRequest) returns
@@ -79,3 +85,27 @@
// none if user not found
optional string userID = 1;
}
+
+// UpdateUserPassword
+
+// Request for updating a user, similar to registration but need a
+// access token to validate user before updating password
+message UpdateUserPasswordStartRequest {
+ // Message sent to initiate PAKE registration (step 1)
+ bytes opaqueRegistrationRequest = 1;
+}
+
+// Do a user registration, but overwrite the existing credentials
+// after validation of user
+message UpdateUserPasswordFinishRequest {
+ // Identifier used to correlate start and finish request
+ string sessionID = 1;
+ // Opaque client registration upload (step 3)
+ bytes opaqueRegistrationUpload = 2;
+}
+
+message UpdateUserPasswordStartResponse {
+ // Identifier used to correlate start request with finish request
+ string sessionID = 1;
+ bytes opaqueRegistrationResponse = 2;
+}
diff --git a/shared/protos/identity_client.proto b/shared/protos/identity_client.proto
--- a/shared/protos/identity_client.proto
+++ b/shared/protos/identity_client.proto
@@ -17,11 +17,6 @@
returns (RegistrationStartResponse) {}
rpc RegisterPasswordUserFinish(RegistrationFinishRequest) returns (
RegistrationFinishResponse) {}
- // Called by user to update password and receive new access token
- rpc UpdateUserPasswordStart(UpdateUserPasswordStartRequest) returns
- (UpdateUserPasswordStartResponse) {}
- rpc UpdateUserPasswordFinish(UpdateUserPasswordFinishRequest) returns
- (Empty) {}
// Called by user to register device and get an access token
rpc LoginPasswordUserStart(OpaqueLoginStartRequest) returns
(OpaqueLoginStartResponse) {}
@@ -174,36 +169,6 @@
string accessToken = 2;
}
-// UpdateUserPassword
-
-// Request for updating a user, similar to registration but need a
-// access token to validate user before updating password
-message UpdateUserPasswordStartRequest {
- // Message sent to initiate PAKE registration (step 1)
- bytes opaqueRegistrationRequest = 1;
- // Used to validate user, before attempting to update password
- string accessToken = 2;
- string userID = 3;
- // Public ed25519 key used for signing. We need this to look up a device's
- // access token
- string deviceIDKey = 4;
-}
-
-// Do a user registration, but overwrite the existing credentials
-// after validation of user
-message UpdateUserPasswordFinishRequest {
- // Identifier used to correlate start and finish request
- string sessionID = 1;
- // Opaque client registration upload (step 3)
- bytes opaqueRegistrationUpload = 2;
-}
-
-message UpdateUserPasswordStartResponse {
- // Identifier used to correlate start request with finish request
- string sessionID = 1;
- bytes opaqueRegistrationResponse = 2;
-}
-
// LoginUser
message OpaqueLoginStartRequest {

File Metadata

Mime Type
text/plain
Expires
Wed, Nov 27, 5:24 AM (19 h, 55 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2588453
Default Alt Text
D9930.id33408.diff (12 KB)

Event Timeline