ruest/security/
extract.rs1use async_trait::async_trait;
2use axum::extract::FromRequestParts;
3use axum::http::request::Parts;
4use crate::http::AppError;
5
6use super::claims::RuestClaims;
7use super::context::AuthContext;
8
9#[derive(Debug, Clone)]
11pub struct AuthUser(pub RuestClaims);
12
13impl AuthUser {
14 pub fn claims(&self) -> &RuestClaims {
15 &self.0
16 }
17
18 pub fn subject(&self) -> &str {
19 &self.0.sub
20 }
21
22 pub fn require_roles(&self, roles: &[&str]) -> Result<(), AppError> {
23 self.0.require_roles(roles)
24 }
25}
26
27#[async_trait]
28impl<S> FromRequestParts<S> for AuthUser
29where
30 S: Send + Sync,
31{
32 type Rejection = AppError;
33
34 async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {
35 parts
36 .extensions
37 .get::<AuthContext>()
38 .map(|ctx| AuthUser(ctx.claims.clone()))
39 .ok_or_else(|| {
40 AppError::unauthorized(
41 "not authenticated — enable .with_jwt_auth() or use a public route",
42 )
43 })
44 }
45}