mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-12 15:30:39 +00:00
93 lines
3.5 KiB
Swift
93 lines
3.5 KiB
Swift
import Foundation
|
|
import Testing
|
|
@testable import OpenClaw
|
|
|
|
@Suite(.serialized)
|
|
struct ExecApprovalsStoreRefactorTests {
|
|
private func withTempStateDir(
|
|
_ body: @escaping @Sendable (URL) async throws -> Void) async throws
|
|
{
|
|
let stateDir = FileManager().temporaryDirectory
|
|
.appendingPathComponent("openclaw-state-\(UUID().uuidString)", isDirectory: true)
|
|
defer { try? FileManager().removeItem(at: stateDir) }
|
|
|
|
try await TestIsolation.withEnvValues(["OPENCLAW_STATE_DIR": stateDir.path]) {
|
|
try await body(stateDir)
|
|
}
|
|
}
|
|
|
|
@Test
|
|
func `ensure file skips rewrite when unchanged`() async throws {
|
|
try await self.withTempStateDir { _ in
|
|
_ = ExecApprovalsStore.ensureFile()
|
|
let url = ExecApprovalsStore.fileURL()
|
|
let firstWriteDate = try Self.modificationDate(at: url)
|
|
|
|
try await Task.sleep(nanoseconds: 1_100_000_000)
|
|
_ = ExecApprovalsStore.ensureFile()
|
|
let secondWriteDate = try Self.modificationDate(at: url)
|
|
|
|
#expect(firstWriteDate == secondWriteDate)
|
|
}
|
|
}
|
|
|
|
@Test
|
|
func `update allowlist reports rejected basename pattern`() async throws {
|
|
try await self.withTempStateDir { _ in
|
|
let rejected = ExecApprovalsStore.updateAllowlist(
|
|
agentId: "main",
|
|
allowlist: [
|
|
ExecAllowlistEntry(pattern: "echo"),
|
|
ExecAllowlistEntry(pattern: "/bin/echo"),
|
|
])
|
|
#expect(rejected.count == 1)
|
|
#expect(rejected.first?.reason == .missingPathComponent)
|
|
#expect(rejected.first?.pattern == "echo")
|
|
|
|
let resolved = ExecApprovalsStore.resolve(agentId: "main")
|
|
#expect(resolved.allowlist.map(\.pattern) == ["/bin/echo"])
|
|
}
|
|
}
|
|
|
|
@Test
|
|
func `update allowlist migrates legacy pattern from resolved path`() async throws {
|
|
try await self.withTempStateDir { _ in
|
|
let rejected = ExecApprovalsStore.updateAllowlist(
|
|
agentId: "main",
|
|
allowlist: [
|
|
ExecAllowlistEntry(
|
|
pattern: "echo",
|
|
lastUsedAt: nil,
|
|
lastUsedCommand: nil,
|
|
lastResolvedPath: " /usr/bin/echo "),
|
|
])
|
|
#expect(rejected.isEmpty)
|
|
|
|
let resolved = ExecApprovalsStore.resolve(agentId: "main")
|
|
#expect(resolved.allowlist.map(\.pattern) == ["/usr/bin/echo"])
|
|
}
|
|
}
|
|
|
|
@Test
|
|
func `ensure file hardens state directory permissions`() async throws {
|
|
try await self.withTempStateDir { stateDir in
|
|
try FileManager().createDirectory(at: stateDir, withIntermediateDirectories: true)
|
|
try FileManager().setAttributes([.posixPermissions: 0o755], ofItemAtPath: stateDir.path)
|
|
|
|
_ = ExecApprovalsStore.ensureFile()
|
|
let attrs = try FileManager().attributesOfItem(atPath: stateDir.path)
|
|
let permissions = (attrs[.posixPermissions] as? NSNumber)?.intValue ?? -1
|
|
#expect(permissions & 0o777 == 0o700)
|
|
}
|
|
}
|
|
|
|
private static func modificationDate(at url: URL) throws -> Date {
|
|
let attributes = try FileManager().attributesOfItem(atPath: url.path)
|
|
guard let date = attributes[.modificationDate] as? Date else {
|
|
struct MissingDateError: Error {}
|
|
throw MissingDateError()
|
|
}
|
|
return date
|
|
}
|
|
}
|