1use crate::error::AuthError;
4use crate::identity::AuthIdentity;
5use crate::state::global;
6use axum::body::Body;
7use axum::http::Request;
8use axum::middleware::Next;
9use axum::response::Response;
10
11pub async fn auth_layer(req: Request<Body>, next: Next) -> Response {
14 let state = match crate::state::try_global() {
15 Some(s) => s,
16 None => return next.run(req).await,
17 };
18
19 let (mut parts, body) = req.into_parts();
20 for strategy in &state.strategies {
21 match strategy.authenticate(&parts, &state.db).await {
22 Ok(Some(identity)) => {
23 parts.extensions.insert(identity);
24 break;
25 }
26 Ok(None) => {}
27 Err(_) => {}
28 }
29 }
30 next.run(Request::from_parts(parts, body)).await
31}
32
33pub fn current_identity(parts: &http::request::Parts) -> Option<AuthIdentity> {
35 crate::strategy::identity_from_parts(parts)
36}
37
38pub async fn current_user<U: crate::user::AuthUser>(
40 parts: &http::request::Parts,
41) -> Result<U, AuthError> {
42 let identity = crate::strategy::require_identity(parts)?;
43 let id: U::Id = serde_json::from_value(identity.user_id.clone())
44 .map_err(|e| AuthError::Internal(e.to_string()))?;
45 U::find_by_id(&global().db, id)
46 .await
47 .map_err(|e| AuthError::Internal(e.to_string()))?
48 .ok_or(AuthError::Unauthorized)
49}