Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use std::fmt::{Debug, Display};
- use std::path::PathBuf;
- use std::{fs, io};
- use derive_more::From as DeriveFrom;
- use failure::Fail;
- #[derive(Debug, Fail)]
- pub enum SecretsDbError<T>
- where
- T: Display + Debug + Send + Sync + 'static,
- {
- #[fail(display = "read only")]
- ReadOnly,
- #[fail(display = "secret doesn't exist")]
- SecretDoesntExist(String),
- #[fail(display = "internal error")]
- InternalError(T),
- }
- pub trait SecretsDb<E>
- where
- E: Display + Debug + Send + Sync,
- {
- type Secret;
- type SecretDescriptor;
- fn get_secret<D>(&self, secret_descriptor: D) -> Result<Self::Secret, SecretsDbError<E>>
- where
- D: Into<Self::SecretDescriptor>;
- fn put_secret<S>(&mut self, secret: S) -> Result<(), SecretsDbError<E>>
- where
- S: Into<Self::Secret>;
- fn create_secret<S>(&mut self, secret: S) -> Result<(), SecretsDbError<E>>
- where
- S: Into<Self::Secret>;
- }
- // FileSecretsDb
- #[derive(Debug)]
- pub struct FileSecret {
- pub filename: String,
- pub content: Option<Vec<u8>>,
- }
- impl From<&str> for FileSecret {
- fn from(s: &str) -> Self {
- Self {
- filename: s.to_string(),
- content: None,
- }
- }
- }
- impl<T, U> From<(T, U)> for FileSecret
- where
- T: Into<String>,
- U: Into<Vec<u8>>,
- {
- fn from((filename, content): (T, U)) -> Self {
- let filename = filename.into();
- let content = Some(content.into());
- Self { filename, content }
- }
- }
- #[derive(Debug)]
- pub struct FileSecretsDb {
- read_only: bool,
- root_path: PathBuf,
- }
- impl FileSecretsDb {
- pub fn new<T>(root_path: T, read_only: bool) -> Self
- where
- T: Into<PathBuf>
- {
- Self {
- read_only,
- root_path: root_path.into(),
- }
- }
- }
- #[derive(Debug, Fail, DeriveFrom)]
- pub enum FileSecretsDbError {
- #[fail(display = "io error")]
- IoError(io::Error),
- #[fail(display = "empty secret")]
- EmptySecret,
- #[fail(display = "secret already exist")]
- SecretAlreadyExist,
- }
- impl SecretsDb<FileSecretsDbError> for FileSecretsDb {
- type Secret = FileSecret;
- type SecretDescriptor = FileSecret;
- fn get_secret<D>(
- &self,
- secret_descriptor: D,
- ) -> Result<Self::Secret, SecretsDbError<FileSecretsDbError>>
- where
- D: Into<Self::SecretDescriptor>,
- {
- let FileSecret { filename, .. } = secret_descriptor.into();
- let secrets_path = self.root_path.join(&filename);
- Ok(Self::Secret {
- filename,
- content: Some(
- fs::read(secrets_path)
- .map_err(FileSecretsDbError::IoError)
- .map_err(SecretsDbError::InternalError)?,
- ),
- })
- }
- fn put_secret<S>(&mut self, secret: S) -> Result<(), SecretsDbError<FileSecretsDbError>>
- where
- S: Into<Self::Secret>,
- {
- if self.read_only {
- return Err(SecretsDbError::ReadOnly);
- }
- let secret = secret.into();
- let secret_path = self.root_path.join(secret.filename);
- secret
- .content
- .ok_or(SecretsDbError::InternalError(
- FileSecretsDbError::EmptySecret,
- ))
- .and_then(|content| {
- fs::write(secret_path, content)
- .map_err(FileSecretsDbError::IoError)
- .map_err(SecretsDbError::InternalError)
- })
- }
- fn create_secret<S>(&mut self, secret: S) -> Result<(), SecretsDbError<FileSecretsDbError>>
- where
- S: Into<Self::Secret>,
- {
- if self.read_only {
- return Err(SecretsDbError::ReadOnly);
- }
- let secret = secret.into();
- if self.root_path.join(&secret.filename).exists() {
- return Err(SecretsDbError::InternalError(FileSecretsDbError::SecretAlreadyExist))
- }
- self.put_secret(secret)
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement