use std::collections::HashMap;
use secrecy::SecretString;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
use crate::constraints::Constraint;
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum TenantMode {
RootOnly,
#[default]
Subtree,
}
#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum BarrierMode {
#[default]
Respect,
Ignore,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum Capability {
TenantHierarchy,
GroupMembership,
GroupHierarchy,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DenyReason {
pub error_code: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub details: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EvaluationRequest {
pub subject: Subject,
pub action: Action,
pub resource: Resource,
pub context: EvaluationRequestContext,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[allow(clippy::struct_field_names)] pub struct Subject {
pub id: Uuid,
#[serde(rename = "type", default, skip_serializing_if = "Option::is_none")]
pub subject_type: Option<String>,
#[serde(default)]
pub properties: HashMap<String, serde_json::Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Action {
pub name: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[allow(clippy::struct_field_names)] pub struct Resource {
#[serde(rename = "type")]
pub resource_type: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub id: Option<Uuid>,
#[serde(default)]
pub properties: HashMap<String, serde_json::Value>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct TenantContext {
#[serde(default)]
pub mode: TenantMode,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub root_id: Option<Uuid>,
#[serde(default)]
pub barrier_mode: BarrierMode,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub tenant_status: Option<Vec<String>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[allow(clippy::struct_field_names)] pub struct EvaluationRequestContext {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub tenant_context: Option<TenantContext>,
#[serde(default)]
pub token_scopes: Vec<String>,
#[serde(default)]
pub require_constraints: bool,
#[serde(default)]
pub capabilities: Vec<Capability>,
#[serde(default)]
pub supported_properties: Vec<String>,
#[serde(skip)]
pub bearer_token: Option<SecretString>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct EvaluationResponseContext {
#[serde(default)]
pub constraints: Vec<Constraint>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub deny_reason: Option<DenyReason>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EvaluationResponse {
pub decision: bool,
#[serde(default)]
pub context: EvaluationResponseContext,
}