redfish_core/
extract.rs

1use crate::{
2    auth::{unauthorized, AuthenticateRequest, AuthenticatedUser},
3    privilege::SatisfiesPrivilege,
4};
5use axum::{async_trait, extract::FromRequestParts, http::request::Parts, response::Response};
6use std::marker::PhantomData;
7
8pub struct RedfishAuth<T: SatisfiesPrivilege> {
9    pub user: Option<AuthenticatedUser>,
10    privilege: PhantomData<T>,
11}
12
13#[async_trait]
14impl<S, T> FromRequestParts<S> for RedfishAuth<T>
15where
16    S: AsRef<dyn AuthenticateRequest> + Send + Sync + Clone + 'static,
17    T: SatisfiesPrivilege,
18{
19    type Rejection = Response;
20
21    async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {
22        match state.as_ref().authenticate_request(parts) {
23            Ok(Some(user)) => {
24                if T::is_satisfied(&user.role.privileges()) {
25                    Ok(RedfishAuth::<T> {
26                        user: Some(user),
27                        privilege: Default::default(),
28                    })
29                } else {
30                    Err(unauthorized(&state.as_ref().challenge()))
31                }
32            }
33            Ok(None) => Ok(RedfishAuth::<T> {
34                user: None,
35                privilege: Default::default(),
36            }),
37            Err(error) => Err(error),
38        }
39    }
40}