use crate::capability::AccessMode;
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use std::time::SystemTime;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CapabilityRequest {
pub request_id: String,
pub path: PathBuf,
pub access: AccessMode,
pub reason: Option<String>,
pub child_pid: u32,
pub session_id: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "capability_type", rename_all = "snake_case")]
pub enum ApprovalRequest {
Capability {
request_id: String,
path: PathBuf,
access: AccessMode,
reason: Option<String>,
child_pid: u32,
session_id: String,
},
Network {
request_id: String,
host: String,
port: u16,
protocol: String,
resolved_ips: Vec<String>,
reason: Option<String>,
child_pid: u32,
session_id: String,
},
Endpoint {
request_id: String,
route_id: String,
upstream: String,
method: String,
path: String,
rule_label: String,
reason: Option<String>,
child_pid: u32,
session_id: String,
},
Command {
request_id: String,
command: String,
args: Vec<String>,
caller: String,
intercept_rule: String,
reason: Option<String>,
child_pid: u32,
session_id: String,
},
}
impl ApprovalRequest {
#[must_use]
pub fn request_id(&self) -> &str {
match self {
ApprovalRequest::Capability { request_id, .. }
| ApprovalRequest::Network { request_id, .. }
| ApprovalRequest::Endpoint { request_id, .. }
| ApprovalRequest::Command { request_id, .. } => request_id,
}
}
#[must_use]
pub fn session_id(&self) -> &str {
match self {
ApprovalRequest::Capability { session_id, .. }
| ApprovalRequest::Network { session_id, .. }
| ApprovalRequest::Endpoint { session_id, .. }
| ApprovalRequest::Command { session_id, .. } => session_id,
}
}
}
impl From<CapabilityRequest> for ApprovalRequest {
fn from(r: CapabilityRequest) -> Self {
ApprovalRequest::Capability {
request_id: r.request_id,
path: r.path,
access: r.access,
reason: r.reason,
child_pid: r.child_pid,
session_id: r.session_id,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ApprovalDecision {
Granted,
Denied {
reason: String,
},
Timeout,
}
impl ApprovalDecision {
#[must_use]
pub fn is_granted(&self) -> bool {
matches!(self, ApprovalDecision::Granted)
}
#[must_use]
pub fn is_denied(&self) -> bool {
matches!(self, ApprovalDecision::Denied { .. })
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuditEntry {
pub timestamp: SystemTime,
pub request: ApprovalRequest,
pub decision: ApprovalDecision,
pub backend: String,
pub duration_ms: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UrlOpenRequest {
pub request_id: String,
pub url: String,
pub child_pid: u32,
pub session_id: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum SupervisorMessage {
Request(CapabilityRequest),
OpenUrl(UrlOpenRequest),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum SupervisorResponse {
Decision {
request_id: String,
decision: ApprovalDecision,
},
UrlOpened {
request_id: String,
success: bool,
error: Option<String>,
},
}