use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use serde_json::Value;
pub type Attributes = HashMap<String, Value>;
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
pub struct Subject {
pub id: String,
pub roles: Vec<String>,
pub attributes: Attributes,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
pub struct Resource {
pub resource_type: String,
pub id: String,
pub attributes: Attributes,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
pub struct Request {
pub subject: Subject,
pub resource: Resource,
pub action: String,
pub context: Attributes,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Permission {
pub resource: String,
pub action: String,
#[serde(default)]
pub conditions: Vec<Condition>,
}
impl Permission {
#[must_use]
pub fn matches(&self, resource: &str, action: &str) -> bool {
crate::matcher::match_pattern(&self.resource, resource)
&& crate::matcher::match_pattern(&self.action, action)
}
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
pub struct Role {
pub name: String,
pub inherits: Vec<String>,
pub permissions: Vec<Permission>,
}
#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub enum Effect {
Allow,
#[default]
Deny,
}
#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub enum AttributeSource {
#[default]
Subject,
Resource,
Context,
}
#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub enum Operator {
#[default]
Equals,
NotEquals,
OneOf,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
pub struct Condition {
pub source: AttributeSource,
pub key: String,
pub operator: Operator,
pub values: Vec<Value>,
pub compare_source: Option<AttributeSource>,
pub compare_key: Option<String>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
pub struct Policy {
pub name: String,
pub effect: Effect,
pub actions: Vec<String>,
pub resources: Vec<String>,
pub conditions: Vec<Condition>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Decision {
pub allowed: bool,
pub reason: String,
}