haste_server/auth_n/middleware/
project_access.rs1use crate::{
2 auth_n::middleware::jwt::User,
3 extract::path_tenant::{ProjectIdentifier, TenantIdentifier},
4};
5use axum::{Extension, extract::Request, middleware::Next, response::Response};
6use axum_extra::extract::Cached;
7use haste_fhir_model::r4::generated::terminology::IssueType;
8use haste_fhir_operation_error::OperationOutcomeError;
9use std::sync::Arc;
10
11pub async fn project_access(
12 Cached(TenantIdentifier { tenant }): Cached<TenantIdentifier>,
13 Cached(ProjectIdentifier { project }): Cached<ProjectIdentifier>,
14 Extension(user): Extension<Arc<User>>,
16 request: Request,
20 next: Next,
21) -> Result<Response, OperationOutcomeError> {
22 if user.claims.tenant != tenant {
23 return Err(OperationOutcomeError::error(
24 IssueType::Forbidden(None),
25 format!("User does not have access to tenant '{}'.", tenant),
26 ));
27 }
28
29 let Some(user_project) = &user.claims.project else {
30 return Err(OperationOutcomeError::error(
31 IssueType::Forbidden(None),
32 format!("User does not have access to project '{}'.", project),
33 ));
34 };
35
36 if user_project != &project {
37 return Err(OperationOutcomeError::error(
38 IssueType::Forbidden(None),
39 format!("User does not have access to project '{}'.", project),
40 ));
41 }
42
43 Ok(next.run(request).await)
44}