Files
imphnen-backend-service/imphnen-iam/src/v1/permissions/permissions_guard.rs
T

61 lines
1.7 KiB
Rust
Raw Normal View History

2025-04-02 09:35:37 +07:00
use super::PermissionsEnum;
use crate::{AppState, common_response, decode_access_token, UsersRepository};
2025-04-02 09:35:37 +07:00
use axum::{
http::{HeaderMap, StatusCode},
response::Response, Extension,
2025-04-02 09:35:37 +07:00
};
use axum_extra::headers::{authorization::Bearer, Authorization, HeaderMapExt};
2025-04-02 09:35:37 +07:00
pub async fn permissions_guard(
headers: HeaderMap,
Extension(state): Extension<AppState>,
2025-04-02 09:35:37 +07:00
required_permissions: Vec<PermissionsEnum>,
) -> Result<(imphnen_libs::jsonwebtoken::Claims, AppState), Response> {
let auth_header = headers
.typed_get::<Authorization<Bearer>>()
.ok_or_else(|| {
common_response(
StatusCode::UNAUTHORIZED,
"Invalid or missing authorization token",
)
})?;
let token = auth_header.token();
let claims = decode_access_token(token)
2025-04-02 09:35:37 +07:00
.map_err(|_| {
common_response(
StatusCode::UNAUTHORIZED,
"Invalid or expired token",
2025-04-02 09:35:37 +07:00
)
})?
.claims;
// Fetch user from database to get permissions
let user_repo = UsersRepository::new(&state);
let user = match user_repo.query_user_by_email(claims.sub.clone()).await {
Ok(user) => user,
Err(_) => {
return Err(common_response(
StatusCode::UNAUTHORIZED,
"User not found",
));
}
};
// Check permissions from database
let user_permissions: Vec<String> = user.role.permissions.as_ref().unwrap_or(&vec![]).iter().filter_map(|p| p.as_ref().and_then(|pp| pp.name.clone())).collect();
for required in &required_permissions {
let required_str = required.to_string();
if !user_permissions.contains(&required_str) {
eprintln!(" MISSING REQUIRED PERMISSION: {required_str}");
return Err(common_response(
StatusCode::FORBIDDEN,
"You don't have the required permissions",
));
}
2025-04-02 09:35:37 +07:00
}
Ok((claims, state))
2025-04-02 09:35:37 +07:00
}