vault_client_rs/types/
secret.rs1use serde::{Deserialize, Serialize};
2
3use crate::VaultError;
4
5pub use secrecy::SecretString;
6
7fn validate_vault_path(s: &str, kind: &str) -> Result<(), VaultError> {
8 if s.is_empty()
9 || s.contains("..")
10 || s.starts_with('/')
11 || s.ends_with('/')
12 || s.contains('\0')
13 || s.contains("%2e")
14 || s.contains("%2E")
15 || s.contains("%2f")
16 || s.contains("%2F")
17 || s.chars().any(|c| c.is_control())
18 {
19 return Err(VaultError::Config(format!("invalid {kind}: {s:?}")));
20 }
21 Ok(())
22}
23
24macro_rules! vault_path_type {
25 ($Name:ident, $label:literal) => {
26 impl $Name {
27 pub fn new(s: impl Into<String>) -> Result<Self, VaultError> {
28 let s = s.into();
29 validate_vault_path(&s, $label)?;
30 Ok(Self(s))
31 }
32
33 pub fn as_str(&self) -> &str {
34 &self.0
35 }
36 }
37
38 impl TryFrom<String> for $Name {
39 type Error = VaultError;
40 fn try_from(s: String) -> Result<Self, Self::Error> {
41 Self::new(s)
42 }
43 }
44
45 impl TryFrom<&str> for $Name {
46 type Error = VaultError;
47 fn try_from(s: &str) -> Result<Self, Self::Error> {
48 Self::new(s)
49 }
50 }
51
52 impl<'de> Deserialize<'de> for $Name {
53 fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
54 let s = String::deserialize(d)?;
55 Self::new(s).map_err(serde::de::Error::custom)
56 }
57 }
58
59 impl std::fmt::Display for $Name {
60 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61 f.write_str(&self.0)
62 }
63 }
64
65 impl AsRef<str> for $Name {
66 fn as_ref(&self) -> &str {
67 &self.0
68 }
69 }
70
71 impl std::borrow::Borrow<str> for $Name {
72 fn borrow(&self) -> &str {
73 &self.0
74 }
75 }
76
77 impl From<$Name> for String {
78 fn from(p: $Name) -> Self {
79 p.0
80 }
81 }
82 };
83}
84
85#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize)]
90pub struct MountPath(String);
91vault_path_type!(MountPath, "mount path");
92
93#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize)]
97pub struct SecretPath(String);
98vault_path_type!(SecretPath, "secret path");