169 lines
5.0 KiB
Rust
169 lines
5.0 KiB
Rust
//! System permission use cases.
|
|
//!
|
|
//! These use cases persist the wanted project/agent policies separately from
|
|
//! filesystem/bash permissions and resolve them through a read-only runtime
|
|
//! probe.
|
|
|
|
use std::sync::Arc;
|
|
|
|
use domain::ports::{RuntimePermissionProbe, SystemPermissionStore};
|
|
use domain::{
|
|
resolve_agent_system_permissions, AgentId, Project, ProjectSystemPermissions,
|
|
ResolvedAgentSystemPermissions, SystemPermissionSet,
|
|
};
|
|
|
|
use crate::error::AppError;
|
|
|
|
/// Reads the full project system permission document.
|
|
pub struct GetProjectSystemPermissions {
|
|
store: Arc<dyn SystemPermissionStore>,
|
|
}
|
|
|
|
impl GetProjectSystemPermissions {
|
|
/// Builds the use case.
|
|
#[must_use]
|
|
pub fn new(store: Arc<dyn SystemPermissionStore>) -> Self {
|
|
Self { store }
|
|
}
|
|
|
|
/// Executes the read.
|
|
pub async fn execute(
|
|
&self,
|
|
input: GetProjectSystemPermissionsInput,
|
|
) -> Result<GetProjectSystemPermissionsOutput, AppError> {
|
|
let permissions = self.store.load_system_permissions(&input.project).await?;
|
|
Ok(GetProjectSystemPermissionsOutput { permissions })
|
|
}
|
|
}
|
|
|
|
/// Input for [`GetProjectSystemPermissions`].
|
|
pub struct GetProjectSystemPermissionsInput {
|
|
/// Target project.
|
|
pub project: Project,
|
|
}
|
|
|
|
/// Output for project system permission reads/mutations.
|
|
pub struct GetProjectSystemPermissionsOutput {
|
|
/// Persisted system permission document.
|
|
pub permissions: ProjectSystemPermissions,
|
|
}
|
|
|
|
/// Replaces the project default system permissions.
|
|
pub struct UpdateProjectSystemPermissions {
|
|
store: Arc<dyn SystemPermissionStore>,
|
|
}
|
|
|
|
impl UpdateProjectSystemPermissions {
|
|
/// Builds the use case.
|
|
#[must_use]
|
|
pub fn new(store: Arc<dyn SystemPermissionStore>) -> Self {
|
|
Self { store }
|
|
}
|
|
|
|
/// Executes the mutation.
|
|
pub async fn execute(
|
|
&self,
|
|
input: UpdateProjectSystemPermissionsInput,
|
|
) -> Result<GetProjectSystemPermissionsOutput, AppError> {
|
|
let mut doc = self.store.load_system_permissions(&input.project).await?;
|
|
doc.set_project_default(input.permissions);
|
|
self.store
|
|
.save_system_permissions(&input.project, &doc)
|
|
.await?;
|
|
Ok(GetProjectSystemPermissionsOutput { permissions: doc })
|
|
}
|
|
}
|
|
|
|
/// Input for [`UpdateProjectSystemPermissions`].
|
|
pub struct UpdateProjectSystemPermissionsInput {
|
|
/// Target project.
|
|
pub project: Project,
|
|
/// New project default policy. `None` removes project defaults.
|
|
pub permissions: Option<SystemPermissionSet>,
|
|
}
|
|
|
|
/// Replaces one agent system permission override.
|
|
pub struct UpdateAgentSystemPermissions {
|
|
store: Arc<dyn SystemPermissionStore>,
|
|
}
|
|
|
|
impl UpdateAgentSystemPermissions {
|
|
/// Builds the use case.
|
|
#[must_use]
|
|
pub fn new(store: Arc<dyn SystemPermissionStore>) -> Self {
|
|
Self { store }
|
|
}
|
|
|
|
/// Executes the mutation.
|
|
pub async fn execute(
|
|
&self,
|
|
input: UpdateAgentSystemPermissionsInput,
|
|
) -> Result<GetProjectSystemPermissionsOutput, AppError> {
|
|
let mut doc = self.store.load_system_permissions(&input.project).await?;
|
|
doc.set_agent_permissions(input.agent_id, input.permissions);
|
|
self.store
|
|
.save_system_permissions(&input.project, &doc)
|
|
.await?;
|
|
Ok(GetProjectSystemPermissionsOutput { permissions: doc })
|
|
}
|
|
}
|
|
|
|
/// Input for [`UpdateAgentSystemPermissions`].
|
|
pub struct UpdateAgentSystemPermissionsInput {
|
|
/// Target project.
|
|
pub project: Project,
|
|
/// Target agent.
|
|
pub agent_id: AgentId,
|
|
/// New agent policy. `None` removes the override.
|
|
pub permissions: Option<SystemPermissionSet>,
|
|
}
|
|
|
|
/// Resolves effective system permissions for one agent.
|
|
pub struct ResolveAgentSystemPermissions {
|
|
store: Arc<dyn SystemPermissionStore>,
|
|
runtime_probe: Arc<dyn RuntimePermissionProbe>,
|
|
}
|
|
|
|
impl ResolveAgentSystemPermissions {
|
|
/// Builds the use case.
|
|
#[must_use]
|
|
pub fn new(
|
|
store: Arc<dyn SystemPermissionStore>,
|
|
runtime_probe: Arc<dyn RuntimePermissionProbe>,
|
|
) -> Self {
|
|
Self {
|
|
store,
|
|
runtime_probe,
|
|
}
|
|
}
|
|
|
|
/// Executes the resolution.
|
|
pub async fn execute(
|
|
&self,
|
|
input: ResolveAgentSystemPermissionsInput,
|
|
) -> Result<ResolveAgentSystemPermissionsOutput, AppError> {
|
|
let doc = self.store.load_system_permissions(&input.project).await?;
|
|
let runtime = self
|
|
.runtime_probe
|
|
.probe_runtime_permissions(&input.project, input.agent_id)
|
|
.await?;
|
|
Ok(ResolveAgentSystemPermissionsOutput {
|
|
permissions: resolve_agent_system_permissions(&doc, input.agent_id, runtime),
|
|
})
|
|
}
|
|
}
|
|
|
|
/// Input for [`ResolveAgentSystemPermissions`].
|
|
pub struct ResolveAgentSystemPermissionsInput {
|
|
/// Target project.
|
|
pub project: Project,
|
|
/// Target agent.
|
|
pub agent_id: AgentId,
|
|
}
|
|
|
|
/// Output for [`ResolveAgentSystemPermissions`].
|
|
pub struct ResolveAgentSystemPermissionsOutput {
|
|
/// Resolved system permissions.
|
|
pub permissions: ResolvedAgentSystemPermissions,
|
|
}
|