Skip to main content

haste_access_control/
context.rs

1use 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}