#![cfg(feature = "aws")]
use std::sync::Arc;
use async_trait::async_trait;
use aws_sdk_kms::error::SdkError;
use aws_sdk_secretsmanager::Client;
use crate::error::generator::PersistError;
use super::DEKPersisterTrait;
pub struct AWSPersister {
pub(crate) client: Arc<Client>,
}
impl AWSPersister {
pub fn new(client: Arc<Client>) -> Self {
Self { client }
}
}
#[async_trait]
impl DEKPersisterTrait for AWSPersister {
async fn persist(&self, dek: &Vec<u8>, context: String) -> Result<Vec<u8>, PersistError> {
let hex_secret = hex::encode(dek);
let secret = self.client.get_secret_value().secret_id(context.clone()).send();
match secret.await {
Ok(result) =>
match result.name() {
Some(_) =>
self.client
.update_secret()
.secret_id(context)
.secret_string(hex_secret.clone())
.send().await
.map_err(|e| {
PersistError::Error(
format!("Error when persisting secret: {:?}", e)
)
})
.map(|_| hex_secret.into_bytes()),
None =>
self.client
.create_secret()
.name(context)
.secret_string(hex_secret.clone())
.send().await
.map_err(|e| {
PersistError::Error(
format!("Error when persisting secret: {:?}", e)
)
})
.map(|_| hex_secret.into_bytes()),
}
Err(e) =>
match e {
SdkError::ServiceError(ref err) => {
if err.err().is_resource_not_found_exception() {
self.client
.create_secret()
.name(context)
.secret_string(hex_secret.clone())
.send().await
.map_err(|e| {
PersistError::Error(
format!("Error when persisting secret: {:?}", e)
)
})
.map(|_| hex_secret.into_bytes())
} else {
Err(
PersistError::Error(
format!("Error when identifying secret: {:?}", e)
)
)
}
}
_ =>
Err(PersistError::Error(format!("Error when identifying secret: {:?}", e))),
}
}
}
async fn fetch(&self, context: String) -> Result<Vec<u8>, PersistError> {
let secret = self.client.get_secret_value().secret_id(&context).send();
match secret.await {
Ok(secret) =>
match secret.secret_string() {
Some(secret) =>
hex
::decode(secret)
.map_err(|e| {
PersistError::Error(
format!("Could not decode secret, Error: {:?}", e)
)
}),
None =>
Err(
PersistError::Error(
format!("No secret with identifier ({}) was found in result", context)
)
),
}
Err(e) =>
Err(
PersistError::Error(
format!(
"Could not fetch secret with identifier ({}), Error: {:?}",
context,
e
)
)
),
}
}
}