openzeppelin_relayer/config/config_file/signer/
vault_transit.rs1use crate::{
18 config::ConfigFileError,
19 models::{validate_plain_or_env_value, PlainOrEnvValue},
20};
21use serde::{Deserialize, Serialize};
22use validator::Validate;
23
24use super::{validate_with_validator, SignerConfigValidate};
25
26#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Validate)]
27#[serde(deny_unknown_fields)]
28pub struct VaultTransitSignerFileConfig {
29 #[validate(length(min = 1, message = "Key name cannot be empty"))]
30 pub key_name: String,
31 #[validate(url)]
32 pub address: String,
33 #[validate(custom(function = "validate_plain_or_env_value"))]
34 pub role_id: PlainOrEnvValue,
35 #[validate(custom(function = "validate_plain_or_env_value"))]
36 pub secret_id: PlainOrEnvValue,
37 #[validate(length(min = 1, message = "pubkey cannot be empty"))]
38 pub pubkey: String,
39 pub mount_point: Option<String>,
40 pub namespace: Option<String>,
41}
42
43impl SignerConfigValidate for VaultTransitSignerFileConfig {
44 fn validate(&self) -> Result<(), ConfigFileError> {
45 validate_with_validator(self)
46 }
47}
48#[cfg(test)]
49mod tests {
50 use crate::models::SecretString;
51
52 use super::*;
53
54 #[test]
55 fn test_vault_transit_signer_file_config_valid() {
56 let config = VaultTransitSignerFileConfig {
57 key_name: "transit-key".to_string(),
58 address: "https://vault.example.com:8200".to_string(),
59 role_id: PlainOrEnvValue::Plain {
60 value: SecretString::new("role-123"),
61 },
62 secret_id: PlainOrEnvValue::Plain {
63 value: SecretString::new("secret-456"),
64 },
65 pubkey: "MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEd+vn+WOG+lGUiJCzHsj8VItmr7Lmdv/Zr+tIhJM7rM+QT9QEzvEX2jWOPyXrvCwUyvVgWoMwUYIo3hd1PFTy7A==".to_string(),
66 mount_point: Some("transit".to_string()),
67 namespace: Some("namespace1".to_string()),
68 };
69
70 assert!(Validate::validate(&config).is_ok());
71 assert!(SignerConfigValidate::validate(&config).is_ok());
72 }
73
74 #[test]
75 fn test_vault_transit_signer_file_config_invalid_address() {
76 let config = VaultTransitSignerFileConfig {
77 key_name: "transit-key".to_string(),
78 address: "not-a-url".to_string(),
79 role_id: PlainOrEnvValue::Plain {
80 value: SecretString::new("role-123"),
81 },
82 secret_id: PlainOrEnvValue::Plain {
83 value: SecretString::new("secret-456"),
84 },
85 pubkey: "MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEd+vn+WOG+lGUiJCzHsj8VItmr7Lmdv/Zr+tIhJM7rM+QT9QEzvEX2jWOPyXrvCwUyvVgWoMwUYIo3hd1PFTy7A==".to_string(),
86 mount_point: Some("transit".to_string()),
87 namespace: None,
88 };
89
90 let result = SignerConfigValidate::validate(&config);
91 assert!(result.is_err());
92 if let Err(e) = result {
93 let error_message = format!("{:?}", e);
94 assert!(error_message.contains("address"));
95 }
96 }
97
98 #[test]
99 fn test_vault_transit_signer_file_config_empty_key_name() {
100 let config = VaultTransitSignerFileConfig {
101 key_name: "".to_string(),
102 address: "https://vault.example.com:8200".to_string(),
103 role_id: PlainOrEnvValue::Plain {
104 value: SecretString::new("role-123"),
105 },
106 secret_id: PlainOrEnvValue::Plain {
107 value: SecretString::new("secret-456"),
108 },
109 pubkey: "MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEd+vn+WOG+lGUiJCzHsj8VItmr7Lmdv/Zr+tIhJM7rM+QT9QEzvEX2jWOPyXrvCwUyvVgWoMwUYIo3hd1PFTy7A==".to_string(),
110 mount_point: Some("transit".to_string()),
111 namespace: None,
112 };
113
114 let result = SignerConfigValidate::validate(&config);
115 assert!(result.is_err());
116 if let Err(e) = result {
117 let error_message = format!("{:?}", e);
118 assert!(error_message.contains("key_name"));
119 assert!(error_message.contains("cannot be empty"));
120 }
121 }
122
123 #[test]
124 fn test_vault_transit_signer_file_config_empty_role_id() {
125 let config = VaultTransitSignerFileConfig {
126 key_name: "transit-key".to_string(),
127 address: "https://vault.example.com:8200".to_string(),
128 role_id: PlainOrEnvValue::Plain {
129 value: SecretString::new(""),
130 },
131 secret_id: PlainOrEnvValue::Plain {
132 value: SecretString::new("secret-456"),
133 },
134 pubkey: "MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEd+vn+WOG+lGUiJCzHsj8VItmr7Lmdv/Zr+tIhJM7rM+QT9QEzvEX2jWOPyXrvCwUyvVgWoMwUYIo3hd1PFTy7A==".to_string(),
135 mount_point: Some("transit".to_string()),
136 namespace: None,
137 };
138
139 let result = SignerConfigValidate::validate(&config);
140 assert!(result.is_err());
141 if let Err(e) = result {
142 let error_message = format!("{:?}", e);
143 assert!(error_message.contains("role_id"));
144 }
145 }
146
147 #[test]
148 fn test_vault_transit_signer_file_config_empty_secret_id() {
149 let config = VaultTransitSignerFileConfig {
150 key_name: "transit-key".to_string(),
151 address: "https://vault.example.com:8200".to_string(),
152 role_id: PlainOrEnvValue::Plain {
153 value: SecretString::new("role-123"),
154 },
155 secret_id: PlainOrEnvValue::Plain {
156 value: SecretString::new(""),
157 },
158 pubkey: "MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEd+vn+WOG+lGUiJCzHsj8VItmr7Lmdv/Zr+tIhJM7rM+QT9QEzvEX2jWOPyXrvCwUyvVgWoMwUYIo3hd1PFTy7A==".to_string(),
159 mount_point: Some("transit".to_string()),
160 namespace: None,
161 };
162
163 let result = SignerConfigValidate::validate(&config);
164 assert!(result.is_err());
165 if let Err(e) = result {
166 let error_message = format!("{:?}", e);
167 assert!(error_message.contains("secret_id"));
168 }
169 }
170
171 #[test]
172 fn test_vault_transit_signer_file_config_empty_pubkey() {
173 let config = VaultTransitSignerFileConfig {
174 key_name: "transit-key".to_string(),
175 address: "https://vault.example.com:8200".to_string(),
176 role_id: PlainOrEnvValue::Plain {
177 value: SecretString::new("role-123"),
178 },
179 secret_id: PlainOrEnvValue::Plain {
180 value: SecretString::new("secret-456"),
181 },
182 pubkey: "".to_string(),
183 mount_point: Some("transit".to_string()),
184 namespace: None,
185 };
186
187 let result = SignerConfigValidate::validate(&config);
188 assert!(result.is_err());
189 if let Err(e) = result {
190 let error_message = format!("{:?}", e);
191 assert!(error_message.contains("pubkey"));
192 assert!(error_message.contains("cannot be empty"));
193 }
194 }
195
196 #[test]
197 fn test_vault_transit_signer_file_config_optional_fields() {
198 let config = VaultTransitSignerFileConfig {
199 key_name: "transit-key".to_string(),
200 address: "https://vault.example.com:8200".to_string(),
201 role_id: PlainOrEnvValue::Plain {
202 value: SecretString::new("role-123"),
203 },
204 secret_id: PlainOrEnvValue::Plain {
205 value: SecretString::new("secret-456"),
206 },
207 pubkey: "MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEd+vn+WOG+lGUiJCzHsj8VItmr7Lmdv/Zr+tIhJM7rM+QT9QEzvEX2jWOPyXrvCwUyvVgWoMwUYIo3hd1PFTy7A==".to_string(),
208 mount_point: None,
209 namespace: None,
210 };
211
212 assert!(SignerConfigValidate::validate(&config).is_ok());
213 }
214
215 #[test]
216 fn test_vault_transit_signer_file_config_multiple_errors() {
217 let config = VaultTransitSignerFileConfig {
218 key_name: "".to_string(),
219 address: "invalid-url".to_string(),
220 role_id: PlainOrEnvValue::Plain {
221 value: SecretString::new("role-123"),
222 },
223 secret_id: PlainOrEnvValue::Plain {
224 value: SecretString::new("secret-456"),
225 },
226 pubkey: "".to_string(),
227 mount_point: None,
228 namespace: None,
229 };
230
231 let result = validate_with_validator(&config);
232 assert!(result.is_err());
233
234 if let Err(e) = result {
235 if let ConfigFileError::InvalidFormat(msg) = e {
236 assert!(msg.contains("key_name"));
237 assert!(msg.contains("address"));
238 assert!(msg.contains("pubkey"));
239 } else {
240 panic!("Expected ConfigFileError::InvalidFormat, got {:?}", e);
241 }
242 }
243 }
244
245 #[test]
246 fn test_serde_deserialize() {
247 let json = r#"
248 {
249 "key_name": "transit-key",
250 "address": "https://vault.example.com:8200",
251 "role_id": {
252 "type": "plain",
253 "value": "role-123"
254 },
255 "secret_id": {
256 "type": "plain",
257 "value": "secret-456"
258 },
259 "pubkey": "MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEd+vn+WOG+lGUiJCzHsj8VItmr7Lmdv/Zr+tIhJM7rM+QT9QEzvEX2jWOPyXrvCwUyvVgWoMwUYIo3hd1PFTy7A==",
260 "mount_point": "transit",
261 "namespace": "my-namespace"
262 }
263 "#;
264
265 let config: VaultTransitSignerFileConfig = serde_json::from_str(json).unwrap();
266 assert_eq!(config.key_name, "transit-key");
267 assert_eq!(config.address, "https://vault.example.com:8200");
268 assert_eq!(
269 config.role_id.get_value().unwrap().to_str().as_str(),
270 "role-123"
271 );
272 assert_eq!(
273 config.secret_id.get_value().unwrap().to_str().as_str(),
274 "secret-456"
275 );
276 assert_eq!(config.pubkey, "MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEd+vn+WOG+lGUiJCzHsj8VItmr7Lmdv/Zr+tIhJM7rM+QT9QEzvEX2jWOPyXrvCwUyvVgWoMwUYIo3hd1PFTy7A==");
277 assert_eq!(config.mount_point, Some("transit".to_string()));
278 assert_eq!(config.namespace, Some("my-namespace".to_string()));
279 }
280
281 #[test]
282 fn test_serde_unknown_field() {
283 let json = r#"
284 {
285 "key_name": "transit-key",
286 "address": "https://vault.example.com:8200",
287 "role_id": "role-123",
288 "secret_id": "secret-456",
289 "pubkey": "MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEd+vn+WOG+lGUiJCzHsj8VItmr7Lmdv/Zr+tIhJM7rM+QT9QEzvEX2jWOPyXrvCwUyvVgWoMwUYIo3hd1PFTy7A==",
290 "mount_point": "transit",
291 "namespace": "my-namespace",
292 "unknown_field": "should cause error"
293 }
294 "#;
295
296 let result: Result<VaultTransitSignerFileConfig, _> = serde_json::from_str(json);
297 assert!(result.is_err());
298 }
299
300 #[test]
301 fn test_serde_serialize_deserialize() {
302 let config = VaultTransitSignerFileConfig {
303 key_name: "transit-key".to_string(),
304 address: "https://vault.example.com:8200".to_string(),
305 role_id: PlainOrEnvValue::Plain {
306 value: SecretString::new("role-123"),
307 },
308 secret_id: PlainOrEnvValue::Plain {
309 value: SecretString::new("secret-456"),
310 },
311 pubkey: "MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEd+vn+WOG+lGUiJCzHsj8VItmr7Lmdv/Zr+tIhJM7rM+QT9QEzvEX2jWOPyXrvCwUyvVgWoMwUYIo3hd1PFTy7A==".to_string(),
312 mount_point: Some("transit".to_string()),
313 namespace: Some("namespace1".to_string()),
314 };
315
316 let serialized = serde_json::to_string(&config).unwrap();
317 let deserialized: VaultTransitSignerFileConfig = serde_json::from_str(&serialized).unwrap();
318
319 assert_eq!(config.address, deserialized.address);
320 assert_eq!(config.key_name, deserialized.key_name);
321 assert_eq!(config.mount_point, deserialized.mount_point);
322 assert_eq!(config.namespace, deserialized.namespace);
323 assert_eq!(config.pubkey, deserialized.pubkey);
324 assert_ne!(config.role_id, deserialized.role_id);
325 assert_ne!(config.secret_id, deserialized.secret_id);
326 }
327}