redfish_axum/
key_collection.rs

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