use astrid_core::PrincipalId;
use astrid_core::profile::Quotas;
use serde::{Deserialize, Serialize};
pub const SYSTEM_SESSION_UUID: &str = "00000000-0000-0000-0000-000000000000";
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "method", content = "params")]
pub enum KernelRequest {
InstallCapsule {
source: String,
workspace: bool,
},
ApproveCapability {
request_id: String,
signature: String,
},
ListCapsules,
ReloadCapsules,
GetCommands,
GetCapsuleMetadata,
Shutdown {
reason: Option<String>,
},
GetStatus,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "status", content = "data")]
pub enum KernelResponse {
Success(serde_json::Value),
Commands(Vec<CommandInfo>),
CapsuleMetadata(Vec<CapsuleMetadataEntry>),
Error(String),
Status(DaemonStatus),
ApprovalRequired {
request_id: String,
description: String,
capabilities: Vec<String>,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DaemonStatus {
pub pid: u32,
pub uptime_secs: u64,
pub version: String,
pub ephemeral: bool,
pub connected_clients: u32,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub connections_by_principal: Vec<PrincipalConnectionCount>,
pub loaded_capsules: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PrincipalConnectionCount {
pub principal: String,
pub count: u32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CapsuleMetadataEntry {
pub name: String,
pub interceptor_events: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CommandInfo {
pub name: String,
pub description: String,
pub provider_capsule: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AdminKernelRequest {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub request_id: Option<String>,
#[serde(flatten)]
pub kind: AdminRequestKind,
}
impl AdminKernelRequest {
#[must_use]
pub const fn new(kind: AdminRequestKind) -> Self {
Self {
request_id: None,
kind,
}
}
#[must_use]
pub fn with_request_id(request_id: impl Into<String>, kind: AdminRequestKind) -> Self {
Self {
request_id: Some(request_id.into()),
kind,
}
}
}
impl From<AdminRequestKind> for AdminKernelRequest {
fn from(kind: AdminRequestKind) -> Self {
Self::new(kind)
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "method", content = "params")]
pub enum AdminRequestKind {
AgentCreate {
name: String,
#[serde(default)]
groups: Vec<String>,
#[serde(default)]
grants: Vec<String>,
},
AgentDelete {
principal: PrincipalId,
},
AgentEnable {
principal: PrincipalId,
},
AgentDisable {
principal: PrincipalId,
},
AgentList,
AgentModify {
principal: PrincipalId,
#[serde(default)]
add_groups: Vec<String>,
#[serde(default)]
remove_groups: Vec<String>,
},
QuotaSet {
principal: PrincipalId,
quotas: Quotas,
},
QuotaGet {
principal: PrincipalId,
},
GroupCreate {
name: String,
capabilities: Vec<String>,
#[serde(default)]
description: Option<String>,
#[serde(default)]
unsafe_admin: bool,
},
GroupDelete {
name: String,
},
GroupModify {
name: String,
#[serde(default)]
capabilities: Option<Vec<String>>,
#[serde(default)]
description: Option<Option<String>>,
#[serde(default)]
unsafe_admin: Option<bool>,
},
GroupList,
CapsGrant {
principal: PrincipalId,
capabilities: Vec<String>,
#[serde(default)]
unsafe_admin: bool,
},
CapsRevoke {
principal: PrincipalId,
capabilities: Vec<String>,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AdminKernelResponse {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub request_id: Option<String>,
#[serde(flatten)]
pub body: AdminResponseBody,
}
impl AdminKernelResponse {
#[must_use]
pub const fn new(body: AdminResponseBody) -> Self {
Self {
request_id: None,
body,
}
}
#[must_use]
pub fn for_request(request_id: Option<String>, body: AdminResponseBody) -> Self {
Self { request_id, body }
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "status", content = "data")]
pub enum AdminResponseBody {
Success(serde_json::Value),
AgentList(Vec<AgentSummary>),
GroupList(Vec<GroupSummary>),
Quotas(Quotas),
Error(String),
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct AgentSummary {
pub principal: PrincipalId,
pub enabled: bool,
pub groups: Vec<String>,
pub grants: Vec<String>,
pub revokes: Vec<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct GroupSummary {
pub name: String,
pub capabilities: Vec<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
pub unsafe_admin: bool,
pub builtin: bool,
}