use std::collections::HashMap;
use super::{PermissionDecision, PermissionPolicy};
#[derive(Debug, Default, Clone)]
pub struct MatchingRules {
pub deny: Vec<String>,
pub allow: Vec<String>,
pub ask: Vec<String>,
}
impl MatchingRules {
pub fn is_empty(&self) -> bool {
self.deny.is_empty() && self.allow.is_empty() && self.ask.is_empty()
}
}
#[derive(Debug)]
pub struct PermissionManager {
global_policy: PermissionPolicy,
session_policies: HashMap<String, PermissionPolicy>,
}
impl Default for PermissionManager {
fn default() -> Self {
Self::new()
}
}
impl PermissionManager {
pub fn new() -> Self {
Self {
global_policy: PermissionPolicy::default(),
session_policies: HashMap::new(),
}
}
pub fn with_global_policy(policy: PermissionPolicy) -> Self {
Self {
global_policy: policy,
session_policies: HashMap::new(),
}
}
pub fn set_global_policy(&mut self, policy: PermissionPolicy) {
self.global_policy = policy;
}
pub fn global_policy(&self) -> &PermissionPolicy {
&self.global_policy
}
pub fn set_session_policy(&mut self, session_id: &str, policy: PermissionPolicy) {
self.session_policies.insert(session_id.to_string(), policy);
}
pub fn remove_session_policy(&mut self, session_id: &str) {
self.session_policies.remove(session_id);
}
pub fn get_effective_policy(&self, session_id: &str) -> &PermissionPolicy {
self.session_policies
.get(session_id)
.unwrap_or(&self.global_policy)
}
pub fn check(
&self,
session_id: &str,
tool_name: &str,
args: &serde_json::Value,
) -> PermissionDecision {
let policy = self.get_effective_policy(session_id);
for rule in &policy.deny {
if rule.matches(tool_name, args) {
return PermissionDecision::Deny;
}
}
if !self.session_policies.contains_key(session_id) {
} else {
for rule in &self.global_policy.deny {
if rule.matches(tool_name, args) {
return PermissionDecision::Deny;
}
}
}
for rule in &policy.allow {
if rule.matches(tool_name, args) {
return PermissionDecision::Allow;
}
}
for rule in &policy.ask {
if rule.matches(tool_name, args) {
return PermissionDecision::Ask;
}
}
policy.default_decision
}
}