mirror of
https://github.com/denoland/deno.git
synced 2025-01-08 23:28:18 -05:00
dx: descriptive permission errors (#3808)
Before: ``` ▶ target/debug/deno https://deno.land/std/examples/echo_server.ts error: Uncaught PermissionDenied: run again with the --allow-net flag ► $deno$/dispatch_json.ts:40:11 at DenoError ($deno$/errors.ts:20:5) at unwrapResponse ($deno$/dispatch_json.ts:40:11) at sendSync ($deno$/dispatch_json.ts:67:10) at listen ($deno$/net.ts:170:15) at https://deno.land/std/examples/echo_server.ts:4:23 ``` ``` ▶ target/debug/deno --allow-read=/usr https://deno.land/std/examples/cat.ts /etc/passwd error: Uncaught PermissionDenied: run again with the --allow-read flag ► $deno$/dispatch_json.ts:40:11 at DenoError ($deno$/errors.ts:20:5) at unwrapResponse ($deno$/dispatch_json.ts:40:11) at sendAsync ($deno$/dispatch_json.ts:91:10) ``` After: ``` ▶ target/debug/deno https://deno.land/std/examples/echo_server.ts error: Uncaught PermissionDenied: network access to "0.0.0.0:8080", run again with the --allow-net flag ► $deno$/dispatch_json.ts:40:11 at DenoError ($deno$/errors.ts:20:5) at unwrapResponse ($deno$/dispatch_json.ts:40:11) at sendSync ($deno$/dispatch_json.ts:67:10) at listen ($deno$/net.ts:170:15) at https://deno.land/std/examples/echo_server.ts:4:23 ``` ``` ▶ target/debug/deno --allow-read=/usr https://deno.land/std/examples/cat.ts /etc/passwd error: Uncaught PermissionDenied: read access to "/etc/passwd", run again with the --allow-read flag ► $deno$/dispatch_json.ts:40:11 at DenoError ($deno$/errors.ts:20:5) at unwrapResponse ($deno$/dispatch_json.ts:40:11) at sendAsync ($deno$/dispatch_json.ts:91:10) ```
This commit is contained in:
parent
ac10d79d23
commit
f32c31a0eb
7 changed files with 25 additions and 28 deletions
|
@ -29,12 +29,13 @@ pub enum PermissionState {
|
||||||
|
|
||||||
impl PermissionState {
|
impl PermissionState {
|
||||||
/// Checks the permission state and returns the result.
|
/// Checks the permission state and returns the result.
|
||||||
pub fn check(self, msg: &str, err_msg: &str) -> Result<(), ErrBox> {
|
pub fn check(self, msg: &str, flag_name: &str) -> Result<(), ErrBox> {
|
||||||
if self == PermissionState::Allow {
|
if self == PermissionState::Allow {
|
||||||
log_perm_access(msg);
|
log_perm_access(msg);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
Err(permission_denied_msg(err_msg.to_string()))
|
let m = format!("{}, run again with the {} flag", msg, flag_name);
|
||||||
|
Err(permission_denied_msg(m))
|
||||||
}
|
}
|
||||||
pub fn is_allow(self) -> bool {
|
pub fn is_allow(self) -> bool {
|
||||||
self == PermissionState::Allow
|
self == PermissionState::Allow
|
||||||
|
@ -129,10 +130,9 @@ impl DenoPermissions {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_run(&self) -> Result<(), ErrBox> {
|
pub fn check_run(&self) -> Result<(), ErrBox> {
|
||||||
self.allow_run.check(
|
self
|
||||||
"access to run a subprocess",
|
.allow_run
|
||||||
"run again with the --allow-run flag",
|
.check("access to run a subprocess", "--allow-run")
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_state_read(&self, path: &Option<&Path>) -> PermissionState {
|
fn get_state_read(&self, path: &Option<&Path>) -> PermissionState {
|
||||||
|
@ -145,7 +145,7 @@ impl DenoPermissions {
|
||||||
pub fn check_read(&self, path: &Path) -> Result<(), ErrBox> {
|
pub fn check_read(&self, path: &Path) -> Result<(), ErrBox> {
|
||||||
self.get_state_read(&Some(path)).check(
|
self.get_state_read(&Some(path)).check(
|
||||||
&format!("read access to \"{}\"", path.display()),
|
&format!("read access to \"{}\"", path.display()),
|
||||||
"run again with the --allow-read flag",
|
"--allow-read",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,7 +159,7 @@ impl DenoPermissions {
|
||||||
pub fn check_write(&self, path: &Path) -> Result<(), ErrBox> {
|
pub fn check_write(&self, path: &Path) -> Result<(), ErrBox> {
|
||||||
self.get_state_write(&Some(path)).check(
|
self.get_state_write(&Some(path)).check(
|
||||||
&format!("write access to \"{}\"", path.display()),
|
&format!("write access to \"{}\"", path.display()),
|
||||||
"run again with the --allow-write flag",
|
"--allow-write",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,30 +188,26 @@ impl DenoPermissions {
|
||||||
pub fn check_net(&self, hostname: &str, port: u16) -> Result<(), ErrBox> {
|
pub fn check_net(&self, hostname: &str, port: u16) -> Result<(), ErrBox> {
|
||||||
self.get_state_net(hostname, Some(port)).check(
|
self.get_state_net(hostname, Some(port)).check(
|
||||||
&format!("network access to \"{}:{}\"", hostname, port),
|
&format!("network access to \"{}:{}\"", hostname, port),
|
||||||
"run again with the --allow-net flag",
|
"--allow-net",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_net_url(&self, url: &url::Url) -> Result<(), ErrBox> {
|
pub fn check_net_url(&self, url: &url::Url) -> Result<(), ErrBox> {
|
||||||
self
|
self
|
||||||
.get_state_net(&format!("{}", url.host().unwrap()), url.port())
|
.get_state_net(&format!("{}", url.host().unwrap()), url.port())
|
||||||
.check(
|
.check(&format!("network access to \"{}\"", url), "--allow-net")
|
||||||
&format!("network access to \"{}\"", url),
|
|
||||||
"run again with the --allow-net flag",
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_env(&self) -> Result<(), ErrBox> {
|
pub fn check_env(&self) -> Result<(), ErrBox> {
|
||||||
self.allow_env.check(
|
self
|
||||||
"access to environment variables",
|
.allow_env
|
||||||
"run again with the --allow-env flag",
|
.check("access to environment variables", "--allow-env")
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_plugin(&self, path: &Path) -> Result<(), ErrBox> {
|
pub fn check_plugin(&self, path: &Path) -> Result<(), ErrBox> {
|
||||||
self.allow_plugin.check(
|
self.allow_plugin.check(
|
||||||
&format!("access to open a plugin: {}", path.display()),
|
&format!("access to open a plugin: {}", path.display()),
|
||||||
"run again with the --allow-plugin flag",
|
"--allow-plugin",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
error: Uncaught TypeError: run again with the --allow-net flag
|
error: Uncaught TypeError: network access to "http://localhost:4545/tests/subdir/mod4.js", run again with the --allow-net flag
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
[WILDCARD]
|
[WILDCARD]
|
||||||
error: Uncaught TypeError: run again with the --allow-read flag
|
error: Uncaught TypeError: read access to "[WILDCARD]passwd", run again with the --allow-read flag
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import { test } from "../testing/mod.ts";
|
import { test } from "../testing/mod.ts";
|
||||||
import {
|
import {
|
||||||
assertEquals,
|
assertEquals,
|
||||||
|
assertStrContains,
|
||||||
assertThrows,
|
assertThrows,
|
||||||
assertThrowsAsync
|
assertThrowsAsync
|
||||||
} from "../testing/asserts.ts";
|
} from "../testing/asserts.ts";
|
||||||
|
@ -227,7 +228,7 @@ test(async function emptyDirPermission(): Promise<void> {
|
||||||
|
|
||||||
const output = await Deno.readAll(stdout);
|
const output = await Deno.readAll(stdout);
|
||||||
|
|
||||||
assertEquals(new TextDecoder().decode(output), s.output);
|
assertStrContains(new TextDecoder().decode(output), s.output);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
await Deno.remove(testfolder, { recursive: true });
|
await Deno.remove(testfolder, { recursive: true });
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||||
import { test } from "../testing/mod.ts";
|
import { test } from "../testing/mod.ts";
|
||||||
import { assertEquals } from "../testing/asserts.ts";
|
import { assertEquals, assertStrContains } from "../testing/asserts.ts";
|
||||||
import * as path from "../path/mod.ts";
|
import * as path from "../path/mod.ts";
|
||||||
import { exists, existsSync } from "./exists.ts";
|
import { exists, existsSync } from "./exists.ts";
|
||||||
|
|
||||||
|
@ -134,7 +134,7 @@ test(async function existsPermission(): Promise<void> {
|
||||||
|
|
||||||
const output = await Deno.readAll(stdout);
|
const output = await Deno.readAll(stdout);
|
||||||
|
|
||||||
assertEquals(new TextDecoder().decode(output), s.output);
|
assertStrContains(new TextDecoder().decode(output), s.output);
|
||||||
}
|
}
|
||||||
|
|
||||||
// done
|
// done
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||||
import { test } from "../testing/mod.ts";
|
import { test } from "../testing/mod.ts";
|
||||||
import { assert, assertEquals } from "../testing/asserts.ts";
|
import { assert, assertEquals, assertStrContains } from "../testing/asserts.ts";
|
||||||
import { BufReader } from "../io/bufio.ts";
|
import { BufReader } from "../io/bufio.ts";
|
||||||
import { TextProtoReader } from "../textproto/mod.ts";
|
import { TextProtoReader } from "../textproto/mod.ts";
|
||||||
|
|
||||||
|
@ -109,8 +109,8 @@ test(async function servePermissionDenied(): Promise<void> {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await fetch("http://localhost:4500/");
|
await fetch("http://localhost:4500/");
|
||||||
assertEquals(
|
assertStrContains(
|
||||||
await errReader.readLine(),
|
(await errReader.readLine()) as string,
|
||||||
"run again with the --allow-read flag"
|
"run again with the --allow-read flag"
|
||||||
);
|
);
|
||||||
} finally {
|
} finally {
|
||||||
|
|
|
@ -229,7 +229,7 @@ When this program is started, it throws PermissionDenied error.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ deno https://deno.land/std/examples/echo_server.ts
|
$ deno https://deno.land/std/examples/echo_server.ts
|
||||||
error: Uncaught PermissionDenied: run again with the --allow-net flag
|
error: Uncaught PermissionDenied: network access to "0.0.0.0:8080", run again with the --allow-net flag
|
||||||
► $deno$/dispatch_json.ts:40:11
|
► $deno$/dispatch_json.ts:40:11
|
||||||
at DenoError ($deno$/errors.ts:20:5)
|
at DenoError ($deno$/errors.ts:20:5)
|
||||||
...
|
...
|
||||||
|
@ -329,7 +329,7 @@ This is an example to restrict file system access by whitelist.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ deno --allow-read=/usr https://deno.land/std/examples/cat.ts /etc/passwd
|
$ deno --allow-read=/usr https://deno.land/std/examples/cat.ts /etc/passwd
|
||||||
error: Uncaught PermissionDenied: run again with the --allow-read flag
|
error: Uncaught PermissionDenied: read access to "/etc/passwd", run again with the --allow-read flag
|
||||||
► $deno$/dispatch_json.ts:40:11
|
► $deno$/dispatch_json.ts:40:11
|
||||||
at DenoError ($deno$/errors.ts:20:5)
|
at DenoError ($deno$/errors.ts:20:5)
|
||||||
...
|
...
|
||||||
|
|
Loading…
Reference in a new issue