Skip to main content

signstar_config/config/
error.rs

1//! Error handling for Signstar configuration and related components.
2
3use std::path::PathBuf;
4
5#[cfg(feature = "nethsm")]
6use nethsm::{KeyId, NamespaceId, SystemWideUserId, UserId};
7
8use crate::{SystemUserId, config::Config};
9
10/// An error that may occur when using a Signstar configuration.
11#[derive(Debug, thiserror::Error)]
12pub enum Error {
13    /// The Signstar configuration is missing.
14    #[error("No configuration file found in {}.",
15        Config::list_config_dirs().iter().map(|path| path.display().to_string()).collect::<Vec<_>>().join(", ")
16    )]
17    ConfigIsMissing,
18
19    /// A Signstar configuration file has no file extension.
20    #[error("The Signstar configuration file {path} has no file extension.")]
21    MissingFileExtension {
22        /// The path of the file.
23        path: PathBuf,
24    },
25
26    /// A Signstar configuration file has an unsupported file extension.
27    #[error(
28        "The Signstar configuration file {path} uses the unsupported file extension {extension}."
29    )]
30    UnsupportedFileExtension {
31        /// The path of the file.
32        path: PathBuf,
33        /// The file extension.
34        extension: String,
35    },
36
37    /// Duplicate NetHSM user names
38    #[cfg(feature = "nethsm")]
39    #[error("The NetHSM user ID {nethsm_user_id} is used more than once!")]
40    DuplicateNetHsmUserId {
41        /// The name of a NetHSM user that is used more than once.
42        nethsm_user_id: UserId,
43    },
44
45    /// An SSH public key is used more than once.
46    #[error("The SSH public key \"{ssh_public_key}\" is used more than once!")]
47    DuplicateSshPublicKey {
48        /// The SSH public key that is used more than once.
49        ssh_public_key: String,
50    },
51
52    /// Duplicate key ID
53    #[cfg(feature = "nethsm")]
54    #[error(
55        "The key ID \"{key_id}\" ({}) is used more than once",
56        if let Some(namespace) = namespace {
57            format!("namespace: \"{namespace}\"")
58        } else {
59            "system-wide".to_string()
60        },
61    )]
62    DuplicateKeyId {
63        /// The name of a key that is used more than once.
64        key_id: KeyId,
65        /// The optional `namespace` in which more than one `key_id` exists.
66        namespace: Option<NamespaceId>,
67    },
68
69    /// Duplicate system user names
70    #[error("The system user ID {system_user_id} is used more than once!")]
71    DuplicateSystemUserId {
72        /// The name of a system user that is usd more than once.
73        system_user_id: SystemUserId,
74    },
75
76    /// A tag for a user/key is used more than once.
77    #[cfg(feature = "nethsm")]
78    #[error(
79        "The tag {tag} ({}) is used more than once",
80        if let Some(namespace) = namespace {
81            format!("namespace: \"{namespace}\"")
82        } else {
83            "system-wide".to_string()
84        },
85    )]
86    DuplicateTag {
87        /// The tag of a key/user that is used more than once.
88        tag: String,
89        /// The optional name of a namespace in which `tag` is used more than once.
90        namespace: Option<NamespaceId>,
91    },
92
93    /// A system username is invalid
94    #[error("The system user name {name} is invalid")]
95    InvalidSystemUserName {
96        /// The invalid system user name.
97        name: String,
98    },
99
100    /// An entry in authorized_keys is invalid.
101    #[error("The SSH authorized key \"{entry}\" is invalid")]
102    InvalidAuthorizedKeyEntry {
103        /// A string that represents an invalid SSH public key.
104        entry: String,
105    },
106
107    /// A [`UserId`] is used both for a user in the [`Metrics`][`nethsm::UserRole::Metrics`] and
108    /// [`Operator`][`nethsm::UserRole::Operator`] role.
109    #[cfg(feature = "nethsm")]
110    #[error("The NetHsm user {metrics_user} is both in the Metrics and Operator role!")]
111    MetricsAlsoOperator {
112        /// The system-wide User ID of a NetHSM user that is both in the
113        /// [`Metrics`][`nethsm::UserRole::Metrics`] and
114        /// [`Operator`][`nethsm::UserRole::Operator`] role.
115        metrics_user: SystemWideUserId,
116    },
117
118    /// A user in the Administrator role is missing system-wide (_R-Administrator_) or in one or
119    /// more namespaces (_N-Administrator_).
120    #[cfg(feature = "nethsm")]
121    #[error(
122        "No user in the Administrator role exists ({})",
123        if let Some(namespaces) = namespaces {
124            namespaces.iter().map(|id| id.to_string()).collect::<Vec<_>>().join(", ")
125        } else {
126            "system-wide".to_string()
127        }
128    )]
129    MissingAdministrator {
130        /// The list of namespaces in which administrators are missing.
131        namespaces: Option<Vec<NamespaceId>>,
132    },
133
134    /// Missing system user for downloading shares of a shared secret
135    #[error("No system user for downloading shares of a shared secret exists.")]
136    MissingShareDownloadSystemUser,
137
138    /// Missing system user for uploading shares of a shared secret
139    #[error("No system user for uploading shares of a shared secret exists.")]
140    MissingShareUploadSystemUser,
141
142    /// There are no SSH authorized keys
143    #[error("No SSH authorized key provided!")]
144    NoAuthorizedKeys,
145
146    /// There is no mapping for a provided system user name.
147    #[error("No mapping found where a system user matches the name {name}")]
148    NoMatchingMappingForSystemUser {
149        /// The name of a system user for which no mapping exists.
150        name: String,
151    },
152
153    /// Shamir's Secret Sharing (SSS) is not used for administrative secret handling, but users for
154    /// handling of secret shares are defined
155    #[error(
156        "Shamir's Secret Sharing not used for administrative secret handling, but the following users are setup to handle shares: {share_users:?}"
157    )]
158    NoSssButShareUsers {
159        /// A list of system user names that are setup for Shamir's Secret Sharing.
160        share_users: Vec<SystemUserId>,
161    },
162
163    /// User data is invalid
164    #[cfg(feature = "nethsm")]
165    #[error("User data invalid: {0}")]
166    User(#[from] nethsm::UserError),
167
168    /// An SSH key error
169    #[error("SSH key error: {0}")]
170    SshKey(#[from] ssh_key::Error),
171
172    /// An error occurred while deserializing an object as a YAML string.
173    #[error("YAML deserialization error while {context}:\n{source}")]
174    YamlDeserialize {
175        /// The context in which the error occurred.
176        ///
177        /// This is meant to complete the sentence "YAML deserialization error while ".
178        context: String,
179        /// The error source.
180        source: serde_saphyr::Error,
181    },
182
183    /// An error occurred while serializing an object as a YAML string.
184    #[error("YAML serialization error while {context}:\n{source}")]
185    YamlSerialize {
186        /// The context in which the error occurred.
187        ///
188        /// This is meant to complete the sentence "YAML serialization error while ".
189        context: &'static str,
190        /// The error source.
191        source: serde_saphyr::ser_error::Error,
192    },
193}