1pub 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::ConfigureComponents;
9 type Put = redfish_core::privilege::ConfigureComponents;
10 type Patch = redfish_core::privilege::ConfigureComponents;
11 type Delete = redfish_core::privilege::ConfigureComponents;
12}
13
14pub struct EnvironmentMetricsPrivileges;
17impl redfish_core::privilege::OperationPrivilegeMapping for EnvironmentMetricsPrivileges {
18 type Get = redfish_core::privilege::Login;
19 type Head = redfish_core::privilege::Login;
20 type Post = redfish_core::privilege::ConfigureComponents;
21 type Put = redfish_core::privilege::ConfigureComponents;
22 type Patch = redfish_core::privilege::ConfigureComponents;
23 type Delete = redfish_core::privilege::ConfigureComponents;
24}
25
26pub struct Processor<S, P>
32where
33 S: Clone,
34{
35 router: axum::routing::MethodRouter<S>,
36 privilege_marker: std::marker::PhantomData<fn() -> P>,
37 allowed_methods: Vec<axum::http::method::Method>,
38 processor_metrics: Option<axum::Router<S>>,
39 acceleration_functions: Option<axum::Router<S>>,
40 certificates: Option<axum::Router<S>>,
41 environment_metrics: Option<axum::Router<S>>,
42 operating_configs: Option<axum::Router<S>>,
43 assembly: Option<axum::Router<S>>,
44 ports: Option<axum::Router<S>>,
45 sub_processors: Option<axum::Router<S>>,
46 reset: Option<axum::routing::MethodRouter<S>>,
47 reset_to_defaults: Option<axum::routing::MethodRouter<S>>,
48}
49
50impl<S> Default for Processor<S, DefaultPrivileges>
51where
52 S: Clone,
53{
54 fn default() -> Self {
55 Self {
56 router: Default::default(),
57 privilege_marker: Default::default(),
58 allowed_methods: Vec::new(),
59 processor_metrics: Default::default(),
60 acceleration_functions: Default::default(),
61 certificates: Default::default(),
62 environment_metrics: Default::default(),
63 operating_configs: Default::default(),
64 assembly: Default::default(),
65 ports: Default::default(),
66 sub_processors: Default::default(),
67 reset: Default::default(),
68 reset_to_defaults: Default::default(),
69 }
70 }
71}
72
73impl<S, P> Processor<S, P>
74where
75 S: AsRef<dyn redfish_core::auth::AuthenticateRequest> + Clone + Send + Sync + 'static,
76 P: redfish_core::privilege::OperationPrivilegeMapping + 'static,
77 <P as redfish_core::privilege::OperationPrivilegeMapping>::Get: Send,
78 <P as redfish_core::privilege::OperationPrivilegeMapping>::Put: Send,
79 <P as redfish_core::privilege::OperationPrivilegeMapping>::Patch: Send,
80 <P as redfish_core::privilege::OperationPrivilegeMapping>::Post: Send,
81{
82 pub fn get<H, T>(mut self, handler: H) -> Self
83 where
84 H: axum::handler::Handler<T, S, axum::body::Body>,
85 T: 'static,
86 {
87 let operation = axum::routing::get(
88 |auth: redfish_core::extract::RedfishAuth<P::Get>,
89 axum::extract::State(state): axum::extract::State<S>,
90 mut request: axum::http::Request<axum::body::Body>| async {
91 request.extensions_mut().insert(auth.user);
92 handler.call(request, state).await
93 },
94 );
95 self.router = self.router.get(operation);
96 self.allowed_methods.push(axum::http::method::Method::GET);
97 self
98 }
99
100 pub fn put<H, T>(mut self, handler: H) -> Self
101 where
102 H: axum::handler::Handler<T, S, axum::body::Body>,
103 T: 'static,
104 {
105 let operation = axum::routing::put(
106 |auth: redfish_core::extract::RedfishAuth<P::Put>,
107 axum::extract::State(state): axum::extract::State<S>,
108 mut request: axum::http::Request<axum::body::Body>| async {
109 request.extensions_mut().insert(auth.user);
110 handler.call(request, state).await
111 },
112 );
113 self.router = self.router.put(operation);
114 self.allowed_methods.push(axum::http::method::Method::PUT);
115 self
116 }
117
118 pub fn patch<H, T>(mut self, handler: H) -> Self
119 where
120 H: axum::handler::Handler<T, S, axum::body::Body>,
121 T: 'static,
122 {
123 let operation = axum::routing::patch(
124 |auth: redfish_core::extract::RedfishAuth<P::Patch>,
125 axum::extract::State(state): axum::extract::State<S>,
126 mut request: axum::http::Request<axum::body::Body>| async {
127 request.extensions_mut().insert(auth.user);
128 handler.call(request, state).await
129 },
130 );
131 self.router = self.router.patch(operation);
132 self.allowed_methods.push(axum::http::method::Method::PATCH);
133 self
134 }
135
136 pub fn processor_metrics(mut self, processor_metrics: axum::Router<S>) -> Self {
138 self.processor_metrics = Some(processor_metrics);
139 self
140 }
141
142 pub fn acceleration_functions(mut self, acceleration_functions: axum::Router<S>) -> Self {
144 self.acceleration_functions = Some(acceleration_functions);
145 self
146 }
147
148 pub fn certificates(mut self, certificates: axum::Router<S>) -> Self {
150 self.certificates = Some(certificates);
151 self
152 }
153
154 pub fn environment_metrics(mut self, environment_metrics: axum::Router<S>) -> Self {
156 self.environment_metrics = Some(environment_metrics);
157 self
158 }
159
160 pub fn operating_configs(mut self, operating_configs: axum::Router<S>) -> Self {
162 self.operating_configs = Some(operating_configs);
163 self
164 }
165
166 pub fn assembly(mut self, assembly: axum::Router<S>) -> Self {
168 self.assembly = Some(assembly);
169 self
170 }
171
172 pub fn ports(mut self, ports: axum::Router<S>) -> Self {
174 self.ports = Some(ports);
175 self
176 }
177
178 pub fn sub_processors(mut self, sub_processors: axum::Router<S>) -> Self {
180 self.sub_processors = Some(sub_processors);
181 self
182 }
183
184 pub fn reset<H, T>(mut self, handler: H) -> Self
186 where
187 H: axum::handler::Handler<T, S, axum::body::Body>,
188 T: 'static,
189 {
190 self.reset = Some(axum::routing::post(
191 |auth: redfish_core::extract::RedfishAuth<P::Post>,
192 axum::extract::State(state): axum::extract::State<S>,
193 mut request: axum::http::Request<axum::body::Body>| async {
194 request.extensions_mut().insert(auth.user);
195 handler.call(request, state).await
196 },
197 ));
198 self
199 }
200
201 pub fn reset_to_defaults<H, T>(mut self, handler: H) -> Self
203 where
204 H: axum::handler::Handler<T, S, axum::body::Body>,
205 T: 'static,
206 {
207 self.reset_to_defaults = Some(axum::routing::post(
208 |auth: redfish_core::extract::RedfishAuth<P::Post>,
209 axum::extract::State(state): axum::extract::State<S>,
210 mut request: axum::http::Request<axum::body::Body>| async {
211 request.extensions_mut().insert(auth.user);
212 handler.call(request, state).await
213 },
214 ));
215 self
216 }
217
218 pub fn into_router(self) -> axum::Router<S> {
219 let Self {
220 router,
221 mut allowed_methods,
222 processor_metrics,
223 acceleration_functions,
224 certificates,
225 environment_metrics,
226 operating_configs,
227 assembly,
228 ports,
229 sub_processors,
230 reset,
231 reset_to_defaults,
232 ..
233 } = self;
234 let result = axum::Router::default();
235 let result = match processor_metrics {
236 Some(router) => result.nest("/ProcessorMetrics", router),
237 None => result,
238 };
239 let result = match acceleration_functions {
240 Some(router) => result.nest("/AccelerationFunctions", router),
241 None => result,
242 };
243 let result = match certificates {
244 Some(router) => result.nest("/Certificates", router),
245 None => result,
246 };
247 let result = match environment_metrics {
248 Some(router) => result.nest("/EnvironmentMetrics", router),
249 None => result,
250 };
251 let result = match operating_configs {
252 Some(router) => result.nest("/OperatingConfigs", router),
253 None => result,
254 };
255 let result = match assembly {
256 Some(router) => result.nest("/Assembly", router),
257 None => result,
258 };
259 let result = match ports {
260 Some(router) => result.nest("/Ports", router),
261 None => result,
262 };
263 let result = match sub_processors {
264 Some(router) => result.nest("/SubProcessors", router),
265 None => result,
266 };
267 let result = match reset {
268 Some(router) => result.route("/Actions/Processor.Reset", router),
269 None => result,
270 };
271 let result = match reset_to_defaults {
272 Some(router) => result.route("/Actions/Processor.ResetToDefaults", router),
273 None => result,
274 };
275 allowed_methods.dedup();
276 let allow_header = allowed_methods
277 .into_iter()
278 .map(|method| method.to_string())
279 .reduce(|one, two| one + "," + &two)
280 .unwrap();
281 result.route(
282 "/",
283 router.fallback(|| async {
284 (
285 axum::http::StatusCode::METHOD_NOT_ALLOWED,
286 axum::Json(redfish_core::error::one_message(redfish_codegen::registries::base::v1_16_0::Base::OperationNotAllowed.into())),
287 )
288 })
289 .route_layer(axum::middleware::from_fn_with_state(
290 allow_header,
291 |axum::extract::State(allow_header): axum::extract::State<String>,
292 request: axum::http::Request<axum::body::Body>,
293 next: axum::middleware::Next<axum::body::Body>| async move {
294 let apply_allow = matches!(*request.method(), axum::http::Method::GET | axum::http::Method::HEAD);
295 let mut response = next.run(request).await;
296 if apply_allow && !response.headers().contains_key(axum::http::header::ALLOW) {
297 response.headers_mut().insert(
298 axum::http::header::ALLOW,
299 axum::http::HeaderValue::from_str(&allow_header).unwrap(),
300 );
301 }
302 response
303 },
304 )),
305 )
306 }
307}