//! Auth context — the current authenticated user and their roles/permissions. /// The authenticated user. #[derive(Debug, Clone)] pub struct AuthUser { pub id: String, pub email: String, pub name: String, } impl AuthUser { pub fn new( id: impl Into, email: impl Into, name: impl Into, ) -> Self { Self { id: id.into(), email: email.into(), name: name.into(), } } } /// The auth context — populated by `AuthMiddleware` and available to all /// components and services downstream in the request. /// /// Passed as `ctx.metadata["user_id"]`, `ctx.metadata["roles"]` in the AOP /// layer (see `el-aop`). #[derive(Debug, Clone)] pub struct AuthContext { pub user: Option, pub roles: Vec, pub permissions: Vec, /// The raw token/session ID that was verified. pub token: String, } impl AuthContext { pub fn anonymous() -> Self { Self { user: None, roles: Vec::new(), permissions: Vec::new(), token: String::new(), } } pub fn authenticated(user: AuthUser, roles: Vec, token: impl Into) -> Self { Self { user: Some(user), roles, permissions: Vec::new(), token: token.into(), } } pub fn with_permissions(mut self, perms: Vec) -> Self { self.permissions = perms; self } pub fn is_authenticated(&self) -> bool { self.user.is_some() } pub fn has_role(&self, role: &str) -> bool { self.roles.iter().any(|r| r == role) } pub fn has_permission(&self, permission: &str) -> bool { self.permissions.iter().any(|p| p == permission) } pub fn user_id(&self) -> Option<&str> { self.user.as_ref().map(|u| u.id.as_str()) } }