Files
family_budget/backend/src/middleware.rs
2025-12-15 16:51:09 +03:00

60 lines
1.4 KiB
Rust

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<AuthBackend>,
request: Request,
next: Next,
) -> Result<Response, StatusCode> {
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<Response, StatusCode> {
let path = request.uri().path();
let family_id = extract_family_id_from_path(path)
.ok_or(StatusCode::BAD_REQUEST)?;
let authorized_families: Vec<i32> = 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<i32> {
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::<i32>().ok();
}
}
None
}