signstar_config/nethsm/
config.rs

1//! [`NetHsm`] specific integration for the [`crate::config`] module.
2
3#[cfg(doc)]
4use nethsm::NetHsm;
5use nethsm::{NamespaceId, UserId, UserRole};
6use serde::{Deserialize, Serialize};
7
8use crate::{Error, SystemWideUserId};
9
10/// A filter for retrieving information about users and keys.
11#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
12pub enum FilterUserKeys {
13    /// Consider both system-wide and namespaced users and keys.
14    All,
15
16    /// Only consider users and keys that are in a namespace.
17    Namespaced,
18
19    /// Only consider users and keys that match a specific [`NamespaceId`].
20    Namespace(NamespaceId),
21
22    /// Only consider system-wide users and keys.
23    SystemWide,
24
25    /// Only consider users and keys that match a specific tag.
26    Tag(String),
27}
28
29/// A set of users with unique [`UserId`]s, used for metrics retrieval
30///
31/// This struct tracks a user that is intended for the use in the
32/// [`Metrics`][`nethsm::UserRole::Metrics`] role and a list of users, that are intended to be used
33/// in the [`Operator`][`nethsm::UserRole::Operator`] role.
34#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
35pub struct NetHsmMetricsUsers {
36    metrics_user: SystemWideUserId,
37    operator_users: Vec<UserId>,
38}
39
40impl NetHsmMetricsUsers {
41    /// Creates a new [`NetHsmMetricsUsers`]
42    ///
43    /// # Error
44    ///
45    /// Returns an error, if the provided [`UserId`] of the `metrics_user` is duplicated in the
46    /// provided `operator_users`.
47    ///
48    /// # Examples
49    ///
50    /// ```
51    /// use signstar_config::NetHsmMetricsUsers;
52    ///
53    /// # fn main() -> testresult::TestResult {
54    /// NetHsmMetricsUsers::new(
55    ///     "metrics1".parse()?,
56    ///     vec!["user1".parse()?, "user2".parse()?],
57    /// )?;
58    ///
59    /// // this fails because there are duplicate UserIds
60    /// assert!(
61    ///     NetHsmMetricsUsers::new(
62    ///         "metrics1".parse()?,
63    ///         vec!["metrics1".parse()?, "user2".parse()?,],
64    ///     )
65    ///     .is_err()
66    /// );
67    /// # Ok(())
68    /// # }
69    /// ```
70    pub fn new(metrics_user: SystemWideUserId, operator_users: Vec<UserId>) -> Result<Self, Error> {
71        // prevent duplicate metrics and operator users
72        if operator_users.contains(&metrics_user.clone().into()) {
73            return Err(crate::ConfigError::MetricsAlsoOperator { metrics_user }.into());
74        }
75
76        Ok(Self {
77            metrics_user,
78            operator_users,
79        })
80    }
81
82    /// Returns all tracked [`UserId`]s of the [`NetHsmMetricsUsers`]
83    ///
84    /// # Examples
85    ///
86    /// ```
87    /// use nethsm::UserId;
88    /// use signstar_config::NetHsmMetricsUsers;
89    ///
90    /// # fn main() -> testresult::TestResult {
91    /// let nethsm_metrics_users = NetHsmMetricsUsers::new(
92    ///     "metrics1".parse()?,
93    ///     vec!["user1".parse()?, "user2".parse()?],
94    /// )?;
95    ///
96    /// assert_eq!(
97    ///     nethsm_metrics_users.get_users(),
98    ///     vec![
99    ///         UserId::new("metrics1".to_string())?,
100    ///         UserId::new("user1".to_string())?,
101    ///         UserId::new("user2".to_string())?
102    ///     ]
103    /// );
104    /// # Ok(())
105    /// # }
106    /// ```
107    pub fn get_users(&self) -> Vec<UserId> {
108        [
109            vec![self.metrics_user.clone().into()],
110            self.operator_users.clone(),
111        ]
112        .concat()
113    }
114
115    /// Returns all tracked [`UserId`]s and their respective [`UserRole`].
116    ///
117    /// # Examples
118    ///
119    /// ```
120    /// use nethsm::{UserId, UserRole};
121    /// use signstar_config::NetHsmMetricsUsers;
122    ///
123    /// # fn main() -> testresult::TestResult {
124    /// let nethsm_metrics_users = NetHsmMetricsUsers::new(
125    ///     "metrics1".parse()?,
126    ///     vec!["user1".parse()?, "user2".parse()?],
127    /// )?;
128    ///
129    /// assert_eq!(
130    ///     nethsm_metrics_users.get_users_and_roles(),
131    ///     vec![
132    ///         (UserId::new("metrics1".to_string())?, UserRole::Metrics),
133    ///         (UserId::new("user1".to_string())?, UserRole::Operator),
134    ///         (UserId::new("user2".to_string())?, UserRole::Operator)
135    ///     ]
136    /// );
137    /// # Ok(())
138    /// # }
139    /// ```
140    pub fn get_users_and_roles(&self) -> Vec<(UserId, UserRole)> {
141        [
142            vec![(self.metrics_user.clone().into(), UserRole::Metrics)],
143            self.operator_users
144                .iter()
145                .map(|user| (user.clone(), UserRole::Operator))
146                .collect(),
147        ]
148        .concat()
149    }
150}
151
152#[cfg(test)]
153mod tests {
154    use testresult::TestResult;
155
156    use super::*;
157
158    #[test]
159    fn nethsm_metrics_users_succeeds() -> TestResult {
160        NetHsmMetricsUsers::new(
161            SystemWideUserId::new("metrics".to_string())?,
162            vec![
163                UserId::new("operator".to_string())?,
164                UserId::new("ns1~operator".to_string())?,
165            ],
166        )?;
167        Ok(())
168    }
169
170    #[test]
171    fn nethsm_metrics_users_fails() -> TestResult {
172        if let Ok(user) = NetHsmMetricsUsers::new(
173            SystemWideUserId::new("metrics".to_string())?,
174            vec![
175                UserId::new("metrics".to_string())?,
176                UserId::new("ns1~operator".to_string())?,
177            ],
178        ) {
179            panic!("Succeeded creating a NetHsmMetricsUsers, but should have failed:\n{user:?}")
180        }
181        Ok(())
182    }
183}