diff --git a/Cargo.lock b/Cargo.lock index 6b07f078e8..142788eb30 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1432,6 +1432,7 @@ dependencies = [ "bytes", "data-url", "deno_core", + "deno_permissions", "deno_tls", "dyn-clone", "http 0.2.12", @@ -1447,6 +1448,7 @@ name = "deno_ffi" version = "0.142.0" dependencies = [ "deno_core", + "deno_permissions", "dlopen2", "dynasmrt", "libffi", @@ -1466,6 +1468,7 @@ dependencies = [ "base32", "deno_core", "deno_io", + "deno_permissions", "filetime", "junction", "libc", @@ -1572,6 +1575,7 @@ dependencies = [ "deno_core", "deno_fetch", "deno_node", + "deno_permissions", "deno_tls", "denokv_proto", "denokv_remote", @@ -1631,6 +1635,7 @@ name = "deno_napi" version = "0.85.0" dependencies = [ "deno_core", + "deno_permissions", "libloading 0.7.4", ] @@ -1652,6 +1657,7 @@ name = "deno_net" version = "0.147.0" dependencies = [ "deno_core", + "deno_permissions", "deno_tls", "pin-project", "rustls-tokio-stream", @@ -1928,6 +1934,7 @@ dependencies = [ "deno_bench_util", "deno_console", "deno_core", + "deno_permissions", "deno_url", "deno_webidl", "encoding_rs", @@ -1965,6 +1972,7 @@ dependencies = [ "bytes", "deno_core", "deno_net", + "deno_permissions", "deno_tls", "fastwebsockets", "h2 0.4.4", diff --git a/cli/args/flags.rs b/cli/args/flags.rs index 03d19746a1..711ec4c612 100644 --- a/cli/args/flags.rs +++ b/cli/args/flags.rs @@ -17,8 +17,8 @@ use deno_core::error::AnyError; use deno_core::resolve_url_or_path; use deno_core::url::Url; use deno_graph::GraphKind; -use deno_runtime::permissions::parse_sys_kind; -use deno_runtime::permissions::PermissionsOptions; +use deno_runtime::deno_permissions::parse_sys_kind; +use deno_runtime::deno_permissions::PermissionsOptions; use log::debug; use log::Level; use serde::Deserialize; diff --git a/cli/args/import_map.rs b/cli/args/import_map.rs index 767d0f770b..2dc5a21d1a 100644 --- a/cli/args/import_map.rs +++ b/cli/args/import_map.rs @@ -4,7 +4,7 @@ use deno_core::anyhow::Context; use deno_core::error::AnyError; use deno_core::serde_json; use deno_core::url::Url; -use deno_runtime::permissions::PermissionsContainer; +use deno_runtime::deno_permissions::PermissionsContainer; use import_map::ImportMap; use import_map::ImportMapDiagnostic; use log::warn; diff --git a/cli/args/mod.rs b/cli/args/mod.rs index d5e37acc8b..7422498355 100644 --- a/cli/args/mod.rs +++ b/cli/args/mod.rs @@ -47,13 +47,13 @@ use deno_core::parking_lot::Mutex; use deno_core::serde_json; use deno_core::url::Url; use deno_runtime::deno_node::PackageJson; +use deno_runtime::deno_permissions::PermissionsOptions; use deno_runtime::deno_tls::deno_native_certs::load_native_certs; use deno_runtime::deno_tls::rustls; use deno_runtime::deno_tls::rustls::RootCertStore; use deno_runtime::deno_tls::rustls_pemfile; use deno_runtime::deno_tls::webpki_roots; use deno_runtime::inspector_server::InspectorServer; -use deno_runtime::permissions::PermissionsOptions; use deno_terminal::colors; use dotenvy::from_filename; use once_cell::sync::Lazy; diff --git a/cli/cache/mod.rs b/cli/cache/mod.rs index aaaa427d7e..a8c60e97a2 100644 --- a/cli/cache/mod.rs +++ b/cli/cache/mod.rs @@ -17,7 +17,7 @@ use deno_graph::source::CacheInfo; use deno_graph::source::LoadFuture; use deno_graph::source::LoadResponse; use deno_graph::source::Loader; -use deno_runtime::permissions::PermissionsContainer; +use deno_runtime::deno_permissions::PermissionsContainer; use std::collections::HashMap; use std::path::Path; use std::path::PathBuf; diff --git a/cli/file_fetcher.rs b/cli/file_fetcher.rs index 0e0589d346..19acf2e2b8 100644 --- a/cli/file_fetcher.rs +++ b/cli/file_fetcher.rs @@ -22,8 +22,8 @@ use deno_core::url::Url; use deno_core::ModuleSpecifier; use deno_graph::source::LoaderChecksum; +use deno_runtime::deno_permissions::PermissionsContainer; use deno_runtime::deno_web::BlobStore; -use deno_runtime::permissions::PermissionsContainer; use log::debug; use std::borrow::Cow; use std::collections::HashMap; diff --git a/cli/graph_container.rs b/cli/graph_container.rs index ec18ffaab4..40ccda9b20 100644 --- a/cli/graph_container.rs +++ b/cli/graph_container.rs @@ -8,7 +8,7 @@ use deno_core::parking_lot::RwLock; use deno_core::resolve_url_or_path; use deno_graph::ModuleGraph; use deno_runtime::colors; -use deno_runtime::permissions::PermissionsContainer; +use deno_runtime::deno_permissions::PermissionsContainer; use crate::args::CliOptions; use crate::module_loader::ModuleLoadPreparer; diff --git a/cli/graph_util.rs b/cli/graph_util.rs index 5e587b0d41..502702b075 100644 --- a/cli/graph_util.rs +++ b/cli/graph_util.rs @@ -41,7 +41,7 @@ use deno_graph::ResolutionError; use deno_graph::SpecifierError; use deno_runtime::deno_fs::FileSystem; use deno_runtime::deno_node; -use deno_runtime::permissions::PermissionsContainer; +use deno_runtime::deno_permissions::PermissionsContainer; use deno_semver::package::PackageNv; use deno_semver::package::PackageReq; use import_map::ImportMapError; diff --git a/cli/jsr.rs b/cli/jsr.rs index af0ace404e..e582ab9f0e 100644 --- a/cli/jsr.rs +++ b/cli/jsr.rs @@ -10,7 +10,7 @@ use deno_core::ModuleSpecifier; use deno_graph::packages::JsrPackageInfo; use deno_graph::packages::JsrPackageVersionInfo; use deno_lockfile::Lockfile; -use deno_runtime::permissions::PermissionsContainer; +use deno_runtime::deno_permissions::PermissionsContainer; use deno_semver::jsr::JsrPackageReqReference; use deno_semver::package::PackageNv; use deno_semver::package::PackageReq; diff --git a/cli/lsp/config.rs b/cli/lsp/config.rs index 449051931b..f033888957 100644 --- a/cli/lsp/config.rs +++ b/cli/lsp/config.rs @@ -29,8 +29,8 @@ use deno_lint::linter::LintConfig; use deno_lockfile::Lockfile; use deno_npm::npm_rc::ResolvedNpmRc; use deno_runtime::deno_node::PackageJson; +use deno_runtime::deno_permissions::PermissionsContainer; use deno_runtime::fs_util::specifier_to_file_path; -use deno_runtime::permissions::PermissionsContainer; use import_map::ImportMap; use lsp::Url; use lsp_types::ClientCapabilities; diff --git a/cli/lsp/jsr.rs b/cli/lsp/jsr.rs index a7b2f46acb..27db4b0c8d 100644 --- a/cli/lsp/jsr.rs +++ b/cli/lsp/jsr.rs @@ -7,7 +7,7 @@ use dashmap::DashMap; use deno_core::anyhow::anyhow; use deno_core::error::AnyError; use deno_core::serde_json; -use deno_runtime::permissions::PermissionsContainer; +use deno_runtime::deno_permissions::PermissionsContainer; use deno_semver::package::PackageNv; use deno_semver::Version; use serde::Deserialize; diff --git a/cli/lsp/npm.rs b/cli/lsp/npm.rs index d051237fbc..e5aa337440 100644 --- a/cli/lsp/npm.rs +++ b/cli/lsp/npm.rs @@ -4,7 +4,7 @@ use dashmap::DashMap; use deno_core::anyhow::anyhow; use deno_core::error::AnyError; use deno_core::serde_json; -use deno_runtime::permissions::PermissionsContainer; +use deno_runtime::deno_permissions::PermissionsContainer; use deno_semver::package::PackageNv; use deno_semver::Version; use serde::Deserialize; diff --git a/cli/lsp/registries.rs b/cli/lsp/registries.rs index 9a0ad6dddf..e194c61107 100644 --- a/cli/lsp/registries.rs +++ b/cli/lsp/registries.rs @@ -30,7 +30,7 @@ use deno_core::url::Position; use deno_core::url::Url; use deno_core::ModuleSpecifier; use deno_graph::Dependency; -use deno_runtime::permissions::PermissionsContainer; +use deno_runtime::deno_permissions::PermissionsContainer; use log::error; use once_cell::sync::Lazy; use std::collections::HashMap; diff --git a/cli/lsp/resolver.rs b/cli/lsp/resolver.rs index 2b465f695b..348eae76f6 100644 --- a/cli/lsp/resolver.rs +++ b/cli/lsp/resolver.rs @@ -38,7 +38,6 @@ use deno_runtime::deno_node::NodeResolutionMode; use deno_runtime::deno_node::NodeResolver; use deno_runtime::deno_node::PackageJson; use deno_runtime::fs_util::specifier_to_file_path; -use deno_runtime::permissions::PermissionsContainer; use deno_semver::jsr::JsrPackageReqReference; use deno_semver::npm::NpmPackageReqReference; use deno_semver::package::PackageNv; @@ -247,12 +246,7 @@ impl LspResolver { let node_resolver = self.node_resolver.as_ref()?; Some(NodeResolution::into_specifier_and_media_type( node_resolver - .resolve_req_reference( - req_ref, - &PermissionsContainer::allow_all(), - referrer, - NodeResolutionMode::Types, - ) + .resolve_req_reference(req_ref, referrer, NodeResolutionMode::Types) .ok(), )) } @@ -282,8 +276,10 @@ impl LspResolver { let Some(node_resolver) = self.node_resolver.as_ref() else { return Ok(None); }; - node_resolver - .get_closest_package_json(referrer, &PermissionsContainer::allow_all()) + node_resolver.get_closest_package_json( + referrer, + &mut deno_runtime::deno_node::AllowAllNodePermissions, + ) } pub fn resolve_redirects( diff --git a/cli/lsp/testing/execution.rs b/cli/lsp/testing/execution.rs index f56f5010f1..6393c86427 100644 --- a/cli/lsp/testing/execution.rs +++ b/cli/lsp/testing/execution.rs @@ -26,7 +26,7 @@ use deno_core::parking_lot::RwLock; use deno_core::unsync::spawn; use deno_core::unsync::spawn_blocking; use deno_core::ModuleSpecifier; -use deno_runtime::permissions::Permissions; +use deno_runtime::deno_permissions::Permissions; use deno_runtime::tokio_util::create_and_run_current_thread; use indexmap::IndexMap; use std::collections::HashMap; diff --git a/cli/main.rs b/cli/main.rs index e8bea9f546..f20ca17ff4 100644 --- a/cli/main.rs +++ b/cli/main.rs @@ -318,7 +318,7 @@ pub fn main() { util::windows::ensure_stdio_open(); #[cfg(windows)] colors::enable_ansi(); // For Windows 10 - deno_runtime::permissions::set_prompt_callbacks( + deno_runtime::deno_permissions::set_prompt_callbacks( Box::new(util::draw_thread::DrawThread::hide), Box::new(util::draw_thread::DrawThread::show), ); diff --git a/cli/module_loader.rs b/cli/module_loader.rs index c134f80e19..5bcc22c065 100644 --- a/cli/module_loader.rs +++ b/cli/module_loader.rs @@ -68,7 +68,7 @@ use deno_graph::Resolution; use deno_lockfile::Lockfile; use deno_runtime::code_cache; use deno_runtime::deno_node::NodeResolutionMode; -use deno_runtime::permissions::PermissionsContainer; +use deno_runtime::deno_permissions::PermissionsContainer; use deno_semver::npm::NpmPackageReqReference; pub async fn load_top_level_deps(factory: &CliFactory) -> Result<(), AnyError> { @@ -104,7 +104,7 @@ pub async fn load_top_level_deps(factory: &CliFactory) -> Result<(), AnyError> { &roots, false, factory.cli_options().ts_type_lib_window(), - deno_runtime::permissions::PermissionsContainer::allow_all(), + deno_runtime::deno_permissions::PermissionsContainer::allow_all(), ) .await?; } @@ -348,18 +348,12 @@ impl &self, specifier: &ModuleSpecifier, maybe_referrer: Option<&ModuleSpecifier>, - is_dynamic: bool, requested_module_type: RequestedModuleType, ) -> Result { - let permissions = if is_dynamic { - &self.dynamic_permissions - } else { - &self.root_permissions - }; let code_source = if let Some(result) = self .shared .npm_module_loader - .load_if_in_npm_package(specifier, maybe_referrer, permissions) + .load_if_in_npm_package(specifier, maybe_referrer) .await { result? @@ -448,19 +442,11 @@ impl &self, specifier: &str, referrer: &ModuleSpecifier, - kind: ResolutionKind, ) -> Result { - let permissions = if matches!(kind, ResolutionKind::DynamicImport) { - &self.dynamic_permissions - } else { - &self.root_permissions - }; - if let Some(result) = self.shared.node_resolver.resolve_if_in_npm_package( specifier, referrer, NodeResolutionMode::Execution, - permissions, ) { return match result? { Some(res) => Ok(res.into_url()), @@ -505,7 +491,6 @@ impl .node_resolver .resolve_req_reference( &reference, - permissions, referrer, NodeResolutionMode::Execution, ) @@ -530,7 +515,6 @@ impl module.nv_reference.sub_path(), referrer, NodeResolutionMode::Execution, - permissions, ) .with_context(|| { format!("Could not resolve '{}'.", module.nv_reference) @@ -720,7 +704,7 @@ impl ModuleLoader &self, specifier: &str, referrer: &str, - kind: ResolutionKind, + _kind: ResolutionKind, ) -> Result { fn ensure_not_jsr_non_jsr_remote_import( specifier: &ModuleSpecifier, @@ -736,7 +720,7 @@ impl ModuleLoader } let referrer = self.0.resolve_referrer(referrer)?; - let specifier = self.0.inner_resolve(specifier, &referrer, kind)?; + let specifier = self.0.inner_resolve(specifier, &referrer)?; ensure_not_jsr_non_jsr_remote_import(&specifier, &referrer)?; Ok(specifier) } @@ -745,7 +729,7 @@ impl ModuleLoader &self, specifier: &ModuleSpecifier, maybe_referrer: Option<&ModuleSpecifier>, - is_dynamic: bool, + _is_dynamic: bool, requested_module_type: RequestedModuleType, ) -> deno_core::ModuleLoadResponse { let inner = self.0.clone(); @@ -757,7 +741,6 @@ impl ModuleLoader .load_inner( &specifier, maybe_referrer.as_ref(), - is_dynamic, requested_module_type, ) .await diff --git a/cli/npm/byonm.rs b/cli/npm/byonm.rs index 9317455378..bfb9bed7f7 100644 --- a/cli/npm/byonm.rs +++ b/cli/npm/byonm.rs @@ -160,7 +160,7 @@ impl NpmResolver for ByonmCliNpmResolver { fn ensure_read_permission( &self, - permissions: &dyn NodePermissions, + permissions: &mut dyn NodePermissions, path: &Path, ) -> Result<(), AnyError> { if !path diff --git a/cli/npm/managed/mod.rs b/cli/npm/managed/mod.rs index 6a2dfdd673..2298ea9bd7 100644 --- a/cli/npm/managed/mod.rs +++ b/cli/npm/managed/mod.rs @@ -550,7 +550,7 @@ impl NpmResolver for ManagedCliNpmResolver { fn ensure_read_permission( &self, - permissions: &dyn NodePermissions, + permissions: &mut dyn NodePermissions, path: &Path, ) -> Result<(), AnyError> { self.fs_resolver.ensure_read_permission(permissions, path) diff --git a/cli/npm/managed/resolvers/common.rs b/cli/npm/managed/resolvers/common.rs index 5003e6a058..767b3f9c6d 100644 --- a/cli/npm/managed/resolvers/common.rs +++ b/cli/npm/managed/resolvers/common.rs @@ -53,7 +53,7 @@ pub trait NpmPackageFsResolver: Send + Sync { fn ensure_read_permission( &self, - permissions: &dyn NodePermissions, + permissions: &mut dyn NodePermissions, path: &Path, ) -> Result<(), AnyError>; } @@ -76,7 +76,7 @@ impl RegistryReadPermissionChecker { pub fn ensure_registry_read_permission( &self, - permissions: &dyn NodePermissions, + permissions: &mut dyn NodePermissions, path: &Path, ) -> Result<(), AnyError> { // allow reading if it's in the node_modules diff --git a/cli/npm/managed/resolvers/global.rs b/cli/npm/managed/resolvers/global.rs index 05c2472cf3..bfd2f4de36 100644 --- a/cli/npm/managed/resolvers/global.rs +++ b/cli/npm/managed/resolvers/global.rs @@ -146,7 +146,7 @@ impl NpmPackageFsResolver for GlobalNpmPackageResolver { fn ensure_read_permission( &self, - permissions: &dyn NodePermissions, + permissions: &mut dyn NodePermissions, path: &Path, ) -> Result<(), AnyError> { self diff --git a/cli/npm/managed/resolvers/local.rs b/cli/npm/managed/resolvers/local.rs index c64aacc397..4243d04f2a 100644 --- a/cli/npm/managed/resolvers/local.rs +++ b/cli/npm/managed/resolvers/local.rs @@ -243,7 +243,7 @@ impl NpmPackageFsResolver for LocalNpmPackageResolver { fn ensure_read_permission( &self, - permissions: &dyn NodePermissions, + permissions: &mut dyn NodePermissions, path: &Path, ) -> Result<(), AnyError> { self diff --git a/cli/npm/mod.rs b/cli/npm/mod.rs index ef230372fd..8d801744b1 100644 --- a/cli/npm/mod.rs +++ b/cli/npm/mod.rs @@ -14,7 +14,7 @@ use deno_core::error::AnyError; use deno_core::serde_json; use deno_npm::registry::NpmPackageInfo; use deno_runtime::deno_node::NpmResolver; -use deno_runtime::permissions::PermissionsContainer; +use deno_runtime::deno_permissions::PermissionsContainer; use deno_semver::package::PackageNv; use deno_semver::package::PackageReq; diff --git a/cli/ops/bench.rs b/cli/ops/bench.rs index 2c8c63ed66..5521253ffd 100644 --- a/cli/ops/bench.rs +++ b/cli/ops/bench.rs @@ -11,9 +11,9 @@ use deno_core::op2; use deno_core::v8; use deno_core::ModuleSpecifier; use deno_core::OpState; -use deno_runtime::permissions::create_child_permissions; -use deno_runtime::permissions::ChildPermissionsArg; -use deno_runtime::permissions::PermissionsContainer; +use deno_runtime::deno_permissions::create_child_permissions; +use deno_runtime::deno_permissions::ChildPermissionsArg; +use deno_runtime::deno_permissions::PermissionsContainer; use tokio::sync::mpsc::UnboundedSender; use uuid::Uuid; @@ -61,7 +61,7 @@ pub fn op_pledge_test_permissions( let token = Uuid::new_v4(); let parent_permissions = state.borrow_mut::(); let worker_permissions = { - let mut parent_permissions = parent_permissions.0 .0.lock(); + let mut parent_permissions = parent_permissions.0.lock(); let perms = create_child_permissions(&mut parent_permissions, args)?; PermissionsContainer::new(perms) }; diff --git a/cli/ops/testing.rs b/cli/ops/testing.rs index 6025b99172..b63a729470 100644 --- a/cli/ops/testing.rs +++ b/cli/ops/testing.rs @@ -16,9 +16,9 @@ use deno_core::op2; use deno_core::v8; use deno_core::ModuleSpecifier; use deno_core::OpState; -use deno_runtime::permissions::create_child_permissions; -use deno_runtime::permissions::ChildPermissionsArg; -use deno_runtime::permissions::PermissionsContainer; +use deno_runtime::deno_permissions::create_child_permissions; +use deno_runtime::deno_permissions::ChildPermissionsArg; +use deno_runtime::deno_permissions::PermissionsContainer; use serde::Serialize; use std::sync::atomic::AtomicUsize; use std::sync::atomic::Ordering; @@ -57,7 +57,7 @@ pub fn op_pledge_test_permissions( let token = Uuid::new_v4(); let parent_permissions = state.borrow_mut::(); let worker_permissions = { - let mut parent_permissions = parent_permissions.0 .0.lock(); + let mut parent_permissions = parent_permissions.0.lock(); let perms = create_child_permissions(&mut parent_permissions, args)?; PermissionsContainer::new(perms) }; diff --git a/cli/resolver.rs b/cli/resolver.rs index a28dfce91a..301cd0666d 100644 --- a/cli/resolver.rs +++ b/cli/resolver.rs @@ -30,7 +30,6 @@ use deno_runtime::deno_node::NodeResolver; use deno_runtime::deno_node::NpmResolver as DenoNodeNpmResolver; use deno_runtime::deno_node::PackageJson; use deno_runtime::fs_util::specifier_to_file_path; -use deno_runtime::permissions::PermissionsContainer; use deno_semver::npm::NpmPackageReqReference; use deno_semver::package::PackageReq; use import_map::ImportMap; @@ -100,7 +99,7 @@ impl CliNodeResolver { pub fn get_closest_package_json( &self, referrer: &ModuleSpecifier, - permissions: &dyn NodePermissions, + permissions: &mut dyn NodePermissions, ) -> Result>, AnyError> { self .node_resolver @@ -112,11 +111,10 @@ impl CliNodeResolver { specifier: &str, referrer: &ModuleSpecifier, mode: NodeResolutionMode, - permissions: &PermissionsContainer, ) -> Option, AnyError>> { if self.in_npm_package(referrer) { // we're in an npm package, so use node resolution - Some(self.resolve(specifier, referrer, mode, permissions)) + Some(self.resolve(specifier, referrer, mode)) } else { None } @@ -127,20 +125,15 @@ impl CliNodeResolver { specifier: &str, referrer: &ModuleSpecifier, mode: NodeResolutionMode, - permissions: &PermissionsContainer, ) -> Result, AnyError> { - self.handle_node_resolve_result(self.node_resolver.resolve( - specifier, - referrer, - mode, - permissions, - )) + self.handle_node_resolve_result( + self.node_resolver.resolve(specifier, referrer, mode), + ) } pub fn resolve_req_reference( &self, req_ref: &NpmPackageReqReference, - permissions: &PermissionsContainer, referrer: &ModuleSpecifier, mode: NodeResolutionMode, ) -> Result { @@ -152,7 +145,6 @@ impl CliNodeResolver { req_ref.sub_path(), referrer, mode, - permissions, )?; match maybe_resolution { Some(resolution) => Ok(resolution), @@ -181,7 +173,6 @@ impl CliNodeResolver { sub_path: Option<&str>, referrer: &ModuleSpecifier, mode: NodeResolutionMode, - permissions: &PermissionsContainer, ) -> Result, AnyError> { self.handle_node_resolve_result( self.node_resolver.resolve_package_subpath_from_deno_module( @@ -189,7 +180,6 @@ impl CliNodeResolver { sub_path, referrer, mode, - permissions, ), ) } @@ -278,10 +268,9 @@ impl NpmModuleLoader { &self, specifier: &ModuleSpecifier, maybe_referrer: Option<&ModuleSpecifier>, - permissions: &PermissionsContainer, ) -> Option> { if self.node_resolver.in_npm_package(specifier) { - Some(self.load(specifier, maybe_referrer, permissions).await) + Some(self.load(specifier, maybe_referrer).await) } else { None } @@ -291,7 +280,6 @@ impl NpmModuleLoader { &self, specifier: &ModuleSpecifier, maybe_referrer: Option<&ModuleSpecifier>, - permissions: &PermissionsContainer, ) -> Result { let file_path = specifier.to_file_path().unwrap(); let code = self @@ -336,7 +324,7 @@ impl NpmModuleLoader { ModuleSourceCode::String( self .node_code_translator - .translate_cjs_to_esm(specifier, Some(code), permissions) + .translate_cjs_to_esm(specifier, Some(code)) .await? .into(), ) @@ -638,12 +626,7 @@ impl Resolver for CliGraphResolver { { let node_resolver = self.node_resolver.as_ref().unwrap(); return node_resolver - .resolve_req_reference( - &npm_req_ref, - &PermissionsContainer::allow_all(), - referrer, - to_node_mode(mode), - ) + .resolve_req_reference(&npm_req_ref, referrer, to_node_mode(mode)) .map(|res| res.into_url()) .map_err(|err| err.into()); } @@ -651,12 +634,8 @@ impl Resolver for CliGraphResolver { Err(_) => { if referrer.scheme() == "file" { if let Some(node_resolver) = &self.node_resolver { - let node_result = node_resolver.resolve( - specifier, - referrer, - to_node_mode(mode), - &PermissionsContainer::allow_all(), - ); + let node_result = + node_resolver.resolve(specifier, referrer, to_node_mode(mode)); match node_result { Ok(Some(res)) => { return Ok(res.into_url()); @@ -694,7 +673,6 @@ impl Resolver for CliGraphResolver { specifier, referrer, to_node_mode(mode), - &PermissionsContainer::allow_all(), ); if let Some(Ok(Some(res))) = node_result { return Ok(res.into_url()); diff --git a/cli/standalone/mod.rs b/cli/standalone/mod.rs index 5e8c5c0b64..91e524ddaa 100644 --- a/cli/standalone/mod.rs +++ b/cli/standalone/mod.rs @@ -53,10 +53,10 @@ use deno_runtime::deno_fs; use deno_runtime::deno_node::analyze::NodeCodeTranslator; use deno_runtime::deno_node::NodeResolutionMode; use deno_runtime::deno_node::NodeResolver; +use deno_runtime::deno_permissions::Permissions; +use deno_runtime::deno_permissions::PermissionsContainer; use deno_runtime::deno_tls::rustls::RootCertStore; use deno_runtime::deno_tls::RootCertStoreProvider; -use deno_runtime::permissions::Permissions; -use deno_runtime::permissions::PermissionsContainer; use deno_runtime::WorkerExecutionMode; use deno_runtime::WorkerLogLevel; use deno_semver::npm::NpmPackageReqReference; @@ -112,16 +112,10 @@ impl ModuleLoader for EmbeddedModuleLoader { })? }; - let permissions = if matches!(kind, ResolutionKind::DynamicImport) { - &self.dynamic_permissions - } else { - &self.root_permissions - }; if let Some(result) = self.shared.node_resolver.resolve_if_in_npm_package( specifier, &referrer, NodeResolutionMode::Execution, - permissions, ) { return match result? { Some(res) => Ok(res.into_url()), @@ -146,7 +140,6 @@ impl ModuleLoader for EmbeddedModuleLoader { .node_resolver .resolve_req_reference( &reference, - permissions, &referrer, NodeResolutionMode::Execution, ) @@ -174,7 +167,7 @@ impl ModuleLoader for EmbeddedModuleLoader { &self, original_specifier: &ModuleSpecifier, maybe_referrer: Option<&ModuleSpecifier>, - is_dynamic: bool, + _is_dynamic: bool, _requested_module_type: RequestedModuleType, ) -> deno_core::ModuleLoadResponse { if original_specifier.scheme() == "data" { @@ -203,15 +196,10 @@ impl ModuleLoader for EmbeddedModuleLoader { let npm_module_loader = self.shared.npm_module_loader.clone(); let original_specifier = original_specifier.clone(); let maybe_referrer = maybe_referrer.cloned(); - let permissions = if is_dynamic { - self.dynamic_permissions.clone() - } else { - self.root_permissions.clone() - }; return deno_core::ModuleLoadResponse::Async( async move { let code_source = npm_module_loader - .load(&original_specifier, maybe_referrer.as_ref(), &permissions) + .load(&original_specifier, maybe_referrer.as_ref()) .await?; Ok(deno_core::ModuleSource::new_with_redirect( match code_source.media_type { diff --git a/cli/tools/bench/mod.rs b/cli/tools/bench/mod.rs index a6c8d3e16b..0378d6ae21 100644 --- a/cli/tools/bench/mod.rs +++ b/cli/tools/bench/mod.rs @@ -31,8 +31,8 @@ use deno_core::unsync::spawn_blocking; use deno_core::v8; use deno_core::ModuleSpecifier; use deno_core::PollEventLoopOptions; -use deno_runtime::permissions::Permissions; -use deno_runtime::permissions::PermissionsContainer; +use deno_runtime::deno_permissions::Permissions; +use deno_runtime::deno_permissions::PermissionsContainer; use deno_runtime::tokio_util::create_and_run_current_thread; use deno_runtime::WorkerExecutionMode; use indexmap::IndexMap; diff --git a/cli/tools/jupyter/mod.rs b/cli/tools/jupyter/mod.rs index 4b5009ba76..3b08928437 100644 --- a/cli/tools/jupyter/mod.rs +++ b/cli/tools/jupyter/mod.rs @@ -18,8 +18,8 @@ use deno_core::serde_json; use deno_core::url::Url; use deno_runtime::deno_io::Stdio; use deno_runtime::deno_io::StdioPipe; -use deno_runtime::permissions::Permissions; -use deno_runtime::permissions::PermissionsContainer; +use deno_runtime::deno_permissions::Permissions; +use deno_runtime::deno_permissions::PermissionsContainer; use deno_runtime::WorkerExecutionMode; use deno_terminal::colors; diff --git a/cli/tools/repl/mod.rs b/cli/tools/repl/mod.rs index c29e29e71f..db1d75dadc 100644 --- a/cli/tools/repl/mod.rs +++ b/cli/tools/repl/mod.rs @@ -13,8 +13,8 @@ use deno_core::error::AnyError; use deno_core::futures::StreamExt; use deno_core::serde_json; use deno_core::unsync::spawn_blocking; -use deno_runtime::permissions::Permissions; -use deno_runtime::permissions::PermissionsContainer; +use deno_runtime::deno_permissions::Permissions; +use deno_runtime::deno_permissions::PermissionsContainer; use deno_runtime::WorkerExecutionMode; use rustyline::error::ReadlineError; diff --git a/cli/tools/run/mod.rs b/cli/tools/run/mod.rs index 82dcae711c..f70cfd066f 100644 --- a/cli/tools/run/mod.rs +++ b/cli/tools/run/mod.rs @@ -3,8 +3,8 @@ use std::io::Read; use deno_core::error::AnyError; -use deno_runtime::permissions::Permissions; -use deno_runtime::permissions::PermissionsContainer; +use deno_runtime::deno_permissions::Permissions; +use deno_runtime::deno_permissions::PermissionsContainer; use deno_runtime::WorkerExecutionMode; use crate::args::EvalFlags; diff --git a/cli/tools/test/mod.rs b/cli/tools/test/mod.rs index 06ff39abe1..7416b5a262 100644 --- a/cli/tools/test/mod.rs +++ b/cli/tools/test/mod.rs @@ -54,9 +54,9 @@ use deno_core::OpState; use deno_core::PollEventLoopOptions; use deno_runtime::deno_io::Stdio; use deno_runtime::deno_io::StdioPipe; +use deno_runtime::deno_permissions::Permissions; +use deno_runtime::deno_permissions::PermissionsContainer; use deno_runtime::fmt_errors::format_js_error; -use deno_runtime::permissions::Permissions; -use deno_runtime::permissions::PermissionsContainer; use deno_runtime::tokio_util::create_and_run_current_thread; use deno_runtime::worker::MainWorker; use deno_runtime::WorkerExecutionMode; diff --git a/cli/tsc/mod.rs b/cli/tsc/mod.rs index c5365628d5..de4c05e27c 100644 --- a/cli/tsc/mod.rs +++ b/cli/tsc/mod.rs @@ -33,7 +33,6 @@ use deno_graph::ResolutionResolved; use deno_runtime::deno_node::NodeResolution; use deno_runtime::deno_node::NodeResolutionMode; use deno_runtime::deno_node::NodeResolver; -use deno_runtime::permissions::PermissionsContainer; use deno_semver::npm::NpmPackageReqReference; use lsp_types::Url; use once_cell::sync::Lazy; @@ -742,7 +741,6 @@ fn resolve_graph_specifier_types( module.nv_reference.sub_path(), referrer, NodeResolutionMode::Types, - &PermissionsContainer::allow_all(), )?; Ok(Some(NodeResolution::into_specifier_and_media_type( maybe_resolution, @@ -779,12 +777,7 @@ fn resolve_non_graph_specifier_types( // we're in an npm package, so use node resolution Ok(Some(NodeResolution::into_specifier_and_media_type( node_resolver - .resolve( - specifier, - referrer, - NodeResolutionMode::Types, - &PermissionsContainer::allow_all(), - ) + .resolve(specifier, referrer, NodeResolutionMode::Types) .ok() .flatten(), ))) @@ -802,7 +795,6 @@ fn resolve_non_graph_specifier_types( npm_req_ref.sub_path(), referrer, NodeResolutionMode::Types, - &PermissionsContainer::allow_all(), )?; Ok(Some(NodeResolution::into_specifier_and_media_type( maybe_resolution, diff --git a/cli/worker.rs b/cli/worker.rs index 7efa84369f..cb52b6101b 100644 --- a/cli/worker.rs +++ b/cli/worker.rs @@ -28,12 +28,12 @@ use deno_runtime::deno_node; use deno_runtime::deno_node::NodeResolution; use deno_runtime::deno_node::NodeResolutionMode; use deno_runtime::deno_node::NodeResolver; +use deno_runtime::deno_permissions::PermissionsContainer; use deno_runtime::deno_tls::RootCertStoreProvider; use deno_runtime::deno_web::BlobStore; use deno_runtime::fmt_errors::format_js_error; use deno_runtime::inspector_server::InspectorServer; use deno_runtime::ops::worker_host::CreateWebWorkerCb; -use deno_runtime::permissions::PermissionsContainer; use deno_runtime::web_worker::WebWorker; use deno_runtime::web_worker::WebWorkerOptions; use deno_runtime::worker::MainWorker; @@ -522,11 +522,8 @@ impl CliMainWorkerFactory { package_ref.req(), &referrer, )?; - let node_resolution = self.resolve_binary_entrypoint( - &package_folder, - package_ref.sub_path(), - &permissions, - )?; + let node_resolution = self + .resolve_binary_entrypoint(&package_folder, package_ref.sub_path())?; let is_main_cjs = matches!(node_resolution, NodeResolution::CommonJs(_)); if let Some(lockfile) = &shared.maybe_lockfile { @@ -636,6 +633,7 @@ impl CliMainWorkerFactory { strace_ops: shared.options.strace_ops.clone(), module_loader, fs: shared.fs.clone(), + node_resolver: Some(shared.node_resolver.clone()), npm_resolver: Some(shared.npm_resolver.clone().into_npm_resolver()), get_error_class_fn: Some(&errors::get_error_class_name), cache_storage_dir, @@ -687,7 +685,6 @@ impl CliMainWorkerFactory { &self, package_folder: &Path, sub_path: Option<&str>, - permissions: &PermissionsContainer, ) -> Result { match self .shared @@ -697,11 +694,8 @@ impl CliMainWorkerFactory { Ok(node_resolution) => Ok(node_resolution), Err(original_err) => { // if the binary entrypoint was not found, fallback to regular node resolution - let result = self.resolve_binary_entrypoint_fallback( - package_folder, - sub_path, - permissions, - ); + let result = + self.resolve_binary_entrypoint_fallback(package_folder, sub_path); match result { Ok(Some(resolution)) => Ok(resolution), Ok(None) => Err(original_err), @@ -718,7 +712,6 @@ impl CliMainWorkerFactory { &self, package_folder: &Path, sub_path: Option<&str>, - permissions: &PermissionsContainer, ) -> Result, AnyError> { // only fallback if the user specified a sub path if sub_path.is_none() { @@ -739,7 +732,6 @@ impl CliMainWorkerFactory { sub_path, &referrer, NodeResolutionMode::Execution, - permissions, )? else { return Ok(None); @@ -843,6 +835,7 @@ fn create_web_worker_callback( source_map_getter, module_loader, fs: shared.fs.clone(), + node_resolver: Some(shared.node_resolver.clone()), npm_resolver: Some(shared.npm_resolver.clone().into_npm_resolver()), worker_type: args.worker_type, maybe_inspector_server, @@ -877,7 +870,7 @@ fn create_web_worker_callback( mod tests { use super::*; use deno_core::resolve_path; - use deno_runtime::permissions::Permissions; + use deno_runtime::deno_permissions::Permissions; fn create_test_worker() -> MainWorker { let main_module = diff --git a/ext/fetch/Cargo.toml b/ext/fetch/Cargo.toml index 75884466b0..a5cc650b12 100644 --- a/ext/fetch/Cargo.toml +++ b/ext/fetch/Cargo.toml @@ -17,6 +17,7 @@ path = "lib.rs" bytes.workspace = true data-url.workspace = true deno_core.workspace = true +deno_permissions.workspace = true deno_tls.workspace = true dyn-clone = "1" http_v02.workspace = true diff --git a/ext/fetch/lib.rs b/ext/fetch/lib.rs index 21ca040277..066f1685b0 100644 --- a/ext/fetch/lib.rs +++ b/ext/fetch/lib.rs @@ -281,6 +281,26 @@ pub trait FetchPermissions { fn check_read(&mut self, _p: &Path, api_name: &str) -> Result<(), AnyError>; } +impl FetchPermissions for deno_permissions::PermissionsContainer { + #[inline(always)] + fn check_net_url( + &mut self, + url: &Url, + api_name: &str, + ) -> Result<(), AnyError> { + deno_permissions::PermissionsContainer::check_net_url(self, url, api_name) + } + + #[inline(always)] + fn check_read( + &mut self, + path: &Path, + api_name: &str, + ) -> Result<(), AnyError> { + deno_permissions::PermissionsContainer::check_read(self, path, api_name) + } +} + #[op2] #[serde] #[allow(clippy::too_many_arguments)] diff --git a/ext/ffi/Cargo.toml b/ext/ffi/Cargo.toml index fb0d4ae2a1..e8e984acbf 100644 --- a/ext/ffi/Cargo.toml +++ b/ext/ffi/Cargo.toml @@ -15,6 +15,7 @@ path = "lib.rs" [dependencies] deno_core.workspace = true +deno_permissions.workspace = true dlopen2.workspace = true dynasmrt = "1.2.3" libffi = "=3.2.0" diff --git a/ext/ffi/lib.rs b/ext/ffi/lib.rs index 4e81292408..26b06d98fb 100644 --- a/ext/ffi/lib.rs +++ b/ext/ffi/lib.rs @@ -53,6 +53,13 @@ pub trait FfiPermissions { fn check_partial(&mut self, path: Option<&Path>) -> Result<(), AnyError>; } +impl FfiPermissions for deno_permissions::PermissionsContainer { + #[inline(always)] + fn check_partial(&mut self, path: Option<&Path>) -> Result<(), AnyError> { + deno_permissions::PermissionsContainer::check_ffi_partial(self, path) + } +} + deno_core::extension!(deno_ffi, deps = [ deno_web ], parameters = [P: FfiPermissions], diff --git a/ext/fs/Cargo.toml b/ext/fs/Cargo.toml index b5ac5199c7..f13dc1cbf2 100644 --- a/ext/fs/Cargo.toml +++ b/ext/fs/Cargo.toml @@ -21,6 +21,7 @@ async-trait.workspace = true base32.workspace = true deno_core.workspace = true deno_io.workspace = true +deno_permissions.workspace = true filetime.workspace = true libc.workspace = true rand.workspace = true diff --git a/ext/fs/lib.rs b/ext/fs/lib.rs index d6794d3acf..2dce04b325 100644 --- a/ext/fs/lib.rs +++ b/ext/fs/lib.rs @@ -23,9 +23,10 @@ use crate::ops::*; use deno_core::error::AnyError; use deno_core::OpState; use deno_io::fs::FsError; +use std::borrow::Cow; use std::path::Path; -pub trait FsPermissions: Send + Sync { +pub trait FsPermissions { fn check_open<'a>( &mut self, resolved: bool, @@ -78,6 +79,92 @@ pub trait FsPermissions: Send + Sync { } } +impl FsPermissions for deno_permissions::PermissionsContainer { + fn check_open<'a>( + &mut self, + resolved: bool, + read: bool, + write: bool, + path: &'a Path, + api_name: &str, + ) -> Result, FsError> { + if resolved { + self.check_special_file(path, api_name).map_err(|_| { + std::io::Error::from(std::io::ErrorKind::PermissionDenied) + })?; + return Ok(Cow::Borrowed(path)); + } + + // If somehow read or write aren't specified, use read + let read = read || !write; + if read { + FsPermissions::check_read(self, path, api_name) + .map_err(|_| FsError::PermissionDenied("read"))?; + } + if write { + FsPermissions::check_write(self, path, api_name) + .map_err(|_| FsError::PermissionDenied("write"))?; + } + Ok(Cow::Borrowed(path)) + } + + fn check_read( + &mut self, + path: &Path, + api_name: &str, + ) -> Result<(), AnyError> { + deno_permissions::PermissionsContainer::check_read(self, path, api_name) + } + + fn check_read_blind( + &mut self, + path: &Path, + display: &str, + api_name: &str, + ) -> Result<(), AnyError> { + deno_permissions::PermissionsContainer::check_read_blind( + self, path, display, api_name, + ) + } + + fn check_write( + &mut self, + path: &Path, + api_name: &str, + ) -> Result<(), AnyError> { + deno_permissions::PermissionsContainer::check_write(self, path, api_name) + } + + fn check_write_partial( + &mut self, + path: &Path, + api_name: &str, + ) -> Result<(), AnyError> { + deno_permissions::PermissionsContainer::check_write_partial( + self, path, api_name, + ) + } + + fn check_write_blind( + &mut self, + p: &Path, + display: &str, + api_name: &str, + ) -> Result<(), AnyError> { + deno_permissions::PermissionsContainer::check_write_blind( + self, p, display, api_name, + ) + } + + fn check_read_all(&mut self, api_name: &str) -> Result<(), AnyError> { + deno_permissions::PermissionsContainer::check_read_all(self, api_name) + } + + fn check_write_all(&mut self, api_name: &str) -> Result<(), AnyError> { + deno_permissions::PermissionsContainer::check_write_all(self, api_name) + } +} + pub const UNSTABLE_FEATURE_NAME: &str = "fs"; /// Helper for checking unstable features. Used for sync ops. diff --git a/ext/kv/Cargo.toml b/ext/kv/Cargo.toml index 9cc7e08895..99f3d8051c 100644 --- a/ext/kv/Cargo.toml +++ b/ext/kv/Cargo.toml @@ -21,6 +21,7 @@ chrono = { workspace = true, features = ["now"] } deno_core.workspace = true deno_fetch.workspace = true deno_node.workspace = true +deno_permissions.workspace = true deno_tls.workspace = true denokv_proto.workspace = true denokv_remote.workspace = true diff --git a/ext/kv/remote.rs b/ext/kv/remote.rs index 9d5e099c73..a1273e78b8 100644 --- a/ext/kv/remote.rs +++ b/ext/kv/remote.rs @@ -48,6 +48,22 @@ pub trait RemoteDbHandlerPermissions { ) -> Result<(), AnyError>; } +impl RemoteDbHandlerPermissions for deno_permissions::PermissionsContainer { + #[inline(always)] + fn check_env(&mut self, var: &str) -> Result<(), AnyError> { + deno_permissions::PermissionsContainer::check_env(self, var) + } + + #[inline(always)] + fn check_net_url( + &mut self, + url: &Url, + api_name: &str, + ) -> Result<(), AnyError> { + deno_permissions::PermissionsContainer::check_net_url(self, url, api_name) + } +} + pub struct RemoteDbHandler { http_options: HttpOptions, _p: std::marker::PhantomData

, diff --git a/ext/kv/sqlite.rs b/ext/kv/sqlite.rs index a8a7fbace3..6dd821bda9 100644 --- a/ext/kv/sqlite.rs +++ b/ext/kv/sqlite.rs @@ -40,6 +40,18 @@ pub trait SqliteDbHandlerPermissions { fn check_write(&mut self, p: &Path, api_name: &str) -> Result<(), AnyError>; } +impl SqliteDbHandlerPermissions for deno_permissions::PermissionsContainer { + #[inline(always)] + fn check_read(&mut self, p: &Path, api_name: &str) -> Result<(), AnyError> { + deno_permissions::PermissionsContainer::check_read(self, p, api_name) + } + + #[inline(always)] + fn check_write(&mut self, p: &Path, api_name: &str) -> Result<(), AnyError> { + deno_permissions::PermissionsContainer::check_write(self, p, api_name) + } +} + impl SqliteDbHandler

{ pub fn new( default_storage_dir: Option, diff --git a/ext/napi/Cargo.toml b/ext/napi/Cargo.toml index 2342f313fc..c6f3c76853 100644 --- a/ext/napi/Cargo.toml +++ b/ext/napi/Cargo.toml @@ -15,4 +15,5 @@ path = "lib.rs" [dependencies] deno_core.workspace = true +deno_permissions.workspace = true libloading = { version = "0.7" } diff --git a/ext/napi/lib.rs b/ext/napi/lib.rs index b3313f0fec..f4fa33438f 100644 --- a/ext/napi/lib.rs +++ b/ext/napi/lib.rs @@ -432,6 +432,15 @@ pub trait NapiPermissions { -> std::result::Result<(), AnyError>; } +// NOTE(bartlomieju): for now, NAPI uses `--allow-ffi` flag, but that might +// change in the future. +impl NapiPermissions for deno_permissions::PermissionsContainer { + #[inline(always)] + fn check(&mut self, path: Option<&Path>) -> Result<(), AnyError> { + deno_permissions::PermissionsContainer::check_ffi(self, path) + } +} + /// # Safety /// /// This function is unsafe because it dereferences raw pointer Env. diff --git a/ext/net/Cargo.toml b/ext/net/Cargo.toml index b9ddf8d70a..10dfd0d77d 100644 --- a/ext/net/Cargo.toml +++ b/ext/net/Cargo.toml @@ -15,6 +15,7 @@ path = "lib.rs" [dependencies] deno_core.workspace = true +deno_permissions.workspace = true deno_tls.workspace = true pin-project.workspace = true rustls-tokio-stream.workspace = true diff --git a/ext/net/lib.rs b/ext/net/lib.rs index fa8074b345..3b6c05282b 100644 --- a/ext/net/lib.rs +++ b/ext/net/lib.rs @@ -30,6 +30,35 @@ pub trait NetPermissions { -> Result<(), AnyError>; } +impl NetPermissions for deno_permissions::PermissionsContainer { + #[inline(always)] + fn check_net>( + &mut self, + host: &(T, Option), + api_name: &str, + ) -> Result<(), AnyError> { + deno_permissions::PermissionsContainer::check_net(self, host, api_name) + } + + #[inline(always)] + fn check_read( + &mut self, + path: &Path, + api_name: &str, + ) -> Result<(), AnyError> { + deno_permissions::PermissionsContainer::check_read(self, path, api_name) + } + + #[inline(always)] + fn check_write( + &mut self, + path: &Path, + api_name: &str, + ) -> Result<(), AnyError> { + deno_permissions::PermissionsContainer::check_write(self, path, api_name) + } +} + /// Helper for checking unstable features. Used for sync ops. fn check_unstable(state: &OpState, api_name: &str) { // TODO(bartlomieju): replace with `state.feature_checker.check_or_exit` diff --git a/ext/node/analyze.rs b/ext/node/analyze.rs index b7adfd5ce8..df68cb0fc4 100644 --- a/ext/node/analyze.rs +++ b/ext/node/analyze.rs @@ -17,8 +17,8 @@ use deno_core::error::AnyError; use crate::path::to_file_specifier; use crate::resolution::NodeResolverRc; +use crate::AllowAllNodePermissions; use crate::NodeModuleKind; -use crate::NodePermissions; use crate::NodeResolutionMode; use crate::NpmResolverRc; use crate::PackageJson; @@ -87,7 +87,6 @@ impl NodeCodeTranslator { &self, entry_specifier: &ModuleSpecifier, source: Option, - permissions: &dyn NodePermissions, ) -> Result { let mut temp_var_count = 0; @@ -115,7 +114,6 @@ impl NodeCodeTranslator { .analyze_reexports( entry_specifier, analysis.reexports, - permissions, &mut all_exports, &mut errors, ) @@ -161,7 +159,6 @@ impl NodeCodeTranslator { &'a self, entry_specifier: &url::Url, reexports: Vec, - permissions: &dyn NodePermissions, all_exports: &mut HashSet, // this goes through the modules concurrently, so collect // the errors in order to be deterministic @@ -194,7 +191,6 @@ impl NodeCodeTranslator { // should be `deno-require`, because `deno` is already used in `esm_resolver.rs` &["deno", "require", "default"], NodeResolutionMode::Execution, - permissions, ); let reexport_specifier = match result { Ok(specifier) => specifier, @@ -287,7 +283,6 @@ impl NodeCodeTranslator { referrer: &ModuleSpecifier, conditions: &[&str], mode: NodeResolutionMode, - permissions: &dyn NodePermissions, ) -> Result { if specifier.starts_with('/') { todo!(); @@ -319,7 +314,7 @@ impl NodeCodeTranslator { let package_json = PackageJson::load( &*self.fs, &*self.npm_resolver, - permissions, + &mut AllowAllNodePermissions, package_json_path.clone(), )?; if package_json.exists { @@ -332,7 +327,6 @@ impl NodeCodeTranslator { NodeModuleKind::Esm, conditions, mode, - permissions, ); } @@ -345,7 +339,7 @@ impl NodeCodeTranslator { let package_json = PackageJson::load( &*self.fs, &*self.npm_resolver, - permissions, + &mut AllowAllNodePermissions, package_json_path, )?; if package_json.exists { diff --git a/ext/node/global.rs b/ext/node/global.rs index 0aaa6ed8bc..d2fe7a1e57 100644 --- a/ext/node/global.rs +++ b/ext/node/global.rs @@ -1,13 +1,12 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. use std::mem::MaybeUninit; -use std::rc::Rc; use deno_core::v8; use deno_core::v8::GetPropertyNamesArgs; use deno_core::v8::MapFnTo; -use crate::NodeResolver; +use crate::resolution::NodeResolverRc; // NOTE(bartlomieju): somehow calling `.map_fn_to()` multiple times on a function // returns two different pointers. That shouldn't be the case as `.map_fn_to()` @@ -271,7 +270,7 @@ fn current_mode(scope: &mut v8::HandleScope) -> Mode { }; let op_state = deno_core::JsRuntime::op_state_from(scope); let op_state = op_state.borrow(); - let Some(node_resolver) = op_state.try_borrow::>() else { + let Some(node_resolver) = op_state.try_borrow::() else { return Mode::Deno; }; let mut buffer = [MaybeUninit::uninit(); 2048]; diff --git a/ext/node/lib.rs b/ext/node/lib.rs index 2b31f704f6..a15125f603 100644 --- a/ext/node/lib.rs +++ b/ext/node/lib.rs @@ -6,7 +6,6 @@ use std::collections::HashSet; use std::path::Path; use std::path::PathBuf; -use std::rc::Rc; use deno_core::error::AnyError; use deno_core::located_script_name; @@ -46,6 +45,7 @@ pub use resolution::NodeModuleKind; pub use resolution::NodeResolution; pub use resolution::NodeResolutionMode; pub use resolution::NodeResolver; +use resolution::NodeResolverRc; use crate::global::global_object_middleware; use crate::global::global_template_middleware; @@ -57,23 +57,23 @@ pub trait NodePermissions { api_name: &str, ) -> Result<(), AnyError>; #[inline(always)] - fn check_read(&self, path: &Path) -> Result<(), AnyError> { + fn check_read(&mut self, path: &Path) -> Result<(), AnyError> { self.check_read_with_api_name(path, None) } fn check_read_with_api_name( - &self, + &mut self, path: &Path, api_name: Option<&str>, ) -> Result<(), AnyError>; - fn check_sys(&self, kind: &str, api_name: &str) -> Result<(), AnyError>; + fn check_sys(&mut self, kind: &str, api_name: &str) -> Result<(), AnyError>; fn check_write_with_api_name( - &self, + &mut self, path: &Path, api_name: Option<&str>, ) -> Result<(), AnyError>; } -pub(crate) struct AllowAllNodePermissions; +pub struct AllowAllNodePermissions; impl NodePermissions for AllowAllNodePermissions { fn check_net_url( @@ -84,24 +84,65 @@ impl NodePermissions for AllowAllNodePermissions { Ok(()) } fn check_read_with_api_name( - &self, + &mut self, _path: &Path, _api_name: Option<&str>, ) -> Result<(), AnyError> { Ok(()) } fn check_write_with_api_name( - &self, + &mut self, _path: &Path, _api_name: Option<&str>, ) -> Result<(), AnyError> { Ok(()) } - fn check_sys(&self, _kind: &str, _api_name: &str) -> Result<(), AnyError> { + fn check_sys( + &mut self, + _kind: &str, + _api_name: &str, + ) -> Result<(), AnyError> { Ok(()) } } +impl NodePermissions for deno_permissions::PermissionsContainer { + #[inline(always)] + fn check_net_url( + &mut self, + url: &Url, + api_name: &str, + ) -> Result<(), AnyError> { + deno_permissions::PermissionsContainer::check_net_url(self, url, api_name) + } + + #[inline(always)] + fn check_read_with_api_name( + &mut self, + path: &Path, + api_name: Option<&str>, + ) -> Result<(), AnyError> { + deno_permissions::PermissionsContainer::check_read_with_api_name( + self, path, api_name, + ) + } + + #[inline(always)] + fn check_write_with_api_name( + &mut self, + path: &Path, + api_name: Option<&str>, + ) -> Result<(), AnyError> { + deno_permissions::PermissionsContainer::check_write_with_api_name( + self, path, api_name, + ) + } + + fn check_sys(&mut self, kind: &str, api_name: &str) -> Result<(), AnyError> { + deno_permissions::PermissionsContainer::check_sys(self, kind, api_name) + } +} + #[allow(clippy::disallowed_types)] pub type NpmResolverRc = deno_fs::sync::MaybeArc; @@ -146,7 +187,7 @@ pub trait NpmResolver: std::fmt::Debug + MaybeSend + MaybeSync { fn ensure_read_permission( &self, - permissions: &dyn NodePermissions, + permissions: &mut dyn NodePermissions, path: &Path, ) -> Result<(), AnyError>; } @@ -582,18 +623,21 @@ deno_core::extension!(deno_node, "node:zlib" = "zlib.ts", ], options = { + maybe_node_resolver: Option, maybe_npm_resolver: Option, fs: deno_fs::FileSystemRc, }, state = |state, options| { - let fs = options.fs; - state.put(fs.clone()); - if let Some(npm_resolver) = options.maybe_npm_resolver { + // you should provide both of these or neither + debug_assert_eq!(options.maybe_node_resolver.is_some(), options.maybe_npm_resolver.is_some()); + + state.put(options.fs.clone()); + + if let Some(node_resolver) = &options.maybe_node_resolver { + state.put(node_resolver.clone()); + } + if let Some(npm_resolver) = &options.maybe_npm_resolver { state.put(npm_resolver.clone()); - state.put(Rc::new(NodeResolver::new( - fs, - npm_resolver, - ))) } }, global_template_middleware = global_template_middleware, diff --git a/ext/node/ops/require.rs b/ext/node/ops/require.rs index 176d64e56b..de26870013 100644 --- a/ext/node/ops/require.rs +++ b/ext/node/ops/require.rs @@ -16,10 +16,11 @@ use std::path::PathBuf; use std::rc::Rc; use crate::resolution; +use crate::resolution::NodeResolverRc; +use crate::AllowAllNodePermissions; use crate::NodeModuleKind; use crate::NodePermissions; use crate::NodeResolutionMode; -use crate::NodeResolver; use crate::NpmResolverRc; use crate::PackageJson; @@ -30,8 +31,8 @@ fn ensure_read_permission

( where P: NodePermissions + 'static, { - let resolver = state.borrow::(); - let permissions = state.borrow::

(); + let resolver = state.borrow::().clone(); + let permissions = state.borrow_mut::

(); resolver.ensure_read_permission(permissions, file_path) } @@ -386,12 +387,11 @@ where return Ok(None); } - let node_resolver = state.borrow::>(); - let permissions = state.borrow::

(); + let node_resolver = state.borrow::(); let pkg = node_resolver .get_closest_package_json( &Url::from_file_path(parent_path.unwrap()).unwrap(), - permissions, + &mut AllowAllNodePermissions, ) .ok() .flatten(); @@ -428,7 +428,6 @@ where NodeModuleKind::Cjs, resolution::REQUIRE_CONDITIONS, NodeResolutionMode::Execution, - permissions, )?; Ok(Some(if r.scheme() == "file" { url_to_file_path_string(&r)? @@ -483,8 +482,7 @@ where { let fs = state.borrow::(); let npm_resolver = state.borrow::(); - let node_resolver = state.borrow::>(); - let permissions = state.borrow::

(); + let node_resolver = state.borrow::(); let pkg_path = if npm_resolver .in_npm_package_at_file_path(&PathBuf::from(&modules_path)) @@ -501,7 +499,7 @@ where } }; let pkg = node_resolver.load_package_json( - permissions, + &mut AllowAllNodePermissions, PathBuf::from(&pkg_path).join("package.json"), )?; @@ -515,7 +513,6 @@ where NodeModuleKind::Cjs, resolution::REQUIRE_CONDITIONS, NodeResolutionMode::Execution, - permissions, )?; Ok(Some(if r.scheme() == "file" { url_to_file_path_string(&r)? @@ -540,8 +537,8 @@ where state, PathBuf::from(&filename).parent().unwrap(), )?; - let node_resolver = state.borrow::>(); - let permissions = state.borrow::

(); + let node_resolver = state.borrow::().clone(); + let permissions = state.borrow_mut::

(); node_resolver .get_closest_package_json( &Url::from_file_path(filename).unwrap(), @@ -559,8 +556,8 @@ pub fn op_require_read_package_scope

( where P: NodePermissions + 'static, { - let node_resolver = state.borrow::>(); - let permissions = state.borrow::

(); + let node_resolver = state.borrow::().clone(); + let permissions = state.borrow_mut::

(); let package_json_path = PathBuf::from(package_json_path); node_resolver .load_package_json(permissions, package_json_path) @@ -580,10 +577,11 @@ where { let referrer_path = PathBuf::from(&referrer_filename); ensure_read_permission::

(state, &referrer_path)?; - let node_resolver = state.borrow::>(); - let permissions = state.borrow::

(); - let Some(pkg) = node_resolver - .get_closest_package_json_from_path(&referrer_path, permissions)? + let node_resolver = state.borrow::(); + let Some(pkg) = node_resolver.get_closest_package_json_from_path( + &referrer_path, + &mut AllowAllNodePermissions, + )? else { return Ok(None); }; @@ -598,7 +596,6 @@ where Some(&pkg), resolution::REQUIRE_CONDITIONS, NodeResolutionMode::Execution, - permissions, )?; Ok(Some(url_to_file_path_string(&url)?)) } else { diff --git a/ext/node/ops/worker_threads.rs b/ext/node/ops/worker_threads.rs index 18a4157d42..182ba0118d 100644 --- a/ext/node/ops/worker_threads.rs +++ b/ext/node/ops/worker_threads.rs @@ -8,11 +8,10 @@ use deno_core::OpState; use deno_fs::FileSystemRc; use std::path::Path; use std::path::PathBuf; -use std::rc::Rc; use crate::resolution; +use crate::resolution::NodeResolverRc; use crate::NodePermissions; -use crate::NodeResolver; use crate::NpmResolverRc; fn ensure_read_permission

( @@ -22,8 +21,8 @@ fn ensure_read_permission

( where P: NodePermissions + 'static, { - let resolver = state.borrow::(); - let permissions = state.borrow::

(); + let resolver = state.borrow::().clone(); + let permissions = state.borrow_mut::

(); resolver.ensure_read_permission(permissions, file_path) } @@ -63,7 +62,7 @@ where if !fs.exists_sync(&url_path) { return Err(generic_error(format!("File not found [{:?}]", url_path))); } - let node_resolver = state.borrow::>(); + let node_resolver = state.borrow::(); match node_resolver.url_to_node_resolution(url)? { resolution::NodeResolution::Esm(u) => Ok(u.to_string()), resolution::NodeResolution::CommonJs(u) => wrap_cjs(u), diff --git a/ext/node/package_json.rs b/ext/node/package_json.rs index d4ffc80d68..adae7d6344 100644 --- a/ext/node/package_json.rs +++ b/ext/node/package_json.rs @@ -65,7 +65,7 @@ impl PackageJson { pub fn load( fs: &dyn deno_fs::FileSystem, resolver: &dyn NpmResolver, - permissions: &dyn NodePermissions, + permissions: &mut dyn NodePermissions, path: PathBuf, ) -> Result, AnyError> { resolver.ensure_read_permission(permissions, &path)?; diff --git a/ext/node/resolution.rs b/ext/node/resolution.rs index 37598810d3..834b465cde 100644 --- a/ext/node/resolution.rs +++ b/ext/node/resolution.rs @@ -154,7 +154,6 @@ impl NodeResolver { specifier: &str, referrer: &ModuleSpecifier, mode: NodeResolutionMode, - permissions: &dyn NodePermissions, ) -> Result, AnyError> { // Note: if we are here, then the referrer is an esm module // TODO(bartlomieju): skipped "policy" part as we don't plan to support it @@ -187,13 +186,8 @@ impl NodeResolver { } } - let url = self.module_resolve( - specifier, - referrer, - DEFAULT_CONDITIONS, - mode, - permissions, - )?; + let url = + self.module_resolve(specifier, referrer, DEFAULT_CONDITIONS, mode)?; let url = match url { Some(url) => url, None => return Ok(None), @@ -204,12 +198,8 @@ impl NodeResolver { let path = url.to_file_path().unwrap(); // todo(16370): the module kind is not correct here. I think we need // typescript to tell us if the referrer is esm or cjs - let maybe_decl_url = self.path_to_declaration_url( - path, - referrer, - NodeModuleKind::Esm, - permissions, - )?; + let maybe_decl_url = + self.path_to_declaration_url(path, referrer, NodeModuleKind::Esm)?; match maybe_decl_url { Some(url) => url, None => return Ok(None), @@ -229,7 +219,6 @@ impl NodeResolver { referrer: &ModuleSpecifier, conditions: &[&str], mode: NodeResolutionMode, - permissions: &dyn NodePermissions, ) -> Result, AnyError> { // note: if we're here, the referrer is an esm module let url = if should_be_treated_as_relative_or_absolute_path(specifier) { @@ -242,13 +231,13 @@ impl NodeResolver { file_path, referrer, NodeModuleKind::Esm, - permissions, )? } else { Some(resolved_specifier) } } else if specifier.starts_with('#') { - let pkg_config = self.get_closest_package_json(referrer, permissions)?; + let pkg_config = self + .get_closest_package_json(referrer, &mut AllowAllNodePermissions)?; Some(self.package_imports_resolve( specifier, referrer, @@ -256,7 +245,6 @@ impl NodeResolver { pkg_config.as_deref(), conditions, mode, - permissions, )?) } else if let Ok(resolved) = Url::parse(specifier) { Some(resolved) @@ -267,7 +255,6 @@ impl NodeResolver { NodeModuleKind::Esm, conditions, mode, - permissions, )? }; Ok(match url { @@ -337,11 +324,12 @@ impl NodeResolver { package_subpath: Option<&str>, referrer: &ModuleSpecifier, mode: NodeResolutionMode, - permissions: &dyn NodePermissions, ) -> Result, AnyError> { let package_json_path = package_dir.join("package.json"); - let package_json = - self.load_package_json(permissions, package_json_path.clone())?; + let package_json = self.load_package_json( + &mut AllowAllNodePermissions, + package_json_path.clone(), + )?; let node_module_kind = NodeModuleKind::Esm; let package_subpath = package_subpath .map(|s| format!("./{s}")) @@ -354,7 +342,6 @@ impl NodeResolver { node_module_kind, DEFAULT_CONDITIONS, mode, - permissions, ) .with_context(|| { format!( @@ -376,7 +363,6 @@ impl NodeResolver { path, referrer, node_module_kind, - permissions, )? { Some(url) => url, None => return Ok(None), @@ -397,8 +383,10 @@ impl NodeResolver { package_folder: &Path, ) -> Result, AnyError> { let package_json_path = package_folder.join("package.json"); - let package_json = self - .load_package_json(&AllowAllNodePermissions, package_json_path.clone())?; + let package_json = self.load_package_json( + &mut AllowAllNodePermissions, + package_json_path.clone(), + )?; Ok(match &package_json.bin { Some(Value::String(_)) => { @@ -420,8 +408,10 @@ impl NodeResolver { sub_path: Option<&str>, ) -> Result { let package_json_path = package_folder.join("package.json"); - let package_json = self - .load_package_json(&AllowAllNodePermissions, package_json_path.clone())?; + let package_json = self.load_package_json( + &mut AllowAllNodePermissions, + package_json_path.clone(), + )?; let bin_entry = resolve_bin_entry_value(&package_json, sub_path)?; let url = to_file_specifier(&package_folder.join(bin_entry)); @@ -440,7 +430,7 @@ impl NodeResolver { Ok(NodeResolution::Esm(url)) } else if url_str.ends_with(".js") || url_str.ends_with(".d.ts") { let maybe_package_config = - self.get_closest_package_json(&url, &AllowAllNodePermissions)?; + self.get_closest_package_json(&url, &mut AllowAllNodePermissions)?; match maybe_package_config { Some(c) if c.typ == "module" => Ok(NodeResolution::Esm(url)), Some(_) => Ok(NodeResolution::CommonJs(url)), @@ -467,7 +457,6 @@ impl NodeResolver { path: PathBuf, referrer: &ModuleSpecifier, referrer_kind: NodeModuleKind, - permissions: &dyn NodePermissions, ) -> Result, AnyError> { fn probe_extensions( fs: &dyn deno_fs::FileSystem, @@ -528,7 +517,7 @@ impl NodeResolver { if self.fs.is_dir_sync(&path) { let package_json_path = path.join("package.json"); if let Ok(pkg_json) = - self.load_package_json(permissions, package_json_path) + self.load_package_json(&mut AllowAllNodePermissions, package_json_path) { let maybe_resolution = self.resolve_package_subpath( &pkg_json, @@ -540,7 +529,6 @@ impl NodeResolver { NodeModuleKind::Cjs => REQUIRE_CONDITIONS, }, NodeResolutionMode::Types, - permissions, )?; if let Some(resolution) = maybe_resolution { return Ok(Some(resolution)); @@ -572,7 +560,6 @@ impl NodeResolver { referrer_pkg_json: Option<&PackageJson>, conditions: &[&str], mode: NodeResolutionMode, - permissions: &dyn NodePermissions, ) -> Result { if name == "#" || name.starts_with("#/") || name.ends_with('/') { let reason = "is not a valid internal imports specifier name"; @@ -601,7 +588,6 @@ impl NodeResolver { true, conditions, mode, - permissions, )?; if let Some(resolved) = maybe_resolved { return Ok(resolved); @@ -644,7 +630,6 @@ impl NodeResolver { true, conditions, mode, - permissions, )?; if let Some(resolved) = maybe_resolved { return Ok(resolved); @@ -675,7 +660,6 @@ impl NodeResolver { internal: bool, conditions: &[&str], mode: NodeResolutionMode, - permissions: &dyn NodePermissions, ) -> Result { if !subpath.is_empty() && !pattern && !target.ends_with('/') { return Err(throw_invalid_package_target( @@ -715,7 +699,6 @@ impl NodeResolver { referrer_kind, conditions, mode, - permissions, ) { Ok(Some(url)) => Ok(url), Ok(None) => Err(generic_error("not found")), @@ -804,7 +787,6 @@ impl NodeResolver { internal: bool, conditions: &[&str], mode: NodeResolutionMode, - permissions: &dyn NodePermissions, ) -> Result, AnyError> { if let Some(target) = target.as_str() { let url = self.resolve_package_target_string( @@ -818,16 +800,10 @@ impl NodeResolver { internal, conditions, mode, - permissions, )?; if mode.is_types() && url.scheme() == "file" { let path = url.to_file_path().unwrap(); - return self.path_to_declaration_url( - path, - referrer, - referrer_kind, - permissions, - ); + return self.path_to_declaration_url(path, referrer, referrer_kind); } else { return Ok(Some(url)); } @@ -849,7 +825,6 @@ impl NodeResolver { internal, conditions, mode, - permissions, ); match resolved_result { @@ -898,7 +873,6 @@ impl NodeResolver { internal, conditions, mode, - permissions, )?; match resolved { Some(resolved) => return Ok(Some(resolved)), @@ -931,7 +905,6 @@ impl NodeResolver { referrer_kind: NodeModuleKind, conditions: &[&str], mode: NodeResolutionMode, - permissions: &dyn NodePermissions, ) -> Result { if package_exports.contains_key(package_subpath) && package_subpath.find('*').is_none() @@ -949,7 +922,6 @@ impl NodeResolver { false, conditions, mode, - permissions, )?; return match resolved { Some(resolved) => Ok(resolved), @@ -1009,7 +981,6 @@ impl NodeResolver { false, conditions, mode, - permissions, )?; if let Some(resolved) = maybe_resolved { return Ok(resolved); @@ -1038,13 +1009,12 @@ impl NodeResolver { referrer_kind: NodeModuleKind, conditions: &[&str], mode: NodeResolutionMode, - permissions: &dyn NodePermissions, ) -> Result, AnyError> { let (package_name, package_subpath, _is_scoped) = parse_npm_pkg_name(specifier, referrer)?; let Some(package_config) = - self.get_closest_package_json(referrer, permissions)? + self.get_closest_package_json(referrer, &mut AllowAllNodePermissions)? else { return Ok(None); }; @@ -1062,7 +1032,6 @@ impl NodeResolver { referrer_kind, conditions, mode, - permissions, ) .map(Some); } @@ -1087,8 +1056,8 @@ impl NodeResolver { // )) // Package match. - let package_json = - self.load_package_json(permissions, package_json_path)?; + let package_json = self + .load_package_json(&mut AllowAllNodePermissions, package_json_path)?; self.resolve_package_subpath( &package_json, &package_subpath, @@ -1096,7 +1065,6 @@ impl NodeResolver { referrer_kind, conditions, mode, - permissions, ) } @@ -1109,7 +1077,6 @@ impl NodeResolver { referrer_kind: NodeModuleKind, conditions: &[&str], mode: NodeResolutionMode, - permissions: &dyn NodePermissions, ) -> Result, AnyError> { if let Some(exports) = &package_json.exports { let result = self.package_exports_resolve( @@ -1120,7 +1087,6 @@ impl NodeResolver { referrer_kind, conditions, mode, - permissions, ); match result { Ok(found) => return Ok(Some(found)), @@ -1131,7 +1097,6 @@ impl NodeResolver { referrer, referrer_kind, mode, - permissions, ); } return Err(exports_err); @@ -1144,18 +1109,12 @@ impl NodeResolver { referrer, referrer_kind, mode, - permissions, ); } let file_path = package_json.path.parent().unwrap().join(package_subpath); if mode.is_types() { - self.path_to_declaration_url( - file_path, - referrer, - referrer_kind, - permissions, - ) + self.path_to_declaration_url(file_path, referrer, referrer_kind) } else { Ok(Some(to_file_specifier(&file_path))) } @@ -1164,7 +1123,7 @@ impl NodeResolver { pub fn get_closest_package_json( &self, url: &ModuleSpecifier, - permissions: &dyn NodePermissions, + permissions: &mut dyn NodePermissions, ) -> Result>, AnyError> { let Ok(file_path) = url.to_file_path() else { return Ok(None); @@ -1175,7 +1134,7 @@ impl NodeResolver { pub fn get_closest_package_json_from_path( &self, file_path: &Path, - permissions: &dyn NodePermissions, + permissions: &mut dyn NodePermissions, ) -> Result>, AnyError> { let Some(package_json_path) = self.get_closest_package_json_path(file_path)? @@ -1212,7 +1171,7 @@ impl NodeResolver { pub(super) fn load_package_json( &self, - permissions: &dyn NodePermissions, + permissions: &mut dyn NodePermissions, package_json_path: PathBuf, ) -> Result, AnyError> { PackageJson::load( @@ -1229,7 +1188,6 @@ impl NodeResolver { referrer: &ModuleSpecifier, referrer_kind: NodeModuleKind, mode: NodeResolutionMode, - permissions: &dyn NodePermissions, ) -> Result, AnyError> { let maybe_main = if mode.is_types() { match package_json.types.as_ref() { @@ -1239,12 +1197,8 @@ impl NodeResolver { // a corresponding declaration file if let Some(main) = package_json.main(referrer_kind) { let main = package_json.path.parent().unwrap().join(main).clean(); - let maybe_decl_url = self.path_to_declaration_url( - main, - referrer, - referrer_kind, - permissions, - )?; + let maybe_decl_url = + self.path_to_declaration_url(main, referrer, referrer_kind)?; if let Some(path) = maybe_decl_url { return Ok(Some(path)); } diff --git a/ext/web/Cargo.toml b/ext/web/Cargo.toml index f99193e0b5..ec65d51b44 100644 --- a/ext/web/Cargo.toml +++ b/ext/web/Cargo.toml @@ -18,6 +18,7 @@ async-trait.workspace = true base64-simd = "0.8" bytes.workspace = true deno_core.workspace = true +deno_permissions.workspace = true encoding_rs.workspace = true flate2 = { workspace = true, features = ["default"] } futures.workspace = true diff --git a/ext/web/timers.rs b/ext/web/timers.rs index b3060a46fd..648be57155 100644 --- a/ext/web/timers.rs +++ b/ext/web/timers.rs @@ -10,6 +10,13 @@ pub trait TimersPermission { fn allow_hrtime(&mut self) -> bool; } +impl TimersPermission for deno_permissions::PermissionsContainer { + #[inline(always)] + fn allow_hrtime(&mut self) -> bool { + deno_permissions::PermissionsContainer::allow_hrtime(self) + } +} + pub type StartTime = Instant; // Returns a milliseconds and nanoseconds subsec diff --git a/ext/websocket/Cargo.toml b/ext/websocket/Cargo.toml index f2e8c90f9c..059f40f633 100644 --- a/ext/websocket/Cargo.toml +++ b/ext/websocket/Cargo.toml @@ -17,6 +17,7 @@ path = "lib.rs" bytes.workspace = true deno_core.workspace = true deno_net.workspace = true +deno_permissions.workspace = true deno_tls.workspace = true fastwebsockets.workspace = true h2.workspace = true diff --git a/ext/websocket/lib.rs b/ext/websocket/lib.rs index 06a75faabd..87503120bf 100644 --- a/ext/websocket/lib.rs +++ b/ext/websocket/lib.rs @@ -99,6 +99,17 @@ pub trait WebSocketPermissions { ) -> Result<(), AnyError>; } +impl WebSocketPermissions for deno_permissions::PermissionsContainer { + #[inline(always)] + fn check_net_url( + &mut self, + url: &url::Url, + api_name: &str, + ) -> Result<(), AnyError> { + deno_permissions::PermissionsContainer::check_net_url(self, url, api_name) + } +} + /// `UnsafelyIgnoreCertificateErrors` is a wrapper struct so it can be placed inside `GothamState`; /// using type alias for a `Option>` could work, but there's a high chance /// that there might be another type alias pointing to a `Option>`, which diff --git a/runtime/examples/extension/main.rs b/runtime/examples/extension/main.rs index 0d7c4efb00..4339bdf679 100644 --- a/runtime/examples/extension/main.rs +++ b/runtime/examples/extension/main.rs @@ -10,7 +10,7 @@ use deno_core::error::AnyError; use deno_core::op2; use deno_core::FsModuleLoader; use deno_core::ModuleSpecifier; -use deno_runtime::permissions::PermissionsContainer; +use deno_runtime::deno_permissions::PermissionsContainer; use deno_runtime::worker::MainWorker; use deno_runtime::worker::WorkerOptions; diff --git a/runtime/lib.rs b/runtime/lib.rs index ec751f207a..c92f5aea21 100644 --- a/runtime/lib.rs +++ b/runtime/lib.rs @@ -33,7 +33,6 @@ pub mod fs_util; pub mod inspector_server; pub mod js; pub mod ops; -pub mod permissions; pub mod snapshot; pub mod tokio_util; pub mod web_worker; diff --git a/runtime/ops/fs_events.rs b/runtime/ops/fs_events.rs index 1e8fab936b..367866162f 100644 --- a/runtime/ops/fs_events.rs +++ b/runtime/ops/fs_events.rs @@ -1,6 +1,5 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. -use crate::permissions::PermissionsContainer; use deno_core::error::AnyError; use deno_core::parking_lot::Mutex; use deno_core::AsyncRefCell; @@ -13,6 +12,7 @@ use deno_core::ResourceId; use deno_core::op2; +use deno_permissions::PermissionsContainer; use notify::event::Event as NotifyEvent; use notify::Error as NotifyError; use notify::EventKind; diff --git a/runtime/ops/os/mod.rs b/runtime/ops/os/mod.rs index f6f55f68fa..c2611f869b 100644 --- a/runtime/ops/os/mod.rs +++ b/runtime/ops/os/mod.rs @@ -1,7 +1,6 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. use super::utils::into_string; -use crate::permissions::PermissionsContainer; use crate::worker::ExitCode; use deno_core::error::type_error; use deno_core::error::AnyError; @@ -10,6 +9,7 @@ use deno_core::url::Url; use deno_core::v8; use deno_core::OpState; use deno_node::NODE_ENV_VAR_ALLOWLIST; +use deno_permissions::PermissionsContainer; use serde::Serialize; use std::collections::HashMap; use std::env; diff --git a/runtime/ops/process.rs b/runtime/ops/process.rs index bda6045aca..b894b35db7 100644 --- a/runtime/ops/process.rs +++ b/runtime/ops/process.rs @@ -1,7 +1,6 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. use super::check_unstable; -use crate::permissions::PermissionsContainer; use deno_core::anyhow::Context; use deno_core::error::type_error; use deno_core::error::AnyError; @@ -18,6 +17,7 @@ use deno_io::fs::FileResource; use deno_io::ChildStderrResource; use deno_io::ChildStdinResource; use deno_io::ChildStdoutResource; +use deno_permissions::PermissionsContainer; use serde::Deserialize; use serde::Serialize; use std::borrow::Cow; diff --git a/runtime/ops/runtime.rs b/runtime/ops/runtime.rs index 5b0b092c19..306e6ce8f7 100644 --- a/runtime/ops/runtime.rs +++ b/runtime/ops/runtime.rs @@ -1,10 +1,10 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. -use crate::permissions::PermissionsContainer; use deno_core::error::AnyError; use deno_core::op2; use deno_core::ModuleSpecifier; use deno_core::OpState; +use deno_permissions::PermissionsContainer; deno_core::extension!( deno_runtime, diff --git a/runtime/ops/worker_host.rs b/runtime/ops/worker_host.rs index e3360b8305..19475fedf1 100644 --- a/runtime/ops/worker_host.rs +++ b/runtime/ops/worker_host.rs @@ -1,9 +1,6 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. use crate::ops::TestingFeaturesEnabled; -use crate::permissions::create_child_permissions; -use crate::permissions::ChildPermissionsArg; -use crate::permissions::PermissionsContainer; use crate::web_worker::run_web_worker; use crate::web_worker::SendableWebWorkerHandle; use crate::web_worker::WebWorker; @@ -20,6 +17,9 @@ use deno_core::CancelFuture; use deno_core::CancelHandle; use deno_core::ModuleSpecifier; use deno_core::OpState; +use deno_permissions::create_child_permissions; +use deno_permissions::ChildPermissionsArg; +use deno_permissions::PermissionsContainer; use deno_web::deserialize_js_transferables; use deno_web::JsMessageData; use log::debug; @@ -156,7 +156,7 @@ fn op_create_worker( let parent_permissions = state.borrow_mut::(); let worker_permissions = if let Some(child_permissions_arg) = args.permissions { - let mut parent_permissions = parent_permissions.0 .0.lock(); + let mut parent_permissions = parent_permissions.0.lock(); let perms = create_child_permissions(&mut parent_permissions, child_permissions_arg)?; PermissionsContainer::new(perms) diff --git a/runtime/permissions.rs b/runtime/permissions.rs deleted file mode 100644 index edd03e1d52..0000000000 --- a/runtime/permissions.rs +++ /dev/null @@ -1,268 +0,0 @@ -// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. - -use std::borrow::Cow; -use std::path::Path; - -use deno_core::error::AnyError; -use deno_core::url::Url; -pub use deno_io::fs::FsError; -pub use deno_permissions::create_child_permissions; -pub use deno_permissions::parse_sys_kind; -pub use deno_permissions::set_prompt_callbacks; -pub use deno_permissions::ChildPermissionsArg; -pub use deno_permissions::Permissions; -pub use deno_permissions::PermissionsOptions; - -// NOTE: Temporary permissions container to satisfy traits. We are migrating to the deno_permissions -// crate. -#[derive(Debug, Clone)] - -pub struct PermissionsContainer(pub deno_permissions::PermissionsContainer); - -impl PermissionsContainer { - pub fn new(permissions: deno_permissions::Permissions) -> Self { - Self(deno_permissions::PermissionsContainer::new(permissions)) - } - - pub fn allow_all() -> Self { - Self(deno_permissions::PermissionsContainer::allow_all()) - } -} - -impl std::ops::Deref for PermissionsContainer { - type Target = deno_permissions::PermissionsContainer; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl std::ops::DerefMut for PermissionsContainer { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} - -impl deno_node::NodePermissions for PermissionsContainer { - #[inline(always)] - fn check_net_url( - &mut self, - url: &Url, - api_name: &str, - ) -> Result<(), AnyError> { - self.0.check_net_url(url, api_name) - } - - #[inline(always)] - fn check_read_with_api_name( - &self, - path: &Path, - api_name: Option<&str>, - ) -> Result<(), AnyError> { - self.0.check_read_with_api_name(path, api_name) - } - - #[inline(always)] - fn check_write_with_api_name( - &self, - path: &Path, - api_name: Option<&str>, - ) -> Result<(), AnyError> { - self.0.check_write_with_api_name(path, api_name) - } - - fn check_sys(&self, kind: &str, api_name: &str) -> Result<(), AnyError> { - self.0.check_sys(kind, api_name) - } -} - -impl deno_fetch::FetchPermissions for PermissionsContainer { - #[inline(always)] - fn check_net_url( - &mut self, - url: &Url, - api_name: &str, - ) -> Result<(), AnyError> { - self.0.check_net_url(url, api_name) - } - - #[inline(always)] - fn check_read( - &mut self, - path: &Path, - api_name: &str, - ) -> Result<(), AnyError> { - self.0.check_read(path, api_name) - } -} - -impl deno_net::NetPermissions for PermissionsContainer { - #[inline(always)] - fn check_net>( - &mut self, - host: &(T, Option), - api_name: &str, - ) -> Result<(), AnyError> { - self.0.check_net(host, api_name) - } - - #[inline(always)] - fn check_read( - &mut self, - path: &Path, - api_name: &str, - ) -> Result<(), AnyError> { - self.0.check_read(path, api_name) - } - - #[inline(always)] - fn check_write( - &mut self, - path: &Path, - api_name: &str, - ) -> Result<(), AnyError> { - self.0.check_write(path, api_name) - } -} - -impl deno_web::TimersPermission for PermissionsContainer { - #[inline(always)] - fn allow_hrtime(&mut self) -> bool { - self.0.allow_hrtime() - } -} - -impl deno_websocket::WebSocketPermissions for PermissionsContainer { - #[inline(always)] - fn check_net_url( - &mut self, - url: &Url, - api_name: &str, - ) -> Result<(), AnyError> { - self.0.check_net_url(url, api_name) - } -} - -impl deno_fs::FsPermissions for PermissionsContainer { - fn check_open<'a>( - &mut self, - resolved: bool, - read: bool, - write: bool, - path: &'a Path, - api_name: &str, - ) -> Result, FsError> { - if resolved { - self.check_special_file(path, api_name).map_err(|_| { - std::io::Error::from(std::io::ErrorKind::PermissionDenied) - })?; - return Ok(Cow::Borrowed(path)); - } - - // If somehow read or write aren't specified, use read - let read = read || !write; - if read { - deno_fs::FsPermissions::check_read(self, path, api_name) - .map_err(|_| FsError::PermissionDenied("read"))?; - } - if write { - deno_fs::FsPermissions::check_write(self, path, api_name) - .map_err(|_| FsError::PermissionDenied("write"))?; - } - Ok(Cow::Borrowed(path)) - } - - fn check_read( - &mut self, - path: &Path, - api_name: &str, - ) -> Result<(), AnyError> { - self.0.check_read(path, api_name) - } - - fn check_read_blind( - &mut self, - path: &Path, - display: &str, - api_name: &str, - ) -> Result<(), AnyError> { - self.0.check_read_blind(path, display, api_name) - } - - fn check_write( - &mut self, - path: &Path, - api_name: &str, - ) -> Result<(), AnyError> { - self.0.check_write(path, api_name) - } - - fn check_write_partial( - &mut self, - path: &Path, - api_name: &str, - ) -> Result<(), AnyError> { - self.0.check_write_partial(path, api_name) - } - - fn check_write_blind( - &mut self, - p: &Path, - display: &str, - api_name: &str, - ) -> Result<(), AnyError> { - self.0.check_write_blind(p, display, api_name) - } - - fn check_read_all(&mut self, api_name: &str) -> Result<(), AnyError> { - self.0.check_read_all(api_name) - } - - fn check_write_all(&mut self, api_name: &str) -> Result<(), AnyError> { - self.0.check_write_all(api_name) - } -} - -// NOTE(bartlomieju): for now, NAPI uses `--allow-ffi` flag, but that might -// change in the future. -impl deno_napi::NapiPermissions for PermissionsContainer { - #[inline(always)] - fn check(&mut self, path: Option<&Path>) -> Result<(), AnyError> { - self.0.check_ffi(path) - } -} - -impl deno_ffi::FfiPermissions for PermissionsContainer { - #[inline(always)] - fn check_partial(&mut self, path: Option<&Path>) -> Result<(), AnyError> { - self.0.check_ffi_partial(path) - } -} - -impl deno_kv::sqlite::SqliteDbHandlerPermissions for PermissionsContainer { - #[inline(always)] - fn check_read(&mut self, p: &Path, api_name: &str) -> Result<(), AnyError> { - self.0.check_read(p, api_name) - } - - #[inline(always)] - fn check_write(&mut self, p: &Path, api_name: &str) -> Result<(), AnyError> { - self.0.check_write(p, api_name) - } -} - -impl deno_kv::remote::RemoteDbHandlerPermissions for PermissionsContainer { - #[inline(always)] - fn check_env(&mut self, var: &str) -> Result<(), AnyError> { - self.0.check_env(var) - } - - #[inline(always)] - fn check_net_url( - &mut self, - url: &Url, - api_name: &str, - ) -> Result<(), AnyError> { - self.0.check_net_url(url, api_name) - } -} diff --git a/runtime/snapshot.rs b/runtime/snapshot.rs index 923ea0b759..7ae5e3ae5b 100644 --- a/runtime/snapshot.rs +++ b/runtime/snapshot.rs @@ -81,21 +81,21 @@ impl deno_node::NodePermissions for Permissions { unreachable!("snapshotting!") } fn check_read_with_api_name( - &self, + &mut self, _p: &Path, _api_name: Option<&str>, ) -> Result<(), deno_core::error::AnyError> { unreachable!("snapshotting!") } fn check_write_with_api_name( - &self, + &mut self, _p: &Path, _api_name: Option<&str>, ) -> Result<(), deno_core::error::AnyError> { unreachable!("snapshotting!") } fn check_sys( - &self, + &mut self, _kind: &str, _api_name: &str, ) -> Result<(), deno_core::error::AnyError> { @@ -254,7 +254,7 @@ pub fn create_runtime_snapshot( deno_http::deno_http::init_ops_and_esm::(), deno_io::deno_io::init_ops_and_esm(Default::default()), deno_fs::deno_fs::init_ops_and_esm::(fs.clone()), - deno_node::deno_node::init_ops_and_esm::(None, fs), + deno_node::deno_node::init_ops_and_esm::(None, None, fs), runtime::init_ops_and_esm(), ops::runtime::deno_runtime::init_ops("deno:runtime".parse().unwrap()), ops::worker_host::deno_worker_host::init_ops( diff --git a/runtime/web_worker.rs b/runtime/web_worker.rs index 8360356940..07a955efb8 100644 --- a/runtime/web_worker.rs +++ b/runtime/web_worker.rs @@ -2,7 +2,6 @@ use crate::inspector_server::InspectorServer; use crate::ops; use crate::ops::worker_host::WorkersTable; -use crate::permissions::PermissionsContainer; use crate::shared::maybe_transpile_source; use crate::shared::runtime; use crate::tokio_util::create_and_run_current_thread; @@ -45,6 +44,8 @@ use deno_fs::FileSystem; use deno_http::DefaultHttpPropertyExtractor; use deno_io::Stdio; use deno_kv::dynamic::MultiBackendDbHandler; +use deno_node::NodeResolver; +use deno_permissions::PermissionsContainer; use deno_terminal::colors; use deno_tls::RootCertStoreProvider; use deno_tls::TlsKeys; @@ -364,6 +365,7 @@ pub struct WebWorkerOptions { pub seed: Option, pub fs: Arc, pub module_loader: Rc, + pub node_resolver: Option>, pub npm_resolver: Option>, pub create_web_worker_cb: Arc, pub format_js_error_fn: Option>, @@ -411,7 +413,6 @@ impl WebWorker { enable_testing_features: bool, }, state = |state, options| { - state.put::(options.permissions.0.clone()); state.put::(options.permissions); state.put(ops::TestingFeaturesEnabled(options.enable_testing_features)); }, @@ -491,6 +492,7 @@ impl WebWorker { options.fs.clone(), ), deno_node::deno_node::init_ops_and_esm::( + options.node_resolver, options.npm_resolver, options.fs, ), diff --git a/runtime/worker.rs b/runtime/worker.rs index 09faa6e087..4e16afeeb1 100644 --- a/runtime/worker.rs +++ b/runtime/worker.rs @@ -39,6 +39,7 @@ use deno_fs::FileSystem; use deno_http::DefaultHttpPropertyExtractor; use deno_io::Stdio; use deno_kv::dynamic::MultiBackendDbHandler; +use deno_permissions::PermissionsContainer; use deno_tls::RootCertStoreProvider; use deno_tls::TlsKeys; use deno_web::BlobStore; @@ -48,7 +49,6 @@ use crate::code_cache::CodeCache; use crate::code_cache::CodeCacheType; use crate::inspector_server::InspectorServer; use crate::ops; -use crate::permissions::PermissionsContainer; use crate::shared::maybe_transpile_source; use crate::shared::runtime; use crate::BootstrapOptions; @@ -156,6 +156,7 @@ pub struct WorkerOptions { /// If not provided runtime will error if code being /// executed tries to load modules. pub module_loader: Rc, + pub node_resolver: Option>, pub npm_resolver: Option>, // Callbacks invoked when creating new instance of WebWorker pub create_web_worker_cb: Arc, @@ -227,6 +228,7 @@ impl Default for WorkerOptions { broadcast_channel: Default::default(), source_map_getter: Default::default(), root_cert_store_provider: Default::default(), + node_resolver: Default::default(), npm_resolver: Default::default(), blob_store: Default::default(), extensions: Default::default(), @@ -329,9 +331,6 @@ impl MainWorker { enable_testing_features: bool, }, state = |state, options| { - // Save the permissions container and the wrapper. - state.put::(options.permissions.0.clone()); - // This is temporary until we migrate all exts/ to the deno_permissions crate. state.put::(options.permissions); state.put(ops::TestingFeaturesEnabled(options.enable_testing_features)); }, @@ -419,6 +418,7 @@ impl MainWorker { options.fs.clone(), ), deno_node::deno_node::init_ops_and_esm::( + options.node_resolver, options.npm_resolver, options.fs, ),