2025-04-02 09:35:37 +07:00
|
|
|
use super::PermissionsEnum;
|
2025-09-22 07:52:00 +07:00
|
|
|
use crate::{AppState, common_response, decode_access_token, UsersRepository};
|
2025-04-02 09:35:37 +07:00
|
|
|
use axum::{
|
|
|
|
|
http::{HeaderMap, StatusCode},
|
2025-08-14 22:46:42 +07:00
|
|
|
response::Response, Extension,
|
2025-04-02 09:35:37 +07:00
|
|
|
};
|
2025-08-14 22:46:42 +07:00
|
|
|
use axum_extra::headers::{authorization::Bearer, Authorization, HeaderMapExt};
|
2025-04-02 09:35:37 +07:00
|
|
|
|
|
|
|
|
pub async fn permissions_guard(
|
2025-08-14 22:46:42 +07:00
|
|
|
headers: HeaderMap,
|
|
|
|
|
Extension(state): Extension<AppState>,
|
2025-04-02 09:35:37 +07:00
|
|
|
required_permissions: Vec<PermissionsEnum>,
|
2025-08-14 23:11:44 +07:00
|
|
|
) -> Result<(imphnen_libs::jsonwebtoken::Claims, AppState), Response> {
|
2025-08-14 22:46:42 +07:00
|
|
|
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,
|
2025-08-14 22:46:42 +07:00
|
|
|
"Invalid or expired token",
|
2025-04-02 09:35:37 +07:00
|
|
|
)
|
2025-08-14 22:46:42 +07:00
|
|
|
})?
|
|
|
|
|
.claims;
|
2025-07-21 21:29:04 +07:00
|
|
|
|
2025-09-22 07:52:00 +07:00
|
|
|
// 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
|
2025-09-26 01:08:18 +07:00
|
|
|
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();
|
2025-07-21 21:29:04 +07:00
|
|
|
for required in &required_permissions {
|
|
|
|
|
let required_str = required.to_string();
|
2025-09-22 07:52:00 +07:00
|
|
|
if !user_permissions.contains(&required_str) {
|
2025-07-21 21:29:04 +07:00
|
|
|
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
|
|
|
}
|
2025-08-14 22:46:42 +07:00
|
|
|
|
2025-08-14 23:11:44 +07:00
|
|
|
Ok((claims, state))
|
2025-04-02 09:35:37 +07:00
|
|
|
}
|