redfish_axum/
session_collection.rs

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