From 6fb7e8d93bb9fd8cdd81130a394ae6061930c4f6 Mon Sep 17 00:00:00 2001 From: Asher Gomez Date: Thu, 3 Aug 2023 21:19:19 +1000 Subject: feat(permissions): add "--deny-*" flags (#19070) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit adds new "--deny-*" permission flags. These are complimentary to "--allow-*" flags. These flags can be used to restrict access to certain resources, even if they were granted using "--allow-*" flags or the "--allow-all" ("-A") flag. Eg. specifying "--allow-read --deny-read" will result in a permission error, while "--allow-read --deny-read=/etc" will allow read access to all FS but the "/etc" directory. Runtime permissions APIs ("Deno.permissions") were adjusted as well, mainly by adding, a new "PermissionStatus.partial" field. This field denotes that while permission might be granted to requested resource, it's only partial (ie. a "--deny-*" flag was specified that excludes some of the requested resources). Eg. specifying "--allow-read=foo/ --deny-read=foo/bar" and then querying for permissions like "Deno.permissions.query({ name: "read", path: "foo/" })" will return "PermissionStatus { state: "granted", onchange: null, partial: true }", denoting that some of the subpaths don't have read access. Closes #18804. --------- Co-authored-by: Bartek IwaƄczuk Co-authored-by: Nayeem Rahman --- cli/tests/testdata/run/deny_all_permission_args.js | 8 ++++++++ .../testdata/run/deny_all_permission_args.out | 8 ++++++++ .../testdata/run/deny_some_permission_args.js | 22 ++++++++++++++++++++++ .../testdata/run/deny_some_permission_args.out | 22 ++++++++++++++++++++++ cli/tests/testdata/run/permissions_cache.ts | 5 +++++ 5 files changed, 65 insertions(+) create mode 100644 cli/tests/testdata/run/deny_all_permission_args.js create mode 100644 cli/tests/testdata/run/deny_all_permission_args.out create mode 100644 cli/tests/testdata/run/deny_some_permission_args.js create mode 100644 cli/tests/testdata/run/deny_some_permission_args.out create mode 100644 cli/tests/testdata/run/permissions_cache.ts (limited to 'cli/tests/testdata/run') diff --git a/cli/tests/testdata/run/deny_all_permission_args.js b/cli/tests/testdata/run/deny_all_permission_args.js new file mode 100644 index 000000000..b0ca864fb --- /dev/null +++ b/cli/tests/testdata/run/deny_all_permission_args.js @@ -0,0 +1,8 @@ +console.log(Deno.permissions.querySync({ name: "env" })); +console.log(Deno.permissions.querySync({ name: "read" })); +console.log(Deno.permissions.querySync({ name: "write" })); +console.log(Deno.permissions.querySync({ name: "ffi" })); +console.log(Deno.permissions.querySync({ name: "run" })); +console.log(Deno.permissions.querySync({ name: "sys" })); +console.log(Deno.permissions.querySync({ name: "net" })); +console.log(Deno.permissions.querySync({ name: "hrtime" })); diff --git a/cli/tests/testdata/run/deny_all_permission_args.out b/cli/tests/testdata/run/deny_all_permission_args.out new file mode 100644 index 000000000..2a5228d62 --- /dev/null +++ b/cli/tests/testdata/run/deny_all_permission_args.out @@ -0,0 +1,8 @@ +PermissionStatus { state: "denied", onchange: null } +PermissionStatus { state: "denied", onchange: null } +PermissionStatus { state: "denied", onchange: null } +PermissionStatus { state: "denied", onchange: null } +PermissionStatus { state: "denied", onchange: null } +PermissionStatus { state: "denied", onchange: null } +PermissionStatus { state: "denied", onchange: null } +PermissionStatus { state: "denied", onchange: null } diff --git a/cli/tests/testdata/run/deny_some_permission_args.js b/cli/tests/testdata/run/deny_some_permission_args.js new file mode 100644 index 000000000..320376b6f --- /dev/null +++ b/cli/tests/testdata/run/deny_some_permission_args.js @@ -0,0 +1,22 @@ +console.log(Deno.permissions.querySync({ name: "env" })); +console.log(Deno.permissions.querySync({ name: "env", variable: "FOO" })); +console.log(Deno.permissions.querySync({ name: "env", variable: "BAR" })); +console.log(Deno.permissions.querySync({ name: "read" })); +console.log(Deno.permissions.querySync({ name: "read", path: "/foo" })); +console.log(Deno.permissions.querySync({ name: "read", path: "/bar" })); +console.log(Deno.permissions.querySync({ name: "write" })); +console.log(Deno.permissions.querySync({ name: "write", path: "/foo" })); +console.log(Deno.permissions.querySync({ name: "write", path: "/bar" })); +console.log(Deno.permissions.querySync({ name: "ffi" })); +console.log(Deno.permissions.querySync({ name: "ffi", path: "/foo" })); +console.log(Deno.permissions.querySync({ name: "ffi", path: "/bar" })); +console.log(Deno.permissions.querySync({ name: "run" })); +console.log(Deno.permissions.querySync({ name: "run", command: "foo" })); +console.log(Deno.permissions.querySync({ name: "run", command: "bar" })); +console.log(Deno.permissions.querySync({ name: "sys" })); +console.log(Deno.permissions.querySync({ name: "sys", kind: "hostname" })); +console.log(Deno.permissions.querySync({ name: "sys", kind: "loadavg" })); +console.log(Deno.permissions.querySync({ name: "net" })); +console.log(Deno.permissions.querySync({ name: "net", host: "127.0.0.1" })); +console.log(Deno.permissions.querySync({ name: "net", host: "192.168.0.1" })); +console.log(Deno.permissions.querySync({ name: "hrtime" })); diff --git a/cli/tests/testdata/run/deny_some_permission_args.out b/cli/tests/testdata/run/deny_some_permission_args.out new file mode 100644 index 000000000..80c37159b --- /dev/null +++ b/cli/tests/testdata/run/deny_some_permission_args.out @@ -0,0 +1,22 @@ +PermissionStatus { state: "granted", onchange: null, partial: true } +PermissionStatus { state: "denied", onchange: null } +PermissionStatus { state: "granted", onchange: null } +PermissionStatus { state: "granted", onchange: null, partial: true } +PermissionStatus { state: "denied", onchange: null } +PermissionStatus { state: "granted", onchange: null } +PermissionStatus { state: "granted", onchange: null, partial: true } +PermissionStatus { state: "denied", onchange: null } +PermissionStatus { state: "granted", onchange: null } +PermissionStatus { state: "granted", onchange: null, partial: true } +PermissionStatus { state: "denied", onchange: null } +PermissionStatus { state: "granted", onchange: null } +PermissionStatus { state: "granted", onchange: null, partial: true } +PermissionStatus { state: "denied", onchange: null } +PermissionStatus { state: "granted", onchange: null } +PermissionStatus { state: "granted", onchange: null, partial: true } +PermissionStatus { state: "denied", onchange: null } +PermissionStatus { state: "granted", onchange: null } +PermissionStatus { state: "granted", onchange: null, partial: true } +PermissionStatus { state: "denied", onchange: null } +PermissionStatus { state: "granted", onchange: null } +PermissionStatus { state: "denied", onchange: null } diff --git a/cli/tests/testdata/run/permissions_cache.ts b/cli/tests/testdata/run/permissions_cache.ts new file mode 100644 index 000000000..c77ee0f36 --- /dev/null +++ b/cli/tests/testdata/run/permissions_cache.ts @@ -0,0 +1,5 @@ +const status = await Deno.permissions.query({ name: "read", path: "foo" }); +console.log(status.state); +status.onchange = () => console.log(status.state); +await Deno.permissions.request({ name: "read", path: "foo" }); // y +await Deno.permissions.revoke({ name: "read", path: "foo" }); -- cgit v1.2.3