haste_access_control/
context.rs1use crate::request_reflection::RequestReflection;
2use haste_fhir_client::{
3 FHIRClient,
4 request::{FHIRRequest, FHIRResponse},
5};
6use haste_fhir_operation_error::{OperationOutcomeError, derive::OperationOutcomeError};
7use haste_fhirpath::FPEngine;
8use haste_jwt::{ProjectId, TenantId};
9use haste_reflect::{MetaValue, derive::Reflect};
10use std::{collections::HashMap, sync::Arc};
11
12#[derive(PartialEq, Eq, Debug)]
13pub enum PermissionLevel {
14 Deny,
15 Undetermined,
16 Allow,
17}
18
19impl From<&PermissionLevel> for i8 {
20 fn from(level: &PermissionLevel) -> Self {
21 match level {
22 PermissionLevel::Deny => -1,
23 PermissionLevel::Undetermined => 0,
24 PermissionLevel::Allow => 1,
25 }
26 }
27}
28
29#[derive(Debug, OperationOutcomeError)]
30pub enum PermissionLevelError {
31 #[error(
32 code = "invalid",
33 diagnostic = "Invalid permission level value: '{arg0}'."
34 )]
35 InvalidPermissionLevel(i8),
36}
37
38impl TryFrom<i8> for PermissionLevel {
39 type Error = PermissionLevelError;
40
41 fn try_from(value: i8) -> Result<Self, Self::Error> {
42 match value {
43 -1 => Ok(PermissionLevel::Deny),
44 0 => Ok(PermissionLevel::Undetermined),
45 1 => Ok(PermissionLevel::Allow),
46 _ => Err(PermissionLevelError::InvalidPermissionLevel(value)),
47 }
48 }
49}
50
51#[derive(Debug, Reflect)]
52#[fhir_type = "BackboneElement"]
53pub struct UserInfo {
54 pub id: String,
55}
56
57#[derive(Debug)]
58pub struct PolicyEnvironment {
59 pub tenant: TenantId,
60 pub project: ProjectId,
61 pub request: Arc<RequestReflection>,
62 pub user: Arc<UserInfo>,
63}
64
65impl PolicyEnvironment {
66 pub fn new(
67 tenant: TenantId,
68 project: ProjectId,
69 request: FHIRRequest,
70 user: Arc<UserInfo>,
71 ) -> Self {
72 Self {
73 tenant,
74 project,
75 request: Arc::new(RequestReflection::from(request)),
76 user,
77 }
78 }
79}
80
81pub struct PolicyContext<CTX, Client: FHIRClient<CTX, OperationOutcomeError>> {
82 pub fp_engine: haste_fhirpath::FPEngine,
83 pub client: Arc<Client>,
84 pub client_context: CTX,
85
86 #[allow(dead_code)]
87 attributes_cache: HashMap<String, FHIRResponse>,
88 pub environment: PolicyEnvironment,
89}
90
91impl<CTX, Client: FHIRClient<CTX, OperationOutcomeError>> PolicyContext<CTX, Client> {
92 pub fn new(client: Arc<Client>, client_context: CTX, environment: PolicyEnvironment) -> Self {
93 Self {
94 fp_engine: FPEngine::new(),
95 client,
96 client_context,
97 attributes_cache: HashMap::new(),
98 environment,
99 }
100 }
101}