Advertisement
Guest User

Untitled

a guest
Mar 26th, 2019
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.85 KB | None | 0 0
  1. use std::fmt::{Debug, Display};
  2. use std::path::PathBuf;
  3. use std::{fs, io};
  4.  
  5. use derive_more::From as DeriveFrom;
  6. use failure::Fail;
  7.  
  8. #[derive(Debug, Fail)]
  9. pub enum SecretsDbError<T>
  10. where
  11. T: Display + Debug + Send + Sync + 'static,
  12. {
  13. #[fail(display = "read only")]
  14. ReadOnly,
  15.  
  16. #[fail(display = "secret doesn't exist")]
  17. SecretDoesntExist(String),
  18.  
  19. #[fail(display = "internal error")]
  20. InternalError(T),
  21. }
  22.  
  23. pub trait SecretsDb<E>
  24. where
  25. E: Display + Debug + Send + Sync,
  26. {
  27. type Secret;
  28. type SecretDescriptor;
  29.  
  30. fn get_secret<D>(&self, secret_descriptor: D) -> Result<Self::Secret, SecretsDbError<E>>
  31. where
  32. D: Into<Self::SecretDescriptor>;
  33.  
  34. fn put_secret<S>(&mut self, secret: S) -> Result<(), SecretsDbError<E>>
  35. where
  36. S: Into<Self::Secret>;
  37.  
  38. fn create_secret<S>(&mut self, secret: S) -> Result<(), SecretsDbError<E>>
  39. where
  40. S: Into<Self::Secret>;
  41. }
  42.  
  43.  
  44.  
  45. // FileSecretsDb
  46.  
  47.  
  48.  
  49. #[derive(Debug)]
  50. pub struct FileSecret {
  51. pub filename: String,
  52. pub content: Option<Vec<u8>>,
  53. }
  54.  
  55. impl From<&str> for FileSecret {
  56. fn from(s: &str) -> Self {
  57. Self {
  58. filename: s.to_string(),
  59. content: None,
  60. }
  61. }
  62. }
  63.  
  64. impl<T, U> From<(T, U)> for FileSecret
  65. where
  66. T: Into<String>,
  67. U: Into<Vec<u8>>,
  68. {
  69. fn from((filename, content): (T, U)) -> Self {
  70. let filename = filename.into();
  71. let content = Some(content.into());
  72.  
  73. Self { filename, content }
  74. }
  75. }
  76.  
  77. #[derive(Debug)]
  78. pub struct FileSecretsDb {
  79. read_only: bool,
  80. root_path: PathBuf,
  81. }
  82.  
  83.  
  84. impl FileSecretsDb {
  85. pub fn new<T>(root_path: T, read_only: bool) -> Self
  86. where
  87. T: Into<PathBuf>
  88. {
  89. Self {
  90. read_only,
  91. root_path: root_path.into(),
  92. }
  93. }
  94. }
  95.  
  96. #[derive(Debug, Fail, DeriveFrom)]
  97. pub enum FileSecretsDbError {
  98. #[fail(display = "io error")]
  99. IoError(io::Error),
  100.  
  101. #[fail(display = "empty secret")]
  102. EmptySecret,
  103.  
  104. #[fail(display = "secret already exist")]
  105. SecretAlreadyExist,
  106. }
  107.  
  108. impl SecretsDb<FileSecretsDbError> for FileSecretsDb {
  109. type Secret = FileSecret;
  110. type SecretDescriptor = FileSecret;
  111.  
  112. fn get_secret<D>(
  113. &self,
  114. secret_descriptor: D,
  115. ) -> Result<Self::Secret, SecretsDbError<FileSecretsDbError>>
  116. where
  117. D: Into<Self::SecretDescriptor>,
  118. {
  119. let FileSecret { filename, .. } = secret_descriptor.into();
  120. let secrets_path = self.root_path.join(&filename);
  121.  
  122. Ok(Self::Secret {
  123. filename,
  124. content: Some(
  125. fs::read(secrets_path)
  126. .map_err(FileSecretsDbError::IoError)
  127. .map_err(SecretsDbError::InternalError)?,
  128. ),
  129. })
  130. }
  131.  
  132. fn put_secret<S>(&mut self, secret: S) -> Result<(), SecretsDbError<FileSecretsDbError>>
  133. where
  134. S: Into<Self::Secret>,
  135. {
  136. if self.read_only {
  137. return Err(SecretsDbError::ReadOnly);
  138. }
  139.  
  140. let secret = secret.into();
  141. let secret_path = self.root_path.join(secret.filename);
  142.  
  143. secret
  144. .content
  145. .ok_or(SecretsDbError::InternalError(
  146. FileSecretsDbError::EmptySecret,
  147. ))
  148. .and_then(|content| {
  149. fs::write(secret_path, content)
  150. .map_err(FileSecretsDbError::IoError)
  151. .map_err(SecretsDbError::InternalError)
  152. })
  153. }
  154.  
  155. fn create_secret<S>(&mut self, secret: S) -> Result<(), SecretsDbError<FileSecretsDbError>>
  156. where
  157. S: Into<Self::Secret>,
  158. {
  159. if self.read_only {
  160. return Err(SecretsDbError::ReadOnly);
  161. }
  162.  
  163. let secret = secret.into();
  164.  
  165. if self.root_path.join(&secret.filename).exists() {
  166. return Err(SecretsDbError::InternalError(FileSecretsDbError::SecretAlreadyExist))
  167. }
  168.  
  169. self.put_secret(secret)
  170. }
  171. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement