feat(permissions): expose network permission state (#103)
This commit is contained in:
@ -40,7 +40,10 @@ import type {
|
||||
ProjectMcpToolPermissions,
|
||||
ProjectPermissions,
|
||||
ProjectWorkState,
|
||||
ProjectSystemPermissions,
|
||||
ProfileAvailability,
|
||||
ResolvedAgentSystemPermissions,
|
||||
SystemPermissionSet,
|
||||
Skill,
|
||||
SkillScope,
|
||||
Template,
|
||||
@ -364,6 +367,37 @@ export class HttpPermissionGateway implements PermissionGateway {
|
||||
request: { projectId, agentId },
|
||||
});
|
||||
}
|
||||
getProjectSystemPermissions(projectId: string): Promise<ProjectSystemPermissions> {
|
||||
return this.http.invoke<ProjectSystemPermissions>("get_project_system_permissions", {
|
||||
projectId,
|
||||
});
|
||||
}
|
||||
updateProjectSystemPermissions(
|
||||
projectId: string,
|
||||
permissions: SystemPermissionSet | null,
|
||||
): Promise<ProjectSystemPermissions> {
|
||||
return this.http.invoke<ProjectSystemPermissions>("update_project_system_permissions", {
|
||||
request: { projectId, permissions },
|
||||
});
|
||||
}
|
||||
updateAgentSystemPermissions(
|
||||
projectId: string,
|
||||
agentId: string,
|
||||
permissions: SystemPermissionSet | null,
|
||||
): Promise<ProjectSystemPermissions> {
|
||||
return this.http.invoke<ProjectSystemPermissions>("update_agent_system_permissions", {
|
||||
request: { projectId, agentId, permissions },
|
||||
});
|
||||
}
|
||||
resolveAgentSystemPermissions(
|
||||
projectId: string,
|
||||
agentId: string,
|
||||
): Promise<ResolvedAgentSystemPermissions> {
|
||||
return this.http.invoke<ResolvedAgentSystemPermissions>(
|
||||
"resolve_agent_system_permissions",
|
||||
{ request: { projectId, agentId } },
|
||||
);
|
||||
}
|
||||
getMcpToolPermissions(projectId: string): Promise<ProjectMcpToolPermissions> {
|
||||
return this.http.invoke<ProjectMcpToolPermissions>("get_mcp_tool_permissions", { projectId });
|
||||
}
|
||||
|
||||
@ -50,8 +50,10 @@ import type {
|
||||
ProjectMcpToolPermissions,
|
||||
ProjectPermissions,
|
||||
ProjectWorkState,
|
||||
ProjectSystemPermissions,
|
||||
ProfileAvailability,
|
||||
ResumableAgent,
|
||||
ResolvedAgentSystemPermissions,
|
||||
ServerExposurePreview,
|
||||
ServerExposureSettings,
|
||||
Skill,
|
||||
@ -59,6 +61,7 @@ import type {
|
||||
SkillScope,
|
||||
Sprint,
|
||||
Template,
|
||||
SystemPermissionSet,
|
||||
TerminalSession,
|
||||
Ticket,
|
||||
TicketCarnet,
|
||||
@ -2186,6 +2189,8 @@ export class MockDeviceGateway implements DeviceGateway {
|
||||
/** In-memory permissions gateway. */
|
||||
export class MockPermissionGateway implements PermissionGateway {
|
||||
private docs = new Map<string, ProjectPermissions>();
|
||||
private systemDocs = new Map<string, ProjectSystemPermissions>();
|
||||
private systemRuntime = new Map<string, ResolvedAgentSystemPermissions>();
|
||||
|
||||
private doc(projectId: string): ProjectPermissions {
|
||||
if (!this.docs.has(projectId)) {
|
||||
@ -2234,6 +2239,72 @@ export class MockPermissionGateway implements PermissionGateway {
|
||||
};
|
||||
}
|
||||
|
||||
private systemDoc(projectId: string): ProjectSystemPermissions {
|
||||
if (!this.systemDocs.has(projectId)) {
|
||||
this.systemDocs.set(projectId, { version: 1, agents: [] });
|
||||
}
|
||||
return this.systemDocs.get(projectId)!;
|
||||
}
|
||||
|
||||
async getProjectSystemPermissions(
|
||||
projectId: string,
|
||||
): Promise<ProjectSystemPermissions> {
|
||||
return structuredClone(this.systemDoc(projectId));
|
||||
}
|
||||
|
||||
async updateProjectSystemPermissions(
|
||||
projectId: string,
|
||||
permissions: SystemPermissionSet | null,
|
||||
): Promise<ProjectSystemPermissions> {
|
||||
const doc = this.systemDoc(projectId);
|
||||
if (permissions && Object.keys(permissions).length > 0) {
|
||||
doc.projectDefault = structuredClone(permissions);
|
||||
} else {
|
||||
delete doc.projectDefault;
|
||||
}
|
||||
return structuredClone(doc);
|
||||
}
|
||||
|
||||
async updateAgentSystemPermissions(
|
||||
projectId: string,
|
||||
agentId: string,
|
||||
permissions: SystemPermissionSet | null,
|
||||
): Promise<ProjectSystemPermissions> {
|
||||
const doc = this.systemDoc(projectId);
|
||||
const agents = (doc.agents ?? []).filter((entry) => entry.agentId !== agentId);
|
||||
if (permissions && Object.keys(permissions).length > 0) {
|
||||
agents.push({ agentId, permissions: structuredClone(permissions) });
|
||||
}
|
||||
doc.agents = agents;
|
||||
return structuredClone(doc);
|
||||
}
|
||||
|
||||
async resolveAgentSystemPermissions(
|
||||
projectId: string,
|
||||
agentId: string,
|
||||
): Promise<ResolvedAgentSystemPermissions> {
|
||||
const runtime = this.systemRuntime.get(agentId);
|
||||
if (runtime) return structuredClone(runtime);
|
||||
const doc = this.systemDoc(projectId);
|
||||
const wanted =
|
||||
doc.agents?.find((entry) => entry.agentId === agentId)?.permissions.network ??
|
||||
doc.projectDefault?.network ??
|
||||
null;
|
||||
return {
|
||||
wanted,
|
||||
effective: wanted ?? "ask",
|
||||
runtimeLock: { state: "none" },
|
||||
control: { mode: "editable" },
|
||||
};
|
||||
}
|
||||
|
||||
setResolvedAgentSystemPermissions(
|
||||
agentId: string,
|
||||
resolved: ResolvedAgentSystemPermissions,
|
||||
): void {
|
||||
this.systemRuntime.set(agentId, structuredClone(resolved));
|
||||
}
|
||||
|
||||
// ── MCP tool permissions (ticket #82) — mirrors the backend catalogue in
|
||||
// `crates/infrastructure/src/orchestrator/mcp/tools.rs`, a separate durable
|
||||
// document from the file/command permissions above. ─────────────────────
|
||||
|
||||
@ -6,6 +6,9 @@ import type {
|
||||
PermissionSet,
|
||||
ProjectMcpToolPermissions,
|
||||
ProjectPermissions,
|
||||
ProjectSystemPermissions,
|
||||
ResolvedAgentSystemPermissions,
|
||||
SystemPermissionSet,
|
||||
} from "@/domain";
|
||||
import type { PermissionGateway } from "@/ports";
|
||||
|
||||
@ -43,6 +46,41 @@ export class TauriPermissionGateway implements PermissionGateway {
|
||||
});
|
||||
}
|
||||
|
||||
getProjectSystemPermissions(projectId: string): Promise<ProjectSystemPermissions> {
|
||||
return invoke<ProjectSystemPermissions>("get_project_system_permissions", {
|
||||
projectId,
|
||||
});
|
||||
}
|
||||
|
||||
updateProjectSystemPermissions(
|
||||
projectId: string,
|
||||
permissions: SystemPermissionSet | null,
|
||||
): Promise<ProjectSystemPermissions> {
|
||||
return invoke<ProjectSystemPermissions>("update_project_system_permissions", {
|
||||
request: { projectId, permissions },
|
||||
});
|
||||
}
|
||||
|
||||
updateAgentSystemPermissions(
|
||||
projectId: string,
|
||||
agentId: string,
|
||||
permissions: SystemPermissionSet | null,
|
||||
): Promise<ProjectSystemPermissions> {
|
||||
return invoke<ProjectSystemPermissions>("update_agent_system_permissions", {
|
||||
request: { projectId, agentId, permissions },
|
||||
});
|
||||
}
|
||||
|
||||
resolveAgentSystemPermissions(
|
||||
projectId: string,
|
||||
agentId: string,
|
||||
): Promise<ResolvedAgentSystemPermissions> {
|
||||
return invoke<ResolvedAgentSystemPermissions>(
|
||||
"resolve_agent_system_permissions",
|
||||
{ request: { projectId, agentId } },
|
||||
);
|
||||
}
|
||||
|
||||
getMcpToolPermissions(projectId: string): Promise<ProjectMcpToolPermissions> {
|
||||
return invoke<ProjectMcpToolPermissions>("get_mcp_tool_permissions", {
|
||||
projectId,
|
||||
|
||||
Reference in New Issue
Block a user