fix(health): FHIR allowed_patient_ids=None 拒绝所有访问
This commit is contained in:
@@ -70,14 +70,19 @@ pub struct FhirSearchParams {
|
||||
|
||||
/// 检查单个 patient_id 是否在 OAuth 客户端的允许范围内
|
||||
fn enforce_patient_scope(fhir_ctx: &FhirAuthContext, patient_id: Uuid) -> Result<(), AppError> {
|
||||
if let Some(ref allowed) = fhir_ctx.allowed_patient_ids {
|
||||
if !allowed.iter().any(|id| id == &patient_id.to_string()) {
|
||||
tracing::warn!(
|
||||
client_id = %fhir_ctx.client_id,
|
||||
requested_patient = %patient_id,
|
||||
"FHIR 客户端尝试访问授权范围外的患者"
|
||||
);
|
||||
return Err(AppError::Forbidden("Access denied: patient not in allowed scope".into()));
|
||||
match &fhir_ctx.allowed_patient_ids {
|
||||
Some(allowed) if !allowed.is_empty() => {
|
||||
if !allowed.iter().any(|id| id == &patient_id.to_string()) {
|
||||
tracing::warn!(
|
||||
client_id = %fhir_ctx.client_id,
|
||||
requested_patient = %patient_id,
|
||||
"FHIR 客户端尝试访问授权范围外的患者"
|
||||
);
|
||||
return Err(AppError::Forbidden("Access denied: patient not in allowed scope".into()));
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(AppError::Forbidden("OAuth client has no patient access configured".into()));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
@@ -751,3 +756,59 @@ pub async fn patient_everything(
|
||||
"entry": entries,
|
||||
})))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::oauth::middleware::FhirAuthContext;
|
||||
|
||||
fn default_fhir_ctx() -> FhirAuthContext {
|
||||
FhirAuthContext {
|
||||
client_id: Uuid::now_v7(),
|
||||
tenant_id: Uuid::now_v7(),
|
||||
scopes: vec!["patient/*.read".to_string()],
|
||||
allowed_patient_ids: None,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_enforce_patient_scope_none_is_denied() {
|
||||
let fhir_ctx = FhirAuthContext {
|
||||
allowed_patient_ids: None,
|
||||
..default_fhir_ctx()
|
||||
};
|
||||
let result = enforce_patient_scope(&fhir_ctx, Uuid::now_v7());
|
||||
assert!(result.is_err(), "None should deny all access");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_enforce_patient_scope_empty_vec_is_denied() {
|
||||
let fhir_ctx = FhirAuthContext {
|
||||
allowed_patient_ids: Some(vec![]),
|
||||
..default_fhir_ctx()
|
||||
};
|
||||
let result = enforce_patient_scope(&fhir_ctx, Uuid::now_v7());
|
||||
assert!(result.is_err(), "Empty list should deny all access");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_enforce_patient_scope_allowed_access() {
|
||||
let patient_id = Uuid::now_v7();
|
||||
let fhir_ctx = FhirAuthContext {
|
||||
allowed_patient_ids: Some(vec![patient_id.to_string()]),
|
||||
..default_fhir_ctx()
|
||||
};
|
||||
let result = enforce_patient_scope(&fhir_ctx, patient_id);
|
||||
assert!(result.is_ok(), "Patient in allowed list should succeed");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_enforce_patient_scope_wrong_patient_denied() {
|
||||
let fhir_ctx = FhirAuthContext {
|
||||
allowed_patient_ids: Some(vec![Uuid::now_v7().to_string()]),
|
||||
..default_fhir_ctx()
|
||||
};
|
||||
let result = enforce_patient_scope(&fhir_ctx, Uuid::now_v7());
|
||||
assert!(result.is_err(), "Patient not in allowed list should be denied");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user