1use bitwarden_api_api::apis::Error as ApiApisError;
2use log::debug;
3use thiserror::Error;
4use validator::ValidationErrors;
5
6#[derive(Debug, thiserror::Error)]
7pub enum SecretsManagerError {
8 #[error(transparent)]
9 ValidationError(ValidationError),
10 #[error(transparent)]
11 VaultLocked(#[from] bitwarden_core::VaultLockedError),
12 #[error(transparent)]
13 CryptoError(#[from] bitwarden_crypto::CryptoError),
14 #[error(transparent)]
15 Chrono(#[from] chrono::ParseError),
16
17 #[error(transparent)]
18 ApiError(#[from] bitwarden_core::ApiError),
19 #[error(transparent)]
20 MissingFieldError(#[from] bitwarden_core::MissingFieldError),
21}
22
23#[derive(Debug, Error)]
25pub enum ValidationError {
26 #[error("{0} must not be empty")]
27 Required(String),
28 #[error("{0} must not exceed {1} characters in length")]
29 ExceedsCharacterLength(String, u64),
30 #[error("{0} must not contain only whitespaces")]
31 OnlyWhitespaces(String),
32 #[error("Unknown validation error: {0}")]
33 Unknown(String),
34}
35
36const VALIDATION_LENGTH_CODE: &str = "length";
37const VALIDATION_ONLY_WHITESPACES_CODE: &str = "only_whitespaces";
38
39pub fn validate_only_whitespaces(value: &str) -> Result<(), validator::ValidationError> {
40 if !value.is_empty() && value.trim().is_empty() {
41 return Err(validator::ValidationError::new(
42 VALIDATION_ONLY_WHITESPACES_CODE,
43 ));
44 }
45 Ok(())
46}
47
48impl From<ValidationErrors> for ValidationError {
49 fn from(e: ValidationErrors) -> Self {
50 debug!("Validation errors: {:#?}", e);
51 for (field_name, errors) in e.field_errors() {
52 for error in errors {
53 match error.code.as_ref() {
54 VALIDATION_LENGTH_CODE => {
55 if error.params.contains_key("min")
56 && error.params["min"].as_u64().expect("Min provided") == 1
57 && error.params["value"]
58 .as_str()
59 .expect("Value provided")
60 .is_empty()
61 {
62 return ValidationError::Required(field_name.to_string());
63 } else if error.params.contains_key("max") {
64 return ValidationError::ExceedsCharacterLength(
65 field_name.to_string(),
66 error.params["max"].as_u64().expect("Max provided"),
67 );
68 }
69 }
70 VALIDATION_ONLY_WHITESPACES_CODE => {
71 return ValidationError::OnlyWhitespaces(field_name.to_string());
72 }
73 _ => {}
74 }
75 }
76 }
77 ValidationError::Unknown(format!("{:#?}", e))
78 }
79}
80
81impl From<ValidationErrors> for SecretsManagerError {
82 fn from(e: ValidationErrors) -> Self {
83 SecretsManagerError::ValidationError(e.into())
84 }
85}
86
87impl<T> From<ApiApisError<T>> for SecretsManagerError {
88 fn from(e: bitwarden_api_api::apis::Error<T>) -> Self {
89 SecretsManagerError::ApiError(e.into())
90 }
91}