redfish_axum/
control.rs

1// Generated by redfish-codegen. Do not modify.
2
3/// The default privileges required for accessing Control instances.
4pub struct DefaultPrivileges;
5impl redfish_core::privilege::OperationPrivilegeMapping for DefaultPrivileges {
6    type Get = redfish_core::privilege::Login;
7    type Head = redfish_core::privilege::Login;
8    type Post = redfish_core::privilege::ConfigureManager;
9    type Put = redfish_core::privilege::ConfigureManager;
10    type Patch = redfish_core::privilege::ConfigureManager;
11    type Delete = redfish_core::privilege::ConfigureManager;
12}
13
14/// This endpoint implements the Control component.
15///
16/// It can be mounted on the following components:
17/// * [ControlCollection][crate::control_collection::ControlCollection]
18pub struct Control<S, P>
19where
20    S: Clone,
21{
22    router: axum::routing::MethodRouter<S>,
23    privilege_marker: std::marker::PhantomData<fn() -> P>,
24    allowed_methods: Vec<axum::http::method::Method>,
25    reset_to_defaults: Option<axum::routing::MethodRouter<S>>,
26}
27
28impl<S> Default for Control<S, DefaultPrivileges>
29where
30    S: Clone,
31{
32    fn default() -> Self {
33        Self {
34            router: Default::default(),
35            privilege_marker: Default::default(),
36            allowed_methods: Vec::new(),
37            reset_to_defaults: Default::default(),
38        }
39    }
40}
41
42impl<S, P> Control<S, P>
43where
44    S: AsRef<dyn redfish_core::auth::AuthenticateRequest> + Clone + Send + Sync + 'static,
45    P: redfish_core::privilege::OperationPrivilegeMapping + 'static,
46    <P as redfish_core::privilege::OperationPrivilegeMapping>::Get: Send,
47    <P as redfish_core::privilege::OperationPrivilegeMapping>::Put: Send,
48    <P as redfish_core::privilege::OperationPrivilegeMapping>::Patch: Send,
49    <P as redfish_core::privilege::OperationPrivilegeMapping>::Post: Send,
50{
51    pub fn get<H, T>(mut self, handler: H) -> Self
52    where
53        H: axum::handler::Handler<T, S, axum::body::Body>,
54        T: 'static,
55    {
56        let operation = axum::routing::get(
57            |auth: redfish_core::extract::RedfishAuth<P::Get>,
58             axum::extract::State(state): axum::extract::State<S>,
59             mut request: axum::http::Request<axum::body::Body>| async {
60                request.extensions_mut().insert(auth.user);
61                handler.call(request, state).await
62            },
63        );
64        self.router = self.router.get(operation);
65        self.allowed_methods.push(axum::http::method::Method::GET);
66        self
67    }
68
69    pub fn put<H, T>(mut self, handler: H) -> Self
70    where
71        H: axum::handler::Handler<T, S, axum::body::Body>,
72        T: 'static,
73    {
74        let operation = axum::routing::put(
75            |auth: redfish_core::extract::RedfishAuth<P::Put>,
76             axum::extract::State(state): axum::extract::State<S>,
77             mut request: axum::http::Request<axum::body::Body>| async {
78                request.extensions_mut().insert(auth.user);
79                handler.call(request, state).await
80            },
81        );
82        self.router = self.router.put(operation);
83        self.allowed_methods.push(axum::http::method::Method::PUT);
84        self
85    }
86
87    pub fn patch<H, T>(mut self, handler: H) -> Self
88    where
89        H: axum::handler::Handler<T, S, axum::body::Body>,
90        T: 'static,
91    {
92        let operation = axum::routing::patch(
93            |auth: redfish_core::extract::RedfishAuth<P::Patch>,
94             axum::extract::State(state): axum::extract::State<S>,
95             mut request: axum::http::Request<axum::body::Body>| async {
96                request.extensions_mut().insert(auth.user);
97                handler.call(request, state).await
98            },
99        );
100        self.router = self.router.patch(operation);
101        self.allowed_methods.push(axum::http::method::Method::PATCH);
102        self
103    }
104
105    /// Perform the ResetToDefaults operation on this Control instance.
106    pub fn reset_to_defaults<H, T>(mut self, handler: H) -> Self
107    where
108        H: axum::handler::Handler<T, S, axum::body::Body>,
109        T: 'static,
110    {
111        self.reset_to_defaults = Some(axum::routing::post(
112            |auth: redfish_core::extract::RedfishAuth<P::Post>,
113             axum::extract::State(state): axum::extract::State<S>,
114             mut request: axum::http::Request<axum::body::Body>| async {
115                request.extensions_mut().insert(auth.user);
116                handler.call(request, state).await
117            },
118        ));
119        self
120    }
121
122    pub fn into_router(self) -> axum::Router<S> {
123        let Self {
124            router,
125            mut allowed_methods,
126            reset_to_defaults,
127            ..
128        } = self;
129        let result = axum::Router::default();
130        let result = match reset_to_defaults {
131            Some(router) => result.route("/Actions/Control.ResetToDefaults", router),
132            None => result,
133        };
134        allowed_methods.dedup();
135        let allow_header = allowed_methods
136            .into_iter()
137            .map(|method| method.to_string())
138            .reduce(|one, two| one + "," + &two)
139            .unwrap();
140        result.route(
141            "/",
142            router.fallback(|| async {
143                (
144                    axum::http::StatusCode::METHOD_NOT_ALLOWED,
145                    axum::Json(redfish_core::error::one_message(redfish_codegen::registries::base::v1_16_0::Base::OperationNotAllowed.into())),
146                )
147            })
148            .route_layer(axum::middleware::from_fn_with_state(
149                allow_header,
150                |axum::extract::State(allow_header): axum::extract::State<String>,
151                 request: axum::http::Request<axum::body::Body>,
152                 next: axum::middleware::Next<axum::body::Body>| async move {
153                    let apply_allow = matches!(*request.method(), axum::http::Method::GET | axum::http::Method::HEAD);
154                    let mut response = next.run(request).await;
155                    if apply_allow && !response.headers().contains_key(axum::http::header::ALLOW) {
156                        response.headers_mut().insert(
157                            axum::http::header::ALLOW,
158                            axum::http::HeaderValue::from_str(&allow_header).unwrap(),
159                        );
160                    }
161                    response
162                },
163            )),
164        )
165    }
166}