summaryrefslogtreecommitdiff
path: root/runtime/ops/worker_host.rs
diff options
context:
space:
mode:
authorNayeem Rahman <nayeemrmn99@gmail.com>2021-10-13 18:04:44 +0100
committerGitHub <noreply@github.com>2021-10-13 13:04:44 -0400
commit7a22df9b7641274b2a83ce53845215d17cfda2c8 (patch)
tree6cf99f74682635a0128c5cf79f5f7d3ecfbc85f1 /runtime/ops/worker_host.rs
parent43a63530acb16e57cbb190eacedbd097c536a775 (diff)
fix(runtime/ops/worker_host): move permission arg parsing to Rust (#12297)
Diffstat (limited to 'runtime/ops/worker_host.rs')
-rw-r--r--runtime/ops/worker_host.rs391
1 files changed, 11 insertions, 380 deletions
diff --git a/runtime/ops/worker_host.rs b/runtime/ops/worker_host.rs
index c1ce782da..e9eb380e0 100644
--- a/runtime/ops/worker_host.rs
+++ b/runtime/ops/worker_host.rs
@@ -1,18 +1,9 @@
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
use crate::ops::TestingFeaturesEnabled;
-use crate::permissions::resolve_read_allowlist;
-use crate::permissions::resolve_write_allowlist;
-use crate::permissions::EnvDescriptor;
-use crate::permissions::FfiDescriptor;
-use crate::permissions::NetDescriptor;
-use crate::permissions::PermissionState;
+use crate::permissions::create_child_permissions;
+use crate::permissions::ChildPermissionsArg;
use crate::permissions::Permissions;
-use crate::permissions::ReadDescriptor;
-use crate::permissions::RunDescriptor;
-use crate::permissions::UnaryPermission;
-use crate::permissions::UnitPermission;
-use crate::permissions::WriteDescriptor;
use crate::web_worker::run_web_worker;
use crate::web_worker::SendableWebWorkerHandle;
use crate::web_worker::WebWorker;
@@ -20,14 +11,10 @@ use crate::web_worker::WebWorkerHandle;
use crate::web_worker::WebWorkerType;
use crate::web_worker::WorkerControlEvent;
use crate::web_worker::WorkerId;
-use deno_core::error::custom_error;
use deno_core::error::AnyError;
use deno_core::op_async;
use deno_core::op_sync;
-use deno_core::serde::de;
-use deno_core::serde::de::SeqAccess;
use deno_core::serde::Deserialize;
-use deno_core::serde::Deserializer;
use deno_core::Extension;
use deno_core::ModuleSpecifier;
use deno_core::OpState;
@@ -35,10 +22,6 @@ use deno_web::JsMessageData;
use log::debug;
use std::cell::RefCell;
use std::collections::HashMap;
-use std::collections::HashSet;
-use std::convert::From;
-use std::fmt;
-use std::path::PathBuf;
use std::rc::Rc;
use std::sync::Arc;
use std::thread::JoinHandle;
@@ -131,369 +114,12 @@ pub fn init(create_web_worker_cb: Arc<CreateWebWorkerCb>) -> Extension {
.build()
}
-fn merge_boolean_permission(
- mut main: UnitPermission,
- worker: Option<PermissionState>,
-) -> Result<UnitPermission, AnyError> {
- if let Some(worker) = worker {
- if worker < main.state {
- return Err(custom_error(
- "PermissionDenied",
- "Can't escalate parent thread permissions",
- ));
- } else {
- main.state = worker;
- }
- }
- Ok(main)
-}
-
-fn merge_net_permission(
- mut main: UnaryPermission<NetDescriptor>,
- worker: Option<UnaryPermission<NetDescriptor>>,
-) -> Result<UnaryPermission<NetDescriptor>, AnyError> {
- if let Some(worker) = worker {
- if (worker.global_state < main.global_state)
- || !worker
- .granted_list
- .iter()
- .all(|x| main.check(&(&x.0, x.1)).is_ok())
- {
- return Err(custom_error(
- "PermissionDenied",
- "Can't escalate parent thread permissions",
- ));
- } else {
- main.global_state = worker.global_state;
- main.granted_list = worker.granted_list;
- }
- }
- Ok(main)
-}
-
-fn merge_read_permission(
- mut main: UnaryPermission<ReadDescriptor>,
- worker: Option<UnaryPermission<ReadDescriptor>>,
-) -> Result<UnaryPermission<ReadDescriptor>, AnyError> {
- if let Some(worker) = worker {
- if (worker.global_state < main.global_state)
- || !worker
- .granted_list
- .iter()
- .all(|x| main.check(x.0.as_path()).is_ok())
- {
- return Err(custom_error(
- "PermissionDenied",
- "Can't escalate parent thread permissions",
- ));
- } else {
- main.global_state = worker.global_state;
- main.granted_list = worker.granted_list;
- }
- }
- Ok(main)
-}
-
-fn merge_write_permission(
- mut main: UnaryPermission<WriteDescriptor>,
- worker: Option<UnaryPermission<WriteDescriptor>>,
-) -> Result<UnaryPermission<WriteDescriptor>, AnyError> {
- if let Some(worker) = worker {
- if (worker.global_state < main.global_state)
- || !worker
- .granted_list
- .iter()
- .all(|x| main.check(x.0.as_path()).is_ok())
- {
- return Err(custom_error(
- "PermissionDenied",
- "Can't escalate parent thread permissions",
- ));
- } else {
- main.global_state = worker.global_state;
- main.granted_list = worker.granted_list;
- }
- }
- Ok(main)
-}
-
-fn merge_env_permission(
- mut main: UnaryPermission<EnvDescriptor>,
- worker: Option<UnaryPermission<EnvDescriptor>>,
-) -> Result<UnaryPermission<EnvDescriptor>, AnyError> {
- if let Some(worker) = worker {
- if (worker.global_state < main.global_state)
- || !worker
- .granted_list
- .iter()
- .all(|x| main.check(x.as_ref()).is_ok())
- {
- return Err(custom_error(
- "PermissionDenied",
- "Can't escalate parent thread permissions",
- ));
- } else {
- main.global_state = worker.global_state;
- main.granted_list = worker.granted_list;
- }
- }
- Ok(main)
-}
-
-fn merge_run_permission(
- mut main: UnaryPermission<RunDescriptor>,
- worker: Option<UnaryPermission<RunDescriptor>>,
-) -> Result<UnaryPermission<RunDescriptor>, AnyError> {
- if let Some(worker) = worker {
- if (worker.global_state < main.global_state)
- || !worker.granted_list.iter().all(|x| main.check(&x.0).is_ok())
- {
- return Err(custom_error(
- "PermissionDenied",
- "Can't escalate parent thread permissions",
- ));
- } else {
- main.global_state = worker.global_state;
- main.granted_list = worker.granted_list;
- }
- }
- Ok(main)
-}
-
-fn merge_ffi_permission(
- mut main: UnaryPermission<FfiDescriptor>,
- worker: Option<UnaryPermission<FfiDescriptor>>,
-) -> Result<UnaryPermission<FfiDescriptor>, AnyError> {
- if let Some(worker) = worker {
- if (worker.global_state < main.global_state)
- || !worker.granted_list.iter().all(|x| main.check(&x.0).is_ok())
- {
- return Err(custom_error(
- "PermissionDenied",
- "Can't escalate parent thread permissions",
- ));
- } else {
- main.global_state = worker.global_state;
- main.granted_list = worker.granted_list;
- }
- }
- Ok(main)
-}
-
-pub fn create_worker_permissions(
- main_perms: Permissions,
- worker_perms: PermissionsArg,
-) -> Result<Permissions, AnyError> {
- Ok(Permissions {
- env: merge_env_permission(main_perms.env, worker_perms.env)?,
- hrtime: merge_boolean_permission(main_perms.hrtime, worker_perms.hrtime)?,
- net: merge_net_permission(main_perms.net, worker_perms.net)?,
- ffi: merge_ffi_permission(main_perms.ffi, worker_perms.ffi)?,
- read: merge_read_permission(main_perms.read, worker_perms.read)?,
- run: merge_run_permission(main_perms.run, worker_perms.run)?,
- write: merge_write_permission(main_perms.write, worker_perms.write)?,
- })
-}
-
-#[derive(Debug, Deserialize)]
-pub struct PermissionsArg {
- #[serde(default, deserialize_with = "as_unary_env_permission")]
- env: Option<UnaryPermission<EnvDescriptor>>,
- #[serde(default, deserialize_with = "as_permission_state")]
- hrtime: Option<PermissionState>,
- #[serde(default, deserialize_with = "as_unary_net_permission")]
- net: Option<UnaryPermission<NetDescriptor>>,
- #[serde(default, deserialize_with = "as_unary_ffi_permission")]
- ffi: Option<UnaryPermission<FfiDescriptor>>,
- #[serde(default, deserialize_with = "as_unary_read_permission")]
- read: Option<UnaryPermission<ReadDescriptor>>,
- #[serde(default, deserialize_with = "as_unary_run_permission")]
- run: Option<UnaryPermission<RunDescriptor>>,
- #[serde(default, deserialize_with = "as_unary_write_permission")]
- write: Option<UnaryPermission<WriteDescriptor>>,
-}
-
-fn as_permission_state<'de, D>(
- deserializer: D,
-) -> Result<Option<PermissionState>, D::Error>
-where
- D: Deserializer<'de>,
-{
- let value: bool = Deserialize::deserialize(deserializer)?;
-
- match value {
- true => Ok(Some(PermissionState::Granted)),
- false => Ok(Some(PermissionState::Denied)),
- }
-}
-
-struct UnaryPermissionBase {
- global_state: PermissionState,
- paths: Vec<String>,
-}
-
-struct ParseBooleanOrStringVec;
-
-impl<'de> de::Visitor<'de> for ParseBooleanOrStringVec {
- type Value = UnaryPermissionBase;
-
- fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- formatter.write_str("a vector of strings or a boolean")
- }
-
- // visit_unit maps undefined/missing values to false
- fn visit_unit<E>(self) -> Result<UnaryPermissionBase, E>
- where
- E: de::Error,
- {
- self.visit_bool(false)
- }
-
- fn visit_bool<E>(self, v: bool) -> Result<UnaryPermissionBase, E>
- where
- E: de::Error,
- {
- Ok(UnaryPermissionBase {
- global_state: match v {
- true => PermissionState::Granted,
- false => PermissionState::Denied,
- },
- paths: Vec::new(),
- })
- }
-
- fn visit_seq<V>(self, mut visitor: V) -> Result<UnaryPermissionBase, V::Error>
- where
- V: SeqAccess<'de>,
- {
- let mut vec: Vec<String> = Vec::new();
-
- let mut value = visitor.next_element::<String>()?;
- while value.is_some() {
- vec.push(value.unwrap());
- value = visitor.next_element()?;
- }
- Ok(UnaryPermissionBase {
- global_state: PermissionState::Prompt,
- paths: vec,
- })
- }
-}
-
-fn as_unary_net_permission<'de, D>(
- deserializer: D,
-) -> Result<Option<UnaryPermission<NetDescriptor>>, D::Error>
-where
- D: Deserializer<'de>,
-{
- let value: UnaryPermissionBase =
- deserializer.deserialize_any(ParseBooleanOrStringVec)?;
-
- let allowed: HashSet<NetDescriptor> = value
- .paths
- .into_iter()
- .map(NetDescriptor::from_string)
- .collect();
-
- Ok(Some(UnaryPermission::<NetDescriptor> {
- global_state: value.global_state,
- granted_list: allowed,
- ..Default::default()
- }))
-}
-
-fn as_unary_read_permission<'de, D>(
- deserializer: D,
-) -> Result<Option<UnaryPermission<ReadDescriptor>>, D::Error>
-where
- D: Deserializer<'de>,
-{
- let value: UnaryPermissionBase =
- deserializer.deserialize_any(ParseBooleanOrStringVec)?;
-
- let paths: Vec<PathBuf> =
- value.paths.into_iter().map(PathBuf::from).collect();
-
- Ok(Some(UnaryPermission::<ReadDescriptor> {
- global_state: value.global_state,
- granted_list: resolve_read_allowlist(&Some(paths)),
- ..Default::default()
- }))
-}
-
-fn as_unary_write_permission<'de, D>(
- deserializer: D,
-) -> Result<Option<UnaryPermission<WriteDescriptor>>, D::Error>
-where
- D: Deserializer<'de>,
-{
- let value: UnaryPermissionBase =
- deserializer.deserialize_any(ParseBooleanOrStringVec)?;
-
- let paths: Vec<PathBuf> =
- value.paths.into_iter().map(PathBuf::from).collect();
-
- Ok(Some(UnaryPermission::<WriteDescriptor> {
- global_state: value.global_state,
- granted_list: resolve_write_allowlist(&Some(paths)),
- ..Default::default()
- }))
-}
-
-fn as_unary_env_permission<'de, D>(
- deserializer: D,
-) -> Result<Option<UnaryPermission<EnvDescriptor>>, D::Error>
-where
- D: Deserializer<'de>,
-{
- let value: UnaryPermissionBase =
- deserializer.deserialize_any(ParseBooleanOrStringVec)?;
-
- Ok(Some(UnaryPermission::<EnvDescriptor> {
- global_state: value.global_state,
- granted_list: value.paths.into_iter().map(EnvDescriptor::new).collect(),
- ..Default::default()
- }))
-}
-
-fn as_unary_run_permission<'de, D>(
- deserializer: D,
-) -> Result<Option<UnaryPermission<RunDescriptor>>, D::Error>
-where
- D: Deserializer<'de>,
-{
- let value: UnaryPermissionBase =
- deserializer.deserialize_any(ParseBooleanOrStringVec)?;
-
- Ok(Some(UnaryPermission::<RunDescriptor> {
- global_state: value.global_state,
- granted_list: value.paths.into_iter().map(RunDescriptor).collect(),
- ..Default::default()
- }))
-}
-
-fn as_unary_ffi_permission<'de, D>(
- deserializer: D,
-) -> Result<Option<UnaryPermission<FfiDescriptor>>, D::Error>
-where
- D: Deserializer<'de>,
-{
- let value: UnaryPermissionBase =
- deserializer.deserialize_any(ParseBooleanOrStringVec)?;
-
- Ok(Some(UnaryPermission::<FfiDescriptor> {
- global_state: value.global_state,
- granted_list: value.paths.into_iter().map(FfiDescriptor).collect(),
- ..Default::default()
- }))
-}
-
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CreateWorkerArgs {
has_source_code: bool,
name: Option<String>,
- permissions: Option<PermissionsArg>,
+ permissions: Option<ChildPermissionsArg>,
source_code: String,
specifier: String,
use_deno_namespace: bool,
@@ -528,13 +154,18 @@ fn op_create_worker(
);
}
}
- let parent_permissions = state.borrow::<Permissions>().clone();
- let worker_permissions = if let Some(permissions) = args.permissions {
+
+ if args.permissions.is_some() {
super::check_unstable(state, "Worker.deno.permissions");
- create_worker_permissions(parent_permissions.clone(), permissions)?
+ }
+ let parent_permissions = state.borrow_mut::<Permissions>();
+ let worker_permissions = if let Some(child_permissions_arg) = args.permissions
+ {
+ create_child_permissions(parent_permissions, child_permissions_arg)?
} else {
parent_permissions.clone()
};
+ let parent_permissions = parent_permissions.clone();
let worker_id = state.take::<WorkerId>();
let create_module_loader = state.take::<CreateWebWorkerCbHolder>();