Skip to content

Commit

Permalink
refactor: add logs wherever necessary and fix few error propagation (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
Chethan-rao authored Dec 29, 2024
1 parent e2c964c commit a5351d2
Show file tree
Hide file tree
Showing 10 changed files with 104 additions and 54 deletions.
15 changes: 10 additions & 5 deletions src/custom_extractors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,19 @@ use std::sync::Arc;

use axum::{async_trait, extract::FromRequestParts, http::request::Parts};

use crate::{app::TenantAppState, error::ApiError, storage::consts, tenant::GlobalAppState};
use crate::{
app::TenantAppState,
error::{ApiError, ContainerError},
storage::consts,
tenant::GlobalAppState,
};

#[derive(Clone)]
pub struct TenantStateResolver(pub Arc<TenantAppState>);

#[async_trait]
impl FromRequestParts<Arc<GlobalAppState>> for TenantStateResolver {
type Rejection = ApiError;
type Rejection = ContainerError<ApiError>;

async fn from_request_parts(
parts: &mut Parts,
Expand All @@ -21,7 +26,7 @@ impl FromRequestParts<Arc<GlobalAppState>> for TenantStateResolver {
.and_then(|h| h.to_str().ok())
.ok_or(ApiError::TenantError("x-tenant-id not found in headers"))?;

state.is_known_tenant(tenant_id).await?;
state.is_known_tenant(tenant_id)?;
Ok(Self(state.get_app_state_of_tenant(tenant_id).await?))
}
}
Expand All @@ -33,7 +38,7 @@ pub struct TenantId(pub String);
#[cfg(feature = "key_custodian")]
#[async_trait]
impl FromRequestParts<Arc<GlobalAppState>> for TenantId {
type Rejection = ApiError;
type Rejection = ContainerError<ApiError>;

async fn from_request_parts(
parts: &mut Parts,
Expand All @@ -46,7 +51,7 @@ impl FromRequestParts<Arc<GlobalAppState>> for TenantId {
.map(ToString::to_string)
.ok_or(ApiError::TenantError("x-tenant-id not found in header"))?;

state.is_known_tenant(&tenant_id).await?;
state.is_known_tenant(&tenant_id)?;
state.is_custodian_unlocked(&tenant_id).await?;

Ok(Self(tenant_id))
Expand Down
2 changes: 1 addition & 1 deletion src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ impl<T: axum::response::IntoResponse + error_stack::Context + Copy> axum::respon
for ContainerError<T>
{
fn into_response(self) -> axum::response::Response {
crate::logger::error!(?self.error);
crate::logger::error!(error=?self.error);
(*self.error.current_context()).into_response()
}
}
Expand Down
28 changes: 19 additions & 9 deletions src/routes/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::{
},
custom_extractors::TenantStateResolver,
error::{self, ContainerError, ResultContainerExt},
logger,
storage::{FingerprintInterface, HashInterface, LockerInterface},
tenant::GlobalAppState,
utils,
Expand Down Expand Up @@ -102,7 +103,7 @@ pub async fn add_card(
crypto_operation::decrypt_data(&tenant_app_state, crypto_manager, locker)
.await?;

let duplication_check = transformers::validate_card_metadata(
let duplication_check = transformers::get_data_duplication_status(
&decrypted_locker_data,
&request.data,
)?;
Expand Down Expand Up @@ -139,10 +140,10 @@ pub async fn add_card(
}
};

Ok(Json(types::StoreCardResponse::from((
duplication_check,
output,
))))
let response = Json(types::StoreCardResponse::from((duplication_check, output)));
logger::info!(add_card_response=?response);

Ok(response)
}

/// `/data/delete` handling the requirement of deleting data
Expand All @@ -163,9 +164,12 @@ pub async fn delete_card(
)
.await?;

Ok(Json(types::DeleteCardResponse {
let response = Json(types::DeleteCardResponse {
status: types::Status::Ok,
}))
});
logger::info!(delete_card_response=?response);

Ok(response)
}

/// `/data/retrieve` handling the requirement of retrieving data
Expand Down Expand Up @@ -211,7 +215,10 @@ pub async fn retrieve_card(
})
.transpose()?;

Ok(Json(decrypted_locker_data.try_into()?))
let response = Json(decrypted_locker_data.try_into()?);
logger::info!(retrieve_card_response = "card retrieve was successful");

Ok(response)
}

/// `/cards/fingerprint` handling the creation and retrieval of card fingerprint
Expand All @@ -224,5 +231,8 @@ pub async fn get_or_insert_fingerprint(
.get_or_insert_fingerprint(request.data, request.key)
.await?;

Ok(Json(fingerprint.into()))
let response = Json(fingerprint.into());
logger::info!(fingerprint_response=?response);

Ok(response)
}
2 changes: 1 addition & 1 deletion src/routes/data/transformers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ where
Ok(hash_data)
}

pub fn validate_card_metadata(
pub fn get_data_duplication_status(
stored_payload: &storage::types::Locker,
request_data: &types::Data,
) -> Result<DataDuplicationCheck, ContainerError<error::ApiError>> {
Expand Down
36 changes: 23 additions & 13 deletions src/routes/data/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,24 @@ pub enum Data {
#[derive(Debug, serde::Serialize, Default)]
pub struct Ttl(pub Option<time::PrimitiveDateTime>);

impl Validation for Ttl {
type Error = error::ApiError;

fn validate(&self) -> Result<(), Self::Error> {
self.0
.map(|ttl| -> Result<(), Self::Error> {
if ttl <= utils::date_time::now() {
Err(error::ApiError::InvalidTtl)
} else {
Ok(())
}
})
.transpose()?;

Ok(())
}
}

impl<'de> serde::Deserialize<'de> for Ttl {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
Expand All @@ -90,7 +108,7 @@ impl std::ops::Deref for Ttl {
}
}

#[derive(serde::Serialize, serde::Deserialize)]
#[derive(serde::Serialize, serde::Deserialize, Debug)]
pub struct StoreCardResponse {
pub status: Status,
pub payload: Option<StoreCardRespPayload>,
Expand Down Expand Up @@ -124,7 +142,7 @@ pub struct DeleteCardRequest {
pub card_reference: String,
}

#[derive(serde::Serialize, serde::Deserialize)]
#[derive(serde::Serialize, serde::Deserialize, Debug)]
pub struct DeleteCardResponse {
pub status: Status,
}
Expand All @@ -135,7 +153,7 @@ pub struct FingerprintRequest {
pub key: Secret<String>,
}

#[derive(serde::Serialize, serde::Deserialize)]
#[derive(serde::Serialize, serde::Deserialize, Debug)]
pub struct FingerprintResponse {
pub fingerprint_id: Secret<String>,
}
Expand All @@ -146,7 +164,7 @@ pub enum StoredData {
CardData(Card),
}

#[derive(serde::Serialize, serde::Deserialize)]
#[derive(serde::Serialize, serde::Deserialize, Debug)]
#[serde(rename_all = "PascalCase")]
pub enum Status {
Ok,
Expand All @@ -162,15 +180,7 @@ impl Validation for StoreCardRequest {
type Error = error::ApiError;

fn validate(&self) -> Result<(), Self::Error> {
self.ttl
.map(|ttl| -> Result<(), Self::Error> {
if ttl <= utils::date_time::now() {
Err(error::ApiError::InvalidTtl)
} else {
Ok(())
}
})
.transpose()?;
self.ttl.validate()?;

match &self.data {
Data::EncData { .. } => Ok(()),
Expand Down
9 changes: 3 additions & 6 deletions src/routes/key_custodian.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,9 @@ pub async fn decrypt(
message: "Decryption of Custodian key is successful".into(),
}))
}
_ => {
logger::error!("Both the custodian keys are not present to decrypt");
Err(error::ApiError::DecryptingKeysFailed(
"Both the custodain keys are not present to decrypt",
))
}
_ => Err(error::ApiError::DecryptingKeysFailed(
"Both the custodain keys are not present to decrypt",
)),
};
match decrypt_output {
Ok(inner) => Ok(inner),
Expand Down
28 changes: 22 additions & 6 deletions src/routes/routes_v2/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ use crate::{
crypto::keymanager::{self, KeyProvider},
custom_extractors::TenantStateResolver,
error::{self, ContainerError, ResultContainerExt},
routes::data::crypto_operation,
logger,
routes::data::{crypto_operation, types::Validation},
storage::storage_v2::VaultInterface,
utils,
};
Expand All @@ -20,14 +21,22 @@ pub async fn delete_data(
.find_by_entity_id(&tenant_app_state, request.entity_id.clone())
.await?;

let _delete_status = tenant_app_state
let delete_status = tenant_app_state
.db
.delete_from_vault(request.vault_id.clone().into(), &request.entity_id)
.await?;
Ok(Json(types::DeleteDataResponse {

let response = Json(types::DeleteDataResponse {
entity_id: request.entity_id,
vault_id: request.vault_id,
}))
vault_id: request.vault_id.into(),
});

match delete_status {
0 => logger::info!(delete_data_response = "data not found to delete"),
_ => logger::info!(delete_data_response=?response, "delete data was successful"),
}

Ok(response)
}

pub async fn retrieve_data(
Expand Down Expand Up @@ -71,13 +80,17 @@ pub async fn retrieve_data(
let data_value = serde_json::from_slice(decrypted_inner_data.peek().as_ref())
.change_error(error::ApiError::DecodingError)?;

logger::info!(retrieve_data_response = "retrieve data was successful");

Ok(Json(types::RetrieveDataResponse { data: data_value }))
}

pub async fn add_data(
TenantStateResolver(tenant_app_state): TenantStateResolver,
Json(request): Json<types::StoreDataRequest>,
) -> Result<Json<types::StoreDataResponse>, ContainerError<error::ApiError>> {
request.validate()?;

let crypto_manager = keymanager::get_dek_manager()
.find_or_create_entity(&tenant_app_state, request.entity_id.clone())
.await?;
Expand All @@ -89,5 +102,8 @@ pub async fn add_data(
)
.await?;

Ok(Json(types::StoreDataResponse::from(insert_data)))
let response = Json(types::StoreDataResponse::from(insert_data));
logger::info!(add_data_response=?response, "add data was successful");

Ok(response)
}
17 changes: 13 additions & 4 deletions src/routes/routes_v2/data/types.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use masking::{Secret, StrongSecret};

use crate::{
routes::data::types::{SecretDataManager, Ttl},
error,
routes::data::types::{SecretDataManager, Ttl, Validation},
storage::{storage_v2::types::Vault, types::Encryptable},
};

Expand All @@ -11,10 +12,10 @@ pub struct DeleteDataRequest {
pub vault_id: String,
}

#[derive(serde::Serialize, serde::Deserialize)]
#[derive(serde::Serialize, serde::Deserialize, Debug)]
pub struct DeleteDataResponse {
pub entity_id: String,
pub vault_id: String,
pub vault_id: Secret<String>,
}

#[derive(serde::Serialize, serde::Deserialize)]
Expand All @@ -36,7 +37,7 @@ pub struct StoreDataRequest {
pub ttl: Ttl,
}

#[derive(serde::Serialize, serde::Deserialize)]
#[derive(serde::Serialize, serde::Deserialize, Debug)]
pub struct StoreDataResponse {
pub entity_id: String,
pub vault_id: Secret<String>,
Expand All @@ -52,3 +53,11 @@ impl SecretDataManager for Vault {
self
}
}

impl Validation for StoreDataRequest {
type Error = error::ApiError;

fn validate(&self) -> Result<(), Self::Error> {
self.ttl.validate()
}
}
19 changes: 11 additions & 8 deletions src/storage/storage_v2/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,17 @@ impl VaultInterface for Storage {
.get_result(&mut conn)
.await;

output
.map_err(|error| match error {
diesel::result::Error::NotFound => error::StorageError::NotFoundError,
_ => error::StorageError::FindError,
})
.map_err(error::ContainerError::from)
.map_err(From::from)
.map(|inner| inner.into())
let output = match output {
Err(err) => match err {
diesel::result::Error::NotFound => {
Err(err).change_error(error::StorageError::NotFoundError)
}
_ => Err(err).change_error(error::StorageError::FindError),
},
Ok(vault) => Ok(vault),
};

output.map_err(From::from).map(From::from)
}

async fn insert_or_get_from_vault(
Expand Down
2 changes: 1 addition & 1 deletion src/tenant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ impl GlobalAppState {
.ok_or(ApiError::CustodianLocked)
}

pub async fn is_known_tenant(&self, tenant_id: &str) -> Result<(), ApiError> {
pub fn is_known_tenant(&self, tenant_id: &str) -> Result<(), ApiError> {
self.known_tenants
.contains(tenant_id)
.then_some(())
Expand Down

0 comments on commit a5351d2

Please sign in to comment.