summaryrefslogtreecommitdiff
path: root/cli
diff options
context:
space:
mode:
Diffstat (limited to 'cli')
-rw-r--r--cli/dts/lib.deno.ns.d.ts1
-rw-r--r--cli/dts/lib.deno.unstable.d.ts6
-rw-r--r--cli/flags.rs12
-rw-r--r--cli/ops/testing.rs12
-rw-r--r--cli/tests/integration/worker_tests.rs2
-rw-r--r--cli/tests/testdata/test/allow_all.ts2
-rw-r--r--cli/tests/testdata/workers/no_permissions_worker.js12
-rw-r--r--cli/tests/testdata/workers/parent_read_check_granular_worker.js41
-rw-r--r--cli/tests/testdata/workers/parent_read_check_worker.js39
-rw-r--r--cli/tests/testdata/workers/read_check_granular_worker.js40
-rw-r--r--cli/tests/testdata/workers/test.ts235
11 files changed, 172 insertions, 230 deletions
diff --git a/cli/dts/lib.deno.ns.d.ts b/cli/dts/lib.deno.ns.d.ts
index eb91d6fa4..3fff1c61e 100644
--- a/cli/dts/lib.deno.ns.d.ts
+++ b/cli/dts/lib.deno.ns.d.ts
@@ -2178,6 +2178,7 @@ declare namespace Deno {
export interface FfiPermissionDescriptor {
name: "ffi";
+ path?: string | URL;
}
export interface HrtimePermissionDescriptor {
diff --git a/cli/dts/lib.deno.unstable.d.ts b/cli/dts/lib.deno.unstable.d.ts
index 3bea165e5..fd33e1a74 100644
--- a/cli/dts/lib.deno.unstable.d.ts
+++ b/cli/dts/lib.deno.unstable.d.ts
@@ -910,10 +910,12 @@ declare namespace Deno {
* If set to `"inherit"`, the current `ffi` permission will be inherited.
* If set to `true`, the global `ffi` permission will be requested.
* If set to `false`, the global `ffi` permission will be revoked.
+ * If set to `Array<string | URL>`, the `ffi` permission will be requested with the
+ * specified file paths.
*
* Defaults to "inherit".
*/
- ffi?: "inherit" | boolean;
+ ffi?: "inherit" | boolean | Array<string | URL>;
/** Specifies if the `read` permission should be requested or revoked.
* If set to `"inherit"`, the current `read` permission will be inherited.
@@ -1237,7 +1239,7 @@ declare interface WorkerOptions {
* For example: `["https://deno.land", "localhost:8080"]`.
*/
net?: "inherit" | boolean | string[];
- ffi?: "inherit" | boolean;
+ ffi?: "inherit" | boolean | Array<string | URL>;
read?: "inherit" | boolean | Array<string | URL>;
run?: "inherit" | boolean | Array<string | URL>;
write?: "inherit" | boolean | Array<string | URL>;
diff --git a/cli/flags.rs b/cli/flags.rs
index df17c08da..67c76244d 100644
--- a/cli/flags.rs
+++ b/cli/flags.rs
@@ -198,7 +198,7 @@ pub struct Flags {
pub allow_env: Option<Vec<String>>,
pub allow_hrtime: bool,
pub allow_net: Option<Vec<String>>,
- pub allow_ffi: Option<Vec<String>>,
+ pub allow_ffi: Option<Vec<PathBuf>>,
pub allow_read: Option<Vec<PathBuf>>,
pub allow_run: Option<Vec<String>>,
pub allow_write: Option<Vec<PathBuf>>,
@@ -324,7 +324,7 @@ impl Flags {
args.push("--allow-ffi".to_string());
}
Some(ffi_allowlist) => {
- let s = format!("--allow-ffi={}", ffi_allowlist.join(","));
+ let s = format!("--allow-ffi={}", join_paths(ffi_allowlist, ","));
args.push(s);
}
_ => {}
@@ -1685,10 +1685,10 @@ fn config_arg<'a, 'b>() -> Arg<'a, 'b> {
.long_help(
"Load configuration file.
Before 1.14 Deno only supported loading tsconfig.json that allowed
-to customise TypeScript compiler settings.
+to customise TypeScript compiler settings.
-Starting with 1.14 configuration file can be used to configure different
-subcommands like `deno lint` or `deno fmt`.
+Starting with 1.14 configuration file can be used to configure different
+subcommands like `deno lint` or `deno fmt`.
It's recommended to use `deno.json` or `deno.jsonc` as a filename.",
)
@@ -2202,7 +2202,7 @@ fn permission_args_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
}
if let Some(ffi_wl) = matches.values_of("allow-ffi") {
- let ffi_allowlist: Vec<String> = ffi_wl.map(ToString::to_string).collect();
+ let ffi_allowlist: Vec<PathBuf> = ffi_wl.map(PathBuf::from).collect();
flags.allow_ffi = Some(ffi_allowlist);
debug!("ffi allowlist: {:#?}", &flags.allow_ffi);
}
diff --git a/cli/ops/testing.rs b/cli/ops/testing.rs
index 99cfc670e..31b60b480 100644
--- a/cli/ops/testing.rs
+++ b/cli/ops/testing.rs
@@ -4,8 +4,8 @@ use deno_core::error::AnyError;
use deno_core::JsRuntime;
use deno_core::ModuleSpecifier;
use deno_core::OpState;
-use deno_runtime::ops::worker_host::create_worker_permissions;
-use deno_runtime::ops::worker_host::PermissionsArg;
+use deno_runtime::permissions::create_child_permissions;
+use deno_runtime::permissions::ChildPermissionsArg;
use deno_runtime::permissions::Permissions;
use std::sync::mpsc::Sender;
use uuid::Uuid;
@@ -26,15 +26,15 @@ struct PermissionsHolder(Uuid, Permissions);
pub fn op_pledge_test_permissions(
state: &mut OpState,
- args: PermissionsArg,
+ args: ChildPermissionsArg,
_: (),
) -> Result<Uuid, AnyError> {
deno_runtime::ops::check_unstable(state, "Deno.test.permissions");
let token = Uuid::new_v4();
- let parent_permissions = state.borrow::<Permissions>().clone();
- let worker_permissions =
- create_worker_permissions(parent_permissions.clone(), args)?;
+ let parent_permissions = state.borrow_mut::<Permissions>();
+ let worker_permissions = create_child_permissions(parent_permissions, args)?;
+ let parent_permissions = parent_permissions.clone();
state.put::<PermissionsHolder>(PermissionsHolder(token, parent_permissions));
diff --git a/cli/tests/integration/worker_tests.rs b/cli/tests/integration/worker_tests.rs
index bf1057821..c17b63af9 100644
--- a/cli/tests/integration/worker_tests.rs
+++ b/cli/tests/integration/worker_tests.rs
@@ -3,7 +3,7 @@
use crate::itest;
itest!(workers {
- args: "test --reload --location http://127.0.0.1:4545/ --allow-net --allow-read --unstable workers/test.ts",
+ args: "test --reload --location http://127.0.0.1:4545/ -A --unstable workers/test.ts",
output: "workers/test.ts.out",
http_server: true,
});
diff --git a/cli/tests/testdata/test/allow_all.ts b/cli/tests/testdata/test/allow_all.ts
index abe55a8d5..e70ac46b0 100644
--- a/cli/tests/testdata/test/allow_all.ts
+++ b/cli/tests/testdata/test/allow_all.ts
@@ -18,7 +18,7 @@ for (const name of permissions) {
},
async fn() {
const status = await Deno.permissions.query({ name });
- assertEquals(status.state, "denied");
+ assertEquals(status.state, "prompt");
},
});
diff --git a/cli/tests/testdata/workers/no_permissions_worker.js b/cli/tests/testdata/workers/no_permissions_worker.js
index db0d911ac..f49f690ab 100644
--- a/cli/tests/testdata/workers/no_permissions_worker.js
+++ b/cli/tests/testdata/workers/no_permissions_worker.js
@@ -6,12 +6,12 @@ self.onmessage = async () => {
const run = await Deno.permissions.query({ name: "run" });
const write = await Deno.permissions.query({ name: "write" });
self.postMessage(
- hrtime.state === "denied" &&
- net.state === "denied" &&
- ffi.state === "denied" &&
- read.state === "denied" &&
- run.state === "denied" &&
- write.state === "denied",
+ hrtime.state === "prompt" &&
+ net.state === "prompt" &&
+ ffi.state === "prompt" &&
+ read.state === "prompt" &&
+ run.state === "prompt" &&
+ write.state === "prompt",
);
self.close();
};
diff --git a/cli/tests/testdata/workers/parent_read_check_granular_worker.js b/cli/tests/testdata/workers/parent_read_check_granular_worker.js
deleted file mode 100644
index 1391190cd..000000000
--- a/cli/tests/testdata/workers/parent_read_check_granular_worker.js
+++ /dev/null
@@ -1,41 +0,0 @@
-const worker = new Worker(
- new URL("./read_check_granular_worker.js", import.meta.url).href,
- {
- type: "module",
- deno: {
- namespace: true,
- permissions: {
- read: [],
- },
- },
- },
-);
-
-let received = 0;
-const messages = [];
-
-worker.onmessage = ({ data: childResponse }) => {
- received++;
- postMessage({
- childHasPermission: childResponse.hasPermission,
- index: childResponse.index,
- parentHasPermission: messages[childResponse.index],
- });
- if (received === messages.length) {
- worker.terminate();
- }
-};
-
-onmessage = async ({ data }) => {
- const { state } = await Deno.permissions.query({
- name: "read",
- path: data.path,
- });
-
- messages[data.index] = state === "granted";
-
- worker.postMessage({
- index: data.index,
- route: data.route,
- });
-};
diff --git a/cli/tests/testdata/workers/parent_read_check_worker.js b/cli/tests/testdata/workers/parent_read_check_worker.js
index ec92cca3f..87ea6bded 100644
--- a/cli/tests/testdata/workers/parent_read_check_worker.js
+++ b/cli/tests/testdata/workers/parent_read_check_worker.js
@@ -1,27 +1,18 @@
-onmessage = async () => {
- const { state } = await Deno.permissions.query({
- name: "read",
- });
-
- const worker = new Worker(
- new URL("./read_check_worker.js", import.meta.url).href,
- {
- type: "module",
- deno: {
- namespace: true,
- permissions: {
- read: false,
- },
- },
+const worker = new Worker(
+ new URL("./read_check_granular_worker.js", import.meta.url).href,
+ {
+ type: "module",
+ deno: {
+ namespace: true,
+ permissions: "none",
},
- );
+ },
+);
+
+onmessage = ({ data }) => {
+ worker.postMessage(data);
+};
- worker.onmessage = ({ data: childHasPermission }) => {
- postMessage({
- parentHasPermission: state === "granted",
- childHasPermission,
- });
- close();
- };
- worker.postMessage(null);
+worker.onmessage = ({ data }) => {
+ postMessage(data);
};
diff --git a/cli/tests/testdata/workers/read_check_granular_worker.js b/cli/tests/testdata/workers/read_check_granular_worker.js
index 25f2058b3..d40fac876 100644
--- a/cli/tests/testdata/workers/read_check_granular_worker.js
+++ b/cli/tests/testdata/workers/read_check_granular_worker.js
@@ -1,11 +1,29 @@
-onmessage = async ({ data }) => {
- const { state } = await Deno.permissions.query({
- name: "read",
- path: data.path,
- });
-
- postMessage({
- hasPermission: state === "granted",
- index: data.index,
- });
-};
+// deno-fmt-ignore-file
+postMessage({
+ envGlobal: (await Deno.permissions.query({ name: "env" })).state,
+ envFoo: (await Deno.permissions.query({ name: "env", variable: "foo" })).state,
+ envAbsent: (await Deno.permissions.query({ name: "env", variable: "absent" })).state,
+ hrtime: (await Deno.permissions.query({ name: "hrtime" })).state,
+ netGlobal: (await Deno.permissions.query({ name: "net" })).state,
+ netFoo: (await Deno.permissions.query({ name: "net", host: "foo" })).state,
+ netFoo8000: (await Deno.permissions.query({ name: "net", host: "foo:8000" })).state,
+ netBar: (await Deno.permissions.query({ name: "net", host: "bar" })).state,
+ netBar8000: (await Deno.permissions.query({ name: "net", host: "bar:8000" })).state,
+ ffiGlobal: (await Deno.permissions.query({ name: "ffi" })).state,
+ ffiFoo: (await Deno.permissions.query({ name: "ffi", path: new URL("foo", import.meta.url) })).state,
+ ffiBar: (await Deno.permissions.query({ name: "ffi", path: "bar" })).state,
+ ffiAbsent: (await Deno.permissions.query({ name: "ffi", path: "absent" })).state,
+ readGlobal: (await Deno.permissions.query({ name: "read" })).state,
+ readFoo: (await Deno.permissions.query({ name: "read", path: new URL("foo", import.meta.url) })).state,
+ readBar: (await Deno.permissions.query({ name: "read", path: "bar" })).state,
+ readAbsent: (await Deno.permissions.query({ name: "read", path: "absent" })).state,
+ runGlobal: (await Deno.permissions.query({ name: "run" })).state,
+ runFoo: (await Deno.permissions.query({ name: "run", command: new URL("foo", import.meta.url) })).state,
+ runBar: (await Deno.permissions.query({ name: "run", command: "bar" })).state,
+ runBaz: (await Deno.permissions.query({ name: "run", command: "./baz" })).state,
+ runAbsent: (await Deno.permissions.query({ name: "run", command: "absent" })).state,
+ writeGlobal: (await Deno.permissions.query({ name: "write" })).state,
+ writeFoo: (await Deno.permissions.query({ name: "write", path: new URL("foo", import.meta.url) })).state,
+ writeBar: (await Deno.permissions.query({ name: "write", path: "bar" })).state,
+ writeAbsent: (await Deno.permissions.query({ name: "write", path: "absent" })).state,
+});
diff --git a/cli/tests/testdata/workers/test.ts b/cli/tests/testdata/workers/test.ts
index effd104f5..4a6575863 100644
--- a/cli/tests/testdata/workers/test.ts
+++ b/cli/tests/testdata/workers/test.ts
@@ -8,7 +8,6 @@ import {
assertThrows,
} from "../../../../test_util/std/testing/asserts.ts";
import { deferred } from "../../../../test_util/std/async/deferred.ts";
-import { fromFileUrl } from "../../../../test_util/std/path/mod.ts";
Deno.test({
name: "worker terminate",
@@ -454,7 +453,6 @@ Deno.test("Worker limit children permissions", async function () {
});
Deno.test("Worker limit children permissions granularly", async function () {
- const promise = deferred();
const worker = new Worker(
new URL("./read_check_granular_worker.js", import.meta.url).href,
{
@@ -462,53 +460,52 @@ Deno.test("Worker limit children permissions granularly", async function () {
deno: {
namespace: true,
permissions: {
- read: [
- new URL("./read_check_worker.js", import.meta.url),
- ],
+ env: ["foo"],
+ hrtime: true,
+ net: ["foo", "bar:8000"],
+ ffi: [new URL("foo", import.meta.url), "bar"],
+ read: [new URL("foo", import.meta.url), "bar"],
+ run: [new URL("foo", import.meta.url), "bar", "./baz"],
+ write: [new URL("foo", import.meta.url), "bar"],
},
},
},
);
-
- //Routes are relative to the spawned worker location
- const routes = [
- {
- permission: false,
- path: fromFileUrl(
- new URL("read_check_granular_worker.js", import.meta.url),
- ),
- },
- {
- permission: true,
- path: fromFileUrl(new URL("read_check_worker.js", import.meta.url)),
- },
- ];
-
- let checked = 0;
- worker.onmessage = ({ data }) => {
- checked++;
- assertEquals(data.hasPermission, routes[data.index].permission);
- routes.shift();
- if (checked === routes.length) {
- promise.resolve();
- }
- };
-
- routes.forEach(({ path }, index) =>
- worker.postMessage({
- index,
- path,
- })
- );
-
- await promise;
+ const promise = deferred();
+ worker.onmessage = ({ data }) => promise.resolve(data);
+ assertEquals(await promise, {
+ envGlobal: "prompt",
+ envFoo: "granted",
+ envAbsent: "prompt",
+ hrtime: "granted",
+ netGlobal: "prompt",
+ netFoo: "granted",
+ netFoo8000: "granted",
+ netBar: "prompt",
+ netBar8000: "granted",
+ ffiGlobal: "prompt",
+ ffiFoo: "granted",
+ ffiBar: "granted",
+ ffiAbsent: "prompt",
+ readGlobal: "prompt",
+ readFoo: "granted",
+ readBar: "granted",
+ readAbsent: "prompt",
+ runGlobal: "prompt",
+ runFoo: "granted",
+ runBar: "granted",
+ runBaz: "granted",
+ runAbsent: "prompt",
+ writeGlobal: "prompt",
+ writeFoo: "granted",
+ writeBar: "granted",
+ writeAbsent: "prompt",
+ });
worker.terminate();
});
Deno.test("Nested worker limit children permissions", async function () {
- const promise = deferred();
-
- /** This worker has read permissions but doesn't grant them to its children */
+ /** This worker has permissions but doesn't grant them to its children */
const worker = new Worker(
new URL("./parent_read_check_worker.js", import.meta.url).href,
{
@@ -519,104 +516,65 @@ Deno.test("Nested worker limit children permissions", async function () {
},
},
);
-
- worker.onmessage = ({ data }) => {
- assert(data.parentHasPermission);
- assert(!data.childHasPermission);
- promise.resolve();
- };
-
- worker.postMessage(null);
-
- await promise;
- worker.terminate();
-});
-
-Deno.test("Nested worker limit children permissions granularly", async function () {
const promise = deferred();
-
- /** This worker has read permissions but doesn't grant them to its children */
- const worker = new Worker(
- new URL("./parent_read_check_granular_worker.js", import.meta.url)
- .href,
- {
- type: "module",
- deno: {
- namespace: true,
- permissions: {
- read: [
- new URL("./read_check_granular_worker.js", import.meta.url),
- ],
- },
- },
- },
- );
-
- //Routes are relative to the spawned worker location
- const routes = [
- {
- childHasPermission: false,
- parentHasPermission: true,
- path: fromFileUrl(
- new URL("read_check_granular_worker.js", import.meta.url),
- ),
- },
- {
- childHasPermission: false,
- parentHasPermission: false,
- path: fromFileUrl(new URL("read_check_worker.js", import.meta.url)),
- },
- ];
-
- let checked = 0;
- worker.onmessage = ({ data }) => {
- checked++;
- assertEquals(
- data.childHasPermission,
- routes[data.index].childHasPermission,
- );
- assertEquals(
- data.parentHasPermission,
- routes[data.index].parentHasPermission,
- );
- if (checked === routes.length) {
- promise.resolve();
- }
- };
-
- // Index needed cause requests will be handled asynchronously
- routes.forEach(({ path }, index) =>
- worker.postMessage({
- index,
- path,
- })
- );
-
- await promise;
+ worker.onmessage = ({ data }) => promise.resolve(data);
+ assertEquals(await promise, {
+ envGlobal: "prompt",
+ envFoo: "prompt",
+ envAbsent: "prompt",
+ hrtime: "prompt",
+ netGlobal: "prompt",
+ netFoo: "prompt",
+ netFoo8000: "prompt",
+ netBar: "prompt",
+ netBar8000: "prompt",
+ ffiGlobal: "prompt",
+ ffiFoo: "prompt",
+ ffiBar: "prompt",
+ ffiAbsent: "prompt",
+ readGlobal: "prompt",
+ readFoo: "prompt",
+ readBar: "prompt",
+ readAbsent: "prompt",
+ runGlobal: "prompt",
+ runFoo: "prompt",
+ runBar: "prompt",
+ runBaz: "prompt",
+ runAbsent: "prompt",
+ writeGlobal: "prompt",
+ writeFoo: "prompt",
+ writeBar: "prompt",
+ writeAbsent: "prompt",
+ });
worker.terminate();
});
// This test relies on env permissions not being granted on main thread
-Deno.test("Worker initialization throws on worker permissions greater than parent thread permissions", function () {
- assertThrows(
- () => {
- const worker = new Worker(
- new URL("./deno_worker.ts", import.meta.url).href,
- {
- type: "module",
- deno: {
- namespace: true,
- permissions: {
- env: true,
+Deno.test({
+ name:
+ "Worker initialization throws on worker permissions greater than parent thread permissions",
+ permissions: { env: false },
+ fn: function () {
+ assertThrows(
+ () => {
+ const worker = new Worker(
+ new URL("./deno_worker.ts", import.meta.url).href,
+ {
+ type: "module",
+ deno: {
+ namespace: true,
+ permissions: {
+ env: true,
+ },
},
},
- },
- );
- worker.terminate();
- },
- Deno.errors.PermissionDenied,
- "Can't escalate parent thread permissions",
- );
+ );
+ worker.terminate();
+ },
+ Deno.errors.PermissionDenied,
+ "Can't escalate parent thread permissions",
+ );
+ },
});
Deno.test("Worker with disabled permissions", async function () {
@@ -643,6 +601,19 @@ Deno.test("Worker with disabled permissions", async function () {
worker.terminate();
});
+Deno.test("Worker with invalid permission arg", function () {
+ assertThrows(
+ () =>
+ new Worker(`data:,close();`, {
+ type: "module",
+ // @ts-expect-error invalid env value
+ deno: { permissions: { env: "foo" } },
+ }),
+ TypeError,
+ 'Error parsing args: (deno.permissions.env) invalid value: string "foo", expected "inherit" or boolean or string[]',
+ );
+});
+
Deno.test({
name: "worker location",
fn: async function () {