diff --git a/native/cpp/CommonCpp/grpc/protos/identity.proto b/native/cpp/CommonCpp/grpc/protos/identity.proto --- a/native/cpp/CommonCpp/grpc/protos/identity.proto +++ b/native/cpp/CommonCpp/grpc/protos/identity.proto @@ -42,7 +42,7 @@ // Answer sent to the user upon reception of the PAKE login attempt, // containing a sealed envelope with the user's private key (step 2) bytes pakeCredentialResponse = 1; - bytes token = 2; + string token = 2; } } @@ -110,7 +110,7 @@ message VerifyUserTokenRequest { string userID = 1; string deviceID = 2; - bytes token = 3; + string token = 3; } message VerifyUserTokenResponse { diff --git a/services/identity/Cargo.lock b/services/identity/Cargo.lock --- a/services/identity/Cargo.lock +++ b/services/identity/Cargo.lock @@ -220,6 +220,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" +[[package]] +name = "constant_time_eq" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e31aa570361918e61453e3b5377976b23e4599e8bb5b840380ecd3a20e691d2" + [[package]] name = "convert_case" version = "0.4.0" @@ -689,6 +695,7 @@ "bytes", "chrono", "clap", + "constant_time_eq 0.2.2", "curve25519-dalek", "derive_more", "digest 0.9.0", @@ -890,7 +897,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f25e5f1be61b7a94f388368a24739318fe4edd2b841d20d7077a422a5391e22f" dependencies = [ - "constant_time_eq", + "constant_time_eq 0.1.5", "curve25519-dalek", "digest 0.9.0", "displaydoc", diff --git a/services/identity/Cargo.toml b/services/identity/Cargo.toml --- a/services/identity/Cargo.toml +++ b/services/identity/Cargo.toml @@ -22,6 +22,7 @@ chrono = "0.4.19" rand = "0.8" bytes = "1.1" +constant_time_eq = "0.2.2" [build-dependencies] tonic-build = "0.6" diff --git a/services/identity/Dockerfile b/services/identity/Dockerfile --- a/services/identity/Dockerfile +++ b/services/identity/Dockerfile @@ -1,4 +1,4 @@ -FROM rust:1.57 +FROM rust:1.61 # Create a new user comm and use it to run subsequent commands RUN useradd -m comm diff --git a/services/identity/src/database.rs b/services/identity/src/database.rs --- a/services/identity/src/database.rs +++ b/services/identity/src/database.rs @@ -288,7 +288,7 @@ match auth_type.as_str() { "password" => Ok(AuthType::Password), "wallet" => Ok(AuthType::Wallet), - unsupported => Err(Error::InvalidAuthType), + _ => Err(Error::InvalidAuthType), } } else { Err(Error::MissingAttribute) 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,9 +1,13 @@ +use constant_time_eq::constant_time_eq; use futures_core::Stream; +use rusoto_core::RusotoError; +use rusoto_dynamodb::GetItemError; use std::pin::Pin; use tonic::{Request, Response, Status}; +use tracing::{error, info, instrument}; -use crate::config::Config; use crate::database::DatabaseClient; +use crate::{config::Config, database::Error}; pub use proto::identity_service_server::IdentityServiceServer; use proto::{ @@ -49,11 +53,39 @@ unimplemented!() } + #[instrument(skip(self))] async fn verify_user_token( &self, request: Request, ) -> Result, Status> { - println!("Got a lookup request: {:?}", request); - unimplemented!() + info!("Received VerifyUserToken request: {:?}", request); + let message = request.into_inner(); + let token_valid = match self + .client + .get_token(message.user_id, message.device_id) + .await + { + Ok(Some(access_token)) => constant_time_eq( + access_token.token.as_bytes(), + message.token.as_bytes(), + ), + Ok(None) => false, + Err(Error::RusotoGet(RusotoError::Service( + GetItemError::ResourceNotFound(_), + ))) + | Err(Error::RusotoGet(RusotoError::Credentials(_))) => { + return Err(Status::failed_precondition("internal error")) + } + Err(Error::RusotoGet(_)) => { + return Err(Status::unavailable("please retry")) + } + Err(e) => { + error!("Encountered an unexpected error: {}", e); + return Err(Status::failed_precondition("unexpected error")); + } + }; + let response = Response::new(VerifyUserTokenResponse { token_valid }); + info!("Sending VerifyUserToken response: {:?}", response); + Ok(response) } }