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)]
52pub struct UserInfo {
53    pub id: String,
54}
55
56#[derive(Debug)]
57pub struct PolicyEnvironment {
58    pub tenant: TenantId,
59    pub project: ProjectId,
60    pub request: Arc<RequestReflection>,
61    pub user: Arc<UserInfo>,
62}
63
64impl PolicyEnvironment {
65    pub fn new(
66        tenant: TenantId,
67        project: ProjectId,
68        request: FHIRRequest,
69        user: Arc<UserInfo>,
70    ) -> Self {
71        Self {
72            tenant,
73            project,
74            request: Arc::new(RequestReflection::from(request)),
75            user,
76        }
77    }
78}
79
80pub struct PolicyContext<CTX, Client: FHIRClient<CTX, OperationOutcomeError>> {
81    pub fp_engine: haste_fhirpath::FPEngine,
82    pub client: Arc<Client>,
83    pub client_context: CTX,
84
85    #[allow(dead_code)]
86    attributes_cache: HashMap<String, FHIRResponse>,
87    pub environment: PolicyEnvironment,
88}
89
90impl<CTX, Client: FHIRClient<CTX, OperationOutcomeError>> PolicyContext<CTX, Client> {
91    pub fn new(client: Arc<Client>, client_context: CTX, environment: PolicyEnvironment) -> Self {
92        Self {
93            fp_engine: FPEngine::new(),
94            client,
95            client_context,
96            attributes_cache: HashMap::new(),
97            environment,
98        }
99    }
100}