#![cfg(feature = "azure")]
use std::sync::Arc;
use async_trait::async_trait;
use azure_security_keyvault::prelude::KeyVaultGetSecretResponse;
use azure_security_keyvault::KeyvaultClient;
use super::DEKPersisterTrait;
use crate::error::generator::PersistError;
#[derive(Debug)]
pub struct AzurePersister {
pub(crate) client: Arc<KeyvaultClient>,
}
impl AzurePersister {
pub fn new(client: Arc<KeyvaultClient>) -> Self {
Self { client }
}
}
#[async_trait]
impl DEKPersisterTrait for AzurePersister {
async fn persist(&self, dek: &Vec<u8>, context: String) -> Result<Vec<u8>, PersistError> {
let hash_name = context;
let hex_secret = hex::encode(dek);
let secret_client = self.client.secret_client();
match secret_client.set(hash_name, hex_secret.clone()).await {
Ok(_) => Ok(hex_secret.into_bytes()),
Err(e) => Err(PersistError::Error(format!("Could not persist secret: {:?}", e))),
}
}
async fn fetch(&self, context: String) -> Result<Vec<u8>, PersistError> {
let hash_name = context;
let secret_client = self.client.secret_client();
let secret: Result<KeyVaultGetSecretResponse, azure_core::error::Error> = secret_client.get(
hash_name.clone()
).await;
match secret {
Ok(secret) =>
hex
::decode(secret.value)
.map_err(|e| {
PersistError::Error(format!("Could not decode secret, Error: {:?}", e))
}),
Err(e) =>
Err(
PersistError::Error(
format!(
"Could not fetch secret with identifier ({}), Error: {:?}",
hash_name,
e
)
)
),
}
}
}