60 lines
1.4 KiB
Rust
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
|
|
}
|