summaryrefslogtreecommitdiffhomepage
path: root/packages/core/tests/permission/evaluate.test.ts
blob: c8f45418c68f1a05b8681ad488822fb2b4c42471 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import { describe, expect, it } from "vitest";
import { evaluate } from "../../src/permission/evaluate.js";
import type { Ruleset } from "../../src/permission/index.js";

describe("evaluate", () => {
	it("returns default ask when no rules match", () => {
		const result = evaluate("bash", "ls -la");
		expect(result.action).toBe("ask");
		expect(result.permission).toBe("bash");
		expect(result.pattern).toBe("ls -la");
	});

	it("returns allow when matching rule is allow", () => {
		const rules: Ruleset = [{ permission: "bash", pattern: "ls *", action: "allow" }];
		const result = evaluate("bash", "ls -la", rules);
		expect(result.action).toBe("allow");
	});

	it("returns deny when matching rule is deny", () => {
		const rules: Ruleset = [{ permission: "bash", pattern: "rm *", action: "deny" }];
		const result = evaluate("bash", "rm -rf /", rules);
		expect(result.action).toBe("deny");
	});

	it("last-match-wins: later deny overrides earlier allow", () => {
		const rules: Ruleset = [
			{ permission: "bash", pattern: "*", action: "allow" },
			{ permission: "bash", pattern: "rm *", action: "deny" },
		];
		const result = evaluate("bash", "rm -rf /", rules);
		expect(result.action).toBe("deny");
	});

	it("last-match-wins: later allow overrides earlier deny", () => {
		const rules: Ruleset = [
			{ permission: "bash", pattern: "rm *", action: "deny" },
			{ permission: "bash", pattern: "*", action: "allow" },
		];
		const result = evaluate("bash", "rm -rf /", rules);
		expect(result.action).toBe("allow");
	});

	it("matches permission wildcard", () => {
		const rules: Ruleset = [{ permission: "*", pattern: "*", action: "allow" }];
		const result = evaluate("read", "anything", rules);
		expect(result.action).toBe("allow");
	});

	it("multiple rulesets are concatenated, last match wins across rulesets", () => {
		const baseRules: Ruleset = [{ permission: "bash", pattern: "*", action: "ask" }];
		const overrideRules: Ruleset = [{ permission: "bash", pattern: "git *", action: "allow" }];
		const result = evaluate("bash", "git status", baseRules, overrideRules);
		expect(result.action).toBe("allow");
	});

	it("second ruleset can deny what first ruleset allows", () => {
		const baseRules: Ruleset = [{ permission: "bash", pattern: "*", action: "allow" }];
		const overrideRules: Ruleset = [{ permission: "bash", pattern: "rm *", action: "deny" }];
		const result = evaluate("bash", "rm -rf /", baseRules, overrideRules);
		expect(result.action).toBe("deny");
	});

	it("non-matching permission returns default ask", () => {
		const rules: Ruleset = [{ permission: "bash", pattern: "*", action: "allow" }];
		const result = evaluate("read", "/some/path", rules);
		expect(result.action).toBe("ask");
	});
});