summaryrefslogtreecommitdiff
path: root/runtime/ops
diff options
context:
space:
mode:
authorLeo Kettmeir <crowlkats@toaxl.com>2024-11-04 09:17:21 -0800
committerGitHub <noreply@github.com>2024-11-04 09:17:21 -0800
commitfe9f0ee5934871175758857899fe64e56c397fd5 (patch)
treeee770a45366d1b054e7429cea2eff56b04532830 /runtime/ops
parentfb1d33a7111e45e9b414cfe922a5db5ee4daf3ea (diff)
refactor(runtime/permissions): use concrete error types (#26464)
Diffstat (limited to 'runtime/ops')
-rw-r--r--runtime/ops/fs_events.rs5
-rw-r--r--runtime/ops/os/mod.rs23
-rw-r--r--runtime/ops/permissions.rs43
-rw-r--r--runtime/ops/process.rs24
-rw-r--r--runtime/ops/worker_host.rs2
5 files changed, 45 insertions, 52 deletions
diff --git a/runtime/ops/fs_events.rs b/runtime/ops/fs_events.rs
index 648553376..c8e0228bc 100644
--- a/runtime/ops/fs_events.rs
+++ b/runtime/ops/fs_events.rs
@@ -114,7 +114,7 @@ pub enum FsEventsError {
#[error(transparent)]
Resource(deno_core::error::AnyError),
#[error(transparent)]
- Permission(deno_core::error::AnyError),
+ Permission(#[from] deno_permissions::PermissionCheckError),
#[error(transparent)]
Notify(#[from] NotifyError),
#[error(transparent)]
@@ -181,8 +181,7 @@ fn op_fs_events_open(
for path in &paths {
let path = state
.borrow_mut::<PermissionsContainer>()
- .check_read(path, "Deno.watchFs()")
- .map_err(FsEventsError::Permission)?;
+ .check_read(path, "Deno.watchFs()")?;
let watcher = state.borrow_mut::<WatcherState>();
watcher.watcher.watch(&path, recursive_mode)?;
diff --git a/runtime/ops/os/mod.rs b/runtime/ops/os/mod.rs
index 24b0389e1..9bee9d823 100644
--- a/runtime/ops/os/mod.rs
+++ b/runtime/ops/os/mod.rs
@@ -73,7 +73,7 @@ deno_core::extension!(
#[derive(Debug, thiserror::Error)]
pub enum OsError {
#[error(transparent)]
- Permission(deno_core::error::AnyError),
+ Permission(#[from] deno_permissions::PermissionCheckError),
#[error("File name or path {0:?} is not valid UTF-8")]
InvalidUtf8(std::ffi::OsString),
#[error("Key is an empty string.")]
@@ -94,8 +94,7 @@ fn op_exec_path(state: &mut OpState) -> Result<String, OsError> {
let current_exe = env::current_exe().unwrap();
state
.borrow_mut::<PermissionsContainer>()
- .check_read_blind(&current_exe, "exec_path", "Deno.execPath()")
- .map_err(OsError::Permission)?;
+ .check_read_blind(&current_exe, "exec_path", "Deno.execPath()")?;
// normalize path so it doesn't include '.' or '..' components
let path = normalize_path(current_exe);
@@ -111,10 +110,7 @@ fn op_set_env(
#[string] key: &str,
#[string] value: &str,
) -> Result<(), OsError> {
- state
- .borrow_mut::<PermissionsContainer>()
- .check_env(key)
- .map_err(OsError::Permission)?;
+ state.borrow_mut::<PermissionsContainer>().check_env(key)?;
if key.is_empty() {
return Err(OsError::EnvEmptyKey);
}
@@ -146,10 +142,7 @@ fn op_get_env(
let skip_permission_check = NODE_ENV_VAR_ALLOWLIST.contains(&key);
if !skip_permission_check {
- state
- .borrow_mut::<PermissionsContainer>()
- .check_env(&key)
- .map_err(OsError::Permission)?;
+ state.borrow_mut::<PermissionsContainer>().check_env(&key)?;
}
if key.is_empty() {
@@ -172,10 +165,7 @@ fn op_delete_env(
state: &mut OpState,
#[string] key: String,
) -> Result<(), OsError> {
- state
- .borrow_mut::<PermissionsContainer>()
- .check_env(&key)
- .map_err(OsError::Permission)?;
+ state.borrow_mut::<PermissionsContainer>().check_env(&key)?;
if key.is_empty() || key.contains(&['=', '\0'] as &[char]) {
return Err(OsError::EnvInvalidKey(key.to_string()));
}
@@ -240,8 +230,7 @@ fn op_network_interfaces(
) -> Result<Vec<NetworkInterface>, OsError> {
state
.borrow_mut::<PermissionsContainer>()
- .check_sys("networkInterfaces", "Deno.networkInterfaces()")
- .map_err(OsError::Permission)?;
+ .check_sys("networkInterfaces", "Deno.networkInterfaces()")?;
Ok(netif::up()?.map(NetworkInterface::from).collect())
}
diff --git a/runtime/ops/permissions.rs b/runtime/ops/permissions.rs
index 1dbc85259..9ad963f3b 100644
--- a/runtime/ops/permissions.rs
+++ b/runtime/ops/permissions.rs
@@ -2,8 +2,6 @@
use ::deno_permissions::PermissionState;
use ::deno_permissions::PermissionsContainer;
-use deno_core::error::custom_error;
-use deno_core::error::AnyError;
use deno_core::op2;
use deno_core::OpState;
use serde::Deserialize;
@@ -47,12 +45,26 @@ impl From<PermissionState> for PermissionStatus {
}
}
+#[derive(Debug, thiserror::Error)]
+pub enum PermissionError {
+ #[error("No such permission name: {0}")]
+ InvalidPermissionName(String),
+ #[error("{0}")]
+ PathResolve(#[from] ::deno_permissions::PathResolveError),
+ #[error("{0}")]
+ NetDescriptorParse(#[from] ::deno_permissions::NetDescriptorParseError),
+ #[error("{0}")]
+ SysDescriptorParse(#[from] ::deno_permissions::SysDescriptorParseError),
+ #[error("{0}")]
+ RunDescriptorParse(#[from] ::deno_permissions::RunDescriptorParseError),
+}
+
#[op2]
#[serde]
pub fn op_query_permission(
state: &mut OpState,
#[serde] args: PermissionArgs,
-) -> Result<PermissionStatus, AnyError> {
+) -> Result<PermissionStatus, PermissionError> {
let permissions = state.borrow::<PermissionsContainer>();
let perm = match args.name.as_ref() {
"read" => permissions.query_read(args.path.as_deref())?,
@@ -62,12 +74,7 @@ pub fn op_query_permission(
"sys" => permissions.query_sys(args.kind.as_deref())?,
"run" => permissions.query_run(args.command.as_deref())?,
"ffi" => permissions.query_ffi(args.path.as_deref())?,
- n => {
- return Err(custom_error(
- "ReferenceError",
- format!("No such permission name: {n}"),
- ))
- }
+ _ => return Err(PermissionError::InvalidPermissionName(args.name)),
};
Ok(PermissionStatus::from(perm))
}
@@ -77,7 +84,7 @@ pub fn op_query_permission(
pub fn op_revoke_permission(
state: &mut OpState,
#[serde] args: PermissionArgs,
-) -> Result<PermissionStatus, AnyError> {
+) -> Result<PermissionStatus, PermissionError> {
let permissions = state.borrow::<PermissionsContainer>();
let perm = match args.name.as_ref() {
"read" => permissions.revoke_read(args.path.as_deref())?,
@@ -87,12 +94,7 @@ pub fn op_revoke_permission(
"sys" => permissions.revoke_sys(args.kind.as_deref())?,
"run" => permissions.revoke_run(args.command.as_deref())?,
"ffi" => permissions.revoke_ffi(args.path.as_deref())?,
- n => {
- return Err(custom_error(
- "ReferenceError",
- format!("No such permission name: {n}"),
- ))
- }
+ _ => return Err(PermissionError::InvalidPermissionName(args.name)),
};
Ok(PermissionStatus::from(perm))
}
@@ -102,7 +104,7 @@ pub fn op_revoke_permission(
pub fn op_request_permission(
state: &mut OpState,
#[serde] args: PermissionArgs,
-) -> Result<PermissionStatus, AnyError> {
+) -> Result<PermissionStatus, PermissionError> {
let permissions = state.borrow::<PermissionsContainer>();
let perm = match args.name.as_ref() {
"read" => permissions.request_read(args.path.as_deref())?,
@@ -112,12 +114,7 @@ pub fn op_request_permission(
"sys" => permissions.request_sys(args.kind.as_deref())?,
"run" => permissions.request_run(args.command.as_deref())?,
"ffi" => permissions.request_ffi(args.path.as_deref())?,
- n => {
- return Err(custom_error(
- "ReferenceError",
- format!("No such permission name: {n}"),
- ))
- }
+ _ => return Err(PermissionError::InvalidPermissionName(args.name)),
};
Ok(PermissionStatus::from(perm))
}
diff --git a/runtime/ops/process.rs b/runtime/ops/process.rs
index 28913f7c1..de3141f1f 100644
--- a/runtime/ops/process.rs
+++ b/runtime/ops/process.rs
@@ -206,7 +206,9 @@ pub enum ProcessError {
#[error("failed resolving cwd: {0}")]
FailedResolvingCwd(#[source] std::io::Error),
#[error(transparent)]
- Permission(deno_core::error::AnyError),
+ Permission(#[from] deno_permissions::PermissionCheckError),
+ #[error(transparent)]
+ RunPermission(#[from] CheckRunPermissionError),
#[error(transparent)]
Resource(deno_core::error::AnyError),
#[error(transparent)]
@@ -653,8 +655,7 @@ fn compute_run_cmd_and_check_permissions(
},
&run_env,
api_name,
- )
- .map_err(ProcessError::Permission)?;
+ )?;
Ok((cmd, run_env))
}
@@ -734,12 +735,20 @@ fn resolve_path(path: &str, cwd: &Path) -> PathBuf {
deno_path_util::normalize_path(cwd.join(path))
}
+#[derive(Debug, thiserror::Error)]
+pub enum CheckRunPermissionError {
+ #[error(transparent)]
+ Permission(#[from] deno_permissions::PermissionCheckError),
+ #[error("{0}")]
+ Other(deno_core::error::AnyError),
+}
+
fn check_run_permission(
state: &mut OpState,
cmd: &RunQueryDescriptor,
run_env: &RunEnv,
api_name: &str,
-) -> Result<(), deno_core::error::AnyError> {
+) -> Result<(), CheckRunPermissionError> {
let permissions = state.borrow_mut::<PermissionsContainer>();
if !permissions.query_run_all(api_name) {
// error the same on all platforms
@@ -747,14 +756,14 @@ fn check_run_permission(
if !env_var_names.is_empty() {
// we don't allow users to launch subprocesses with any LD_ or DYLD_*
// env vars set because this allows executing code (ex. LD_PRELOAD)
- return Err(deno_core::error::custom_error(
+ return Err(CheckRunPermissionError::Other(deno_core::error::custom_error(
"NotCapable",
format!(
"Requires --allow-all permissions to spawn subprocess with {} environment variable{}.",
env_var_names.join(", "),
if env_var_names.len() != 1 { "s" } else { "" }
)
- ));
+ )));
}
permissions.check_run(cmd, api_name)?;
}
@@ -1126,8 +1135,7 @@ mod deprecated {
) -> Result<(), ProcessError> {
state
.borrow_mut::<PermissionsContainer>()
- .check_run_all(&api_name)
- .map_err(ProcessError::Permission)?;
+ .check_run_all(&api_name)?;
kill(pid, &signal)
}
}
diff --git a/runtime/ops/worker_host.rs b/runtime/ops/worker_host.rs
index 82cc94924..521284a6a 100644
--- a/runtime/ops/worker_host.rs
+++ b/runtime/ops/worker_host.rs
@@ -123,7 +123,7 @@ pub enum CreateWorkerError {
#[error("Classic workers are not supported.")]
ClassicWorkers,
#[error(transparent)]
- Permission(deno_core::error::AnyError),
+ Permission(deno_permissions::ChildPermissionError),
#[error(transparent)]
ModuleResolution(#[from] deno_core::ModuleResolutionError),
#[error(transparent)]