wick_config/lockdown/
error.rs

1use crate::config::resources::ResourceKind;
2
3/// Error returned when asserting a lockdown configuration fails.
4#[derive(Clone, PartialEq, Eq, Hash, Debug)]
5pub struct LockdownError {
6  failures: Vec<FailureKind>,
7}
8
9impl LockdownError {
10  /// Instantiate a new lockdown error.
11  #[must_use]
12  pub fn new(failures: Vec<FailureKind>) -> Self {
13    Self { failures }
14  }
15
16  /// Get the failures that occurred.
17  #[must_use]
18  pub fn failures(&self) -> &[FailureKind] {
19    &self.failures
20  }
21}
22
23impl std::error::Error for LockdownError {}
24impl std::fmt::Display for LockdownError {
25  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26    write!(
27      f,
28      "lockdown configuration resulted in {} failures: {}",
29      self.failures.len(),
30      self
31        .failures
32        .iter()
33        .map(std::string::ToString::to_string)
34        .collect::<Vec<_>>()
35        .join(", ")
36    )
37  }
38}
39
40/// Errors that occur when a configuration is invalid for a configuration.
41#[derive(Clone, PartialEq, Eq, Hash, Debug)]
42pub enum FailureKind {
43  /// General Error.
44  General(String),
45  /// A lockdown assertion failed.
46  Failed(Box<LockdownError>),
47  /// A component was not expressly allowed via this configuration.
48  NotExpresslyAllowed(String, ResourceKind),
49  /// A component is not allowed to access given volume.
50  Volume(String, String),
51  /// A volume could not be reconciled on the file system.
52  VolumeInvalid(String, String),
53  /// A restriction is not a valid path.
54  VolumeRestrictionInvalid(String),
55  /// A component is not allowed to access given port.
56  Port(String, u16),
57  /// A component is not allowed to access given address.
58  Address(String, String),
59  /// A component is not allowed to access given url.
60  Url(String, String),
61  /// A file:// URL could not be turned into a filepath.
62  FileUrlInvalid(url::Url),
63  /// A file:// URL does not point to a concrete file.
64  FileUrlNotFound(url::Url),
65}
66
67impl std::fmt::Display for FailureKind {
68  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
69    match self {
70      FailureKind::Failed(error) => write!(f, "{error}"),
71      FailureKind::General(s) => f.write_str(s),
72      FailureKind::VolumeInvalid(name, path) => write!(
73        f,
74        "the path {} for volume {} could not be reconciled on the file system",
75        path, name
76      ),
77      FailureKind::Volume(id, path) => write!(f, "component {} is not allowed to access {}", id, path),
78      FailureKind::NotExpresslyAllowed(id,kind) => write!(f, "component {} is not expressly allowed to access a {} resource", id,kind),
79      FailureKind::VolumeRestrictionInvalid(path) => write!(
80        f,
81        "restricted volume '{}' is not valid, it can not be reconciled on the file system and can not be asserted against",
82        path
83      ),
84        FailureKind::Port(id, port) =>  write!(f, "component {} is not allowed to access {}", id, port),
85        FailureKind::Address(id,address) =>  write!(f, "component {} is not allowed to access {}", id, address),
86        FailureKind::Url(id, url) =>  write!(f, "component {} is not allowed to access {}", id, url),
87        FailureKind::FileUrlInvalid(url) =>  write!(f, "could not create a file path out of {}", url),
88        FailureKind::FileUrlNotFound(url) =>  write!(f, "file URL '{}' does not point to a valid file", url),
89    }
90  }
91}