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