summaryrefslogtreecommitdiff
path: root/cli
diff options
context:
space:
mode:
authorBartek IwaƄczuk <biwanczuk@gmail.com>2023-01-07 17:25:34 +0100
committerGitHub <noreply@github.com>2023-01-07 17:25:34 +0100
commitfac64478157ee563b185edb5734688e4523df3a1 (patch)
tree888d562982e1fc37dfb9a4459928bcec84d55dfc /cli
parent82e930726ee5dbac8e6eae0962c07c72daf9843c (diff)
refactor(permissions): add PermissionsContainer struct for internal mutability (#17134)
Turns out we were cloning permissions which after prompting were discarded, so the state of permissions was never preserved. To handle that we need to store all permissions behind "Arc<Mutex<>>" (because there are situations where we need to send them to other thread). Testing and benching code still uses "Permissions" in most places - it's undesirable to share the same permission set between various test/bench files - otherwise granting or revoking permissions in one file would influence behavior of other test files.
Diffstat (limited to 'cli')
-rw-r--r--cli/build.rs18
-rw-r--r--cli/cache/mod.rs14
-rw-r--r--cli/file_fetcher.rs69
-rw-r--r--cli/graph_util.rs6
-rw-r--r--cli/lsp/registries.rs12
-rw-r--r--cli/lsp/testing/execution.rs6
-rw-r--r--cli/module_loader.rs13
-rw-r--r--cli/ops/bench.rs16
-rw-r--r--cli/ops/testing.rs16
-rw-r--r--cli/proc_state.rs16
-rw-r--r--cli/standalone.rs5
-rw-r--r--cli/tests/run_tests.rs17
-rw-r--r--cli/tools/bench.rs13
-rw-r--r--cli/tools/repl/mod.rs7
-rw-r--r--cli/tools/run.rs20
-rw-r--r--cli/tools/standalone.rs4
-rw-r--r--cli/tools/test.rs26
-rw-r--r--cli/worker.rs11
18 files changed, 172 insertions, 117 deletions
diff --git a/cli/build.rs b/cli/build.rs
index faeaed073..b4acc0d1d 100644
--- a/cli/build.rs
+++ b/cli/build.rs
@@ -7,7 +7,7 @@ use std::path::PathBuf;
use deno_core::snapshot_util::*;
use deno_core::Extension;
use deno_runtime::deno_cache::SqliteBackedCache;
-use deno_runtime::permissions::Permissions;
+use deno_runtime::permissions::PermissionsContainer;
use deno_runtime::*;
mod ts {
@@ -294,13 +294,13 @@ fn create_cli_snapshot(snapshot_path: PathBuf, files: Vec<PathBuf>) {
deno_console::init(),
deno_url::init(),
deno_tls::init(),
- deno_web::init::<Permissions>(
+ deno_web::init::<PermissionsContainer>(
deno_web::BlobStore::default(),
Default::default(),
),
- deno_fetch::init::<Permissions>(Default::default()),
+ deno_fetch::init::<PermissionsContainer>(Default::default()),
deno_cache::init::<SqliteBackedCache>(None),
- deno_websocket::init::<Permissions>("".to_owned(), None, None),
+ deno_websocket::init::<PermissionsContainer>("".to_owned(), None, None),
deno_webstorage::init(None),
deno_crypto::init(None),
deno_webgpu::init(false),
@@ -308,15 +308,15 @@ fn create_cli_snapshot(snapshot_path: PathBuf, files: Vec<PathBuf>) {
deno_broadcast_channel::InMemoryBroadcastChannel::default(),
false, // No --unstable.
),
- deno_node::init::<Permissions>(None), // No --unstable.
- deno_ffi::init::<Permissions>(false),
- deno_net::init::<Permissions>(
+ deno_node::init::<PermissionsContainer>(None), // No --unstable.
+ deno_ffi::init::<PermissionsContainer>(false),
+ deno_net::init::<PermissionsContainer>(
None, false, // No --unstable.
None,
),
- deno_napi::init::<Permissions>(false),
+ deno_napi::init::<PermissionsContainer>(false),
deno_http::init(),
- deno_flash::init::<Permissions>(false), // No --unstable
+ deno_flash::init::<PermissionsContainer>(false), // No --unstable
];
create_snapshot(CreateSnapshotOptions {
diff --git a/cli/cache/mod.rs b/cli/cache/mod.rs
index 68bf1e4c6..d2ad1b20a 100644
--- a/cli/cache/mod.rs
+++ b/cli/cache/mod.rs
@@ -11,7 +11,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::Permissions;
+use deno_runtime::permissions::PermissionsContainer;
use std::sync::Arc;
mod check;
@@ -42,17 +42,17 @@ pub const CACHE_PERM: u32 = 0o644;
/// a concise interface to the DENO_DIR when building module graphs.
pub struct FetchCacher {
emit_cache: EmitCache,
- dynamic_permissions: Permissions,
+ dynamic_permissions: PermissionsContainer,
file_fetcher: Arc<FileFetcher>,
- root_permissions: Permissions,
+ root_permissions: PermissionsContainer,
}
impl FetchCacher {
pub fn new(
emit_cache: EmitCache,
file_fetcher: FileFetcher,
- root_permissions: Permissions,
- dynamic_permissions: Permissions,
+ root_permissions: PermissionsContainer,
+ dynamic_permissions: PermissionsContainer,
) -> Self {
let file_fetcher = Arc::new(file_fetcher);
@@ -104,7 +104,7 @@ impl Loader for FetchCacher {
}
let specifier = specifier.clone();
- let mut permissions = if is_dynamic {
+ let permissions = if is_dynamic {
self.dynamic_permissions.clone()
} else {
self.root_permissions.clone()
@@ -113,7 +113,7 @@ impl Loader for FetchCacher {
async move {
file_fetcher
- .fetch(&specifier, &mut permissions)
+ .fetch(&specifier, permissions)
.await
.map_or_else(
|err| {
diff --git a/cli/file_fetcher.rs b/cli/file_fetcher.rs
index cc83e6f5f..2376133f5 100644
--- a/cli/file_fetcher.rs
+++ b/cli/file_fetcher.rs
@@ -31,7 +31,7 @@ use deno_runtime::deno_fetch::reqwest::header::AUTHORIZATION;
use deno_runtime::deno_fetch::reqwest::header::IF_NONE_MATCH;
use deno_runtime::deno_fetch::reqwest::StatusCode;
use deno_runtime::deno_web::BlobStore;
-use deno_runtime::permissions::Permissions;
+use deno_runtime::permissions::PermissionsContainer;
use log::debug;
use std::borrow::Borrow;
use std::collections::HashMap;
@@ -406,7 +406,7 @@ impl FileFetcher {
fn fetch_remote(
&self,
specifier: &ModuleSpecifier,
- permissions: &mut Permissions,
+ permissions: PermissionsContainer,
redirect_limit: i64,
maybe_accept: Option<String>,
) -> Pin<Box<dyn Future<Output = Result<File, AnyError>> + Send>> {
@@ -461,7 +461,6 @@ impl FileFetcher {
};
let maybe_auth_token = self.auth_tokens.get(specifier);
let specifier = specifier.clone();
- let mut permissions = permissions.clone();
let client = self.http_client.clone();
let file_fetcher = self.clone();
// A single pass of fetch either yields code or yields a redirect.
@@ -487,7 +486,7 @@ impl FileFetcher {
file_fetcher
.fetch_remote(
&redirect_url,
- &mut permissions,
+ permissions,
redirect_limit - 1,
maybe_accept,
)
@@ -547,7 +546,7 @@ impl FileFetcher {
pub async fn fetch(
&self,
specifier: &ModuleSpecifier,
- permissions: &mut Permissions,
+ permissions: PermissionsContainer,
) -> Result<File, AnyError> {
debug!("FileFetcher::fetch() - specifier: {}", specifier);
self.fetch_with_accept(specifier, permissions, None).await
@@ -556,7 +555,7 @@ impl FileFetcher {
pub async fn fetch_with_accept(
&self,
specifier: &ModuleSpecifier,
- permissions: &mut Permissions,
+ permissions: PermissionsContainer,
maybe_accept: Option<&str>,
) -> Result<File, AnyError> {
let scheme = get_validated_scheme(specifier)?;
@@ -797,7 +796,7 @@ mod tests {
async fn test_fetch(specifier: &ModuleSpecifier) -> (File, FileFetcher) {
let (file_fetcher, _) = setup(CacheSetting::ReloadAll, None);
let result = file_fetcher
- .fetch(specifier, &mut Permissions::allow_all())
+ .fetch(specifier, PermissionsContainer::allow_all())
.await;
assert!(result.is_ok());
(result.unwrap(), file_fetcher)
@@ -809,7 +808,7 @@ mod tests {
let _http_server_guard = test_util::http_server();
let (file_fetcher, _) = setup(CacheSetting::ReloadAll, None);
let result: Result<File, AnyError> = file_fetcher
- .fetch_remote(specifier, &mut Permissions::allow_all(), 1, None)
+ .fetch_remote(specifier, PermissionsContainer::allow_all(), 1, None)
.await;
assert!(result.is_ok());
let (_, headers, _) = file_fetcher.http_cache.get(specifier).unwrap();
@@ -1053,7 +1052,7 @@ mod tests {
file_fetcher.insert_cached(file.clone());
let result = file_fetcher
- .fetch(&specifier, &mut Permissions::allow_all())
+ .fetch(&specifier, PermissionsContainer::allow_all())
.await;
assert!(result.is_ok());
let result_file = result.unwrap();
@@ -1069,7 +1068,7 @@ mod tests {
.unwrap();
let result = file_fetcher
- .fetch(&specifier, &mut Permissions::allow_all())
+ .fetch(&specifier, PermissionsContainer::allow_all())
.await;
assert!(result.is_ok());
@@ -1098,7 +1097,7 @@ mod tests {
let specifier = resolve_url("data:application/typescript;base64,ZXhwb3J0IGNvbnN0IGEgPSAiYSI7CgpleHBvcnQgZW51bSBBIHsKICBBLAogIEIsCiAgQywKfQo=").unwrap();
let result = file_fetcher
- .fetch(&specifier, &mut Permissions::allow_all())
+ .fetch(&specifier, PermissionsContainer::allow_all())
.await;
assert!(result.is_ok());
let file = result.unwrap();
@@ -1130,7 +1129,7 @@ mod tests {
);
let result = file_fetcher
- .fetch(&specifier, &mut Permissions::allow_all())
+ .fetch(&specifier, PermissionsContainer::allow_all())
.await;
assert!(result.is_ok());
let file = result.unwrap();
@@ -1153,7 +1152,7 @@ mod tests {
resolve_url_or_path("http://localhost:4545/subdir/mod2.ts").unwrap();
let result = file_fetcher
- .fetch(&specifier, &mut Permissions::allow_all())
+ .fetch(&specifier, PermissionsContainer::allow_all())
.await;
assert!(result.is_ok());
let file = result.unwrap();
@@ -1175,7 +1174,7 @@ mod tests {
metadata.write(&cache_filename).unwrap();
let result = file_fetcher_01
- .fetch(&specifier, &mut Permissions::allow_all())
+ .fetch(&specifier, PermissionsContainer::allow_all())
.await;
assert!(result.is_ok());
let file = result.unwrap();
@@ -1196,7 +1195,7 @@ mod tests {
metadata.write(&cache_filename).unwrap();
let result = file_fetcher_02
- .fetch(&specifier, &mut Permissions::allow_all())
+ .fetch(&specifier, PermissionsContainer::allow_all())
.await;
assert!(result.is_ok());
let file = result.unwrap();
@@ -1219,7 +1218,7 @@ mod tests {
)
.unwrap();
let result = file_fetcher
- .fetch(&specifier, &mut Permissions::allow_all())
+ .fetch(&specifier, PermissionsContainer::allow_all())
.await;
assert!(result.is_ok());
let file = result.unwrap();
@@ -1252,7 +1251,7 @@ mod tests {
.unwrap();
let result = file_fetcher_01
- .fetch(&specifier, &mut Permissions::allow_all())
+ .fetch(&specifier, PermissionsContainer::allow_all())
.await;
assert!(result.is_ok());
@@ -1271,7 +1270,7 @@ mod tests {
)
.unwrap();
let result = file_fetcher_02
- .fetch(&specifier, &mut Permissions::allow_all())
+ .fetch(&specifier, PermissionsContainer::allow_all())
.await;
assert!(result.is_ok());
@@ -1303,7 +1302,7 @@ mod tests {
.unwrap();
let result = file_fetcher
- .fetch(&specifier, &mut Permissions::allow_all())
+ .fetch(&specifier, PermissionsContainer::allow_all())
.await;
assert!(result.is_ok());
let file = result.unwrap();
@@ -1356,7 +1355,7 @@ mod tests {
.unwrap();
let result = file_fetcher
- .fetch(&specifier, &mut Permissions::allow_all())
+ .fetch(&specifier, PermissionsContainer::allow_all())
.await;
assert!(result.is_ok());
let file = result.unwrap();
@@ -1422,7 +1421,7 @@ mod tests {
.unwrap();
let result = file_fetcher_01
- .fetch(&specifier, &mut Permissions::allow_all())
+ .fetch(&specifier, PermissionsContainer::allow_all())
.await;
assert!(result.is_ok());
@@ -1442,7 +1441,7 @@ mod tests {
)
.unwrap();
let result = file_fetcher_02
- .fetch(&redirected_specifier, &mut Permissions::allow_all())
+ .fetch(&redirected_specifier, PermissionsContainer::allow_all())
.await;
assert!(result.is_ok());
@@ -1464,12 +1463,12 @@ mod tests {
.unwrap();
let result = file_fetcher
- .fetch_remote(&specifier, &mut Permissions::allow_all(), 2, None)
+ .fetch_remote(&specifier, PermissionsContainer::allow_all(), 2, None)
.await;
assert!(result.is_ok());
let result = file_fetcher
- .fetch_remote(&specifier, &mut Permissions::allow_all(), 1, None)
+ .fetch_remote(&specifier, PermissionsContainer::allow_all(), 1, None)
.await;
assert!(result.is_err());
@@ -1501,7 +1500,7 @@ mod tests {
.unwrap();
let result = file_fetcher
- .fetch(&specifier, &mut Permissions::allow_all())
+ .fetch(&specifier, PermissionsContainer::allow_all())
.await;
assert!(result.is_ok());
let file = result.unwrap();
@@ -1545,7 +1544,7 @@ mod tests {
resolve_url("http://localhost:4545/run/002_hello.ts").unwrap();
let result = file_fetcher
- .fetch(&specifier, &mut Permissions::allow_all())
+ .fetch(&specifier, PermissionsContainer::allow_all())
.await;
assert!(result.is_err());
let err = result.unwrap_err();
@@ -1580,7 +1579,7 @@ mod tests {
resolve_url("http://localhost:4545/run/002_hello.ts").unwrap();
let result = file_fetcher_01
- .fetch(&specifier, &mut Permissions::allow_all())
+ .fetch(&specifier, PermissionsContainer::allow_all())
.await;
assert!(result.is_err());
let err = result.unwrap_err();
@@ -1588,12 +1587,12 @@ mod tests {
assert_eq!(err.to_string(), "Specifier not found in cache: \"http://localhost:4545/run/002_hello.ts\", --cached-only is specified.");
let result = file_fetcher_02
- .fetch(&specifier, &mut Permissions::allow_all())
+ .fetch(&specifier, PermissionsContainer::allow_all())
.await;
assert!(result.is_ok());
let result = file_fetcher_01
- .fetch(&specifier, &mut Permissions::allow_all())
+ .fetch(&specifier, PermissionsContainer::allow_all())
.await;
assert!(result.is_ok());
}
@@ -1606,7 +1605,7 @@ mod tests {
resolve_url_or_path(&fixture_path.to_string_lossy()).unwrap();
fs::write(fixture_path.clone(), r#"console.log("hello deno");"#).unwrap();
let result = file_fetcher
- .fetch(&specifier, &mut Permissions::allow_all())
+ .fetch(&specifier, PermissionsContainer::allow_all())
.await;
assert!(result.is_ok());
let file = result.unwrap();
@@ -1614,7 +1613,7 @@ mod tests {
fs::write(fixture_path, r#"console.log("goodbye deno");"#).unwrap();
let result = file_fetcher
- .fetch(&specifier, &mut Permissions::allow_all())
+ .fetch(&specifier, PermissionsContainer::allow_all())
.await;
assert!(result.is_ok());
let file = result.unwrap();
@@ -1630,7 +1629,7 @@ mod tests {
let specifier =
ModuleSpecifier::parse("http://localhost:4545/dynamic").unwrap();
let result = file_fetcher
- .fetch(&specifier, &mut Permissions::allow_all())
+ .fetch(&specifier, PermissionsContainer::allow_all())
.await;
assert!(result.is_ok());
let file = result.unwrap();
@@ -1639,7 +1638,7 @@ mod tests {
let (file_fetcher, _) =
setup(CacheSetting::RespectHeaders, Some(temp_dir.clone()));
let result = file_fetcher
- .fetch(&specifier, &mut Permissions::allow_all())
+ .fetch(&specifier, PermissionsContainer::allow_all())
.await;
assert!(result.is_ok());
let file = result.unwrap();
@@ -1657,7 +1656,7 @@ mod tests {
let specifier =
ModuleSpecifier::parse("http://localhost:4545/dynamic_cache").unwrap();
let result = file_fetcher
- .fetch(&specifier, &mut Permissions::allow_all())
+ .fetch(&specifier, PermissionsContainer::allow_all())
.await;
assert!(result.is_ok());
let file = result.unwrap();
@@ -1666,7 +1665,7 @@ mod tests {
let (file_fetcher, _) =
setup(CacheSetting::RespectHeaders, Some(temp_dir.clone()));
let result = file_fetcher
- .fetch(&specifier, &mut Permissions::allow_all())
+ .fetch(&specifier, PermissionsContainer::allow_all())
.await;
assert!(result.is_ok());
let file = result.unwrap();
diff --git a/cli/graph_util.rs b/cli/graph_util.rs
index d815e3311..812701892 100644
--- a/cli/graph_util.rs
+++ b/cli/graph_util.rs
@@ -28,7 +28,7 @@ use deno_graph::ModuleGraphError;
use deno_graph::ModuleKind;
use deno_graph::Range;
use deno_graph::Resolved;
-use deno_runtime::permissions::Permissions;
+use deno_runtime::permissions::PermissionsContainer;
use std::collections::BTreeMap;
use std::collections::HashMap;
use std::collections::HashSet;
@@ -514,8 +514,8 @@ pub async fn create_graph_and_maybe_check(
let mut cache = cache::FetchCacher::new(
ps.emit_cache.clone(),
ps.file_fetcher.clone(),
- Permissions::allow_all(),
- Permissions::allow_all(),
+ PermissionsContainer::allow_all(),
+ PermissionsContainer::allow_all(),
);
let maybe_imports = ps.options.to_maybe_imports()?;
let maybe_cli_resolver = CliResolver::maybe_new(
diff --git a/cli/lsp/registries.rs b/cli/lsp/registries.rs
index 81e2552c0..c8e5dad60 100644
--- a/cli/lsp/registries.rs
+++ b/cli/lsp/registries.rs
@@ -30,7 +30,7 @@ use deno_core::url::Url;
use deno_core::ModuleSpecifier;
use deno_graph::Dependency;
use deno_runtime::deno_web::BlobStore;
-use deno_runtime::permissions::Permissions;
+use deno_runtime::permissions::PermissionsContainer;
use log::error;
use once_cell::sync::Lazy;
use regex::Regex;
@@ -519,7 +519,7 @@ impl ModuleRegistry {
.file_fetcher
.fetch_with_accept(
specifier,
- &mut Permissions::allow_all(),
+ PermissionsContainer::allow_all(),
Some("application/vnd.deno.reg.v2+json, application/vnd.deno.reg.v1+json;q=0.9, application/json;q=0.8"),
)
.await;
@@ -617,7 +617,7 @@ impl ModuleRegistry {
.ok()?;
let file = self
.file_fetcher
- .fetch(&endpoint, &mut Permissions::allow_all())
+ .fetch(&endpoint, PermissionsContainer::allow_all())
.await
.ok()?;
let documentation: lsp::Documentation =
@@ -973,7 +973,7 @@ impl ModuleRegistry {
let specifier = Url::parse(url).ok()?;
let file = self
.file_fetcher
- .fetch(&specifier, &mut Permissions::allow_all())
+ .fetch(&specifier, PermissionsContainer::allow_all())
.await
.ok()?;
serde_json::from_str(&file.source).ok()
@@ -1030,7 +1030,7 @@ impl ModuleRegistry {
let specifier = ModuleSpecifier::parse(url).ok()?;
let file = self
.file_fetcher
- .fetch(&specifier, &mut Permissions::allow_all())
+ .fetch(&specifier, PermissionsContainer::allow_all())
.await
.map_err(|err| {
error!(
@@ -1066,7 +1066,7 @@ impl ModuleRegistry {
.ok()?;
let file = self
.file_fetcher
- .fetch(&specifier, &mut Permissions::allow_all())
+ .fetch(&specifier, PermissionsContainer::allow_all())
.await
.map_err(|err| {
error!(
diff --git a/cli/lsp/testing/execution.rs b/cli/lsp/testing/execution.rs
index 722f06e2c..a498df857 100644
--- a/cli/lsp/testing/execution.rs
+++ b/cli/lsp/testing/execution.rs
@@ -30,6 +30,7 @@ use deno_core::ModuleSpecifier;
use deno_runtime::ops::io::Stdio;
use deno_runtime::ops::io::StdioPipe;
use deno_runtime::permissions::Permissions;
+use deno_runtime::permissions::PermissionsContainer;
use deno_runtime::tokio_util::run_local;
use indexmap::IndexMap;
use std::collections::HashMap;
@@ -162,7 +163,7 @@ async fn test_specifier(
let mut worker = create_main_worker_for_test_or_bench(
&ps,
specifier.clone(),
- permissions,
+ PermissionsContainer::new(permissions),
vec![ops::testing::init(sender, fail_fast_tracker, filter)],
Stdio {
stdin: StdioPipe::Inherit,
@@ -254,6 +255,9 @@ impl TestRun {
lsp_log!("Executing test run with arguments: {}", args.join(" "));
let flags = flags_from_vec(args.into_iter().map(String::from).collect())?;
let ps = proc_state::ProcState::build(flags).await?;
+ // Various test files should not share the same permissions in terms of
+ // `PermissionsContainer` - otherwise granting/revoking permissions in one
+ // file would have impact on other files, which is undesirable.
let permissions =
Permissions::from_options(&ps.options.permissions_options())?;
test::check_specifiers(
diff --git a/cli/module_loader.rs b/cli/module_loader.rs
index edc89be77..d452c30cf 100644
--- a/cli/module_loader.rs
+++ b/cli/module_loader.rs
@@ -21,7 +21,7 @@ use deno_core::ModuleSpecifier;
use deno_core::ModuleType;
use deno_core::OpState;
use deno_core::SourceMapGetter;
-use deno_runtime::permissions::Permissions;
+use deno_runtime::permissions::PermissionsContainer;
use std::cell::RefCell;
use std::pin::Pin;
use std::rc::Rc;
@@ -38,7 +38,7 @@ pub struct CliModuleLoader {
/// The initial set of permissions used to resolve the static imports in the
/// worker. They are decoupled from the worker (dynamic) permissions since
/// read access errors must be raised based on the parent thread permissions.
- pub root_permissions: Permissions,
+ pub root_permissions: PermissionsContainer,
pub ps: ProcState,
}
@@ -46,12 +46,15 @@ impl CliModuleLoader {
pub fn new(ps: ProcState) -> Rc<Self> {
Rc::new(CliModuleLoader {
lib: ps.options.ts_type_lib_window(),
- root_permissions: Permissions::allow_all(),
+ root_permissions: PermissionsContainer::allow_all(),
ps,
})
}
- pub fn new_for_worker(ps: ProcState, permissions: Permissions) -> Rc<Self> {
+ pub fn new_for_worker(
+ ps: ProcState,
+ permissions: PermissionsContainer,
+ ) -> Rc<Self> {
Rc::new(CliModuleLoader {
lib: ps.options.ts_type_lib_worker(),
root_permissions: permissions,
@@ -235,7 +238,7 @@ impl ModuleLoader for CliModuleLoader {
let ps = self.ps.clone();
let state = op_state.borrow();
- let dynamic_permissions = state.borrow::<Permissions>().clone();
+ let dynamic_permissions = state.borrow::<PermissionsContainer>().clone();
let root_permissions = if is_dynamic {
dynamic_permissions.clone()
} else {
diff --git a/cli/ops/bench.rs b/cli/ops/bench.rs
index 6fc881f61..3b27ffa7e 100644
--- a/cli/ops/bench.rs
+++ b/cli/ops/bench.rs
@@ -9,7 +9,7 @@ use deno_core::ModuleSpecifier;
use deno_core::OpState;
use deno_runtime::permissions::create_child_permissions;
use deno_runtime::permissions::ChildPermissionsArg;
-use deno_runtime::permissions::Permissions;
+use deno_runtime::permissions::PermissionsContainer;
use serde::Deserialize;
use serde::Serialize;
use std::sync::atomic::AtomicUsize;
@@ -40,7 +40,7 @@ pub fn init(
}
#[derive(Clone)]
-struct PermissionsHolder(Uuid, Permissions);
+struct PermissionsHolder(Uuid, PermissionsContainer);
#[op]
pub fn op_pledge_test_permissions(
@@ -48,8 +48,12 @@ pub fn op_pledge_test_permissions(
args: ChildPermissionsArg,
) -> Result<Uuid, AnyError> {
let token = Uuid::new_v4();
- let parent_permissions = state.borrow_mut::<Permissions>();
- let worker_permissions = create_child_permissions(parent_permissions, args)?;
+ let parent_permissions = state.borrow_mut::<PermissionsContainer>();
+ let worker_permissions = {
+ let mut parent_permissions = parent_permissions.0.lock();
+ let perms = create_child_permissions(&mut parent_permissions, args)?;
+ PermissionsContainer::new(perms)
+ };
let parent_permissions = parent_permissions.clone();
if state.try_take::<PermissionsHolder>().is_some() {
@@ -59,7 +63,7 @@ pub fn op_pledge_test_permissions(
state.put::<PermissionsHolder>(PermissionsHolder(token, parent_permissions));
// NOTE: This call overrides current permission set for the worker
- state.put::<Permissions>(worker_permissions);
+ state.put::<PermissionsContainer>(worker_permissions);
Ok(token)
}
@@ -75,7 +79,7 @@ pub fn op_restore_test_permissions(
}
let permissions = permissions_holder.1;
- state.put::<Permissions>(permissions);
+ state.put::<PermissionsContainer>(permissions);
Ok(())
} else {
Err(generic_error("no permissions to restore"))
diff --git a/cli/ops/testing.rs b/cli/ops/testing.rs
index b6fd29fc7..e5c0a2b99 100644
--- a/cli/ops/testing.rs
+++ b/cli/ops/testing.rs
@@ -17,7 +17,7 @@ use deno_core::ModuleSpecifier;
use deno_core::OpState;
use deno_runtime::permissions::create_child_permissions;
use deno_runtime::permissions::ChildPermissionsArg;
-use deno_runtime::permissions::Permissions;
+use deno_runtime::permissions::PermissionsContainer;
use serde::Deserialize;
use serde::Deserializer;
use serde::Serialize;
@@ -50,7 +50,7 @@ pub fn init(
}
#[derive(Clone)]
-struct PermissionsHolder(Uuid, Permissions);
+struct PermissionsHolder(Uuid, PermissionsContainer);
#[op]
pub fn op_pledge_test_permissions(
@@ -58,8 +58,12 @@ pub fn op_pledge_test_permissions(
args: ChildPermissionsArg,
) -> Result<Uuid, AnyError> {
let token = Uuid::new_v4();
- let parent_permissions = state.borrow_mut::<Permissions>();
- let worker_permissions = create_child_permissions(parent_permissions, args)?;
+ let parent_permissions = state.borrow_mut::<PermissionsContainer>();
+ let worker_permissions = {
+ let mut parent_permissions = parent_permissions.0.lock();
+ let perms = create_child_permissions(&mut parent_permissions, args)?;
+ PermissionsContainer::new(perms)
+ };
let parent_permissions = parent_permissions.clone();
if state.try_take::<PermissionsHolder>().is_some() {
@@ -68,7 +72,7 @@ pub fn op_pledge_test_permissions(
state.put::<PermissionsHolder>(PermissionsHolder(token, parent_permissions));
// NOTE: This call overrides current permission set for the worker
- state.put::<Permissions>(worker_permissions);
+ state.put::<PermissionsContainer>(worker_permissions);
Ok(token)
}
@@ -84,7 +88,7 @@ pub fn op_restore_test_permissions(
}
let permissions = permissions_holder.1;
- state.put::<Permissions>(permissions);
+ state.put::<PermissionsContainer>(permissions);
Ok(())
} else {
Err(generic_error("no permissions to restore"))
diff --git a/cli/proc_state.rs b/cli/proc_state.rs
index eb672d8d0..0dd97b5e3 100644
--- a/cli/proc_state.rs
+++ b/cli/proc_state.rs
@@ -59,7 +59,7 @@ use deno_runtime::deno_node::NodeResolutionMode;
use deno_runtime::deno_tls::rustls::RootCertStore;
use deno_runtime::deno_web::BlobStore;
use deno_runtime::inspector_server::InspectorServer;
-use deno_runtime::permissions::Permissions;
+use deno_runtime::permissions::PermissionsContainer;
use import_map::ImportMap;
use log::warn;
use std::collections::HashSet;
@@ -181,7 +181,7 @@ impl ProcState {
let maybe_import_map =
if let Some(import_map_specifier) = maybe_import_map_specifier {
let file = file_fetcher
- .fetch(&import_map_specifier, &mut Permissions::allow_all())
+ .fetch(&import_map_specifier, PermissionsContainer::allow_all())
.await
.context(format!(
"Unable to load '{}' import map",
@@ -289,8 +289,8 @@ impl ProcState {
roots: Vec<ModuleSpecifier>,
is_dynamic: bool,
lib: TsTypeLib,
- root_permissions: Permissions,
- dynamic_permissions: Permissions,
+ root_permissions: PermissionsContainer,
+ dynamic_permissions: PermissionsContainer,
reload_on_watch: bool,
) -> Result<(), AnyError> {
log::debug!("Preparing module load.");
@@ -490,8 +490,8 @@ impl ProcState {
specifiers,
false,
lib,
- Permissions::allow_all(),
- Permissions::allow_all(),
+ PermissionsContainer::allow_all(),
+ PermissionsContainer::allow_all(),
false,
)
.await
@@ -668,8 +668,8 @@ impl ProcState {
cache::FetchCacher::new(
self.emit_cache.clone(),
self.file_fetcher.clone(),
- Permissions::allow_all(),
- Permissions::allow_all(),
+ PermissionsContainer::allow_all(),
+ PermissionsContainer::allow_all(),
)
}
diff --git a/cli/standalone.rs b/cli/standalone.rs
index c93631327..2b0a77e18 100644
--- a/cli/standalone.rs
+++ b/cli/standalone.rs
@@ -29,6 +29,7 @@ use deno_runtime::deno_tls::rustls_pemfile;
use deno_runtime::deno_web::BlobStore;
use deno_runtime::fmt_errors::format_js_error;
use deno_runtime::permissions::Permissions;
+use deno_runtime::permissions::PermissionsContainer;
use deno_runtime::permissions::PermissionsOptions;
use deno_runtime::worker::MainWorker;
use deno_runtime::worker::WorkerOptions;
@@ -226,7 +227,9 @@ pub async fn run(
let flags = metadata_to_flags(&metadata);
let main_module = &metadata.entrypoint;
let ps = ProcState::build(flags).await?;
- let permissions = Permissions::from_options(&metadata.permissions)?;
+ let permissions = PermissionsContainer::new(Permissions::from_options(
+ &metadata.permissions,
+ )?);
let blob_store = BlobStore::default();
let broadcast_channel = InMemoryBroadcastChannel::default();
let module_loader = Rc::new(EmbeddedModuleLoader {
diff --git a/cli/tests/run_tests.rs b/cli/tests/run_tests.rs
index dfe95d9a8..8460d3f8f 100644
--- a/cli/tests/run_tests.rs
+++ b/cli/tests/run_tests.rs
@@ -3725,4 +3725,21 @@ console.log("finish");
args: "run --quiet run/001_hello.js --allow-net",
output: "run/001_hello.js.out",
});
+
+ // Regression test for https://github.com/denoland/deno/issues/16772
+ #[test]
+ fn file_fetcher_preserves_permissions() {
+ let _guard = util::http_server();
+ util::with_pty(&["repl"], |mut console| {
+ console.write_text(
+ "const a = import('http://127.0.0.1:4545/run/019_media_types.ts');",
+ );
+ console.write_text("y");
+ console.write_line("");
+ console.write_line("close();");
+ let output = console.read_all_output();
+ assert_contains!(output, "success");
+ assert_contains!(output, "true");
+ });
+ }
}
diff --git a/cli/tools/bench.rs b/cli/tools/bench.rs
index 24fb07919..2d54b260d 100644
--- a/cli/tools/bench.rs
+++ b/cli/tools/bench.rs
@@ -28,6 +28,7 @@ use deno_core::futures::StreamExt;
use deno_core::ModuleSpecifier;
use deno_graph::ModuleKind;
use deno_runtime::permissions::Permissions;
+use deno_runtime::permissions::PermissionsContainer;
use deno_runtime::tokio_util::run_local;
use indexmap::IndexMap;
use log::Level;
@@ -337,8 +338,8 @@ async fn check_specifiers(
specifiers,
false,
lib,
- Permissions::allow_all(),
- permissions,
+ PermissionsContainer::allow_all(),
+ PermissionsContainer::new(permissions),
true,
)
.await?;
@@ -358,7 +359,7 @@ async fn bench_specifier(
let mut worker = create_main_worker_for_test_or_bench(
&ps,
specifier.clone(),
- permissions,
+ PermissionsContainer::new(permissions),
vec![ops::bench::init(channel.clone(), filter)],
Default::default(),
)
@@ -490,6 +491,9 @@ pub async fn run_benchmarks(
bench_flags: BenchFlags,
) -> Result<(), AnyError> {
let ps = ProcState::build(flags).await?;
+ // Various bench files should not share the same permissions in terms of
+ // `PermissionsContainer` - otherwise granting/revoking permissions in one
+ // file would have impact on other files, which is undesirable.
let permissions =
Permissions::from_options(&ps.options.permissions_options())?;
@@ -527,6 +531,9 @@ pub async fn run_benchmarks_with_watch(
bench_flags: BenchFlags,
) -> Result<(), AnyError> {
let ps = ProcState::build(flags).await?;
+ // Various bench files should not share the same permissions in terms of
+ // `PermissionsContainer` - otherwise granting/revoking permissions in one
+ // file would have impact on other files, which is undesirable.
let permissions =
Permissions::from_options(&ps.options.permissions_options())?;
diff --git a/cli/tools/repl/mod.rs b/cli/tools/repl/mod.rs
index fc03dee2f..00f10b7d6 100644
--- a/cli/tools/repl/mod.rs
+++ b/cli/tools/repl/mod.rs
@@ -8,6 +8,7 @@ use crate::worker::create_main_worker;
use deno_core::error::AnyError;
use deno_core::resolve_url_or_path;
use deno_runtime::permissions::Permissions;
+use deno_runtime::permissions::PermissionsContainer;
use rustyline::error::ReadlineError;
mod cdp;
@@ -72,7 +73,7 @@ async fn read_eval_file(
let file = ps
.file_fetcher
- .fetch(&specifier, &mut Permissions::allow_all())
+ .fetch(&specifier, PermissionsContainer::allow_all())
.await?;
Ok((*file.source).to_string())
@@ -84,7 +85,9 @@ pub async fn run(flags: Flags, repl_flags: ReplFlags) -> Result<i32, AnyError> {
let mut worker = create_main_worker(
&ps,
main_module.clone(),
- Permissions::from_options(&ps.options.permissions_options())?,
+ PermissionsContainer::new(Permissions::from_options(
+ &ps.options.permissions_options(),
+ )?),
)
.await?;
worker.setup_repl().await?;
diff --git a/cli/tools/run.rs b/cli/tools/run.rs
index af982e483..3830affed 100644
--- a/cli/tools/run.rs
+++ b/cli/tools/run.rs
@@ -9,6 +9,7 @@ use deno_ast::ModuleSpecifier;
use deno_core::error::AnyError;
use deno_core::resolve_url_or_path;
use deno_runtime::permissions::Permissions;
+use deno_runtime::permissions::PermissionsContainer;
use crate::args::EvalFlags;
use crate::args::Flags;
@@ -56,8 +57,9 @@ To grant permissions, set them before the script argument. For example:
} else {
resolve_url_or_path(&run_flags.script)?
};
- let permissions =
- Permissions::from_options(&ps.options.permissions_options())?;
+ let permissions = PermissionsContainer::new(Permissions::from_options(
+ &ps.options.permissions_options(),
+ )?);
let mut worker =
create_main_worker(&ps, main_module.clone(), permissions).await?;
@@ -71,7 +73,9 @@ pub async fn run_from_stdin(flags: Flags) -> Result<i32, AnyError> {
let mut worker = create_main_worker(
&ps.clone(),
main_module.clone(),
- Permissions::from_options(&ps.options.permissions_options())?,
+ PermissionsContainer::new(Permissions::from_options(
+ &ps.options.permissions_options(),
+ )?),
)
.await?;
@@ -110,8 +114,9 @@ async fn run_with_watch(flags: Flags, script: String) -> Result<i32, AnyError> {
let ps =
ProcState::build_for_file_watcher((*flags).clone(), sender.clone())
.await?;
- let permissions =
- Permissions::from_options(&ps.options.permissions_options())?;
+ let permissions = PermissionsContainer::new(Permissions::from_options(
+ &ps.options.permissions_options(),
+ )?);
let worker =
create_main_worker(&ps, main_module.clone(), permissions).await?;
worker.run_for_watcher().await?;
@@ -143,8 +148,9 @@ pub async fn eval_command(
let main_module =
resolve_url_or_path(&format!("./$deno$eval.{}", eval_flags.ext))?;
let ps = ProcState::build(flags).await?;
- let permissions =
- Permissions::from_options(&ps.options.permissions_options())?;
+ let permissions = PermissionsContainer::new(Permissions::from_options(
+ &ps.options.permissions_options(),
+ )?);
let mut worker =
create_main_worker(&ps, main_module.clone(), permissions).await?;
// Create a dummy source file.
diff --git a/cli/tools/standalone.rs b/cli/tools/standalone.rs
index 471c9605d..07baecc05 100644
--- a/cli/tools/standalone.rs
+++ b/cli/tools/standalone.rs
@@ -21,7 +21,7 @@ use deno_core::serde_json;
use deno_core::url::Url;
use deno_graph::ModuleSpecifier;
use deno_runtime::colors;
-use deno_runtime::permissions::Permissions;
+use deno_runtime::permissions::PermissionsContainer;
use std::env;
use std::fs;
use std::fs::File;
@@ -170,7 +170,7 @@ async fn create_standalone_binary(
Some(import_map_specifier) => {
let file = ps
.file_fetcher
- .fetch(&import_map_specifier, &mut Permissions::allow_all())
+ .fetch(&import_map_specifier, PermissionsContainer::allow_all())
.await
.context(format!(
"Unable to load '{}' import map",
diff --git a/cli/tools/test.rs b/cli/tools/test.rs
index 35c0ea079..9d1774fff 100644
--- a/cli/tools/test.rs
+++ b/cli/tools/test.rs
@@ -37,6 +37,7 @@ use deno_runtime::fmt_errors::format_js_error;
use deno_runtime::ops::io::Stdio;
use deno_runtime::ops::io::StdioPipe;
use deno_runtime::permissions::Permissions;
+use deno_runtime::permissions::PermissionsContainer;
use deno_runtime::tokio_util::run_local;
use indexmap::IndexMap;
use log::Level;
@@ -723,7 +724,7 @@ async fn test_specifier(
let mut worker = create_main_worker_for_test_or_bench(
&ps,
specifier.clone(),
- permissions,
+ PermissionsContainer::new(permissions),
vec![ops::testing::init(
sender,
fail_fast_tracker,
@@ -895,11 +896,8 @@ async fn fetch_inline_files(
) -> Result<Vec<File>, AnyError> {
let mut files = Vec::new();
for specifier in specifiers {
- let mut fetch_permissions = Permissions::allow_all();
- let file = ps
- .file_fetcher
- .fetch(&specifier, &mut fetch_permissions)
- .await?;
+ let fetch_permissions = PermissionsContainer::allow_all();
+ let file = ps.file_fetcher.fetch(&specifier, fetch_permissions).await?;
let inline_files = if file.media_type == MediaType::Unknown {
extract_files_from_fenced_blocks(
@@ -957,8 +955,8 @@ pub async fn check_specifiers(
specifiers,
false,
lib,
- Permissions::allow_all(),
- permissions.clone(),
+ PermissionsContainer::new(Permissions::allow_all()),
+ PermissionsContainer::new(permissions.clone()),
false,
)
.await?;
@@ -979,8 +977,8 @@ pub async fn check_specifiers(
module_specifiers,
false,
lib,
- Permissions::allow_all(),
- permissions,
+ PermissionsContainer::allow_all(),
+ PermissionsContainer::new(permissions),
true,
)
.await?;
@@ -1324,7 +1322,7 @@ async fn fetch_specifiers_with_test_mode(
for (specifier, mode) in &mut specifiers_with_mode {
let file = ps
.file_fetcher
- .fetch(specifier, &mut Permissions::allow_all())
+ .fetch(specifier, PermissionsContainer::allow_all())
.await?;
if file.media_type == MediaType::Unknown
@@ -1342,6 +1340,9 @@ pub async fn run_tests(
test_flags: TestFlags,
) -> Result<(), AnyError> {
let ps = ProcState::build(flags).await?;
+ // Various test files should not share the same permissions in terms of
+ // `PermissionsContainer` - otherwise granting/revoking permissions in one
+ // file would have impact on other files, which is undesirable.
let permissions =
Permissions::from_options(&ps.options.permissions_options())?;
let specifiers_with_mode = fetch_specifiers_with_test_mode(
@@ -1383,6 +1384,9 @@ pub async fn run_tests_with_watch(
test_flags: TestFlags,
) -> Result<(), AnyError> {
let ps = ProcState::build(flags).await?;
+ // Various test files should not share the same permissions in terms of
+ // `PermissionsContainer` - otherwise granting/revoking permissions in one
+ // file would have impact on other files, which is undesirable.
let permissions =
Permissions::from_options(&ps.options.permissions_options())?;
diff --git a/cli/worker.rs b/cli/worker.rs
index ea50966f4..2d29a7a53 100644
--- a/cli/worker.rs
+++ b/cli/worker.rs
@@ -16,7 +16,7 @@ use deno_runtime::colors;
use deno_runtime::fmt_errors::format_js_error;
use deno_runtime::ops::worker_host::CreateWebWorkerCb;
use deno_runtime::ops::worker_host::WorkerEventCb;
-use deno_runtime::permissions::Permissions;
+use deno_runtime::permissions::PermissionsContainer;
use deno_runtime::web_worker::WebWorker;
use deno_runtime::web_worker::WebWorkerOptions;
use deno_runtime::worker::MainWorker;
@@ -410,7 +410,7 @@ impl CliMainWorker {
pub async fn create_main_worker(
ps: &ProcState,
main_module: ModuleSpecifier,
- permissions: Permissions,
+ permissions: PermissionsContainer,
) -> Result<CliMainWorker, AnyError> {
create_main_worker_internal(
ps,
@@ -426,7 +426,7 @@ pub async fn create_main_worker(
pub async fn create_main_worker_for_test_or_bench(
ps: &ProcState,
main_module: ModuleSpecifier,
- permissions: Permissions,
+ permissions: PermissionsContainer,
custom_extensions: Vec<Extension>,
stdio: deno_runtime::ops::io::Stdio,
) -> Result<CliMainWorker, AnyError> {
@@ -444,7 +444,7 @@ pub async fn create_main_worker_for_test_or_bench(
async fn create_main_worker_internal(
ps: &ProcState,
main_module: ModuleSpecifier,
- permissions: Permissions,
+ permissions: PermissionsContainer,
mut custom_extensions: Vec<Extension>,
stdio: deno_runtime::ops::io::Stdio,
bench_or_test: bool,
@@ -731,10 +731,11 @@ mod tests {
use deno_core::{resolve_url_or_path, FsModuleLoader};
use deno_runtime::deno_broadcast_channel::InMemoryBroadcastChannel;
use deno_runtime::deno_web::BlobStore;
+ use deno_runtime::permissions::Permissions;
fn create_test_worker() -> MainWorker {
let main_module = resolve_url_or_path("./hello.js").unwrap();
- let permissions = Permissions::default();
+ let permissions = PermissionsContainer::new(Permissions::default());
let options = WorkerOptions {
bootstrap: BootstrapOptions {