use axum::{ extract::Request, http::StatusCode, middleware::Next, response::Response, }; use axum_login::AuthSession; use tower_sessions::Session; use crate::auth::AuthBackend; pub async fn require_admin( auth_session: AuthSession, request: Request, next: Next, ) -> Result { let user = auth_session.user.ok_or(StatusCode::UNAUTHORIZED)?; if !user.is_admin { return Err(StatusCode::FORBIDDEN); } Ok(next.run(request).await) } pub async fn require_family_access( session: Session, request: Request, next: Next, ) -> Result { let path = request.uri().path(); let family_id = extract_family_id_from_path(path) .ok_or(StatusCode::BAD_REQUEST)?; let authorized_families: Vec = session .get("authorized_families") .await .unwrap_or(None) .unwrap_or_default(); if !authorized_families.contains(&family_id) { return Err(StatusCode::FORBIDDEN); } Ok(next.run(request).await) } fn extract_family_id_from_path(path: &str) -> Option { let segments: Vec<&str> = path.split('/').collect(); if let Some(families_idx) = segments.iter().position(|&s| s == "families") { if families_idx + 1 < segments.len() { return segments[families_idx + 1].parse::().ok(); } } None }