mirror of
https://github.com/denoland/deno.git
synced 2024-12-21 23:04:45 -05:00
refactor: clean up permission handling (#9367)
This commit is contained in:
parent
b3fe85163f
commit
0e70d9e59b
20 changed files with 969 additions and 894 deletions
|
@ -1,4 +1,4 @@
|
|||
[WILDCARD]error: Uncaught PermissionDenied: read access to "non-existent", run again with the --allow-read flag
|
||||
[WILDCARD]error: Uncaught PermissionDenied: Requires read access to "non-existent", run again with the --allow-read flag
|
||||
Deno.readFileSync("non-existent");
|
||||
^
|
||||
at [WILDCARD]
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
[WILDCARD]error: Uncaught (in promise) PermissionDenied: read access to "[WILDCARD]001_hello.js", run again with the --allow-read flag
|
||||
[WILDCARD]error: Uncaught (in promise) PermissionDenied: Requires read access to "[WILDCARD]001_hello.js", run again with the --allow-read flag
|
||||
[WILDCARD]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error: Uncaught (in promise) TypeError: network access to "localhost:4545", run again with the --allow-net flag
|
||||
error: Uncaught (in promise) TypeError: Requires net access to "localhost:4545", run again with the --allow-net flag
|
||||
await import("http://localhost:4545/cli/tests/subdir/mod4.js");
|
||||
^
|
||||
at async file:///[WILDCARD]/error_015_dynamic_import_permissions.js:2:3
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
[WILDCARD]
|
||||
error: Uncaught (in worker "") read access to "[WILDCARD]worker_types.ts", run again with the --allow-read flag
|
||||
error: Uncaught (in worker "") Requires read access to "[WILDCARD]worker_types.ts", run again with the --allow-read flag
|
||||
[WILDCARD]
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
[WILDCARD]
|
||||
error: Uncaught (in worker "") network access to "localhost:4545", run again with the --allow-net flag
|
||||
error: Uncaught (in worker "") Requires net access to "localhost:4545", run again with the --allow-net flag
|
||||
[WILDCARD]
|
||||
|
|
|
@ -5520,7 +5520,7 @@ console.log("finish");
|
|||
assert_eq!(util::strip_ansi_codes(&stdout_str), "0.147205063401058\n");
|
||||
let stderr_str = String::from_utf8(output.stderr).unwrap();
|
||||
assert!(util::strip_ansi_codes(&stderr_str)
|
||||
.contains("PermissionDenied: write access"));
|
||||
.contains("PermissionDenied: Requires write access"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -5784,7 +5784,7 @@ console.log("finish");
|
|||
let out = String::from_utf8_lossy(&output.stdout);
|
||||
assert!(!output.status.success());
|
||||
assert!(err.starts_with("Check file"));
|
||||
assert!(err.contains(r#"error: Uncaught (in promise) PermissionDenied: network access to "127.0.0.1:4553""#));
|
||||
assert!(err.contains(r#"error: Uncaught (in promise) PermissionDenied: Requires net access to "127.0.0.1:4553""#));
|
||||
assert!(out.is_empty());
|
||||
}
|
||||
|
||||
|
@ -5806,7 +5806,7 @@ console.log("finish");
|
|||
let out = String::from_utf8_lossy(&output.stdout);
|
||||
assert!(!output.status.success());
|
||||
assert!(err.starts_with("Check file"));
|
||||
assert!(err.contains(r#"error: Uncaught (in promise) PermissionDenied: network access to "127.0.0.1:4553""#));
|
||||
assert!(err.contains(r#"error: Uncaught (in promise) PermissionDenied: Requires net access to "127.0.0.1:4553""#));
|
||||
assert!(out.is_empty());
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ unitTest({ perms: { read: false } }, function dirCwdPermError(): void {
|
|||
Deno.cwd();
|
||||
},
|
||||
Deno.errors.PermissionDenied,
|
||||
"read access to <CWD>, run again with the --allow-read flag",
|
||||
"Requires read access to <CWD>, run again with the --allow-read flag",
|
||||
);
|
||||
});
|
||||
|
||||
|
|
|
@ -158,7 +158,7 @@ unitTest({ perms: { read: false } }, function execPathPerm(): void {
|
|||
Deno.execPath();
|
||||
},
|
||||
Deno.errors.PermissionDenied,
|
||||
"read access to <exec_path>, run again with the --allow-read flag",
|
||||
"Requires read access to <exec_path>, run again with the --allow-read flag",
|
||||
);
|
||||
});
|
||||
|
||||
|
|
|
@ -161,11 +161,11 @@ fn open_helper(
|
|||
let options = args.options;
|
||||
|
||||
if options.read {
|
||||
permissions.check_read(&path)?;
|
||||
permissions.read.check(&path)?;
|
||||
}
|
||||
|
||||
if options.write || options.append {
|
||||
permissions.check_write(&path)?;
|
||||
permissions.write.check(&path)?;
|
||||
}
|
||||
|
||||
open_options
|
||||
|
@ -463,7 +463,7 @@ fn op_chdir(
|
|||
) -> Result<Value, AnyError> {
|
||||
let args: ChdirArgs = serde_json::from_value(args)?;
|
||||
let d = PathBuf::from(&args.directory);
|
||||
state.borrow::<Permissions>().check_read(&d)?;
|
||||
state.borrow::<Permissions>().read.check(&d)?;
|
||||
set_current_dir(&d)?;
|
||||
Ok(json!({}))
|
||||
}
|
||||
|
@ -484,7 +484,7 @@ fn op_mkdir_sync(
|
|||
let args: MkdirArgs = serde_json::from_value(args)?;
|
||||
let path = Path::new(&args.path).to_path_buf();
|
||||
let mode = args.mode.unwrap_or(0o777) & 0o777;
|
||||
state.borrow::<Permissions>().check_write(&path)?;
|
||||
state.borrow::<Permissions>().write.check(&path)?;
|
||||
debug!("op_mkdir {} {:o} {}", path.display(), mode, args.recursive);
|
||||
let mut builder = std::fs::DirBuilder::new();
|
||||
builder.recursive(args.recursive);
|
||||
|
@ -508,7 +508,7 @@ async fn op_mkdir_async(
|
|||
|
||||
{
|
||||
let state = state.borrow();
|
||||
state.borrow::<Permissions>().check_write(&path)?;
|
||||
state.borrow::<Permissions>().write.check(&path)?;
|
||||
}
|
||||
|
||||
tokio::task::spawn_blocking(move || {
|
||||
|
@ -543,7 +543,7 @@ fn op_chmod_sync(
|
|||
let path = Path::new(&args.path).to_path_buf();
|
||||
let mode = args.mode & 0o777;
|
||||
|
||||
state.borrow::<Permissions>().check_write(&path)?;
|
||||
state.borrow::<Permissions>().write.check(&path)?;
|
||||
debug!("op_chmod_sync {} {:o}", path.display(), mode);
|
||||
#[cfg(unix)]
|
||||
{
|
||||
|
@ -572,7 +572,7 @@ async fn op_chmod_async(
|
|||
|
||||
{
|
||||
let state = state.borrow();
|
||||
state.borrow::<Permissions>().check_write(&path)?;
|
||||
state.borrow::<Permissions>().write.check(&path)?;
|
||||
}
|
||||
|
||||
tokio::task::spawn_blocking(move || {
|
||||
|
@ -611,7 +611,7 @@ fn op_chown_sync(
|
|||
) -> Result<Value, AnyError> {
|
||||
let args: ChownArgs = serde_json::from_value(args)?;
|
||||
let path = Path::new(&args.path).to_path_buf();
|
||||
state.borrow::<Permissions>().check_write(&path)?;
|
||||
state.borrow::<Permissions>().write.check(&path)?;
|
||||
debug!(
|
||||
"op_chown_sync {} {:?} {:?}",
|
||||
path.display(),
|
||||
|
@ -643,7 +643,7 @@ async fn op_chown_async(
|
|||
|
||||
{
|
||||
let state = state.borrow();
|
||||
state.borrow::<Permissions>().check_write(&path)?;
|
||||
state.borrow::<Permissions>().write.check(&path)?;
|
||||
}
|
||||
|
||||
tokio::task::spawn_blocking(move || {
|
||||
|
@ -685,7 +685,7 @@ fn op_remove_sync(
|
|||
let path = PathBuf::from(&args.path);
|
||||
let recursive = args.recursive;
|
||||
|
||||
state.borrow::<Permissions>().check_write(&path)?;
|
||||
state.borrow::<Permissions>().write.check(&path)?;
|
||||
|
||||
#[cfg(not(unix))]
|
||||
use std::os::windows::prelude::MetadataExt;
|
||||
|
@ -730,7 +730,7 @@ async fn op_remove_async(
|
|||
|
||||
{
|
||||
let state = state.borrow();
|
||||
state.borrow::<Permissions>().check_write(&path)?;
|
||||
state.borrow::<Permissions>().write.check(&path)?;
|
||||
}
|
||||
|
||||
tokio::task::spawn_blocking(move || {
|
||||
|
@ -786,8 +786,8 @@ fn op_copy_file_sync(
|
|||
let to = PathBuf::from(&args.to);
|
||||
|
||||
let permissions = state.borrow::<Permissions>();
|
||||
permissions.check_read(&from)?;
|
||||
permissions.check_write(&to)?;
|
||||
permissions.read.check(&from)?;
|
||||
permissions.write.check(&to)?;
|
||||
|
||||
debug!("op_copy_file_sync {} {}", from.display(), to.display());
|
||||
// On *nix, Rust reports non-existent `from` as ErrorKind::InvalidInput
|
||||
|
@ -814,8 +814,8 @@ async fn op_copy_file_async(
|
|||
{
|
||||
let state = state.borrow();
|
||||
let permissions = state.borrow::<Permissions>();
|
||||
permissions.check_read(&from)?;
|
||||
permissions.check_write(&to)?;
|
||||
permissions.read.check(&from)?;
|
||||
permissions.write.check(&to)?;
|
||||
}
|
||||
|
||||
debug!("op_copy_file_async {} {}", from.display(), to.display());
|
||||
|
@ -908,7 +908,7 @@ fn op_stat_sync(
|
|||
let args: StatArgs = serde_json::from_value(args)?;
|
||||
let path = PathBuf::from(&args.path);
|
||||
let lstat = args.lstat;
|
||||
state.borrow::<Permissions>().check_read(&path)?;
|
||||
state.borrow::<Permissions>().read.check(&path)?;
|
||||
debug!("op_stat_sync {} {}", path.display(), lstat);
|
||||
let metadata = if lstat {
|
||||
std::fs::symlink_metadata(&path)?
|
||||
|
@ -929,7 +929,7 @@ async fn op_stat_async(
|
|||
|
||||
{
|
||||
let state = state.borrow();
|
||||
state.borrow::<Permissions>().check_read(&path)?;
|
||||
state.borrow::<Permissions>().read.check(&path)?;
|
||||
}
|
||||
|
||||
tokio::task::spawn_blocking(move || {
|
||||
|
@ -960,9 +960,9 @@ fn op_realpath_sync(
|
|||
let path = PathBuf::from(&args.path);
|
||||
|
||||
let permissions = state.borrow::<Permissions>();
|
||||
permissions.check_read(&path)?;
|
||||
permissions.read.check(&path)?;
|
||||
if path.is_relative() {
|
||||
permissions.check_read_blind(¤t_dir()?, "CWD")?;
|
||||
permissions.read.check_blind(¤t_dir()?, "CWD")?;
|
||||
}
|
||||
|
||||
debug!("op_realpath_sync {}", path.display());
|
||||
|
@ -984,9 +984,9 @@ async fn op_realpath_async(
|
|||
{
|
||||
let state = state.borrow();
|
||||
let permissions = state.borrow::<Permissions>();
|
||||
permissions.check_read(&path)?;
|
||||
permissions.read.check(&path)?;
|
||||
if path.is_relative() {
|
||||
permissions.check_read_blind(¤t_dir()?, "CWD")?;
|
||||
permissions.read.check_blind(¤t_dir()?, "CWD")?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1016,7 +1016,7 @@ fn op_read_dir_sync(
|
|||
let args: ReadDirArgs = serde_json::from_value(args)?;
|
||||
let path = PathBuf::from(&args.path);
|
||||
|
||||
state.borrow::<Permissions>().check_read(&path)?;
|
||||
state.borrow::<Permissions>().read.check(&path)?;
|
||||
|
||||
debug!("op_read_dir_sync {}", path.display());
|
||||
let entries: Vec<_> = std::fs::read_dir(path)?
|
||||
|
@ -1048,7 +1048,7 @@ async fn op_read_dir_async(
|
|||
let path = PathBuf::from(&args.path);
|
||||
{
|
||||
let state = state.borrow();
|
||||
state.borrow::<Permissions>().check_read(&path)?;
|
||||
state.borrow::<Permissions>().read.check(&path)?;
|
||||
}
|
||||
tokio::task::spawn_blocking(move || {
|
||||
debug!("op_read_dir_async {}", path.display());
|
||||
|
@ -1092,9 +1092,9 @@ fn op_rename_sync(
|
|||
let newpath = PathBuf::from(&args.newpath);
|
||||
|
||||
let permissions = state.borrow::<Permissions>();
|
||||
permissions.check_read(&oldpath)?;
|
||||
permissions.check_write(&oldpath)?;
|
||||
permissions.check_write(&newpath)?;
|
||||
permissions.read.check(&oldpath)?;
|
||||
permissions.write.check(&oldpath)?;
|
||||
permissions.write.check(&newpath)?;
|
||||
debug!("op_rename_sync {} {}", oldpath.display(), newpath.display());
|
||||
std::fs::rename(&oldpath, &newpath)?;
|
||||
Ok(json!({}))
|
||||
|
@ -1111,9 +1111,9 @@ async fn op_rename_async(
|
|||
{
|
||||
let state = state.borrow();
|
||||
let permissions = state.borrow::<Permissions>();
|
||||
permissions.check_read(&oldpath)?;
|
||||
permissions.check_write(&oldpath)?;
|
||||
permissions.check_write(&newpath)?;
|
||||
permissions.read.check(&oldpath)?;
|
||||
permissions.write.check(&oldpath)?;
|
||||
permissions.write.check(&newpath)?;
|
||||
}
|
||||
tokio::task::spawn_blocking(move || {
|
||||
debug!(
|
||||
|
@ -1145,10 +1145,10 @@ fn op_link_sync(
|
|||
let newpath = PathBuf::from(&args.newpath);
|
||||
|
||||
let permissions = state.borrow::<Permissions>();
|
||||
permissions.check_read(&oldpath)?;
|
||||
permissions.check_write(&oldpath)?;
|
||||
permissions.check_read(&newpath)?;
|
||||
permissions.check_write(&newpath)?;
|
||||
permissions.read.check(&oldpath)?;
|
||||
permissions.write.check(&oldpath)?;
|
||||
permissions.read.check(&newpath)?;
|
||||
permissions.write.check(&newpath)?;
|
||||
|
||||
debug!("op_link_sync {} {}", oldpath.display(), newpath.display());
|
||||
std::fs::hard_link(&oldpath, &newpath)?;
|
||||
|
@ -1167,10 +1167,10 @@ async fn op_link_async(
|
|||
{
|
||||
let state = state.borrow();
|
||||
let permissions = state.borrow::<Permissions>();
|
||||
permissions.check_read(&oldpath)?;
|
||||
permissions.check_write(&oldpath)?;
|
||||
permissions.check_read(&newpath)?;
|
||||
permissions.check_write(&newpath)?;
|
||||
permissions.read.check(&oldpath)?;
|
||||
permissions.write.check(&oldpath)?;
|
||||
permissions.read.check(&newpath)?;
|
||||
permissions.write.check(&newpath)?;
|
||||
}
|
||||
|
||||
tokio::task::spawn_blocking(move || {
|
||||
|
@ -1207,7 +1207,7 @@ fn op_symlink_sync(
|
|||
let oldpath = PathBuf::from(&args.oldpath);
|
||||
let newpath = PathBuf::from(&args.newpath);
|
||||
|
||||
state.borrow::<Permissions>().check_write(&newpath)?;
|
||||
state.borrow::<Permissions>().write.check(&newpath)?;
|
||||
|
||||
debug!(
|
||||
"op_symlink_sync {} {}",
|
||||
|
@ -1259,7 +1259,7 @@ async fn op_symlink_async(
|
|||
|
||||
{
|
||||
let state = state.borrow();
|
||||
state.borrow::<Permissions>().check_write(&newpath)?;
|
||||
state.borrow::<Permissions>().write.check(&newpath)?;
|
||||
}
|
||||
|
||||
tokio::task::spawn_blocking(move || {
|
||||
|
@ -1315,7 +1315,7 @@ fn op_read_link_sync(
|
|||
let args: ReadLinkArgs = serde_json::from_value(args)?;
|
||||
let path = PathBuf::from(&args.path);
|
||||
|
||||
state.borrow::<Permissions>().check_read(&path)?;
|
||||
state.borrow::<Permissions>().read.check(&path)?;
|
||||
|
||||
debug!("op_read_link_value {}", path.display());
|
||||
let target = std::fs::read_link(&path)?.into_os_string();
|
||||
|
@ -1332,7 +1332,7 @@ async fn op_read_link_async(
|
|||
let path = PathBuf::from(&args.path);
|
||||
{
|
||||
let state = state.borrow();
|
||||
state.borrow::<Permissions>().check_read(&path)?;
|
||||
state.borrow::<Permissions>().read.check(&path)?;
|
||||
}
|
||||
tokio::task::spawn_blocking(move || {
|
||||
debug!("op_read_link_async {}", path.display());
|
||||
|
@ -1411,7 +1411,7 @@ fn op_truncate_sync(
|
|||
let path = PathBuf::from(&args.path);
|
||||
let len = args.len;
|
||||
|
||||
state.borrow::<Permissions>().check_write(&path)?;
|
||||
state.borrow::<Permissions>().write.check(&path)?;
|
||||
|
||||
debug!("op_truncate_sync {} {}", path.display(), len);
|
||||
let f = std::fs::OpenOptions::new().write(true).open(&path)?;
|
||||
|
@ -1429,7 +1429,7 @@ async fn op_truncate_async(
|
|||
let len = args.len;
|
||||
{
|
||||
let state = state.borrow();
|
||||
state.borrow::<Permissions>().check_write(&path)?;
|
||||
state.borrow::<Permissions>().write.check(&path)?;
|
||||
}
|
||||
tokio::task::spawn_blocking(move || {
|
||||
debug!("op_truncate_async {} {}", path.display(), len);
|
||||
|
@ -1507,7 +1507,8 @@ fn op_make_temp_dir_sync(
|
|||
|
||||
state
|
||||
.borrow::<Permissions>()
|
||||
.check_write(dir.clone().unwrap_or_else(temp_dir).as_path())?;
|
||||
.write
|
||||
.check(dir.clone().unwrap_or_else(temp_dir).as_path())?;
|
||||
|
||||
// TODO(piscisaureus): use byte vector for paths, not a string.
|
||||
// See https://github.com/denoland/deno/issues/627.
|
||||
|
@ -1538,7 +1539,8 @@ async fn op_make_temp_dir_async(
|
|||
let state = state.borrow();
|
||||
state
|
||||
.borrow::<Permissions>()
|
||||
.check_write(dir.clone().unwrap_or_else(temp_dir).as_path())?;
|
||||
.write
|
||||
.check(dir.clone().unwrap_or_else(temp_dir).as_path())?;
|
||||
}
|
||||
tokio::task::spawn_blocking(move || {
|
||||
// TODO(piscisaureus): use byte vector for paths, not a string.
|
||||
|
@ -1572,7 +1574,8 @@ fn op_make_temp_file_sync(
|
|||
|
||||
state
|
||||
.borrow::<Permissions>()
|
||||
.check_write(dir.clone().unwrap_or_else(temp_dir).as_path())?;
|
||||
.write
|
||||
.check(dir.clone().unwrap_or_else(temp_dir).as_path())?;
|
||||
|
||||
// TODO(piscisaureus): use byte vector for paths, not a string.
|
||||
// See https://github.com/denoland/deno/issues/627.
|
||||
|
@ -1603,7 +1606,8 @@ async fn op_make_temp_file_async(
|
|||
let state = state.borrow();
|
||||
state
|
||||
.borrow::<Permissions>()
|
||||
.check_write(dir.clone().unwrap_or_else(temp_dir).as_path())?;
|
||||
.write
|
||||
.check(dir.clone().unwrap_or_else(temp_dir).as_path())?;
|
||||
}
|
||||
tokio::task::spawn_blocking(move || {
|
||||
// TODO(piscisaureus): use byte vector for paths, not a string.
|
||||
|
@ -1718,7 +1722,7 @@ fn op_utime_sync(
|
|||
let atime = filetime::FileTime::from_unix_time(args.atime.0, args.atime.1);
|
||||
let mtime = filetime::FileTime::from_unix_time(args.mtime.0, args.mtime.1);
|
||||
|
||||
state.borrow::<Permissions>().check_write(&path)?;
|
||||
state.borrow::<Permissions>().write.check(&path)?;
|
||||
filetime::set_file_times(path, atime, mtime)?;
|
||||
Ok(json!({}))
|
||||
}
|
||||
|
@ -1735,7 +1739,7 @@ async fn op_utime_async(
|
|||
let atime = filetime::FileTime::from_unix_time(args.atime.0, args.atime.1);
|
||||
let mtime = filetime::FileTime::from_unix_time(args.mtime.0, args.mtime.1);
|
||||
|
||||
state.borrow().borrow::<Permissions>().check_write(&path)?;
|
||||
state.borrow().borrow::<Permissions>().write.check(&path)?;
|
||||
|
||||
tokio::task::spawn_blocking(move || {
|
||||
filetime::set_file_times(path, atime, mtime)?;
|
||||
|
@ -1753,7 +1757,8 @@ fn op_cwd(
|
|||
let path = current_dir()?;
|
||||
state
|
||||
.borrow::<Permissions>()
|
||||
.check_read_blind(&path, "CWD")?;
|
||||
.read
|
||||
.check_blind(&path, "CWD")?;
|
||||
let path_str = into_string(path.into_os_string())?;
|
||||
Ok(json!(path_str))
|
||||
}
|
||||
|
|
|
@ -112,7 +112,8 @@ fn op_fs_events_open(
|
|||
for path in &args.paths {
|
||||
state
|
||||
.borrow::<Permissions>()
|
||||
.check_read(&PathBuf::from(path))?;
|
||||
.read
|
||||
.check(&PathBuf::from(path))?;
|
||||
watcher.watch(path, recursive_mode)?;
|
||||
}
|
||||
let resource = FsEventsResource {
|
||||
|
|
|
@ -204,7 +204,8 @@ async fn op_datagram_send(
|
|||
{
|
||||
let s = state.borrow();
|
||||
s.borrow::<Permissions>()
|
||||
.check_net(&(&args.hostname, Some(args.port)))?;
|
||||
.net
|
||||
.check(&(&args.hostname, Some(args.port)))?;
|
||||
}
|
||||
let addr = resolve_addr(&args.hostname, args.port)
|
||||
.await?
|
||||
|
@ -229,7 +230,7 @@ async fn op_datagram_send(
|
|||
let address_path = Path::new(&args.path);
|
||||
{
|
||||
let s = state.borrow();
|
||||
s.borrow::<Permissions>().check_write(&address_path)?;
|
||||
s.borrow::<Permissions>().write.check(&address_path)?;
|
||||
}
|
||||
let resource = state
|
||||
.borrow()
|
||||
|
@ -269,7 +270,8 @@ async fn op_connect(
|
|||
let state_ = state.borrow();
|
||||
state_
|
||||
.borrow::<Permissions>()
|
||||
.check_net(&(&args.hostname, Some(args.port)))?;
|
||||
.net
|
||||
.check(&(&args.hostname, Some(args.port)))?;
|
||||
}
|
||||
let addr = resolve_addr(&args.hostname, args.port)
|
||||
.await?
|
||||
|
@ -306,8 +308,8 @@ async fn op_connect(
|
|||
super::check_unstable2(&state, "Deno.connect");
|
||||
{
|
||||
let state_ = state.borrow();
|
||||
state_.borrow::<Permissions>().check_read(&address_path)?;
|
||||
state_.borrow::<Permissions>().check_write(&address_path)?;
|
||||
state_.borrow::<Permissions>().read.check(&address_path)?;
|
||||
state_.borrow::<Permissions>().write.check(&address_path)?;
|
||||
}
|
||||
let path = args.path;
|
||||
let unix_stream = net_unix::UnixStream::connect(Path::new(&path)).await?;
|
||||
|
@ -433,7 +435,7 @@ fn op_listen(
|
|||
if transport == "udp" {
|
||||
super::check_unstable(state, "Deno.listenDatagram");
|
||||
}
|
||||
permissions.check_net(&(&args.hostname, Some(args.port)))?;
|
||||
permissions.net.check(&(&args.hostname, Some(args.port)))?;
|
||||
}
|
||||
let addr = resolve_addr_sync(&args.hostname, args.port)?
|
||||
.next()
|
||||
|
@ -471,8 +473,8 @@ fn op_listen(
|
|||
if transport == "unixpacket" {
|
||||
super::check_unstable(state, "Deno.listenDatagram");
|
||||
}
|
||||
permissions.check_read(&address_path)?;
|
||||
permissions.check_write(&address_path)?;
|
||||
permissions.read.check(&address_path)?;
|
||||
permissions.write.check(&address_path)?;
|
||||
}
|
||||
let (rid, local_addr) = if transport == "unix" {
|
||||
net_unix::listen_unix(state, &address_path)?
|
||||
|
@ -580,7 +582,7 @@ async fn op_dns_resolve(
|
|||
let socker_addr = &ns.socket_addr;
|
||||
let ip = socker_addr.ip().to_string();
|
||||
let port = socker_addr.port();
|
||||
perm.check_net(&(ip, Some(port)))?;
|
||||
perm.net.check(&(ip, Some(port)))?;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,8 @@ fn op_exec_path(
|
|||
let current_exe = env::current_exe().unwrap();
|
||||
state
|
||||
.borrow::<Permissions>()
|
||||
.check_read_blind(¤t_exe, "exec_path")?;
|
||||
.read
|
||||
.check_blind(¤t_exe, "exec_path")?;
|
||||
// Now apply URL parser to current exe to get fully resolved path, otherwise
|
||||
// we might get `./` and `../` bits in `exec_path`
|
||||
let exe_url = Url::from_file_path(current_exe).unwrap();
|
||||
|
@ -54,7 +55,7 @@ fn op_set_env(
|
|||
_zero_copy: &mut [ZeroCopyBuf],
|
||||
) -> Result<Value, AnyError> {
|
||||
let args: SetEnv = serde_json::from_value(args)?;
|
||||
state.borrow::<Permissions>().check_env()?;
|
||||
state.borrow::<Permissions>().env.check()?;
|
||||
let invalid_key =
|
||||
args.key.is_empty() || args.key.contains(&['=', '\0'] as &[char]);
|
||||
let invalid_value = args.value.contains('\0');
|
||||
|
@ -70,7 +71,7 @@ fn op_env(
|
|||
_args: Value,
|
||||
_zero_copy: &mut [ZeroCopyBuf],
|
||||
) -> Result<Value, AnyError> {
|
||||
state.borrow::<Permissions>().check_env()?;
|
||||
state.borrow::<Permissions>().env.check()?;
|
||||
let v = env::vars().collect::<HashMap<String, String>>();
|
||||
Ok(json!(v))
|
||||
}
|
||||
|
@ -86,7 +87,7 @@ fn op_get_env(
|
|||
_zero_copy: &mut [ZeroCopyBuf],
|
||||
) -> Result<Value, AnyError> {
|
||||
let args: GetEnv = serde_json::from_value(args)?;
|
||||
state.borrow::<Permissions>().check_env()?;
|
||||
state.borrow::<Permissions>().env.check()?;
|
||||
if args.key.is_empty() || args.key.contains(&['=', '\0'] as &[char]) {
|
||||
return Err(type_error("Key contains invalid characters."));
|
||||
}
|
||||
|
@ -108,7 +109,7 @@ fn op_delete_env(
|
|||
_zero_copy: &mut [ZeroCopyBuf],
|
||||
) -> Result<Value, AnyError> {
|
||||
let args: DeleteEnv = serde_json::from_value(args)?;
|
||||
state.borrow::<Permissions>().check_env()?;
|
||||
state.borrow::<Permissions>().env.check()?;
|
||||
if args.key.is_empty() || args.key.contains(&['=', '\0'] as &[char]) {
|
||||
return Err(type_error("Key contains invalid characters."));
|
||||
}
|
||||
|
@ -136,7 +137,7 @@ fn op_loadavg(
|
|||
_zero_copy: &mut [ZeroCopyBuf],
|
||||
) -> Result<Value, AnyError> {
|
||||
super::check_unstable(state, "Deno.loadavg");
|
||||
state.borrow::<Permissions>().check_env()?;
|
||||
state.borrow::<Permissions>().env.check()?;
|
||||
match sys_info::loadavg() {
|
||||
Ok(loadavg) => Ok(json!([loadavg.one, loadavg.five, loadavg.fifteen])),
|
||||
Err(_) => Ok(json!([0f64, 0f64, 0f64])),
|
||||
|
@ -149,7 +150,7 @@ fn op_hostname(
|
|||
_zero_copy: &mut [ZeroCopyBuf],
|
||||
) -> Result<Value, AnyError> {
|
||||
super::check_unstable(state, "Deno.hostname");
|
||||
state.borrow::<Permissions>().check_env()?;
|
||||
state.borrow::<Permissions>().env.check()?;
|
||||
let hostname = sys_info::hostname().unwrap_or_else(|_| "".to_string());
|
||||
Ok(json!(hostname))
|
||||
}
|
||||
|
@ -160,7 +161,7 @@ fn op_os_release(
|
|||
_zero_copy: &mut [ZeroCopyBuf],
|
||||
) -> Result<Value, AnyError> {
|
||||
super::check_unstable(state, "Deno.osRelease");
|
||||
state.borrow::<Permissions>().check_env()?;
|
||||
state.borrow::<Permissions>().env.check()?;
|
||||
let release = sys_info::os_release().unwrap_or_else(|_| "".to_string());
|
||||
Ok(json!(release))
|
||||
}
|
||||
|
@ -171,7 +172,7 @@ fn op_system_memory_info(
|
|||
_zero_copy: &mut [ZeroCopyBuf],
|
||||
) -> Result<Value, AnyError> {
|
||||
super::check_unstable(state, "Deno.systemMemoryInfo");
|
||||
state.borrow::<Permissions>().check_env()?;
|
||||
state.borrow::<Permissions>().env.check()?;
|
||||
match sys_info::mem_info() {
|
||||
Ok(info) => Ok(json!({
|
||||
"total": info.total,
|
||||
|
@ -192,7 +193,7 @@ fn op_system_cpu_info(
|
|||
_zero_copy: &mut [ZeroCopyBuf],
|
||||
) -> Result<Value, AnyError> {
|
||||
super::check_unstable(state, "Deno.systemCpuInfo");
|
||||
state.borrow::<Permissions>().check_env()?;
|
||||
state.borrow::<Permissions>().env.check()?;
|
||||
|
||||
let cores = sys_info::cpu_num().ok();
|
||||
let speed = sys_info::cpu_speed().ok();
|
||||
|
|
|
@ -35,19 +35,19 @@ pub fn op_query_permission(
|
|||
let permissions = state.borrow::<Permissions>();
|
||||
let path = args.path.as_deref();
|
||||
let perm = match args.name.as_ref() {
|
||||
"read" => permissions.query_read(&path.as_deref().map(Path::new)),
|
||||
"write" => permissions.query_write(&path.as_deref().map(Path::new)),
|
||||
"net" => permissions.query_net(
|
||||
&match args.host.as_deref() {
|
||||
"read" => permissions.read.query(path.as_deref().map(Path::new)),
|
||||
"write" => permissions.write.query(path.as_deref().map(Path::new)),
|
||||
"net" => permissions.net.query(
|
||||
match args.host.as_deref() {
|
||||
None => None,
|
||||
Some(h) => Some(parse_host(h)?),
|
||||
}
|
||||
.as_ref(),
|
||||
),
|
||||
"env" => permissions.query_env(),
|
||||
"run" => permissions.query_run(),
|
||||
"plugin" => permissions.query_plugin(),
|
||||
"hrtime" => permissions.query_hrtime(),
|
||||
"env" => permissions.env.query(),
|
||||
"run" => permissions.run.query(),
|
||||
"plugin" => permissions.plugin.query(),
|
||||
"hrtime" => permissions.hrtime.query(),
|
||||
n => {
|
||||
return Err(custom_error(
|
||||
"ReferenceError",
|
||||
|
@ -67,19 +67,19 @@ pub fn op_revoke_permission(
|
|||
let permissions = state.borrow_mut::<Permissions>();
|
||||
let path = args.path.as_deref();
|
||||
let perm = match args.name.as_ref() {
|
||||
"read" => permissions.revoke_read(&path.as_deref().map(Path::new)),
|
||||
"write" => permissions.revoke_write(&path.as_deref().map(Path::new)),
|
||||
"net" => permissions.revoke_net(
|
||||
&match args.host.as_deref() {
|
||||
"read" => permissions.read.revoke(path.as_deref().map(Path::new)),
|
||||
"write" => permissions.write.revoke(path.as_deref().map(Path::new)),
|
||||
"net" => permissions.net.revoke(
|
||||
match args.host.as_deref() {
|
||||
None => None,
|
||||
Some(h) => Some(parse_host(h)?),
|
||||
}
|
||||
.as_ref(),
|
||||
),
|
||||
"env" => permissions.revoke_env(),
|
||||
"run" => permissions.revoke_run(),
|
||||
"plugin" => permissions.revoke_plugin(),
|
||||
"hrtime" => permissions.revoke_hrtime(),
|
||||
"env" => permissions.env.revoke(),
|
||||
"run" => permissions.run.revoke(),
|
||||
"plugin" => permissions.plugin.revoke(),
|
||||
"hrtime" => permissions.hrtime.revoke(),
|
||||
n => {
|
||||
return Err(custom_error(
|
||||
"ReferenceError",
|
||||
|
@ -99,19 +99,19 @@ pub fn op_request_permission(
|
|||
let permissions = state.borrow_mut::<Permissions>();
|
||||
let path = args.path.as_deref();
|
||||
let perm = match args.name.as_ref() {
|
||||
"read" => permissions.request_read(&path.as_deref().map(Path::new)),
|
||||
"write" => permissions.request_write(&path.as_deref().map(Path::new)),
|
||||
"net" => permissions.request_net(
|
||||
&match args.host.as_deref() {
|
||||
"read" => permissions.read.request(path.as_deref().map(Path::new)),
|
||||
"write" => permissions.write.request(path.as_deref().map(Path::new)),
|
||||
"net" => permissions.net.request(
|
||||
match args.host.as_deref() {
|
||||
None => None,
|
||||
Some(h) => Some(parse_host(h)?),
|
||||
}
|
||||
.as_ref(),
|
||||
),
|
||||
"env" => permissions.request_env(),
|
||||
"run" => permissions.request_run(),
|
||||
"plugin" => permissions.request_plugin(),
|
||||
"hrtime" => permissions.request_hrtime(),
|
||||
"env" => permissions.env.request(),
|
||||
"run" => permissions.run.request(),
|
||||
"plugin" => permissions.plugin.request(),
|
||||
"hrtime" => permissions.hrtime.request(),
|
||||
n => {
|
||||
return Err(custom_error(
|
||||
"ReferenceError",
|
||||
|
|
|
@ -46,7 +46,7 @@ pub fn op_open_plugin(
|
|||
|
||||
super::check_unstable(state, "Deno.openPlugin");
|
||||
let permissions = state.borrow::<Permissions>();
|
||||
permissions.check_plugin(&filename)?;
|
||||
permissions.plugin.check()?;
|
||||
|
||||
debug!("Loading Plugin: {:#?}", filename);
|
||||
let plugin_lib = Library::open(filename).map(Rc::new)?;
|
||||
|
|
|
@ -88,7 +88,7 @@ fn op_run(
|
|||
_zero_copy: &mut [ZeroCopyBuf],
|
||||
) -> Result<Value, AnyError> {
|
||||
let run_args: RunArgs = serde_json::from_value(args)?;
|
||||
state.borrow::<Permissions>().check_run()?;
|
||||
state.borrow::<Permissions>().run.check()?;
|
||||
|
||||
let args = run_args.cmd;
|
||||
let env = run_args.env;
|
||||
|
@ -193,7 +193,7 @@ async fn op_run_status(
|
|||
|
||||
{
|
||||
let s = state.borrow();
|
||||
s.borrow::<Permissions>().check_run()?;
|
||||
s.borrow::<Permissions>().run.check()?;
|
||||
}
|
||||
|
||||
let resource = state
|
||||
|
@ -285,7 +285,7 @@ fn op_kill(
|
|||
_zero_copy: &mut [ZeroCopyBuf],
|
||||
) -> Result<Value, AnyError> {
|
||||
super::check_unstable(state, "Deno.kill");
|
||||
state.borrow::<Permissions>().check_run()?;
|
||||
state.borrow::<Permissions>().run.check()?;
|
||||
|
||||
let args: KillArgs = serde_json::from_value(args)?;
|
||||
kill(args.pid, args.signo)?;
|
||||
|
|
|
@ -32,7 +32,8 @@ fn op_main_module(
|
|||
let main_path = std::env::current_dir().unwrap().join(main_url.to_string());
|
||||
state
|
||||
.borrow::<Permissions>()
|
||||
.check_read_blind(&main_path, "main_module")?;
|
||||
.read
|
||||
.check_blind(&main_path, "main_module")?;
|
||||
}
|
||||
Ok(json!(&main))
|
||||
}
|
||||
|
|
|
@ -166,7 +166,7 @@ fn op_now(
|
|||
// If the permission is not enabled
|
||||
// Round the nano result on 2 milliseconds
|
||||
// see: https://developer.mozilla.org/en-US/docs/Web/API/DOMHighResTimeStamp#Reduced_time_precision
|
||||
if op_state.borrow::<Permissions>().check_hrtime().is_err() {
|
||||
if op_state.borrow::<Permissions>().hrtime.check().is_err() {
|
||||
subsec_nanos -= subsec_nanos % reduced_time_precision;
|
||||
}
|
||||
|
||||
|
|
|
@ -110,9 +110,9 @@ async fn op_start_tls(
|
|||
super::check_unstable2(&state, "Deno.startTls");
|
||||
let s = state.borrow();
|
||||
let permissions = s.borrow::<Permissions>();
|
||||
permissions.check_net(&(&domain, Some(0)))?;
|
||||
permissions.net.check(&(&domain, Some(0)))?;
|
||||
if let Some(path) = &args.cert_file {
|
||||
permissions.check_read(Path::new(&path))?;
|
||||
permissions.read.check(Path::new(&path))?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -174,9 +174,9 @@ async fn op_connect_tls(
|
|||
{
|
||||
let s = state.borrow();
|
||||
let permissions = s.borrow::<Permissions>();
|
||||
permissions.check_net(&(&args.hostname, Some(args.port)))?;
|
||||
permissions.net.check(&(&args.hostname, Some(args.port)))?;
|
||||
if let Some(path) = &args.cert_file {
|
||||
permissions.check_read(Path::new(&path))?;
|
||||
permissions.read.check(Path::new(&path))?;
|
||||
}
|
||||
}
|
||||
let mut domain = args.hostname.as_str();
|
||||
|
@ -318,9 +318,9 @@ fn op_listen_tls(
|
|||
let key_file = args.key_file;
|
||||
{
|
||||
let permissions = state.borrow::<Permissions>();
|
||||
permissions.check_net(&(&args.hostname, Some(args.port)))?;
|
||||
permissions.check_read(Path::new(&cert_file))?;
|
||||
permissions.check_read(Path::new(&key_file))?;
|
||||
permissions.net.check(&(&args.hostname, Some(args.port)))?;
|
||||
permissions.read.check(Path::new(&cert_file))?;
|
||||
permissions.read.check(Path::new(&key_file))?;
|
||||
}
|
||||
let mut config = ServerConfig::new(NoClientAuth::new());
|
||||
config
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use crate::permissions::resolve_fs_allowlist;
|
||||
use crate::permissions::resolve_read_allowlist;
|
||||
use crate::permissions::resolve_write_allowlist;
|
||||
use crate::permissions::BooleanPermission;
|
||||
use crate::permissions::NetPermission;
|
||||
use crate::permissions::PermissionState;
|
||||
use crate::permissions::Permissions;
|
||||
use crate::permissions::ReadPermission;
|
||||
use crate::permissions::UnaryPermission;
|
||||
use crate::permissions::WritePermission;
|
||||
use crate::web_worker::run_web_worker;
|
||||
use crate::web_worker::WebWorker;
|
||||
use crate::web_worker::WebWorkerHandle;
|
||||
|
@ -105,49 +110,54 @@ pub fn init(
|
|||
);
|
||||
}
|
||||
|
||||
fn merge_permission_state(
|
||||
target: &PermissionState,
|
||||
fn merge_boolean_permission(
|
||||
target: &BooleanPermission,
|
||||
incoming: Option<PermissionState>,
|
||||
) -> Result<PermissionState, AnyError> {
|
||||
match target {
|
||||
) -> Result<BooleanPermission, AnyError> {
|
||||
let mut perm = target.clone();
|
||||
perm.state = match target.state {
|
||||
PermissionState::Granted => match incoming {
|
||||
Some(x) => Ok(x),
|
||||
None => Ok(*target),
|
||||
Some(state) => state,
|
||||
None => perm.state,
|
||||
},
|
||||
_ => match incoming {
|
||||
Some(x) => match x {
|
||||
PermissionState::Denied => Ok(x),
|
||||
_ => Err(custom_error(
|
||||
"PermissionDenied",
|
||||
"Can't escalate parent thread permissions",
|
||||
)),
|
||||
Some(state) => match state {
|
||||
PermissionState::Denied => state,
|
||||
_ => {
|
||||
return Err(custom_error(
|
||||
"PermissionDenied",
|
||||
"Can't escalate parent thread permissions",
|
||||
))
|
||||
}
|
||||
},
|
||||
None => Ok(*target),
|
||||
None => perm.state,
|
||||
},
|
||||
}
|
||||
};
|
||||
Ok(perm)
|
||||
}
|
||||
|
||||
fn check_net_permission_contains(
|
||||
a: &HashSet<String>,
|
||||
b: &HashSet<String>,
|
||||
a: &HashSet<NetPermission>,
|
||||
b: &HashSet<NetPermission>,
|
||||
) -> bool {
|
||||
b.iter().all(|x| a.contains(x))
|
||||
}
|
||||
|
||||
fn merge_net_permissions(
|
||||
target: &UnaryPermission<String>,
|
||||
incoming: Option<UnaryPermission<String>>,
|
||||
) -> Result<UnaryPermission<String>, AnyError> {
|
||||
target: &UnaryPermission<NetPermission>,
|
||||
incoming: Option<UnaryPermission<NetPermission>>,
|
||||
) -> Result<UnaryPermission<NetPermission>, AnyError> {
|
||||
if incoming.is_none() {
|
||||
return Ok(target.clone());
|
||||
};
|
||||
|
||||
let new_permissions = incoming.unwrap();
|
||||
match &target.global_state {
|
||||
PermissionState::Granted => Ok(UnaryPermission::<String> {
|
||||
PermissionState::Granted => Ok(UnaryPermission::<NetPermission> {
|
||||
global_state: new_permissions.global_state,
|
||||
granted_list: new_permissions.granted_list,
|
||||
denied_list: new_permissions.denied_list,
|
||||
..Permissions::new_net(&None)
|
||||
}),
|
||||
PermissionState::Prompt => match new_permissions.global_state {
|
||||
//Throw
|
||||
|
@ -161,10 +171,11 @@ fn merge_net_permissions(
|
|||
&target.granted_list,
|
||||
&new_permissions.granted_list,
|
||||
) {
|
||||
Ok(UnaryPermission::<String> {
|
||||
Ok(UnaryPermission::<NetPermission> {
|
||||
global_state: new_permissions.global_state,
|
||||
granted_list: new_permissions.granted_list,
|
||||
denied_list: target.denied_list.clone(),
|
||||
..Permissions::new_net(&None)
|
||||
})
|
||||
} else {
|
||||
Err(custom_error(
|
||||
|
@ -174,17 +185,19 @@ fn merge_net_permissions(
|
|||
}
|
||||
}
|
||||
//Copy
|
||||
PermissionState::Denied => Ok(UnaryPermission::<String> {
|
||||
PermissionState::Denied => Ok(UnaryPermission::<NetPermission> {
|
||||
global_state: new_permissions.global_state,
|
||||
granted_list: new_permissions.granted_list,
|
||||
denied_list: new_permissions.denied_list,
|
||||
..Permissions::new_net(&None)
|
||||
}),
|
||||
},
|
||||
PermissionState::Denied => match new_permissions.global_state {
|
||||
PermissionState::Denied => Ok(UnaryPermission::<String> {
|
||||
PermissionState::Denied => Ok(UnaryPermission::<NetPermission> {
|
||||
global_state: new_permissions.global_state,
|
||||
granted_list: new_permissions.granted_list,
|
||||
denied_list: new_permissions.denied_list,
|
||||
..Permissions::new_net(&None)
|
||||
}),
|
||||
_ => Err(custom_error(
|
||||
"PermissionDenied",
|
||||
|
@ -194,45 +207,40 @@ fn merge_net_permissions(
|
|||
}
|
||||
}
|
||||
|
||||
enum WorkerPermissionType {
|
||||
READ,
|
||||
WRITE,
|
||||
}
|
||||
|
||||
fn check_read_permissions(
|
||||
allow_list: &HashSet<PathBuf>,
|
||||
allow_list: &HashSet<ReadPermission>,
|
||||
current_permissions: &Permissions,
|
||||
) -> bool {
|
||||
allow_list
|
||||
.iter()
|
||||
.all(|x| current_permissions.check_read(&x).is_ok())
|
||||
.all(|x| current_permissions.read.check(&x.0).is_ok())
|
||||
}
|
||||
|
||||
fn check_write_permissions(
|
||||
allow_list: &HashSet<PathBuf>,
|
||||
allow_list: &HashSet<WritePermission>,
|
||||
current_permissions: &Permissions,
|
||||
) -> bool {
|
||||
allow_list
|
||||
.iter()
|
||||
.all(|x| current_permissions.check_write(&x).is_ok())
|
||||
.all(|x| current_permissions.write.check(&x.0).is_ok())
|
||||
}
|
||||
|
||||
fn merge_read_write_permissions(
|
||||
permission_type: WorkerPermissionType,
|
||||
target: &UnaryPermission<PathBuf>,
|
||||
incoming: Option<UnaryPermission<PathBuf>>,
|
||||
fn merge_read_permissions(
|
||||
target: &UnaryPermission<ReadPermission>,
|
||||
incoming: Option<UnaryPermission<ReadPermission>>,
|
||||
current_permissions: &Permissions,
|
||||
) -> Result<UnaryPermission<PathBuf>, AnyError> {
|
||||
) -> Result<UnaryPermission<ReadPermission>, AnyError> {
|
||||
if incoming.is_none() {
|
||||
return Ok(target.clone());
|
||||
};
|
||||
|
||||
let new_permissions = incoming.unwrap();
|
||||
match &target.global_state {
|
||||
PermissionState::Granted => Ok(UnaryPermission::<PathBuf> {
|
||||
PermissionState::Granted => Ok(UnaryPermission::<ReadPermission> {
|
||||
global_state: new_permissions.global_state,
|
||||
granted_list: new_permissions.granted_list,
|
||||
denied_list: new_permissions.denied_list,
|
||||
..Permissions::new_read(&None)
|
||||
}),
|
||||
PermissionState::Prompt => match new_permissions.global_state {
|
||||
//Throw
|
||||
|
@ -242,20 +250,15 @@ fn merge_read_write_permissions(
|
|||
)),
|
||||
//Merge
|
||||
PermissionState::Prompt => {
|
||||
if match permission_type {
|
||||
WorkerPermissionType::READ => check_read_permissions(
|
||||
&new_permissions.granted_list,
|
||||
current_permissions,
|
||||
),
|
||||
WorkerPermissionType::WRITE => check_write_permissions(
|
||||
&new_permissions.granted_list,
|
||||
current_permissions,
|
||||
),
|
||||
} {
|
||||
Ok(UnaryPermission::<PathBuf> {
|
||||
if check_read_permissions(
|
||||
&new_permissions.granted_list,
|
||||
current_permissions,
|
||||
) {
|
||||
Ok(UnaryPermission::<ReadPermission> {
|
||||
global_state: new_permissions.global_state,
|
||||
granted_list: new_permissions.granted_list,
|
||||
denied_list: target.denied_list.clone(),
|
||||
..Permissions::new_read(&None)
|
||||
})
|
||||
} else {
|
||||
Err(custom_error(
|
||||
|
@ -265,17 +268,84 @@ fn merge_read_write_permissions(
|
|||
}
|
||||
}
|
||||
//Copy
|
||||
PermissionState::Denied => Ok(UnaryPermission::<PathBuf> {
|
||||
PermissionState::Denied => Ok(UnaryPermission::<ReadPermission> {
|
||||
global_state: new_permissions.global_state,
|
||||
granted_list: new_permissions.granted_list,
|
||||
denied_list: new_permissions.denied_list,
|
||||
..Permissions::new_read(&None)
|
||||
}),
|
||||
},
|
||||
PermissionState::Denied => match new_permissions.global_state {
|
||||
PermissionState::Denied => Ok(UnaryPermission::<PathBuf> {
|
||||
PermissionState::Denied => Ok(UnaryPermission::<ReadPermission> {
|
||||
global_state: new_permissions.global_state,
|
||||
granted_list: new_permissions.granted_list,
|
||||
denied_list: new_permissions.denied_list,
|
||||
..Permissions::new_read(&None)
|
||||
}),
|
||||
_ => Err(custom_error(
|
||||
"PermissionDenied",
|
||||
"Can't escalate parent thread permissions",
|
||||
)),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn merge_write_permissions(
|
||||
target: &UnaryPermission<WritePermission>,
|
||||
incoming: Option<UnaryPermission<WritePermission>>,
|
||||
current_permissions: &Permissions,
|
||||
) -> Result<UnaryPermission<WritePermission>, AnyError> {
|
||||
if incoming.is_none() {
|
||||
return Ok(target.clone());
|
||||
};
|
||||
|
||||
let new_permissions = incoming.unwrap();
|
||||
match &target.global_state {
|
||||
PermissionState::Granted => Ok(UnaryPermission::<WritePermission> {
|
||||
global_state: new_permissions.global_state,
|
||||
granted_list: new_permissions.granted_list,
|
||||
denied_list: new_permissions.denied_list,
|
||||
..Permissions::new_write(&None)
|
||||
}),
|
||||
PermissionState::Prompt => match new_permissions.global_state {
|
||||
//Throw
|
||||
PermissionState::Granted => Err(custom_error(
|
||||
"PermissionDenied",
|
||||
"Can't escalate parent thread permissions",
|
||||
)),
|
||||
//Merge
|
||||
PermissionState::Prompt => {
|
||||
if check_write_permissions(
|
||||
&new_permissions.granted_list,
|
||||
current_permissions,
|
||||
) {
|
||||
Ok(UnaryPermission::<WritePermission> {
|
||||
global_state: new_permissions.global_state,
|
||||
granted_list: new_permissions.granted_list,
|
||||
denied_list: target.denied_list.clone(),
|
||||
..Permissions::new_write(&None)
|
||||
})
|
||||
} else {
|
||||
Err(custom_error(
|
||||
"PermissionDenied",
|
||||
"Can't escalate parent thread permissions",
|
||||
))
|
||||
}
|
||||
}
|
||||
//Copy
|
||||
PermissionState::Denied => Ok(UnaryPermission::<WritePermission> {
|
||||
global_state: new_permissions.global_state,
|
||||
granted_list: new_permissions.granted_list,
|
||||
denied_list: new_permissions.denied_list,
|
||||
..Permissions::new_write(&None)
|
||||
}),
|
||||
},
|
||||
PermissionState::Denied => match new_permissions.global_state {
|
||||
PermissionState::Denied => Ok(UnaryPermission::<WritePermission> {
|
||||
global_state: new_permissions.global_state,
|
||||
granted_list: new_permissions.granted_list,
|
||||
denied_list: new_permissions.denied_list,
|
||||
..Permissions::new_write(&None)
|
||||
}),
|
||||
_ => Err(custom_error(
|
||||
"PermissionDenied",
|
||||
|
@ -290,11 +360,11 @@ fn create_worker_permissions(
|
|||
permission_args: PermissionsArg,
|
||||
) -> Result<Permissions, AnyError> {
|
||||
Ok(Permissions {
|
||||
env: merge_permission_state(
|
||||
env: merge_boolean_permission(
|
||||
&main_thread_permissions.env,
|
||||
permission_args.env,
|
||||
)?,
|
||||
hrtime: merge_permission_state(
|
||||
hrtime: merge_boolean_permission(
|
||||
&main_thread_permissions.hrtime,
|
||||
permission_args.hrtime,
|
||||
)?,
|
||||
|
@ -302,22 +372,20 @@ fn create_worker_permissions(
|
|||
&main_thread_permissions.net,
|
||||
permission_args.net,
|
||||
)?,
|
||||
plugin: merge_permission_state(
|
||||
plugin: merge_boolean_permission(
|
||||
&main_thread_permissions.plugin,
|
||||
permission_args.plugin,
|
||||
)?,
|
||||
read: merge_read_write_permissions(
|
||||
WorkerPermissionType::READ,
|
||||
read: merge_read_permissions(
|
||||
&main_thread_permissions.read,
|
||||
permission_args.read,
|
||||
&main_thread_permissions,
|
||||
)?,
|
||||
run: merge_permission_state(
|
||||
run: merge_boolean_permission(
|
||||
&main_thread_permissions.run,
|
||||
permission_args.run,
|
||||
)?,
|
||||
write: merge_read_write_permissions(
|
||||
WorkerPermissionType::WRITE,
|
||||
write: merge_write_permissions(
|
||||
&main_thread_permissions.write,
|
||||
permission_args.write,
|
||||
&main_thread_permissions,
|
||||
|
@ -331,16 +399,16 @@ struct PermissionsArg {
|
|||
env: Option<PermissionState>,
|
||||
#[serde(default, deserialize_with = "as_permission_state")]
|
||||
hrtime: Option<PermissionState>,
|
||||
#[serde(default, deserialize_with = "as_unary_string_permission")]
|
||||
net: Option<UnaryPermission<String>>,
|
||||
#[serde(default, deserialize_with = "as_unary_net_permission")]
|
||||
net: Option<UnaryPermission<NetPermission>>,
|
||||
#[serde(default, deserialize_with = "as_permission_state")]
|
||||
plugin: Option<PermissionState>,
|
||||
#[serde(default, deserialize_with = "as_unary_path_permission")]
|
||||
read: Option<UnaryPermission<PathBuf>>,
|
||||
#[serde(default, deserialize_with = "as_unary_read_permission")]
|
||||
read: Option<UnaryPermission<ReadPermission>>,
|
||||
#[serde(default, deserialize_with = "as_permission_state")]
|
||||
run: Option<PermissionState>,
|
||||
#[serde(default, deserialize_with = "as_unary_path_permission")]
|
||||
write: Option<UnaryPermission<PathBuf>>,
|
||||
#[serde(default, deserialize_with = "as_unary_write_permission")]
|
||||
write: Option<UnaryPermission<WritePermission>>,
|
||||
}
|
||||
|
||||
fn as_permission_state<'de, D>(
|
||||
|
@ -402,27 +470,31 @@ impl<'de> de::Visitor<'de> for ParseBooleanOrStringVec {
|
|||
}
|
||||
}
|
||||
|
||||
fn as_unary_string_permission<'de, D>(
|
||||
fn as_unary_net_permission<'de, D>(
|
||||
deserializer: D,
|
||||
) -> Result<Option<UnaryPermission<String>>, D::Error>
|
||||
) -> Result<Option<UnaryPermission<NetPermission>>, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let value: UnaryPermissionBase =
|
||||
deserializer.deserialize_any(ParseBooleanOrStringVec)?;
|
||||
|
||||
let allowed: HashSet<String> = value.paths.into_iter().collect();
|
||||
let allowed: HashSet<NetPermission> = value
|
||||
.paths
|
||||
.into_iter()
|
||||
.map(NetPermission::from_string)
|
||||
.collect();
|
||||
|
||||
Ok(Some(UnaryPermission::<String> {
|
||||
Ok(Some(UnaryPermission::<NetPermission> {
|
||||
global_state: value.global_state,
|
||||
granted_list: allowed,
|
||||
..Default::default()
|
||||
}))
|
||||
}
|
||||
|
||||
fn as_unary_path_permission<'de, D>(
|
||||
fn as_unary_read_permission<'de, D>(
|
||||
deserializer: D,
|
||||
) -> Result<Option<UnaryPermission<PathBuf>>, D::Error>
|
||||
) -> Result<Option<UnaryPermission<ReadPermission>>, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
|
@ -432,9 +504,28 @@ where
|
|||
let paths: Vec<PathBuf> =
|
||||
value.paths.into_iter().map(PathBuf::from).collect();
|
||||
|
||||
Ok(Some(UnaryPermission::<PathBuf> {
|
||||
Ok(Some(UnaryPermission::<ReadPermission> {
|
||||
global_state: value.global_state,
|
||||
granted_list: resolve_fs_allowlist(&Some(paths)),
|
||||
granted_list: resolve_read_allowlist(&Some(paths)),
|
||||
..Default::default()
|
||||
}))
|
||||
}
|
||||
|
||||
fn as_unary_write_permission<'de, D>(
|
||||
deserializer: D,
|
||||
) -> Result<Option<UnaryPermission<WritePermission>>, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let value: UnaryPermissionBase =
|
||||
deserializer.deserialize_any(ParseBooleanOrStringVec)?;
|
||||
|
||||
let paths: Vec<PathBuf> =
|
||||
value.paths.into_iter().map(PathBuf::from).collect();
|
||||
|
||||
Ok(Some(UnaryPermission::<WritePermission> {
|
||||
global_state: value.global_state,
|
||||
granted_list: resolve_write_allowlist(&Some(paths)),
|
||||
..Default::default()
|
||||
}))
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue