mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-21 01:18:38 +00:00
fix(macos): consolidate exec approval evaluation
This commit is contained in:
@@ -350,21 +350,7 @@ enum ExecApprovalsPromptPresenter {
|
||||
|
||||
@MainActor
|
||||
private enum ExecHostExecutor {
|
||||
private struct ExecApprovalContext {
|
||||
let command: [String]
|
||||
let displayCommand: String
|
||||
let trimmedAgent: String?
|
||||
let approvals: ExecApprovalsResolved
|
||||
let security: ExecSecurity
|
||||
let ask: ExecAsk
|
||||
let autoAllowSkills: Bool
|
||||
let env: [String: String]?
|
||||
let resolution: ExecCommandResolution?
|
||||
let allowlistResolutions: [ExecCommandResolution]
|
||||
let allowlistMatches: [ExecAllowlistEntry]
|
||||
let allowlistSatisfied: Bool
|
||||
let skillAllow: Bool
|
||||
}
|
||||
private typealias ExecApprovalContext = ExecApprovalEvaluation
|
||||
|
||||
static func handle(_ request: ExecHostRequest) async -> ExecHostResponse {
|
||||
let command = request.command.map { $0.trimmingCharacters(in: .whitespacesAndNewlines) }
|
||||
@@ -395,7 +381,7 @@ private enum ExecHostExecutor {
|
||||
if ExecApprovalHelpers.requiresAsk(
|
||||
ask: context.ask,
|
||||
security: context.security,
|
||||
allowlistMatch: context.allowlistSatisfied ? context.allowlistMatches.first : nil,
|
||||
allowlistMatch: context.allowlistMatch,
|
||||
skillAllow: context.skillAllow),
|
||||
approvalDecision == nil
|
||||
{
|
||||
@@ -406,7 +392,7 @@ private enum ExecHostExecutor {
|
||||
host: "node",
|
||||
security: context.security.rawValue,
|
||||
ask: context.ask.rawValue,
|
||||
agentId: context.trimmedAgent,
|
||||
agentId: context.agentId,
|
||||
resolvedPath: context.resolution?.resolvedPath,
|
||||
sessionKey: request.sessionKey))
|
||||
|
||||
@@ -447,7 +433,7 @@ private enum ExecHostExecutor {
|
||||
? context.allowlistResolutions[idx].resolvedPath
|
||||
: nil
|
||||
ExecApprovalsStore.recordAllowlistUse(
|
||||
agentId: context.trimmedAgent,
|
||||
agentId: context.agentId,
|
||||
pattern: match.pattern,
|
||||
command: context.displayCommand,
|
||||
resolvedPath: resolvedPath)
|
||||
@@ -466,49 +452,12 @@ private enum ExecHostExecutor {
|
||||
}
|
||||
|
||||
private static func buildContext(request: ExecHostRequest, command: [String]) async -> ExecApprovalContext {
|
||||
let displayCommand = ExecCommandFormatter.displayString(
|
||||
for: command,
|
||||
rawCommand: request.rawCommand)
|
||||
let agentId = request.agentId?.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
let trimmedAgent = (agentId?.isEmpty == false) ? agentId : nil
|
||||
let approvals = ExecApprovalsStore.resolve(agentId: trimmedAgent)
|
||||
let security = approvals.agent.security
|
||||
let ask = approvals.agent.ask
|
||||
let autoAllowSkills = approvals.agent.autoAllowSkills
|
||||
let env = self.sanitizedEnv(request.env)
|
||||
let allowlistResolutions = ExecCommandResolution.resolveForAllowlist(
|
||||
await ExecApprovalEvaluator.evaluate(
|
||||
command: command,
|
||||
rawCommand: request.rawCommand,
|
||||
cwd: request.cwd,
|
||||
env: env)
|
||||
let resolution = allowlistResolutions.first
|
||||
let allowlistMatches = security == .allowlist
|
||||
? ExecAllowlistMatcher.matchAll(entries: approvals.allowlist, resolutions: allowlistResolutions)
|
||||
: []
|
||||
let allowlistSatisfied = security == .allowlist &&
|
||||
!allowlistResolutions.isEmpty &&
|
||||
allowlistMatches.count == allowlistResolutions.count
|
||||
let skillAllow: Bool
|
||||
if autoAllowSkills, !allowlistResolutions.isEmpty {
|
||||
let bins = await SkillBinsCache.shared.currentBins()
|
||||
skillAllow = allowlistResolutions.allSatisfy { bins.contains($0.executableName) }
|
||||
} else {
|
||||
skillAllow = false
|
||||
}
|
||||
return ExecApprovalContext(
|
||||
command: command,
|
||||
displayCommand: displayCommand,
|
||||
trimmedAgent: trimmedAgent,
|
||||
approvals: approvals,
|
||||
security: security,
|
||||
ask: ask,
|
||||
autoAllowSkills: autoAllowSkills,
|
||||
env: env,
|
||||
resolution: resolution,
|
||||
allowlistResolutions: allowlistResolutions,
|
||||
allowlistMatches: allowlistMatches,
|
||||
allowlistSatisfied: allowlistSatisfied,
|
||||
skillAllow: skillAllow)
|
||||
envOverrides: request.env,
|
||||
agentId: request.agentId)
|
||||
}
|
||||
|
||||
private static func persistAllowlistEntry(
|
||||
@@ -525,7 +474,7 @@ private enum ExecHostExecutor {
|
||||
continue
|
||||
}
|
||||
if seenPatterns.insert(pattern).inserted {
|
||||
ExecApprovalsStore.addAllowlistEntry(agentId: context.trimmedAgent, pattern: pattern)
|
||||
ExecApprovalsStore.addAllowlistEntry(agentId: context.agentId, pattern: pattern)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -586,10 +535,6 @@ private enum ExecHostExecutor {
|
||||
payload: payload,
|
||||
error: nil)
|
||||
}
|
||||
|
||||
private static func sanitizedEnv(_ overrides: [String: String]?) -> [String: String] {
|
||||
HostEnvSanitizer.sanitize(overrides: overrides)
|
||||
}
|
||||
}
|
||||
|
||||
private final class ExecApprovalsSocketServer: @unchecked Sendable {
|
||||
|
||||
Reference in New Issue
Block a user