feat: implement home directory expansion for permission patterns using ~ and $HOME prefixes. (#9813)
This commit is contained in:
@@ -7,11 +7,20 @@ import { Storage } from "@/storage/storage"
|
||||
import { fn } from "@/util/fn"
|
||||
import { Log } from "@/util/log"
|
||||
import { Wildcard } from "@/util/wildcard"
|
||||
import os from "os"
|
||||
import z from "zod"
|
||||
|
||||
export namespace PermissionNext {
|
||||
const log = Log.create({ service: "permission" })
|
||||
|
||||
function expand(pattern: string): string {
|
||||
if (pattern.startsWith("~/")) return os.homedir() + pattern.slice(1)
|
||||
if (pattern === "~") return os.homedir()
|
||||
if (pattern.startsWith("$HOME/")) return os.homedir() + pattern.slice(5)
|
||||
if (pattern.startsWith("$HOME")) return os.homedir() + pattern.slice(5)
|
||||
return pattern
|
||||
}
|
||||
|
||||
export const Action = z.enum(["allow", "deny", "ask"]).meta({
|
||||
ref: "PermissionAction",
|
||||
})
|
||||
@@ -44,7 +53,9 @@ export namespace PermissionNext {
|
||||
})
|
||||
continue
|
||||
}
|
||||
ruleset.push(...Object.entries(value).map(([pattern, action]) => ({ permission: key, pattern, action })))
|
||||
ruleset.push(
|
||||
...Object.entries(value).map(([pattern, action]) => ({ permission: key, pattern: expand(pattern), action })),
|
||||
)
|
||||
}
|
||||
return ruleset
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { test, expect } from "bun:test"
|
||||
import os from "os"
|
||||
import { PermissionNext } from "../../src/permission/next"
|
||||
import { Instance } from "../../src/project/instance"
|
||||
import { Storage } from "../../src/storage/storage"
|
||||
@@ -38,6 +39,43 @@ test("fromConfig - empty object", () => {
|
||||
expect(result).toEqual([])
|
||||
})
|
||||
|
||||
test("fromConfig - expands tilde to home directory", () => {
|
||||
const result = PermissionNext.fromConfig({ external_directory: { "~/projects/*": "allow" } })
|
||||
expect(result).toEqual([{ permission: "external_directory", pattern: `${os.homedir()}/projects/*`, action: "allow" }])
|
||||
})
|
||||
|
||||
test("fromConfig - expands $HOME to home directory", () => {
|
||||
const result = PermissionNext.fromConfig({ external_directory: { "$HOME/projects/*": "allow" } })
|
||||
expect(result).toEqual([{ permission: "external_directory", pattern: `${os.homedir()}/projects/*`, action: "allow" }])
|
||||
})
|
||||
|
||||
test("fromConfig - expands $HOME without trailing slash", () => {
|
||||
const result = PermissionNext.fromConfig({ external_directory: { $HOME: "allow" } })
|
||||
expect(result).toEqual([{ permission: "external_directory", pattern: os.homedir(), action: "allow" }])
|
||||
})
|
||||
|
||||
test("fromConfig - does not expand tilde in middle of path", () => {
|
||||
const result = PermissionNext.fromConfig({ external_directory: { "/some/~/path": "allow" } })
|
||||
expect(result).toEqual([{ permission: "external_directory", pattern: "/some/~/path", action: "allow" }])
|
||||
})
|
||||
|
||||
test("fromConfig - expands exact tilde to home directory", () => {
|
||||
const result = PermissionNext.fromConfig({ external_directory: { "~": "allow" } })
|
||||
expect(result).toEqual([{ permission: "external_directory", pattern: os.homedir(), action: "allow" }])
|
||||
})
|
||||
|
||||
test("evaluate - matches expanded tilde pattern", () => {
|
||||
const ruleset = PermissionNext.fromConfig({ external_directory: { "~/projects/*": "allow" } })
|
||||
const result = PermissionNext.evaluate("external_directory", `${os.homedir()}/projects/file.txt`, ruleset)
|
||||
expect(result.action).toBe("allow")
|
||||
})
|
||||
|
||||
test("evaluate - matches expanded $HOME pattern", () => {
|
||||
const ruleset = PermissionNext.fromConfig({ external_directory: { "$HOME/projects/*": "allow" } })
|
||||
const result = PermissionNext.evaluate("external_directory", `${os.homedir()}/projects/file.txt`, ruleset)
|
||||
expect(result.action).toBe("allow")
|
||||
})
|
||||
|
||||
// merge tests
|
||||
|
||||
test("merge - simple concatenation", () => {
|
||||
|
||||
@@ -78,6 +78,14 @@ Permission patterns use simple wildcard matching:
|
||||
- `?` matches exactly one character
|
||||
- All other characters match literally
|
||||
|
||||
### Home Directory Expansion
|
||||
|
||||
You can use `~` or `$HOME` at the start of a pattern to reference your home directory. This is particularly useful for `external_directory` rules.
|
||||
|
||||
- `~/projects/*` -> `/Users/username/projects/*`
|
||||
- `$HOME/projects/*` -> `/Users/username/projects/*`
|
||||
- `~` -> `/Users/username`
|
||||
|
||||
---
|
||||
|
||||
## Available Permissions
|
||||
|
||||
Reference in New Issue
Block a user