redfish_core/
privilege.rs

1use redfish_codegen::models::privileges::PrivilegeType;
2use std::marker::PhantomData;
3
4/// The privileges called out in the Redfish specification.
5#[derive(Clone, Copy, PartialEq, Eq, Hash, strum::EnumIter, strum::Display, strum::EnumString)]
6#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7pub enum Privilege {
8    Login,
9    ConfigureComponents,
10    ConfigureManager,
11    ConfigureSelf,
12    ConfigureUsers,
13}
14
15impl From<Privilege> for PrivilegeType {
16    fn from(value: Privilege) -> Self {
17        match value {
18            Privilege::Login => PrivilegeType::Login,
19            Privilege::ConfigureComponents => PrivilegeType::ConfigureComponents,
20            Privilege::ConfigureManager => PrivilegeType::ConfigureManager,
21            Privilege::ConfigureSelf => PrivilegeType::ConfigureSelf,
22            Privilege::ConfigureUsers => PrivilegeType::ConfigureUsers,
23        }
24    }
25}
26
27pub trait SatisfiesPrivilege {
28    fn is_satisfied(privileges: &[Privilege]) -> bool;
29}
30
31/// The Login privilege.
32#[derive(Clone, Default)]
33pub struct Login;
34impl SatisfiesPrivilege for Login {
35    fn is_satisfied(privileges: &[Privilege]) -> bool {
36        privileges.contains(&Privilege::Login)
37    }
38}
39
40/// The ConfigureManager privilege.
41#[derive(Clone, Default)]
42pub struct ConfigureManager;
43impl SatisfiesPrivilege for ConfigureManager {
44    fn is_satisfied(privileges: &[Privilege]) -> bool {
45        privileges.contains(&Privilege::ConfigureManager)
46    }
47}
48
49/// The ConfigureUsers privilege.
50#[derive(Clone, Default)]
51pub struct ConfigureUsers;
52impl SatisfiesPrivilege for ConfigureUsers {
53    fn is_satisfied(privileges: &[Privilege]) -> bool {
54        privileges.contains(&Privilege::ConfigureUsers)
55    }
56}
57
58/// The ConfigureComponents privilege.
59#[derive(Clone, Default)]
60pub struct ConfigureComponents;
61impl SatisfiesPrivilege for ConfigureComponents {
62    fn is_satisfied(privileges: &[Privilege]) -> bool {
63        privileges.contains(&Privilege::ConfigureComponents)
64    }
65}
66
67/// The ConfigureSelf privilege.
68#[derive(Clone, Default)]
69pub struct ConfigureSelf;
70impl SatisfiesPrivilege for ConfigureSelf {
71    fn is_satisfied(privileges: &[Privilege]) -> bool {
72        privileges.contains(&Privilege::ConfigureSelf)
73    }
74}
75
76/// This struct can be used to disable authentication and authorization for a Redfish service.
77#[derive(Clone, Default)]
78pub struct NoAuth;
79impl SatisfiesPrivilege for NoAuth {
80    fn is_satisfied(_privileges: &[Privilege]) -> bool {
81        true
82    }
83}
84
85/// A combinator that requires both privileges to be satisfied.
86#[derive(Clone)]
87pub struct And<P, R>(PhantomData<fn() -> (P, R)>)
88where
89    P: SatisfiesPrivilege + Clone,
90    R: SatisfiesPrivilege + Clone;
91impl<P, R> SatisfiesPrivilege for And<P, R>
92where
93    P: SatisfiesPrivilege + Clone,
94    R: SatisfiesPrivilege + Clone,
95{
96    fn is_satisfied(privileges: &[Privilege]) -> bool {
97        P::is_satisfied(privileges) && R::is_satisfied(privileges)
98    }
99}
100
101/// A combinator that requires at least one privilege to be satisfied.
102#[derive(Clone)]
103pub struct Or<P, R>(PhantomData<fn() -> (P, R)>)
104where
105    P: SatisfiesPrivilege + Clone,
106    R: SatisfiesPrivilege + Clone;
107impl<P, R> SatisfiesPrivilege for Or<P, R>
108where
109    P: SatisfiesPrivilege + Clone,
110    R: SatisfiesPrivilege + Clone,
111{
112    fn is_satisfied(privileges: &[Privilege]) -> bool {
113        P::is_satisfied(privileges) || R::is_satisfied(privileges)
114    }
115}
116
117/// The standard roles defined in the Redfish specification.
118#[derive(Clone, Copy, PartialEq, Eq, Hash, strum::EnumIter, strum::Display, strum::EnumString)]
119#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
120pub enum Role {
121    /// Administrators have sufficient privilege to perform any operation.
122    Administrator,
123    /// Operators have all the privileges of ReadOnly users, plus the ConfigureComponents
124    /// privilege.
125    Operator,
126    /// ReadOnly users have only the Login and ConfigureSelf privileges.
127    ReadOnly,
128}
129
130impl Role {
131    pub fn privileges(&self) -> Vec<Privilege> {
132        match &self {
133            Self::Administrator => vec![
134                Privilege::Login,
135                Privilege::ConfigureManager,
136                Privilege::ConfigureUsers,
137                Privilege::ConfigureComponents,
138                Privilege::ConfigureSelf,
139            ],
140            Self::Operator => vec![
141                Privilege::Login,
142                Privilege::ConfigureComponents,
143                Privilege::ConfigureSelf,
144            ],
145            Self::ReadOnly => vec![Privilege::Login, Privilege::ConfigureSelf],
146        }
147    }
148}
149
150/// This trait maps HTTP verbs to required privileges and/or privilege combinators.
151pub trait OperationPrivilegeMapping {
152    type Get: SatisfiesPrivilege;
153    type Head: SatisfiesPrivilege;
154    type Post: SatisfiesPrivilege;
155    type Put: SatisfiesPrivilege;
156    type Patch: SatisfiesPrivilege;
157    type Delete: SatisfiesPrivilege;
158}