mirror of
https://github.com/denoland/deno.git
synced 2024-11-25 15:29:32 -05:00
refactor: bury descriptor parsing in PermissionsContainer (#25936)
Closes https://github.com/denoland/deno/issues/25634
This commit is contained in:
parent
efb413bdaa
commit
c8f692057b
14 changed files with 563 additions and 442 deletions
|
@ -34,8 +34,8 @@ use deno_core::url::Url;
|
||||||
use deno_graph::GraphKind;
|
use deno_graph::GraphKind;
|
||||||
use deno_path_util::normalize_path;
|
use deno_path_util::normalize_path;
|
||||||
use deno_path_util::url_to_file_path;
|
use deno_path_util::url_to_file_path;
|
||||||
use deno_runtime::deno_permissions::parse_sys_kind;
|
|
||||||
use deno_runtime::deno_permissions::PermissionsOptions;
|
use deno_runtime::deno_permissions::PermissionsOptions;
|
||||||
|
use deno_runtime::deno_permissions::SysDescriptor;
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use log::Level;
|
use log::Level;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
@ -3448,7 +3448,7 @@ fn permission_args(app: Command, requires: Option<&'static str>) -> Command {
|
||||||
.require_equals(true)
|
.require_equals(true)
|
||||||
.value_name("API_NAME")
|
.value_name("API_NAME")
|
||||||
.help("Allow access to OS information. Optionally allow specific APIs by function name")
|
.help("Allow access to OS information. Optionally allow specific APIs by function name")
|
||||||
.value_parser(|key: &str| parse_sys_kind(key).map(ToString::to_string))
|
.value_parser(|key: &str| SysDescriptor::parse(key.to_string()).map(|s| s.into_string()))
|
||||||
.hide(true)
|
.hide(true)
|
||||||
;
|
;
|
||||||
if let Some(requires) = requires {
|
if let Some(requires) = requires {
|
||||||
|
@ -3466,7 +3466,7 @@ fn permission_args(app: Command, requires: Option<&'static str>) -> Command {
|
||||||
.require_equals(true)
|
.require_equals(true)
|
||||||
.value_name("API_NAME")
|
.value_name("API_NAME")
|
||||||
.help("Deny access to OS information. Optionally deny specific APIs by function name")
|
.help("Deny access to OS information. Optionally deny specific APIs by function name")
|
||||||
.value_parser(|key: &str| parse_sys_kind(key).map(ToString::to_string))
|
.value_parser(|key: &str| SysDescriptor::parse(key.to_string()).map(|s| s.into_string()))
|
||||||
.hide(true)
|
.hide(true)
|
||||||
;
|
;
|
||||||
if let Some(requires) = requires {
|
if let Some(requires) = requires {
|
||||||
|
|
|
@ -824,7 +824,6 @@ impl CliFactory {
|
||||||
)),
|
)),
|
||||||
node_resolver.clone(),
|
node_resolver.clone(),
|
||||||
npm_resolver.clone(),
|
npm_resolver.clone(),
|
||||||
self.permission_desc_parser()?.clone(),
|
|
||||||
self.root_cert_store_provider().clone(),
|
self.root_cert_store_provider().clone(),
|
||||||
self.root_permissions_container()?.clone(),
|
self.root_permissions_container()?.clone(),
|
||||||
StorageKeyResolver::from_options(cli_options),
|
StorageKeyResolver::from_options(cli_options),
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
use std::sync::atomic::AtomicUsize;
|
use std::sync::atomic::AtomicUsize;
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
use std::sync::Arc;
|
|
||||||
use std::time;
|
use std::time;
|
||||||
|
|
||||||
use deno_core::error::generic_error;
|
use deno_core::error::generic_error;
|
||||||
|
@ -12,9 +11,7 @@ use deno_core::op2;
|
||||||
use deno_core::v8;
|
use deno_core::v8;
|
||||||
use deno_core::ModuleSpecifier;
|
use deno_core::ModuleSpecifier;
|
||||||
use deno_core::OpState;
|
use deno_core::OpState;
|
||||||
use deno_runtime::deno_permissions::create_child_permissions;
|
|
||||||
use deno_runtime::deno_permissions::ChildPermissionsArg;
|
use deno_runtime::deno_permissions::ChildPermissionsArg;
|
||||||
use deno_runtime::deno_permissions::PermissionDescriptorParser;
|
|
||||||
use deno_runtime::deno_permissions::PermissionsContainer;
|
use deno_runtime::deno_permissions::PermissionsContainer;
|
||||||
use tokio::sync::mpsc::UnboundedSender;
|
use tokio::sync::mpsc::UnboundedSender;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
@ -61,19 +58,8 @@ pub fn op_pledge_test_permissions(
|
||||||
#[serde] args: ChildPermissionsArg,
|
#[serde] args: ChildPermissionsArg,
|
||||||
) -> Result<Uuid, AnyError> {
|
) -> Result<Uuid, AnyError> {
|
||||||
let token = Uuid::new_v4();
|
let token = Uuid::new_v4();
|
||||||
let permission_desc_parser = state
|
|
||||||
.borrow::<Arc<dyn PermissionDescriptorParser>>()
|
|
||||||
.clone();
|
|
||||||
let parent_permissions = state.borrow_mut::<PermissionsContainer>();
|
let parent_permissions = state.borrow_mut::<PermissionsContainer>();
|
||||||
let worker_permissions = {
|
let worker_permissions = parent_permissions.create_child_permissions(args)?;
|
||||||
let mut parent_permissions = parent_permissions.inner.lock();
|
|
||||||
let perms = create_child_permissions(
|
|
||||||
permission_desc_parser.as_ref(),
|
|
||||||
&mut parent_permissions,
|
|
||||||
args,
|
|
||||||
)?;
|
|
||||||
PermissionsContainer::new(permission_desc_parser, perms)
|
|
||||||
};
|
|
||||||
let parent_permissions = parent_permissions.clone();
|
let parent_permissions = parent_permissions.clone();
|
||||||
|
|
||||||
if state.try_take::<PermissionsHolder>().is_some() {
|
if state.try_take::<PermissionsHolder>().is_some() {
|
||||||
|
@ -83,7 +69,6 @@ pub fn op_pledge_test_permissions(
|
||||||
state.put::<PermissionsHolder>(PermissionsHolder(token, parent_permissions));
|
state.put::<PermissionsHolder>(PermissionsHolder(token, parent_permissions));
|
||||||
|
|
||||||
// NOTE: This call overrides current permission set for the worker
|
// NOTE: This call overrides current permission set for the worker
|
||||||
state.put(worker_permissions.inner.clone());
|
|
||||||
state.put::<PermissionsContainer>(worker_permissions);
|
state.put::<PermissionsContainer>(worker_permissions);
|
||||||
|
|
||||||
Ok(token)
|
Ok(token)
|
||||||
|
@ -100,7 +85,6 @@ pub fn op_restore_test_permissions(
|
||||||
}
|
}
|
||||||
|
|
||||||
let permissions = permissions_holder.1;
|
let permissions = permissions_holder.1;
|
||||||
state.put(permissions.inner.clone());
|
|
||||||
state.put::<PermissionsContainer>(permissions);
|
state.put::<PermissionsContainer>(permissions);
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -16,13 +16,10 @@ use deno_core::op2;
|
||||||
use deno_core::v8;
|
use deno_core::v8;
|
||||||
use deno_core::ModuleSpecifier;
|
use deno_core::ModuleSpecifier;
|
||||||
use deno_core::OpState;
|
use deno_core::OpState;
|
||||||
use deno_runtime::deno_permissions::create_child_permissions;
|
|
||||||
use deno_runtime::deno_permissions::ChildPermissionsArg;
|
use deno_runtime::deno_permissions::ChildPermissionsArg;
|
||||||
use deno_runtime::deno_permissions::PermissionDescriptorParser;
|
|
||||||
use deno_runtime::deno_permissions::PermissionsContainer;
|
use deno_runtime::deno_permissions::PermissionsContainer;
|
||||||
use std::sync::atomic::AtomicUsize;
|
use std::sync::atomic::AtomicUsize;
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
use std::sync::Arc;
|
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
deno_core::extension!(deno_test,
|
deno_core::extension!(deno_test,
|
||||||
|
@ -56,19 +53,8 @@ pub fn op_pledge_test_permissions(
|
||||||
#[serde] args: ChildPermissionsArg,
|
#[serde] args: ChildPermissionsArg,
|
||||||
) -> Result<Uuid, AnyError> {
|
) -> Result<Uuid, AnyError> {
|
||||||
let token = Uuid::new_v4();
|
let token = Uuid::new_v4();
|
||||||
let permission_desc_parser = state
|
|
||||||
.borrow::<Arc<dyn PermissionDescriptorParser>>()
|
|
||||||
.clone();
|
|
||||||
let parent_permissions = state.borrow_mut::<PermissionsContainer>();
|
let parent_permissions = state.borrow_mut::<PermissionsContainer>();
|
||||||
let worker_permissions = {
|
let worker_permissions = parent_permissions.create_child_permissions(args)?;
|
||||||
let mut parent_permissions = parent_permissions.inner.lock();
|
|
||||||
let perms = create_child_permissions(
|
|
||||||
permission_desc_parser.as_ref(),
|
|
||||||
&mut parent_permissions,
|
|
||||||
args,
|
|
||||||
)?;
|
|
||||||
PermissionsContainer::new(permission_desc_parser, perms)
|
|
||||||
};
|
|
||||||
let parent_permissions = parent_permissions.clone();
|
let parent_permissions = parent_permissions.clone();
|
||||||
|
|
||||||
if state.try_take::<PermissionsHolder>().is_some() {
|
if state.try_take::<PermissionsHolder>().is_some() {
|
||||||
|
@ -77,7 +63,6 @@ pub fn op_pledge_test_permissions(
|
||||||
state.put::<PermissionsHolder>(PermissionsHolder(token, parent_permissions));
|
state.put::<PermissionsHolder>(PermissionsHolder(token, parent_permissions));
|
||||||
|
|
||||||
// NOTE: This call overrides current permission set for the worker
|
// NOTE: This call overrides current permission set for the worker
|
||||||
state.put(worker_permissions.inner.clone());
|
|
||||||
state.put::<PermissionsContainer>(worker_permissions);
|
state.put::<PermissionsContainer>(worker_permissions);
|
||||||
|
|
||||||
Ok(token)
|
Ok(token)
|
||||||
|
@ -94,7 +79,6 @@ pub fn op_restore_test_permissions(
|
||||||
}
|
}
|
||||||
|
|
||||||
let permissions = permissions_holder.1;
|
let permissions = permissions_holder.1;
|
||||||
state.put(permissions.inner.clone());
|
|
||||||
state.put::<PermissionsContainer>(permissions);
|
state.put::<PermissionsContainer>(permissions);
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -693,8 +693,6 @@ pub async fn run(
|
||||||
}
|
}
|
||||||
checker
|
checker
|
||||||
});
|
});
|
||||||
let permission_desc_parser =
|
|
||||||
Arc::new(RuntimePermissionDescriptorParser::new(fs.clone()));
|
|
||||||
let worker_factory = CliMainWorkerFactory::new(
|
let worker_factory = CliMainWorkerFactory::new(
|
||||||
Arc::new(BlobStore::default()),
|
Arc::new(BlobStore::default()),
|
||||||
// Code cache is not supported for standalone binary yet.
|
// Code cache is not supported for standalone binary yet.
|
||||||
|
@ -707,7 +705,6 @@ pub async fn run(
|
||||||
Box::new(module_loader_factory),
|
Box::new(module_loader_factory),
|
||||||
node_resolver,
|
node_resolver,
|
||||||
npm_resolver,
|
npm_resolver,
|
||||||
permission_desc_parser,
|
|
||||||
root_cert_store_provider,
|
root_cert_store_provider,
|
||||||
permissions,
|
permissions,
|
||||||
StorageKeyResolver::empty(),
|
StorageKeyResolver::empty(),
|
||||||
|
|
|
@ -31,7 +31,6 @@ use deno_runtime::fmt_errors::format_js_error;
|
||||||
use deno_runtime::inspector_server::InspectorServer;
|
use deno_runtime::inspector_server::InspectorServer;
|
||||||
use deno_runtime::ops::process::NpmProcessStateProviderRc;
|
use deno_runtime::ops::process::NpmProcessStateProviderRc;
|
||||||
use deno_runtime::ops::worker_host::CreateWebWorkerCb;
|
use deno_runtime::ops::worker_host::CreateWebWorkerCb;
|
||||||
use deno_runtime::permissions::RuntimePermissionDescriptorParser;
|
|
||||||
use deno_runtime::web_worker::WebWorker;
|
use deno_runtime::web_worker::WebWorker;
|
||||||
use deno_runtime::web_worker::WebWorkerOptions;
|
use deno_runtime::web_worker::WebWorkerOptions;
|
||||||
use deno_runtime::web_worker::WebWorkerServiceOptions;
|
use deno_runtime::web_worker::WebWorkerServiceOptions;
|
||||||
|
@ -136,7 +135,6 @@ struct SharedWorkerState {
|
||||||
module_loader_factory: Box<dyn ModuleLoaderFactory>,
|
module_loader_factory: Box<dyn ModuleLoaderFactory>,
|
||||||
node_resolver: Arc<NodeResolver>,
|
node_resolver: Arc<NodeResolver>,
|
||||||
npm_resolver: Arc<dyn CliNpmResolver>,
|
npm_resolver: Arc<dyn CliNpmResolver>,
|
||||||
permission_desc_parser: Arc<RuntimePermissionDescriptorParser>,
|
|
||||||
root_cert_store_provider: Arc<dyn RootCertStoreProvider>,
|
root_cert_store_provider: Arc<dyn RootCertStoreProvider>,
|
||||||
root_permissions: PermissionsContainer,
|
root_permissions: PermissionsContainer,
|
||||||
shared_array_buffer_store: SharedArrayBufferStore,
|
shared_array_buffer_store: SharedArrayBufferStore,
|
||||||
|
@ -433,7 +431,6 @@ impl CliMainWorkerFactory {
|
||||||
module_loader_factory: Box<dyn ModuleLoaderFactory>,
|
module_loader_factory: Box<dyn ModuleLoaderFactory>,
|
||||||
node_resolver: Arc<NodeResolver>,
|
node_resolver: Arc<NodeResolver>,
|
||||||
npm_resolver: Arc<dyn CliNpmResolver>,
|
npm_resolver: Arc<dyn CliNpmResolver>,
|
||||||
permission_parser: Arc<RuntimePermissionDescriptorParser>,
|
|
||||||
root_cert_store_provider: Arc<dyn RootCertStoreProvider>,
|
root_cert_store_provider: Arc<dyn RootCertStoreProvider>,
|
||||||
root_permissions: PermissionsContainer,
|
root_permissions: PermissionsContainer,
|
||||||
storage_key_resolver: StorageKeyResolver,
|
storage_key_resolver: StorageKeyResolver,
|
||||||
|
@ -454,7 +451,6 @@ impl CliMainWorkerFactory {
|
||||||
module_loader_factory,
|
module_loader_factory,
|
||||||
node_resolver,
|
node_resolver,
|
||||||
npm_resolver,
|
npm_resolver,
|
||||||
permission_desc_parser: permission_parser,
|
|
||||||
root_cert_store_provider,
|
root_cert_store_provider,
|
||||||
root_permissions,
|
root_permissions,
|
||||||
shared_array_buffer_store: Default::default(),
|
shared_array_buffer_store: Default::default(),
|
||||||
|
@ -586,7 +582,6 @@ impl CliMainWorkerFactory {
|
||||||
),
|
),
|
||||||
feature_checker,
|
feature_checker,
|
||||||
permissions,
|
permissions,
|
||||||
permission_desc_parser: shared.permission_desc_parser.clone(),
|
|
||||||
v8_code_cache: shared.code_cache.clone(),
|
v8_code_cache: shared.code_cache.clone(),
|
||||||
};
|
};
|
||||||
let options = WorkerOptions {
|
let options = WorkerOptions {
|
||||||
|
@ -784,7 +779,6 @@ fn create_web_worker_callback(
|
||||||
),
|
),
|
||||||
maybe_inspector_server,
|
maybe_inspector_server,
|
||||||
feature_checker,
|
feature_checker,
|
||||||
permission_desc_parser: shared.permission_desc_parser.clone(),
|
|
||||||
npm_process_state_provider: Some(shared.npm_process_state_provider()),
|
npm_process_state_provider: Some(shared.npm_process_state_provider()),
|
||||||
permissions: args.permissions,
|
permissions: args.permissions,
|
||||||
};
|
};
|
||||||
|
@ -849,6 +843,7 @@ mod tests {
|
||||||
use deno_core::FsModuleLoader;
|
use deno_core::FsModuleLoader;
|
||||||
use deno_fs::RealFs;
|
use deno_fs::RealFs;
|
||||||
use deno_runtime::deno_permissions::Permissions;
|
use deno_runtime::deno_permissions::Permissions;
|
||||||
|
use deno_runtime::permissions::RuntimePermissionDescriptorParser;
|
||||||
|
|
||||||
fn create_test_worker() -> MainWorker {
|
fn create_test_worker() -> MainWorker {
|
||||||
let main_module =
|
let main_module =
|
||||||
|
@ -866,7 +861,7 @@ mod tests {
|
||||||
WorkerServiceOptions {
|
WorkerServiceOptions {
|
||||||
module_loader: Rc::new(FsModuleLoader),
|
module_loader: Rc::new(FsModuleLoader),
|
||||||
permissions: PermissionsContainer::new(
|
permissions: PermissionsContainer::new(
|
||||||
permission_desc_parser.clone(),
|
permission_desc_parser,
|
||||||
Permissions::none_without_prompt(),
|
Permissions::none_without_prompt(),
|
||||||
),
|
),
|
||||||
blob_store: Default::default(),
|
blob_store: Default::default(),
|
||||||
|
@ -874,7 +869,6 @@ mod tests {
|
||||||
feature_checker: Default::default(),
|
feature_checker: Default::default(),
|
||||||
node_services: Default::default(),
|
node_services: Default::default(),
|
||||||
npm_process_state_provider: Default::default(),
|
npm_process_state_provider: Default::default(),
|
||||||
permission_desc_parser,
|
|
||||||
root_cert_store_provider: Default::default(),
|
root_cert_store_provider: Default::default(),
|
||||||
shared_array_buffer_store: Default::default(),
|
shared_array_buffer_store: Default::default(),
|
||||||
compiled_wasm_module_store: Default::default(),
|
compiled_wasm_module_store: Default::default(),
|
||||||
|
|
|
@ -43,15 +43,12 @@ async fn main() -> Result<(), AnyError> {
|
||||||
main_module.clone(),
|
main_module.clone(),
|
||||||
WorkerServiceOptions {
|
WorkerServiceOptions {
|
||||||
module_loader: Rc::new(FsModuleLoader),
|
module_loader: Rc::new(FsModuleLoader),
|
||||||
permissions: PermissionsContainer::allow_all(
|
permissions: PermissionsContainer::allow_all(permission_desc_parser),
|
||||||
permission_desc_parser.clone(),
|
|
||||||
),
|
|
||||||
blob_store: Default::default(),
|
blob_store: Default::default(),
|
||||||
broadcast_channel: Default::default(),
|
broadcast_channel: Default::default(),
|
||||||
feature_checker: Default::default(),
|
feature_checker: Default::default(),
|
||||||
node_services: Default::default(),
|
node_services: Default::default(),
|
||||||
npm_process_state_provider: Default::default(),
|
npm_process_state_provider: Default::default(),
|
||||||
permission_desc_parser,
|
|
||||||
root_cert_store_provider: Default::default(),
|
root_cert_store_provider: Default::default(),
|
||||||
shared_array_buffer_store: Default::default(),
|
shared_array_buffer_store: Default::default(),
|
||||||
compiled_wasm_module_store: Default::default(),
|
compiled_wasm_module_store: Default::default(),
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
use ::deno_permissions::parse_sys_kind;
|
|
||||||
use ::deno_permissions::PermissionDescriptorParser;
|
|
||||||
use ::deno_permissions::PermissionState;
|
use ::deno_permissions::PermissionState;
|
||||||
use ::deno_permissions::PermissionsContainer;
|
use ::deno_permissions::PermissionsContainer;
|
||||||
use deno_core::error::custom_error;
|
use deno_core::error::custom_error;
|
||||||
|
@ -10,7 +8,6 @@ use deno_core::op2;
|
||||||
use deno_core::OpState;
|
use deno_core::OpState;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
deno_core::extension!(
|
deno_core::extension!(
|
||||||
deno_permissions,
|
deno_permissions,
|
||||||
|
@ -19,12 +16,6 @@ deno_core::extension!(
|
||||||
op_revoke_permission,
|
op_revoke_permission,
|
||||||
op_request_permission,
|
op_request_permission,
|
||||||
],
|
],
|
||||||
options = {
|
|
||||||
permission_desc_parser: Arc<dyn PermissionDescriptorParser>,
|
|
||||||
},
|
|
||||||
state = |state, options| {
|
|
||||||
state.put(options.permission_desc_parser);
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
|
@ -62,62 +53,15 @@ pub fn op_query_permission(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[serde] args: PermissionArgs,
|
#[serde] args: PermissionArgs,
|
||||||
) -> Result<PermissionStatus, AnyError> {
|
) -> Result<PermissionStatus, AnyError> {
|
||||||
let permissions_container = state.borrow::<PermissionsContainer>();
|
let permissions = state.borrow::<PermissionsContainer>();
|
||||||
// todo(dsherret): don't have this function use the properties of
|
|
||||||
// permission container
|
|
||||||
let desc_parser = &permissions_container.descriptor_parser;
|
|
||||||
let permissions = permissions_container.inner.lock();
|
|
||||||
let path = args.path.as_deref();
|
|
||||||
let perm = match args.name.as_ref() {
|
let perm = match args.name.as_ref() {
|
||||||
"read" => permissions.read.query(
|
"read" => permissions.query_read(args.path.as_deref())?,
|
||||||
path
|
"write" => permissions.query_write(args.path.as_deref())?,
|
||||||
.map(|path| {
|
"net" => permissions.query_net(args.host.as_deref())?,
|
||||||
Result::<_, AnyError>::Ok(
|
"env" => permissions.query_env(args.variable.as_deref()),
|
||||||
desc_parser.parse_path_query(path)?.into_read(),
|
"sys" => permissions.query_sys(args.kind.as_deref())?,
|
||||||
)
|
"run" => permissions.query_run(args.command.as_deref())?,
|
||||||
})
|
"ffi" => permissions.query_ffi(args.path.as_deref())?,
|
||||||
.transpose()?
|
|
||||||
.as_ref(),
|
|
||||||
),
|
|
||||||
"write" => permissions.write.query(
|
|
||||||
path
|
|
||||||
.map(|path| {
|
|
||||||
Result::<_, AnyError>::Ok(
|
|
||||||
desc_parser.parse_path_query(path)?.into_write(),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.transpose()?
|
|
||||||
.as_ref(),
|
|
||||||
),
|
|
||||||
"net" => permissions.net.query(
|
|
||||||
match args.host.as_deref() {
|
|
||||||
None => None,
|
|
||||||
Some(h) => Some(desc_parser.parse_net_descriptor(h)?),
|
|
||||||
}
|
|
||||||
.as_ref(),
|
|
||||||
),
|
|
||||||
"env" => permissions.env.query(args.variable.as_deref()),
|
|
||||||
"sys" => permissions
|
|
||||||
.sys
|
|
||||||
.query(args.kind.as_deref().map(parse_sys_kind).transpose()?),
|
|
||||||
"run" => permissions.run.query(
|
|
||||||
args
|
|
||||||
.command
|
|
||||||
.as_deref()
|
|
||||||
.map(|request| desc_parser.parse_run_query(request))
|
|
||||||
.transpose()?
|
|
||||||
.as_ref(),
|
|
||||||
),
|
|
||||||
"ffi" => permissions.ffi.query(
|
|
||||||
path
|
|
||||||
.map(|path| {
|
|
||||||
Result::<_, AnyError>::Ok(
|
|
||||||
desc_parser.parse_path_query(path)?.into_ffi(),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.transpose()?
|
|
||||||
.as_ref(),
|
|
||||||
),
|
|
||||||
n => {
|
n => {
|
||||||
return Err(custom_error(
|
return Err(custom_error(
|
||||||
"ReferenceError",
|
"ReferenceError",
|
||||||
|
@ -134,62 +78,15 @@ pub fn op_revoke_permission(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[serde] args: PermissionArgs,
|
#[serde] args: PermissionArgs,
|
||||||
) -> Result<PermissionStatus, AnyError> {
|
) -> Result<PermissionStatus, AnyError> {
|
||||||
// todo(dsherret): don't have this function use the properties of
|
let permissions = state.borrow::<PermissionsContainer>();
|
||||||
// permission container
|
|
||||||
let permissions_container = state.borrow_mut::<PermissionsContainer>();
|
|
||||||
let desc_parser = &permissions_container.descriptor_parser;
|
|
||||||
let mut permissions = permissions_container.inner.lock();
|
|
||||||
let path = args.path.as_deref();
|
|
||||||
let perm = match args.name.as_ref() {
|
let perm = match args.name.as_ref() {
|
||||||
"read" => permissions.read.revoke(
|
"read" => permissions.revoke_read(args.path.as_deref())?,
|
||||||
path
|
"write" => permissions.revoke_write(args.path.as_deref())?,
|
||||||
.map(|path| {
|
"net" => permissions.revoke_net(args.host.as_deref())?,
|
||||||
Result::<_, AnyError>::Ok(
|
"env" => permissions.revoke_env(args.variable.as_deref()),
|
||||||
desc_parser.parse_path_query(path)?.into_read(),
|
"sys" => permissions.revoke_sys(args.kind.as_deref())?,
|
||||||
)
|
"run" => permissions.revoke_run(args.command.as_deref())?,
|
||||||
})
|
"ffi" => permissions.revoke_ffi(args.path.as_deref())?,
|
||||||
.transpose()?
|
|
||||||
.as_ref(),
|
|
||||||
),
|
|
||||||
"write" => permissions.write.revoke(
|
|
||||||
path
|
|
||||||
.map(|path| {
|
|
||||||
Result::<_, AnyError>::Ok(
|
|
||||||
desc_parser.parse_path_query(path)?.into_write(),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.transpose()?
|
|
||||||
.as_ref(),
|
|
||||||
),
|
|
||||||
"net" => permissions.net.revoke(
|
|
||||||
match args.host.as_deref() {
|
|
||||||
None => None,
|
|
||||||
Some(h) => Some(desc_parser.parse_net_descriptor(h)?),
|
|
||||||
}
|
|
||||||
.as_ref(),
|
|
||||||
),
|
|
||||||
"env" => permissions.env.revoke(args.variable.as_deref()),
|
|
||||||
"sys" => permissions
|
|
||||||
.sys
|
|
||||||
.revoke(args.kind.as_deref().map(parse_sys_kind).transpose()?),
|
|
||||||
"run" => permissions.run.revoke(
|
|
||||||
args
|
|
||||||
.command
|
|
||||||
.as_deref()
|
|
||||||
.map(|request| desc_parser.parse_run_query(request))
|
|
||||||
.transpose()?
|
|
||||||
.as_ref(),
|
|
||||||
),
|
|
||||||
"ffi" => permissions.ffi.revoke(
|
|
||||||
path
|
|
||||||
.map(|path| {
|
|
||||||
Result::<_, AnyError>::Ok(
|
|
||||||
desc_parser.parse_path_query(path)?.into_ffi(),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.transpose()?
|
|
||||||
.as_ref(),
|
|
||||||
),
|
|
||||||
n => {
|
n => {
|
||||||
return Err(custom_error(
|
return Err(custom_error(
|
||||||
"ReferenceError",
|
"ReferenceError",
|
||||||
|
@ -206,62 +103,15 @@ pub fn op_request_permission(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[serde] args: PermissionArgs,
|
#[serde] args: PermissionArgs,
|
||||||
) -> Result<PermissionStatus, AnyError> {
|
) -> Result<PermissionStatus, AnyError> {
|
||||||
// todo(dsherret): don't have this function use the properties of
|
let permissions = state.borrow::<PermissionsContainer>();
|
||||||
// permission container
|
|
||||||
let permissions_container = state.borrow_mut::<PermissionsContainer>();
|
|
||||||
let desc_parser = &permissions_container.descriptor_parser;
|
|
||||||
let mut permissions = permissions_container.inner.lock();
|
|
||||||
let path = args.path.as_deref();
|
|
||||||
let perm = match args.name.as_ref() {
|
let perm = match args.name.as_ref() {
|
||||||
"read" => permissions.read.request(
|
"read" => permissions.request_read(args.path.as_deref())?,
|
||||||
path
|
"write" => permissions.request_write(args.path.as_deref())?,
|
||||||
.map(|path| {
|
"net" => permissions.request_net(args.host.as_deref())?,
|
||||||
Result::<_, AnyError>::Ok(
|
"env" => permissions.request_env(args.variable.as_deref()),
|
||||||
desc_parser.parse_path_query(path)?.into_read(),
|
"sys" => permissions.request_sys(args.kind.as_deref())?,
|
||||||
)
|
"run" => permissions.request_run(args.command.as_deref())?,
|
||||||
})
|
"ffi" => permissions.request_ffi(args.path.as_deref())?,
|
||||||
.transpose()?
|
|
||||||
.as_ref(),
|
|
||||||
),
|
|
||||||
"write" => permissions.write.request(
|
|
||||||
path
|
|
||||||
.map(|path| {
|
|
||||||
Result::<_, AnyError>::Ok(
|
|
||||||
desc_parser.parse_path_query(path)?.into_write(),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.transpose()?
|
|
||||||
.as_ref(),
|
|
||||||
),
|
|
||||||
"net" => permissions.net.request(
|
|
||||||
match args.host.as_deref() {
|
|
||||||
None => None,
|
|
||||||
Some(h) => Some(desc_parser.parse_net_descriptor(h)?),
|
|
||||||
}
|
|
||||||
.as_ref(),
|
|
||||||
),
|
|
||||||
"env" => permissions.env.request(args.variable.as_deref()),
|
|
||||||
"sys" => permissions
|
|
||||||
.sys
|
|
||||||
.request(args.kind.as_deref().map(parse_sys_kind).transpose()?),
|
|
||||||
"run" => permissions.run.request(
|
|
||||||
args
|
|
||||||
.command
|
|
||||||
.as_deref()
|
|
||||||
.map(|request| desc_parser.parse_run_query(request))
|
|
||||||
.transpose()?
|
|
||||||
.as_ref(),
|
|
||||||
),
|
|
||||||
"ffi" => permissions.ffi.request(
|
|
||||||
path
|
|
||||||
.map(|path| {
|
|
||||||
Result::<_, AnyError>::Ok(
|
|
||||||
desc_parser.parse_path_query(path)?.into_ffi(),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.transpose()?
|
|
||||||
.as_ref(),
|
|
||||||
),
|
|
||||||
n => {
|
n => {
|
||||||
return Err(custom_error(
|
return Err(custom_error(
|
||||||
"ReferenceError",
|
"ReferenceError",
|
||||||
|
|
|
@ -17,9 +17,7 @@ use deno_core::CancelFuture;
|
||||||
use deno_core::CancelHandle;
|
use deno_core::CancelHandle;
|
||||||
use deno_core::ModuleSpecifier;
|
use deno_core::ModuleSpecifier;
|
||||||
use deno_core::OpState;
|
use deno_core::OpState;
|
||||||
use deno_permissions::create_child_permissions;
|
|
||||||
use deno_permissions::ChildPermissionsArg;
|
use deno_permissions::ChildPermissionsArg;
|
||||||
use deno_permissions::PermissionDescriptorParser;
|
|
||||||
use deno_permissions::PermissionsContainer;
|
use deno_permissions::PermissionsContainer;
|
||||||
use deno_web::deserialize_js_transferables;
|
use deno_web::deserialize_js_transferables;
|
||||||
use deno_web::JsMessageData;
|
use deno_web::JsMessageData;
|
||||||
|
@ -154,19 +152,10 @@ fn op_create_worker(
|
||||||
"Worker.deno.permissions",
|
"Worker.deno.permissions",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
let permission_desc_parser = state
|
|
||||||
.borrow::<Arc<dyn PermissionDescriptorParser>>()
|
|
||||||
.clone();
|
|
||||||
let parent_permissions = state.borrow_mut::<PermissionsContainer>();
|
let parent_permissions = state.borrow_mut::<PermissionsContainer>();
|
||||||
let worker_permissions = if let Some(child_permissions_arg) = args.permissions
|
let worker_permissions = if let Some(child_permissions_arg) = args.permissions
|
||||||
{
|
{
|
||||||
let mut parent_permissions = parent_permissions.inner.lock();
|
parent_permissions.create_child_permissions(child_permissions_arg)?
|
||||||
let perms = create_child_permissions(
|
|
||||||
permission_desc_parser.as_ref(),
|
|
||||||
&mut parent_permissions,
|
|
||||||
child_permissions_arg,
|
|
||||||
)?;
|
|
||||||
PermissionsContainer::new(permission_desc_parser, perms)
|
|
||||||
} else {
|
} else {
|
||||||
parent_permissions.clone()
|
parent_permissions.clone()
|
||||||
};
|
};
|
||||||
|
|
|
@ -101,7 +101,7 @@ impl deno_permissions::PermissionDescriptorParser
|
||||||
if text.is_empty() {
|
if text.is_empty() {
|
||||||
Err(AnyError::msg("Empty sys not allowed"))
|
Err(AnyError::msg("Empty sys not allowed"))
|
||||||
} else {
|
} else {
|
||||||
Ok(SysDescriptor(text.to_string()))
|
Ok(SysDescriptor::parse(text.to_string())?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1356,7 +1356,23 @@ fn denies_run_name(name: &str, cmd_path: &Path) -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
|
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
|
||||||
pub struct SysDescriptor(pub String);
|
pub struct SysDescriptor(String);
|
||||||
|
|
||||||
|
impl SysDescriptor {
|
||||||
|
pub fn parse(kind: String) -> Result<Self, AnyError> {
|
||||||
|
match kind.as_str() {
|
||||||
|
"hostname" | "osRelease" | "osUptime" | "loadavg"
|
||||||
|
| "networkInterfaces" | "systemMemoryInfo" | "uid" | "gid" | "cpus"
|
||||||
|
| "homedir" | "getegid" | "username" | "statfs" | "getPriority"
|
||||||
|
| "setPriority" => Ok(Self(kind)),
|
||||||
|
_ => Err(type_error(format!("unknown system info kind \"{kind}\""))),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_string(self) -> String {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl QueryDescriptor for SysDescriptor {
|
impl QueryDescriptor for SysDescriptor {
|
||||||
type AllowDesc = SysDescriptor;
|
type AllowDesc = SysDescriptor;
|
||||||
|
@ -1412,15 +1428,6 @@ impl QueryDescriptor for SysDescriptor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_sys_kind(kind: &str) -> Result<&str, AnyError> {
|
|
||||||
match kind {
|
|
||||||
"hostname" | "osRelease" | "osUptime" | "loadavg" | "networkInterfaces"
|
|
||||||
| "systemMemoryInfo" | "uid" | "gid" | "cpus" | "homedir" | "getegid"
|
|
||||||
| "username" | "statfs" | "getPriority" | "setPriority" => Ok(kind),
|
|
||||||
_ => Err(type_error(format!("unknown system info kind \"{kind}\""))),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
|
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
|
||||||
pub struct FfiQueryDescriptor(pub PathQueryDescriptor);
|
pub struct FfiQueryDescriptor(pub PathQueryDescriptor);
|
||||||
|
|
||||||
|
@ -1664,28 +1671,25 @@ impl UnaryPermission<EnvDescriptor> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UnaryPermission<SysDescriptor> {
|
impl UnaryPermission<SysDescriptor> {
|
||||||
pub fn query(&self, kind: Option<&str>) -> PermissionState {
|
pub fn query(&self, kind: Option<&SysDescriptor>) -> PermissionState {
|
||||||
self.query_desc(
|
self.query_desc(kind, AllowPartial::TreatAsPartialGranted)
|
||||||
kind.map(|k| SysDescriptor(k.to_string())).as_ref(),
|
|
||||||
AllowPartial::TreatAsPartialGranted,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn request(&mut self, kind: Option<&str>) -> PermissionState {
|
pub fn request(&mut self, kind: Option<&SysDescriptor>) -> PermissionState {
|
||||||
self.request_desc(kind.map(|k| SysDescriptor(k.to_string())).as_ref())
|
self.request_desc(kind)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn revoke(&mut self, kind: Option<&str>) -> PermissionState {
|
pub fn revoke(&mut self, kind: Option<&SysDescriptor>) -> PermissionState {
|
||||||
self.revoke_desc(kind.map(|k| SysDescriptor(k.to_string())).as_ref())
|
self.revoke_desc(kind)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check(
|
pub fn check(
|
||||||
&mut self,
|
&mut self,
|
||||||
kind: &str,
|
kind: &SysDescriptor,
|
||||||
api_name: Option<&str>,
|
api_name: Option<&str>,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), AnyError> {
|
||||||
skip_check_if_is_permission_fully_granted!(self);
|
skip_check_if_is_permission_fully_granted!(self);
|
||||||
self.check_desc(Some(&SysDescriptor(kind.to_string())), false, api_name)
|
self.check_desc(Some(kind), false, api_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_all(&mut self) -> Result<(), AnyError> {
|
pub fn check_all(&mut self) -> Result<(), AnyError> {
|
||||||
|
@ -2047,12 +2051,8 @@ pub enum CheckSpecifierKind {
|
||||||
/// to send permissions to a new thread.
|
/// to send permissions to a new thread.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct PermissionsContainer {
|
pub struct PermissionsContainer {
|
||||||
// todo(dsherret): make both of these private as the functionality
|
descriptor_parser: Arc<dyn PermissionDescriptorParser>,
|
||||||
// can just be methods on PermissionsContainer. Additionally, a separate
|
inner: Arc<Mutex<Permissions>>,
|
||||||
// struct should be created in here that handles creating child permissions
|
|
||||||
// so that the code is not so verbose elsewhere.
|
|
||||||
pub descriptor_parser: Arc<dyn PermissionDescriptorParser>,
|
|
||||||
pub inner: Arc<Mutex<Permissions>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PermissionsContainer {
|
impl PermissionsContainer {
|
||||||
|
@ -2072,6 +2072,96 @@ impl PermissionsContainer {
|
||||||
Self::new(descriptor_parser, Permissions::allow_all())
|
Self::new(descriptor_parser, Permissions::allow_all())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn create_child_permissions(
|
||||||
|
&self,
|
||||||
|
child_permissions_arg: ChildPermissionsArg,
|
||||||
|
) -> Result<PermissionsContainer, AnyError> {
|
||||||
|
fn is_granted_unary(arg: &ChildUnaryPermissionArg) -> bool {
|
||||||
|
match arg {
|
||||||
|
ChildUnaryPermissionArg::Inherit | ChildUnaryPermissionArg::Granted => {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
ChildUnaryPermissionArg::NotGranted
|
||||||
|
| ChildUnaryPermissionArg::GrantedList(_) => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut worker_perms = Permissions::none_without_prompt();
|
||||||
|
|
||||||
|
let mut inner = self.inner.lock();
|
||||||
|
worker_perms.all = inner
|
||||||
|
.all
|
||||||
|
.create_child_permissions(ChildUnitPermissionArg::Inherit)?;
|
||||||
|
|
||||||
|
// downgrade the `worker_perms.all` based on the other values
|
||||||
|
if worker_perms.all.query() == PermissionState::Granted {
|
||||||
|
let unary_perms = [
|
||||||
|
&child_permissions_arg.read,
|
||||||
|
&child_permissions_arg.write,
|
||||||
|
&child_permissions_arg.net,
|
||||||
|
&child_permissions_arg.import,
|
||||||
|
&child_permissions_arg.env,
|
||||||
|
&child_permissions_arg.sys,
|
||||||
|
&child_permissions_arg.run,
|
||||||
|
&child_permissions_arg.ffi,
|
||||||
|
];
|
||||||
|
let allow_all = unary_perms.into_iter().all(is_granted_unary);
|
||||||
|
if !allow_all {
|
||||||
|
worker_perms.all.revoke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WARNING: When adding a permission here, ensure it is handled
|
||||||
|
// in the worker_perms.all block above
|
||||||
|
worker_perms.read = inner
|
||||||
|
.read
|
||||||
|
.create_child_permissions(child_permissions_arg.read, |text| {
|
||||||
|
Ok(Some(self.descriptor_parser.parse_read_descriptor(text)?))
|
||||||
|
})?;
|
||||||
|
worker_perms.write = inner
|
||||||
|
.write
|
||||||
|
.create_child_permissions(child_permissions_arg.write, |text| {
|
||||||
|
Ok(Some(self.descriptor_parser.parse_write_descriptor(text)?))
|
||||||
|
})?;
|
||||||
|
worker_perms.import = inner
|
||||||
|
.import
|
||||||
|
.create_child_permissions(child_permissions_arg.import, |text| {
|
||||||
|
Ok(Some(self.descriptor_parser.parse_import_descriptor(text)?))
|
||||||
|
})?;
|
||||||
|
worker_perms.net = inner
|
||||||
|
.net
|
||||||
|
.create_child_permissions(child_permissions_arg.net, |text| {
|
||||||
|
Ok(Some(self.descriptor_parser.parse_net_descriptor(text)?))
|
||||||
|
})?;
|
||||||
|
worker_perms.env = inner
|
||||||
|
.env
|
||||||
|
.create_child_permissions(child_permissions_arg.env, |text| {
|
||||||
|
Ok(Some(self.descriptor_parser.parse_env_descriptor(text)?))
|
||||||
|
})?;
|
||||||
|
worker_perms.sys = inner
|
||||||
|
.sys
|
||||||
|
.create_child_permissions(child_permissions_arg.sys, |text| {
|
||||||
|
Ok(Some(self.descriptor_parser.parse_sys_descriptor(text)?))
|
||||||
|
})?;
|
||||||
|
worker_perms.run = inner.run.create_child_permissions(
|
||||||
|
child_permissions_arg.run,
|
||||||
|
|text| match self.descriptor_parser.parse_allow_run_descriptor(text)? {
|
||||||
|
AllowRunDescriptorParseResult::Unresolved(_) => Ok(None),
|
||||||
|
AllowRunDescriptorParseResult::Descriptor(desc) => Ok(Some(desc)),
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
worker_perms.ffi = inner
|
||||||
|
.ffi
|
||||||
|
.create_child_permissions(child_permissions_arg.ffi, |text| {
|
||||||
|
Ok(Some(self.descriptor_parser.parse_ffi_descriptor(text)?))
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(PermissionsContainer::new(
|
||||||
|
self.descriptor_parser.clone(),
|
||||||
|
worker_perms,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn check_specifier(
|
pub fn check_specifier(
|
||||||
&self,
|
&self,
|
||||||
|
@ -2307,7 +2397,10 @@ impl PermissionsContainer {
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn check_sys(&self, kind: &str, api_name: &str) -> Result<(), AnyError> {
|
pub fn check_sys(&self, kind: &str, api_name: &str) -> Result<(), AnyError> {
|
||||||
self.inner.lock().sys.check(kind, Some(api_name))
|
self.inner.lock().sys.check(
|
||||||
|
&self.descriptor_parser.parse_sys_descriptor(kind)?,
|
||||||
|
Some(api_name),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
@ -2510,6 +2603,336 @@ impl PermissionsContainer {
|
||||||
Ok(desc.0.resolved)
|
Ok(desc.0.resolved)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// query
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn query_read(
|
||||||
|
&self,
|
||||||
|
path: Option<&str>,
|
||||||
|
) -> Result<PermissionState, AnyError> {
|
||||||
|
Ok(
|
||||||
|
self.inner.lock().read.query(
|
||||||
|
path
|
||||||
|
.map(|path| {
|
||||||
|
Result::<_, AnyError>::Ok(
|
||||||
|
self.descriptor_parser.parse_path_query(path)?.into_read(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.transpose()?
|
||||||
|
.as_ref(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn query_write(
|
||||||
|
&self,
|
||||||
|
path: Option<&str>,
|
||||||
|
) -> Result<PermissionState, AnyError> {
|
||||||
|
Ok(
|
||||||
|
self.inner.lock().write.query(
|
||||||
|
path
|
||||||
|
.map(|path| {
|
||||||
|
Result::<_, AnyError>::Ok(
|
||||||
|
self.descriptor_parser.parse_path_query(path)?.into_write(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.transpose()?
|
||||||
|
.as_ref(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn query_net(
|
||||||
|
&self,
|
||||||
|
host: Option<&str>,
|
||||||
|
) -> Result<PermissionState, AnyError> {
|
||||||
|
Ok(
|
||||||
|
self.inner.lock().net.query(
|
||||||
|
match host {
|
||||||
|
None => None,
|
||||||
|
Some(h) => Some(self.descriptor_parser.parse_net_descriptor(h)?),
|
||||||
|
}
|
||||||
|
.as_ref(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn query_env(&self, var: Option<&str>) -> PermissionState {
|
||||||
|
self.inner.lock().env.query(var)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn query_sys(
|
||||||
|
&self,
|
||||||
|
kind: Option<&str>,
|
||||||
|
) -> Result<PermissionState, AnyError> {
|
||||||
|
Ok(
|
||||||
|
self.inner.lock().sys.query(
|
||||||
|
kind
|
||||||
|
.map(|kind| self.descriptor_parser.parse_sys_descriptor(kind))
|
||||||
|
.transpose()?
|
||||||
|
.as_ref(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn query_run(
|
||||||
|
&self,
|
||||||
|
cmd: Option<&str>,
|
||||||
|
) -> Result<PermissionState, AnyError> {
|
||||||
|
Ok(
|
||||||
|
self.inner.lock().run.query(
|
||||||
|
cmd
|
||||||
|
.map(|request| self.descriptor_parser.parse_run_query(request))
|
||||||
|
.transpose()?
|
||||||
|
.as_ref(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn query_ffi(
|
||||||
|
&self,
|
||||||
|
path: Option<&str>,
|
||||||
|
) -> Result<PermissionState, AnyError> {
|
||||||
|
Ok(
|
||||||
|
self.inner.lock().ffi.query(
|
||||||
|
path
|
||||||
|
.map(|path| {
|
||||||
|
Result::<_, AnyError>::Ok(
|
||||||
|
self.descriptor_parser.parse_path_query(path)?.into_ffi(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.transpose()?
|
||||||
|
.as_ref(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// revoke
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn revoke_read(
|
||||||
|
&self,
|
||||||
|
path: Option<&str>,
|
||||||
|
) -> Result<PermissionState, AnyError> {
|
||||||
|
Ok(
|
||||||
|
self.inner.lock().read.revoke(
|
||||||
|
path
|
||||||
|
.map(|path| {
|
||||||
|
Result::<_, AnyError>::Ok(
|
||||||
|
self.descriptor_parser.parse_path_query(path)?.into_read(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.transpose()?
|
||||||
|
.as_ref(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn revoke_write(
|
||||||
|
&self,
|
||||||
|
path: Option<&str>,
|
||||||
|
) -> Result<PermissionState, AnyError> {
|
||||||
|
Ok(
|
||||||
|
self.inner.lock().write.revoke(
|
||||||
|
path
|
||||||
|
.map(|path| {
|
||||||
|
Result::<_, AnyError>::Ok(
|
||||||
|
self.descriptor_parser.parse_path_query(path)?.into_write(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.transpose()?
|
||||||
|
.as_ref(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn revoke_net(
|
||||||
|
&self,
|
||||||
|
host: Option<&str>,
|
||||||
|
) -> Result<PermissionState, AnyError> {
|
||||||
|
Ok(
|
||||||
|
self.inner.lock().net.revoke(
|
||||||
|
match host {
|
||||||
|
None => None,
|
||||||
|
Some(h) => Some(self.descriptor_parser.parse_net_descriptor(h)?),
|
||||||
|
}
|
||||||
|
.as_ref(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn revoke_env(&self, var: Option<&str>) -> PermissionState {
|
||||||
|
self.inner.lock().env.revoke(var)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn revoke_sys(
|
||||||
|
&self,
|
||||||
|
kind: Option<&str>,
|
||||||
|
) -> Result<PermissionState, AnyError> {
|
||||||
|
Ok(
|
||||||
|
self.inner.lock().sys.revoke(
|
||||||
|
kind
|
||||||
|
.map(|kind| self.descriptor_parser.parse_sys_descriptor(kind))
|
||||||
|
.transpose()?
|
||||||
|
.as_ref(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn revoke_run(
|
||||||
|
&self,
|
||||||
|
cmd: Option<&str>,
|
||||||
|
) -> Result<PermissionState, AnyError> {
|
||||||
|
Ok(
|
||||||
|
self.inner.lock().run.revoke(
|
||||||
|
cmd
|
||||||
|
.map(|request| self.descriptor_parser.parse_run_query(request))
|
||||||
|
.transpose()?
|
||||||
|
.as_ref(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn revoke_ffi(
|
||||||
|
&self,
|
||||||
|
path: Option<&str>,
|
||||||
|
) -> Result<PermissionState, AnyError> {
|
||||||
|
Ok(
|
||||||
|
self.inner.lock().ffi.revoke(
|
||||||
|
path
|
||||||
|
.map(|path| {
|
||||||
|
Result::<_, AnyError>::Ok(
|
||||||
|
self.descriptor_parser.parse_path_query(path)?.into_ffi(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.transpose()?
|
||||||
|
.as_ref(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// request
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn request_read(
|
||||||
|
&self,
|
||||||
|
path: Option<&str>,
|
||||||
|
) -> Result<PermissionState, AnyError> {
|
||||||
|
Ok(
|
||||||
|
self.inner.lock().read.request(
|
||||||
|
path
|
||||||
|
.map(|path| {
|
||||||
|
Result::<_, AnyError>::Ok(
|
||||||
|
self.descriptor_parser.parse_path_query(path)?.into_read(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.transpose()?
|
||||||
|
.as_ref(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn request_write(
|
||||||
|
&self,
|
||||||
|
path: Option<&str>,
|
||||||
|
) -> Result<PermissionState, AnyError> {
|
||||||
|
Ok(
|
||||||
|
self.inner.lock().write.request(
|
||||||
|
path
|
||||||
|
.map(|path| {
|
||||||
|
Result::<_, AnyError>::Ok(
|
||||||
|
self.descriptor_parser.parse_path_query(path)?.into_write(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.transpose()?
|
||||||
|
.as_ref(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn request_net(
|
||||||
|
&self,
|
||||||
|
host: Option<&str>,
|
||||||
|
) -> Result<PermissionState, AnyError> {
|
||||||
|
Ok(
|
||||||
|
self.inner.lock().net.request(
|
||||||
|
match host {
|
||||||
|
None => None,
|
||||||
|
Some(h) => Some(self.descriptor_parser.parse_net_descriptor(h)?),
|
||||||
|
}
|
||||||
|
.as_ref(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn request_env(&self, var: Option<&str>) -> PermissionState {
|
||||||
|
self.inner.lock().env.request(var)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn request_sys(
|
||||||
|
&self,
|
||||||
|
kind: Option<&str>,
|
||||||
|
) -> Result<PermissionState, AnyError> {
|
||||||
|
Ok(
|
||||||
|
self.inner.lock().sys.request(
|
||||||
|
kind
|
||||||
|
.map(|kind| self.descriptor_parser.parse_sys_descriptor(kind))
|
||||||
|
.transpose()?
|
||||||
|
.as_ref(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn request_run(
|
||||||
|
&self,
|
||||||
|
cmd: Option<&str>,
|
||||||
|
) -> Result<PermissionState, AnyError> {
|
||||||
|
Ok(
|
||||||
|
self.inner.lock().run.request(
|
||||||
|
cmd
|
||||||
|
.map(|request| self.descriptor_parser.parse_run_query(request))
|
||||||
|
.transpose()?
|
||||||
|
.as_ref(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn request_ffi(
|
||||||
|
&self,
|
||||||
|
path: Option<&str>,
|
||||||
|
) -> Result<PermissionState, AnyError> {
|
||||||
|
Ok(
|
||||||
|
self.inner.lock().ffi.request(
|
||||||
|
path
|
||||||
|
.map(|path| {
|
||||||
|
Result::<_, AnyError>::Ok(
|
||||||
|
self.descriptor_parser.parse_path_query(path)?.into_ffi(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.transpose()?
|
||||||
|
.as_ref(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const fn unit_permission_from_flag_bools(
|
const fn unit_permission_from_flag_bools(
|
||||||
|
@ -2862,93 +3285,6 @@ pub trait PermissionDescriptorParser: Debug + Send + Sync {
|
||||||
) -> Result<RunQueryDescriptor, AnyError>;
|
) -> Result<RunQueryDescriptor, AnyError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_child_permissions(
|
|
||||||
parser: &dyn PermissionDescriptorParser,
|
|
||||||
main_perms: &mut Permissions,
|
|
||||||
child_permissions_arg: ChildPermissionsArg,
|
|
||||||
) -> Result<Permissions, AnyError> {
|
|
||||||
fn is_granted_unary(arg: &ChildUnaryPermissionArg) -> bool {
|
|
||||||
match arg {
|
|
||||||
ChildUnaryPermissionArg::Inherit | ChildUnaryPermissionArg::Granted => {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
ChildUnaryPermissionArg::NotGranted
|
|
||||||
| ChildUnaryPermissionArg::GrantedList(_) => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut worker_perms = Permissions::none_without_prompt();
|
|
||||||
|
|
||||||
worker_perms.all = main_perms
|
|
||||||
.all
|
|
||||||
.create_child_permissions(ChildUnitPermissionArg::Inherit)?;
|
|
||||||
|
|
||||||
// downgrade the `worker_perms.all` based on the other values
|
|
||||||
if worker_perms.all.query() == PermissionState::Granted {
|
|
||||||
let unary_perms = [
|
|
||||||
&child_permissions_arg.read,
|
|
||||||
&child_permissions_arg.write,
|
|
||||||
&child_permissions_arg.net,
|
|
||||||
&child_permissions_arg.import,
|
|
||||||
&child_permissions_arg.env,
|
|
||||||
&child_permissions_arg.sys,
|
|
||||||
&child_permissions_arg.run,
|
|
||||||
&child_permissions_arg.ffi,
|
|
||||||
];
|
|
||||||
let allow_all = unary_perms.into_iter().all(is_granted_unary);
|
|
||||||
if !allow_all {
|
|
||||||
worker_perms.all.revoke();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WARNING: When adding a permission here, ensure it is handled
|
|
||||||
// in the worker_perms.all block above
|
|
||||||
worker_perms.read = main_perms
|
|
||||||
.read
|
|
||||||
.create_child_permissions(child_permissions_arg.read, |text| {
|
|
||||||
Ok(Some(parser.parse_read_descriptor(text)?))
|
|
||||||
})?;
|
|
||||||
worker_perms.write = main_perms
|
|
||||||
.write
|
|
||||||
.create_child_permissions(child_permissions_arg.write, |text| {
|
|
||||||
Ok(Some(parser.parse_write_descriptor(text)?))
|
|
||||||
})?;
|
|
||||||
worker_perms.import = main_perms
|
|
||||||
.import
|
|
||||||
.create_child_permissions(child_permissions_arg.import, |text| {
|
|
||||||
Ok(Some(parser.parse_import_descriptor(text)?))
|
|
||||||
})?;
|
|
||||||
worker_perms.net = main_perms
|
|
||||||
.net
|
|
||||||
.create_child_permissions(child_permissions_arg.net, |text| {
|
|
||||||
Ok(Some(parser.parse_net_descriptor(text)?))
|
|
||||||
})?;
|
|
||||||
worker_perms.env = main_perms
|
|
||||||
.env
|
|
||||||
.create_child_permissions(child_permissions_arg.env, |text| {
|
|
||||||
Ok(Some(parser.parse_env_descriptor(text)?))
|
|
||||||
})?;
|
|
||||||
worker_perms.sys = main_perms
|
|
||||||
.sys
|
|
||||||
.create_child_permissions(child_permissions_arg.sys, |text| {
|
|
||||||
Ok(Some(parser.parse_sys_descriptor(text)?))
|
|
||||||
})?;
|
|
||||||
worker_perms.run = main_perms.run.create_child_permissions(
|
|
||||||
child_permissions_arg.run,
|
|
||||||
|text| match parser.parse_allow_run_descriptor(text)? {
|
|
||||||
AllowRunDescriptorParseResult::Unresolved(_) => Ok(None),
|
|
||||||
AllowRunDescriptorParseResult::Descriptor(desc) => Ok(Some(desc)),
|
|
||||||
},
|
|
||||||
)?;
|
|
||||||
worker_perms.ffi = main_perms
|
|
||||||
.ffi
|
|
||||||
.create_child_permissions(child_permissions_arg.ffi, |text| {
|
|
||||||
Ok(Some(parser.parse_ffi_descriptor(text)?))
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(worker_perms)
|
|
||||||
}
|
|
||||||
|
|
||||||
static IS_STANDALONE: AtomicFlag = AtomicFlag::lowered();
|
static IS_STANDALONE: AtomicFlag = AtomicFlag::lowered();
|
||||||
|
|
||||||
pub fn mark_standalone() {
|
pub fn mark_standalone() {
|
||||||
|
@ -2972,7 +3308,7 @@ mod tests {
|
||||||
($($x:expr),*) => (vec![$($x.to_string()),*]);
|
($($x:expr),*) => (vec![$($x.to_string()),*]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
struct TestPermissionDescriptorParser;
|
struct TestPermissionDescriptorParser;
|
||||||
|
|
||||||
impl TestPermissionDescriptorParser {
|
impl TestPermissionDescriptorParser {
|
||||||
|
@ -3025,7 +3361,7 @@ mod tests {
|
||||||
&self,
|
&self,
|
||||||
text: &str,
|
text: &str,
|
||||||
) -> Result<SysDescriptor, AnyError> {
|
) -> Result<SysDescriptor, AnyError> {
|
||||||
Ok(SysDescriptor(text.to_string()))
|
SysDescriptor::parse(text.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_allow_run_descriptor(
|
fn parse_allow_run_descriptor(
|
||||||
|
@ -3534,15 +3870,16 @@ mod tests {
|
||||||
assert_eq!(perms4.env.query(None), PermissionState::GrantedPartial);
|
assert_eq!(perms4.env.query(None), PermissionState::GrantedPartial);
|
||||||
assert_eq!(perms4.env.query(Some("HOME")), PermissionState::Denied);
|
assert_eq!(perms4.env.query(Some("HOME")), PermissionState::Denied);
|
||||||
assert_eq!(perms4.env.query(Some("AWAY")), PermissionState::Granted);
|
assert_eq!(perms4.env.query(Some("AWAY")), PermissionState::Granted);
|
||||||
|
let sys_desc = |name: &str| SysDescriptor::parse(name.to_string()).unwrap();
|
||||||
assert_eq!(perms1.sys.query(None), PermissionState::Granted);
|
assert_eq!(perms1.sys.query(None), PermissionState::Granted);
|
||||||
assert_eq!(perms1.sys.query(Some("HOME")), PermissionState::Granted);
|
assert_eq!(perms1.sys.query(Some(&sys_desc("osRelease"))), PermissionState::Granted);
|
||||||
assert_eq!(perms2.sys.query(None), PermissionState::Prompt);
|
assert_eq!(perms2.sys.query(None), PermissionState::Prompt);
|
||||||
assert_eq!(perms2.sys.query(Some("hostname")), PermissionState::Granted);
|
assert_eq!(perms2.sys.query(Some(&sys_desc("hostname"))), PermissionState::Granted);
|
||||||
assert_eq!(perms3.sys.query(None), PermissionState::Prompt);
|
assert_eq!(perms3.sys.query(None), PermissionState::Prompt);
|
||||||
assert_eq!(perms3.sys.query(Some("hostname")), PermissionState::Denied);
|
assert_eq!(perms3.sys.query(Some(&sys_desc("hostname"))), PermissionState::Denied);
|
||||||
assert_eq!(perms4.sys.query(None), PermissionState::GrantedPartial);
|
assert_eq!(perms4.sys.query(None), PermissionState::GrantedPartial);
|
||||||
assert_eq!(perms4.sys.query(Some("hostname")), PermissionState::Denied);
|
assert_eq!(perms4.sys.query(Some(&sys_desc("hostname"))), PermissionState::Denied);
|
||||||
assert_eq!(perms4.sys.query(Some("uid")), PermissionState::Granted);
|
assert_eq!(perms4.sys.query(Some(&sys_desc("uid"))), PermissionState::Granted);
|
||||||
assert_eq!(perms1.run.query(None), PermissionState::Granted);
|
assert_eq!(perms1.run.query(None), PermissionState::Granted);
|
||||||
let deno_run_query = RunQueryDescriptor::Path {
|
let deno_run_query = RunQueryDescriptor::Path {
|
||||||
requested: "deno".to_string(),
|
requested: "deno".to_string(),
|
||||||
|
@ -3604,10 +3941,11 @@ mod tests {
|
||||||
prompt_value.set(false);
|
prompt_value.set(false);
|
||||||
assert_eq!(perms.env.request(Some("HOME")), PermissionState::Granted);
|
assert_eq!(perms.env.request(Some("HOME")), PermissionState::Granted);
|
||||||
prompt_value.set(true);
|
prompt_value.set(true);
|
||||||
assert_eq!(perms.sys.request(Some("hostname")), PermissionState::Granted);
|
let sys_desc = |name: &str| SysDescriptor::parse(name.to_string()).unwrap();
|
||||||
|
assert_eq!(perms.sys.request(Some(&sys_desc("hostname"))), PermissionState::Granted);
|
||||||
assert_eq!(perms.sys.query(None), PermissionState::Prompt);
|
assert_eq!(perms.sys.query(None), PermissionState::Prompt);
|
||||||
prompt_value.set(false);
|
prompt_value.set(false);
|
||||||
assert_eq!(perms.sys.request(Some("hostname")), PermissionState::Granted);
|
assert_eq!(perms.sys.request(Some(&sys_desc("hostname"))), PermissionState::Granted);
|
||||||
prompt_value.set(true);
|
prompt_value.set(true);
|
||||||
let run_query = RunQueryDescriptor::Path {
|
let run_query = RunQueryDescriptor::Path {
|
||||||
requested: "deno".to_string(),
|
requested: "deno".to_string(),
|
||||||
|
@ -3924,12 +4262,13 @@ mod tests {
|
||||||
assert!(perms.env.check("PATH", None).is_ok());
|
assert!(perms.env.check("PATH", None).is_ok());
|
||||||
|
|
||||||
prompt_value.set(false);
|
prompt_value.set(false);
|
||||||
assert!(perms.sys.check("hostname", None).is_err());
|
let sys_desc = |name: &str| SysDescriptor::parse(name.to_string()).unwrap();
|
||||||
|
assert!(perms.sys.check(&sys_desc("hostname"), None).is_err());
|
||||||
prompt_value.set(true);
|
prompt_value.set(true);
|
||||||
assert!(perms.sys.check("hostname", None).is_err());
|
assert!(perms.sys.check(&sys_desc("hostname"), None).is_err());
|
||||||
assert!(perms.sys.check("osRelease", None).is_ok());
|
assert!(perms.sys.check(&sys_desc("osRelease"), None).is_ok());
|
||||||
prompt_value.set(false);
|
prompt_value.set(false);
|
||||||
assert!(perms.sys.check("osRelease", None).is_ok());
|
assert!(perms.sys.check(&sys_desc("osRelease"), None).is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -4149,7 +4488,7 @@ mod tests {
|
||||||
fn test_create_child_permissions() {
|
fn test_create_child_permissions() {
|
||||||
set_prompter(Box::new(TestPrompter));
|
set_prompter(Box::new(TestPrompter));
|
||||||
let parser = TestPermissionDescriptorParser;
|
let parser = TestPermissionDescriptorParser;
|
||||||
let mut main_perms = Permissions::from_options(
|
let main_perms = Permissions::from_options(
|
||||||
&parser,
|
&parser,
|
||||||
&PermissionsOptions {
|
&PermissionsOptions {
|
||||||
allow_env: Some(vec![]),
|
allow_env: Some(vec![]),
|
||||||
|
@ -4158,18 +4497,19 @@ mod tests {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
let main_perms = PermissionsContainer::new(Arc::new(parser), main_perms);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
create_child_permissions(
|
main_perms
|
||||||
&parser,
|
.create_child_permissions(ChildPermissionsArg {
|
||||||
&mut main_perms.clone(),
|
|
||||||
ChildPermissionsArg {
|
|
||||||
env: ChildUnaryPermissionArg::Inherit,
|
env: ChildUnaryPermissionArg::Inherit,
|
||||||
net: ChildUnaryPermissionArg::GrantedList(svec!["foo"]),
|
net: ChildUnaryPermissionArg::GrantedList(svec!["foo"]),
|
||||||
ffi: ChildUnaryPermissionArg::NotGranted,
|
ffi: ChildUnaryPermissionArg::NotGranted,
|
||||||
..ChildPermissionsArg::none()
|
..ChildPermissionsArg::none()
|
||||||
}
|
})
|
||||||
)
|
.unwrap()
|
||||||
.unwrap(),
|
.inner
|
||||||
|
.lock()
|
||||||
|
.clone(),
|
||||||
Permissions {
|
Permissions {
|
||||||
env: Permissions::new_unary(Some(HashSet::new()), None, false).unwrap(),
|
env: Permissions::new_unary(Some(HashSet::new()), None, false).unwrap(),
|
||||||
net: Permissions::new_unary(
|
net: Permissions::new_unary(
|
||||||
|
@ -4181,32 +4521,23 @@ mod tests {
|
||||||
..Permissions::none_without_prompt()
|
..Permissions::none_without_prompt()
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
assert!(create_child_permissions(
|
assert!(main_perms
|
||||||
&parser,
|
.create_child_permissions(ChildPermissionsArg {
|
||||||
&mut main_perms.clone(),
|
|
||||||
ChildPermissionsArg {
|
|
||||||
net: ChildUnaryPermissionArg::Granted,
|
net: ChildUnaryPermissionArg::Granted,
|
||||||
..ChildPermissionsArg::none()
|
..ChildPermissionsArg::none()
|
||||||
}
|
})
|
||||||
)
|
|
||||||
.is_err());
|
.is_err());
|
||||||
assert!(create_child_permissions(
|
assert!(main_perms
|
||||||
&parser,
|
.create_child_permissions(ChildPermissionsArg {
|
||||||
&mut main_perms.clone(),
|
|
||||||
ChildPermissionsArg {
|
|
||||||
net: ChildUnaryPermissionArg::GrantedList(svec!["foo", "bar", "baz"]),
|
net: ChildUnaryPermissionArg::GrantedList(svec!["foo", "bar", "baz"]),
|
||||||
..ChildPermissionsArg::none()
|
..ChildPermissionsArg::none()
|
||||||
}
|
})
|
||||||
)
|
|
||||||
.is_err());
|
.is_err());
|
||||||
assert!(create_child_permissions(
|
assert!(main_perms
|
||||||
&parser,
|
.create_child_permissions(ChildPermissionsArg {
|
||||||
&mut main_perms,
|
|
||||||
ChildPermissionsArg {
|
|
||||||
ffi: ChildUnaryPermissionArg::GrantedList(svec!["foo"]),
|
ffi: ChildUnaryPermissionArg::GrantedList(svec!["foo"]),
|
||||||
..ChildPermissionsArg::none()
|
..ChildPermissionsArg::none()
|
||||||
}
|
})
|
||||||
)
|
|
||||||
.is_err());
|
.is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4214,7 +4545,7 @@ mod tests {
|
||||||
fn test_create_child_permissions_with_prompt() {
|
fn test_create_child_permissions_with_prompt() {
|
||||||
set_prompter(Box::new(TestPrompter));
|
set_prompter(Box::new(TestPrompter));
|
||||||
let prompt_value = PERMISSION_PROMPT_STUB_VALUE_SETTER.lock();
|
let prompt_value = PERMISSION_PROMPT_STUB_VALUE_SETTER.lock();
|
||||||
let mut main_perms = Permissions::from_options(
|
let main_perms = Permissions::from_options(
|
||||||
&TestPermissionDescriptorParser,
|
&TestPermissionDescriptorParser,
|
||||||
&PermissionsOptions {
|
&PermissionsOptions {
|
||||||
prompt: true,
|
prompt: true,
|
||||||
|
@ -4222,20 +4553,24 @@ mod tests {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
let main_perms = PermissionsContainer::new(
|
||||||
|
Arc::new(TestPermissionDescriptorParser),
|
||||||
|
main_perms,
|
||||||
|
);
|
||||||
prompt_value.set(true);
|
prompt_value.set(true);
|
||||||
let worker_perms = create_child_permissions(
|
let worker_perms = main_perms
|
||||||
&TestPermissionDescriptorParser,
|
.create_child_permissions(ChildPermissionsArg {
|
||||||
&mut main_perms,
|
|
||||||
ChildPermissionsArg {
|
|
||||||
read: ChildUnaryPermissionArg::Granted,
|
read: ChildUnaryPermissionArg::Granted,
|
||||||
run: ChildUnaryPermissionArg::GrantedList(svec!["foo", "bar"]),
|
run: ChildUnaryPermissionArg::GrantedList(svec!["foo", "bar"]),
|
||||||
..ChildPermissionsArg::none()
|
..ChildPermissionsArg::none()
|
||||||
},
|
})
|
||||||
)
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(main_perms, worker_perms);
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
main_perms.run.granted_list,
|
main_perms.inner.lock().clone(),
|
||||||
|
worker_perms.inner.lock().clone()
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
main_perms.inner.lock().run.granted_list,
|
||||||
HashSet::from([
|
HashSet::from([
|
||||||
AllowRunDescriptor(PathBuf::from("/bar")),
|
AllowRunDescriptor(PathBuf::from("/bar")),
|
||||||
AllowRunDescriptor(PathBuf::from("/foo")),
|
AllowRunDescriptor(PathBuf::from("/foo")),
|
||||||
|
@ -4248,7 +4583,7 @@ mod tests {
|
||||||
set_prompter(Box::new(TestPrompter));
|
set_prompter(Box::new(TestPrompter));
|
||||||
let prompt_value = PERMISSION_PROMPT_STUB_VALUE_SETTER.lock();
|
let prompt_value = PERMISSION_PROMPT_STUB_VALUE_SETTER.lock();
|
||||||
let parser = TestPermissionDescriptorParser;
|
let parser = TestPermissionDescriptorParser;
|
||||||
let mut main_perms = Permissions::from_options(
|
let main_perms = Permissions::from_options(
|
||||||
&parser,
|
&parser,
|
||||||
&PermissionsOptions {
|
&PermissionsOptions {
|
||||||
prompt: true,
|
prompt: true,
|
||||||
|
@ -4256,20 +4591,21 @@ mod tests {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
let main_perms =
|
||||||
|
PermissionsContainer::new(Arc::new(parser.clone()), main_perms);
|
||||||
prompt_value.set(false);
|
prompt_value.set(false);
|
||||||
assert!(main_perms
|
assert!(main_perms
|
||||||
|
.inner
|
||||||
|
.lock()
|
||||||
.write
|
.write
|
||||||
.check(&parser.parse_path_query("foo").unwrap().into_write(), None)
|
.check(&parser.parse_path_query("foo").unwrap().into_write(), None)
|
||||||
.is_err());
|
.is_err());
|
||||||
let worker_perms = create_child_permissions(
|
let worker_perms = main_perms
|
||||||
&TestPermissionDescriptorParser,
|
.create_child_permissions(ChildPermissionsArg::none())
|
||||||
&mut main_perms.clone(),
|
|
||||||
ChildPermissionsArg::none(),
|
|
||||||
)
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
worker_perms.write.flag_denied_list,
|
worker_perms.inner.lock().write.flag_denied_list.clone(),
|
||||||
main_perms.write.flag_denied_list
|
main_perms.inner.lock().write.flag_denied_list
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
use crate::ops;
|
use crate::ops;
|
||||||
use crate::ops::bootstrap::SnapshotOptions;
|
use crate::ops::bootstrap::SnapshotOptions;
|
||||||
use crate::permissions::RuntimePermissionDescriptorParser;
|
|
||||||
use crate::shared::maybe_transpile_source;
|
use crate::shared::maybe_transpile_source;
|
||||||
use crate::shared::runtime;
|
use crate::shared::runtime;
|
||||||
use deno_cache::SqliteBackedCache;
|
use deno_cache::SqliteBackedCache;
|
||||||
|
@ -299,9 +298,7 @@ pub fn create_runtime_snapshot(
|
||||||
),
|
),
|
||||||
ops::fs_events::deno_fs_events::init_ops(),
|
ops::fs_events::deno_fs_events::init_ops(),
|
||||||
ops::os::deno_os::init_ops(Default::default()),
|
ops::os::deno_os::init_ops(Default::default()),
|
||||||
ops::permissions::deno_permissions::init_ops(Arc::new(
|
ops::permissions::deno_permissions::init_ops(),
|
||||||
RuntimePermissionDescriptorParser::new(fs),
|
|
||||||
)),
|
|
||||||
ops::process::deno_process::init_ops(None),
|
ops::process::deno_process::init_ops(None),
|
||||||
ops::signal::deno_signal::init_ops(),
|
ops::signal::deno_signal::init_ops(),
|
||||||
ops::tty::deno_tty::init_ops(),
|
ops::tty::deno_tty::init_ops(),
|
||||||
|
|
|
@ -1,16 +1,5 @@
|
||||||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||||
use crate::inspector_server::InspectorServer;
|
|
||||||
use crate::ops;
|
|
||||||
use crate::ops::process::NpmProcessStateProviderRc;
|
|
||||||
use crate::ops::worker_host::WorkersTable;
|
|
||||||
use crate::shared::maybe_transpile_source;
|
|
||||||
use crate::shared::runtime;
|
|
||||||
use crate::tokio_util::create_and_run_current_thread;
|
|
||||||
use crate::worker::create_op_metrics;
|
|
||||||
use crate::worker::import_meta_resolve_callback;
|
|
||||||
use crate::worker::validate_import_attributes_callback;
|
|
||||||
use crate::worker::FormatJsErrorFn;
|
|
||||||
use crate::BootstrapOptions;
|
|
||||||
use deno_broadcast_channel::InMemoryBroadcastChannel;
|
use deno_broadcast_channel::InMemoryBroadcastChannel;
|
||||||
use deno_cache::CreateCache;
|
use deno_cache::CreateCache;
|
||||||
use deno_cache::SqliteBackedCache;
|
use deno_cache::SqliteBackedCache;
|
||||||
|
@ -45,7 +34,6 @@ use deno_http::DefaultHttpPropertyExtractor;
|
||||||
use deno_io::Stdio;
|
use deno_io::Stdio;
|
||||||
use deno_kv::dynamic::MultiBackendDbHandler;
|
use deno_kv::dynamic::MultiBackendDbHandler;
|
||||||
use deno_node::NodeExtInitServices;
|
use deno_node::NodeExtInitServices;
|
||||||
use deno_permissions::PermissionDescriptorParser;
|
|
||||||
use deno_permissions::PermissionsContainer;
|
use deno_permissions::PermissionsContainer;
|
||||||
use deno_terminal::colors;
|
use deno_terminal::colors;
|
||||||
use deno_tls::RootCertStoreProvider;
|
use deno_tls::RootCertStoreProvider;
|
||||||
|
@ -67,6 +55,19 @@ use std::sync::Arc;
|
||||||
use std::task::Context;
|
use std::task::Context;
|
||||||
use std::task::Poll;
|
use std::task::Poll;
|
||||||
|
|
||||||
|
use crate::inspector_server::InspectorServer;
|
||||||
|
use crate::ops;
|
||||||
|
use crate::ops::process::NpmProcessStateProviderRc;
|
||||||
|
use crate::ops::worker_host::WorkersTable;
|
||||||
|
use crate::shared::maybe_transpile_source;
|
||||||
|
use crate::shared::runtime;
|
||||||
|
use crate::tokio_util::create_and_run_current_thread;
|
||||||
|
use crate::worker::create_op_metrics;
|
||||||
|
use crate::worker::import_meta_resolve_callback;
|
||||||
|
use crate::worker::validate_import_attributes_callback;
|
||||||
|
use crate::worker::FormatJsErrorFn;
|
||||||
|
use crate::BootstrapOptions;
|
||||||
|
|
||||||
pub struct WorkerMetadata {
|
pub struct WorkerMetadata {
|
||||||
pub buffer: DetachedBuffer,
|
pub buffer: DetachedBuffer,
|
||||||
pub transferables: Vec<Transferable>,
|
pub transferables: Vec<Transferable>,
|
||||||
|
@ -348,7 +349,6 @@ pub struct WebWorkerServiceOptions {
|
||||||
pub node_services: Option<NodeExtInitServices>,
|
pub node_services: Option<NodeExtInitServices>,
|
||||||
pub npm_process_state_provider: Option<NpmProcessStateProviderRc>,
|
pub npm_process_state_provider: Option<NpmProcessStateProviderRc>,
|
||||||
pub permissions: PermissionsContainer,
|
pub permissions: PermissionsContainer,
|
||||||
pub permission_desc_parser: Arc<dyn PermissionDescriptorParser>,
|
|
||||||
pub root_cert_store_provider: Option<Arc<dyn RootCertStoreProvider>>,
|
pub root_cert_store_provider: Option<Arc<dyn RootCertStoreProvider>>,
|
||||||
pub shared_array_buffer_store: Option<SharedArrayBufferStore>,
|
pub shared_array_buffer_store: Option<SharedArrayBufferStore>,
|
||||||
}
|
}
|
||||||
|
@ -505,9 +505,7 @@ impl WebWorker {
|
||||||
),
|
),
|
||||||
ops::fs_events::deno_fs_events::init_ops_and_esm(),
|
ops::fs_events::deno_fs_events::init_ops_and_esm(),
|
||||||
ops::os::deno_os_worker::init_ops_and_esm(),
|
ops::os::deno_os_worker::init_ops_and_esm(),
|
||||||
ops::permissions::deno_permissions::init_ops_and_esm(
|
ops::permissions::deno_permissions::init_ops_and_esm(),
|
||||||
services.permission_desc_parser,
|
|
||||||
),
|
|
||||||
ops::process::deno_process::init_ops_and_esm(
|
ops::process::deno_process::init_ops_and_esm(
|
||||||
services.npm_process_state_provider,
|
services.npm_process_state_provider,
|
||||||
),
|
),
|
||||||
|
|
|
@ -139,8 +139,6 @@ pub struct WorkerServiceOptions {
|
||||||
pub module_loader: Rc<dyn ModuleLoader>,
|
pub module_loader: Rc<dyn ModuleLoader>,
|
||||||
pub node_services: Option<NodeExtInitServices>,
|
pub node_services: Option<NodeExtInitServices>,
|
||||||
pub npm_process_state_provider: Option<NpmProcessStateProviderRc>,
|
pub npm_process_state_provider: Option<NpmProcessStateProviderRc>,
|
||||||
pub permission_desc_parser:
|
|
||||||
Arc<dyn deno_permissions::PermissionDescriptorParser>,
|
|
||||||
pub permissions: PermissionsContainer,
|
pub permissions: PermissionsContainer,
|
||||||
pub root_cert_store_provider: Option<Arc<dyn RootCertStoreProvider>>,
|
pub root_cert_store_provider: Option<Arc<dyn RootCertStoreProvider>>,
|
||||||
|
|
||||||
|
@ -422,9 +420,7 @@ impl MainWorker {
|
||||||
),
|
),
|
||||||
ops::fs_events::deno_fs_events::init_ops_and_esm(),
|
ops::fs_events::deno_fs_events::init_ops_and_esm(),
|
||||||
ops::os::deno_os::init_ops_and_esm(exit_code.clone()),
|
ops::os::deno_os::init_ops_and_esm(exit_code.clone()),
|
||||||
ops::permissions::deno_permissions::init_ops_and_esm(
|
ops::permissions::deno_permissions::init_ops_and_esm(),
|
||||||
services.permission_desc_parser,
|
|
||||||
),
|
|
||||||
ops::process::deno_process::init_ops_and_esm(
|
ops::process::deno_process::init_ops_and_esm(
|
||||||
services.npm_process_state_provider,
|
services.npm_process_state_provider,
|
||||||
),
|
),
|
||||||
|
|
Loading…
Reference in a new issue