summaryrefslogtreecommitdiff
path: root/runtime/ops/worker_host.rs
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/ops/worker_host.rs')
-rw-r--r--runtime/ops/worker_host.rs239
1 files changed, 165 insertions, 74 deletions
diff --git a/runtime/ops/worker_host.rs b/runtime/ops/worker_host.rs
index 6b375605f..df624cd44 100644
--- a/runtime/ops/worker_host.rs
+++ b/runtime/ops/worker_host.rs
@@ -1,9 +1,14 @@
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
-use crate::permissions::resolve_fs_allowlist;
+use crate::permissions::resolve_read_allowlist;
+use crate::permissions::resolve_write_allowlist;
+use crate::permissions::BooleanPermission;
+use crate::permissions::NetPermission;
use crate::permissions::PermissionState;
use crate::permissions::Permissions;
+use crate::permissions::ReadPermission;
use crate::permissions::UnaryPermission;
+use crate::permissions::WritePermission;
use crate::web_worker::run_web_worker;
use crate::web_worker::WebWorker;
use crate::web_worker::WebWorkerHandle;
@@ -105,49 +110,54 @@ pub fn init(
);
}
-fn merge_permission_state(
- target: &PermissionState,
+fn merge_boolean_permission(
+ target: &BooleanPermission,
incoming: Option<PermissionState>,
-) -> Result<PermissionState, AnyError> {
- match target {
+) -> Result<BooleanPermission, AnyError> {
+ let mut perm = target.clone();
+ perm.state = match target.state {
PermissionState::Granted => match incoming {
- Some(x) => Ok(x),
- None => Ok(*target),
+ Some(state) => state,
+ None => perm.state,
},
_ => match incoming {
- Some(x) => match x {
- PermissionState::Denied => Ok(x),
- _ => Err(custom_error(
- "PermissionDenied",
- "Can't escalate parent thread permissions",
- )),
+ Some(state) => match state {
+ PermissionState::Denied => state,
+ _ => {
+ return Err(custom_error(
+ "PermissionDenied",
+ "Can't escalate parent thread permissions",
+ ))
+ }
},
- None => Ok(*target),
+ None => perm.state,
},
- }
+ };
+ Ok(perm)
}
fn check_net_permission_contains(
- a: &HashSet<String>,
- b: &HashSet<String>,
+ a: &HashSet<NetPermission>,
+ b: &HashSet<NetPermission>,
) -> bool {
b.iter().all(|x| a.contains(x))
}
fn merge_net_permissions(
- target: &UnaryPermission<String>,
- incoming: Option<UnaryPermission<String>>,
-) -> Result<UnaryPermission<String>, AnyError> {
+ target: &UnaryPermission<NetPermission>,
+ incoming: Option<UnaryPermission<NetPermission>>,
+) -> Result<UnaryPermission<NetPermission>, AnyError> {
if incoming.is_none() {
return Ok(target.clone());
};
let new_permissions = incoming.unwrap();
match &target.global_state {
- PermissionState::Granted => Ok(UnaryPermission::<String> {
+ PermissionState::Granted => Ok(UnaryPermission::<NetPermission> {
global_state: new_permissions.global_state,
granted_list: new_permissions.granted_list,
denied_list: new_permissions.denied_list,
+ ..Permissions::new_net(&None)
}),
PermissionState::Prompt => match new_permissions.global_state {
//Throw
@@ -161,10 +171,11 @@ fn merge_net_permissions(
&target.granted_list,
&new_permissions.granted_list,
) {
- Ok(UnaryPermission::<String> {
+ Ok(UnaryPermission::<NetPermission> {
global_state: new_permissions.global_state,
granted_list: new_permissions.granted_list,
denied_list: target.denied_list.clone(),
+ ..Permissions::new_net(&None)
})
} else {
Err(custom_error(
@@ -174,17 +185,19 @@ fn merge_net_permissions(
}
}
//Copy
- PermissionState::Denied => Ok(UnaryPermission::<String> {
+ PermissionState::Denied => Ok(UnaryPermission::<NetPermission> {
global_state: new_permissions.global_state,
granted_list: new_permissions.granted_list,
denied_list: new_permissions.denied_list,
+ ..Permissions::new_net(&None)
}),
},
PermissionState::Denied => match new_permissions.global_state {
- PermissionState::Denied => Ok(UnaryPermission::<String> {
+ PermissionState::Denied => Ok(UnaryPermission::<NetPermission> {
global_state: new_permissions.global_state,
granted_list: new_permissions.granted_list,
denied_list: new_permissions.denied_list,
+ ..Permissions::new_net(&None)
}),
_ => Err(custom_error(
"PermissionDenied",
@@ -194,45 +207,105 @@ fn merge_net_permissions(
}
}
-enum WorkerPermissionType {
- READ,
- WRITE,
-}
-
fn check_read_permissions(
- allow_list: &HashSet<PathBuf>,
+ allow_list: &HashSet<ReadPermission>,
current_permissions: &Permissions,
) -> bool {
allow_list
.iter()
- .all(|x| current_permissions.check_read(&x).is_ok())
+ .all(|x| current_permissions.read.check(&x.0).is_ok())
}
fn check_write_permissions(
- allow_list: &HashSet<PathBuf>,
+ allow_list: &HashSet<WritePermission>,
current_permissions: &Permissions,
) -> bool {
allow_list
.iter()
- .all(|x| current_permissions.check_write(&x).is_ok())
+ .all(|x| current_permissions.write.check(&x.0).is_ok())
+}
+
+fn merge_read_permissions(
+ target: &UnaryPermission<ReadPermission>,
+ incoming: Option<UnaryPermission<ReadPermission>>,
+ current_permissions: &Permissions,
+) -> Result<UnaryPermission<ReadPermission>, AnyError> {
+ if incoming.is_none() {
+ return Ok(target.clone());
+ };
+
+ let new_permissions = incoming.unwrap();
+ match &target.global_state {
+ PermissionState::Granted => Ok(UnaryPermission::<ReadPermission> {
+ global_state: new_permissions.global_state,
+ granted_list: new_permissions.granted_list,
+ denied_list: new_permissions.denied_list,
+ ..Permissions::new_read(&None)
+ }),
+ PermissionState::Prompt => match new_permissions.global_state {
+ //Throw
+ PermissionState::Granted => Err(custom_error(
+ "PermissionDenied",
+ "Can't escalate parent thread permissions",
+ )),
+ //Merge
+ PermissionState::Prompt => {
+ if check_read_permissions(
+ &new_permissions.granted_list,
+ current_permissions,
+ ) {
+ Ok(UnaryPermission::<ReadPermission> {
+ global_state: new_permissions.global_state,
+ granted_list: new_permissions.granted_list,
+ denied_list: target.denied_list.clone(),
+ ..Permissions::new_read(&None)
+ })
+ } else {
+ Err(custom_error(
+ "PermissionDenied",
+ "Can't escalate parent thread permissions",
+ ))
+ }
+ }
+ //Copy
+ PermissionState::Denied => Ok(UnaryPermission::<ReadPermission> {
+ global_state: new_permissions.global_state,
+ granted_list: new_permissions.granted_list,
+ denied_list: new_permissions.denied_list,
+ ..Permissions::new_read(&None)
+ }),
+ },
+ PermissionState::Denied => match new_permissions.global_state {
+ PermissionState::Denied => Ok(UnaryPermission::<ReadPermission> {
+ global_state: new_permissions.global_state,
+ granted_list: new_permissions.granted_list,
+ denied_list: new_permissions.denied_list,
+ ..Permissions::new_read(&None)
+ }),
+ _ => Err(custom_error(
+ "PermissionDenied",
+ "Can't escalate parent thread permissions",
+ )),
+ },
+ }
}
-fn merge_read_write_permissions(
- permission_type: WorkerPermissionType,
- target: &UnaryPermission<PathBuf>,
- incoming: Option<UnaryPermission<PathBuf>>,
+fn merge_write_permissions(
+ target: &UnaryPermission<WritePermission>,
+ incoming: Option<UnaryPermission<WritePermission>>,
current_permissions: &Permissions,
-) -> Result<UnaryPermission<PathBuf>, AnyError> {
+) -> Result<UnaryPermission<WritePermission>, AnyError> {
if incoming.is_none() {
return Ok(target.clone());
};
let new_permissions = incoming.unwrap();
match &target.global_state {
- PermissionState::Granted => Ok(UnaryPermission::<PathBuf> {
+ PermissionState::Granted => Ok(UnaryPermission::<WritePermission> {
global_state: new_permissions.global_state,
granted_list: new_permissions.granted_list,
denied_list: new_permissions.denied_list,
+ ..Permissions::new_write(&None)
}),
PermissionState::Prompt => match new_permissions.global_state {
//Throw
@@ -242,20 +315,15 @@ fn merge_read_write_permissions(
)),
//Merge
PermissionState::Prompt => {
- if match permission_type {
- WorkerPermissionType::READ => check_read_permissions(
- &new_permissions.granted_list,
- current_permissions,
- ),
- WorkerPermissionType::WRITE => check_write_permissions(
- &new_permissions.granted_list,
- current_permissions,
- ),
- } {
- Ok(UnaryPermission::<PathBuf> {
+ if check_write_permissions(
+ &new_permissions.granted_list,
+ current_permissions,
+ ) {
+ Ok(UnaryPermission::<WritePermission> {
global_state: new_permissions.global_state,
granted_list: new_permissions.granted_list,
denied_list: target.denied_list.clone(),
+ ..Permissions::new_write(&None)
})
} else {
Err(custom_error(
@@ -265,17 +333,19 @@ fn merge_read_write_permissions(
}
}
//Copy
- PermissionState::Denied => Ok(UnaryPermission::<PathBuf> {
+ PermissionState::Denied => Ok(UnaryPermission::<WritePermission> {
global_state: new_permissions.global_state,
granted_list: new_permissions.granted_list,
denied_list: new_permissions.denied_list,
+ ..Permissions::new_write(&None)
}),
},
PermissionState::Denied => match new_permissions.global_state {
- PermissionState::Denied => Ok(UnaryPermission::<PathBuf> {
+ PermissionState::Denied => Ok(UnaryPermission::<WritePermission> {
global_state: new_permissions.global_state,
granted_list: new_permissions.granted_list,
denied_list: new_permissions.denied_list,
+ ..Permissions::new_write(&None)
}),
_ => Err(custom_error(
"PermissionDenied",
@@ -290,11 +360,11 @@ fn create_worker_permissions(
permission_args: PermissionsArg,
) -> Result<Permissions, AnyError> {
Ok(Permissions {
- env: merge_permission_state(
+ env: merge_boolean_permission(
&main_thread_permissions.env,
permission_args.env,
)?,
- hrtime: merge_permission_state(
+ hrtime: merge_boolean_permission(
&main_thread_permissions.hrtime,
permission_args.hrtime,
)?,
@@ -302,22 +372,20 @@ fn create_worker_permissions(
&main_thread_permissions.net,
permission_args.net,
)?,
- plugin: merge_permission_state(
+ plugin: merge_boolean_permission(
&main_thread_permissions.plugin,
permission_args.plugin,
)?,
- read: merge_read_write_permissions(
- WorkerPermissionType::READ,
+ read: merge_read_permissions(
&main_thread_permissions.read,
permission_args.read,
&main_thread_permissions,
)?,
- run: merge_permission_state(
+ run: merge_boolean_permission(
&main_thread_permissions.run,
permission_args.run,
)?,
- write: merge_read_write_permissions(
- WorkerPermissionType::WRITE,
+ write: merge_write_permissions(
&main_thread_permissions.write,
permission_args.write,
&main_thread_permissions,
@@ -331,16 +399,16 @@ struct PermissionsArg {
env: Option<PermissionState>,
#[serde(default, deserialize_with = "as_permission_state")]
hrtime: Option<PermissionState>,
- #[serde(default, deserialize_with = "as_unary_string_permission")]
- net: Option<UnaryPermission<String>>,
+ #[serde(default, deserialize_with = "as_unary_net_permission")]
+ net: Option<UnaryPermission<NetPermission>>,
#[serde(default, deserialize_with = "as_permission_state")]
plugin: Option<PermissionState>,
- #[serde(default, deserialize_with = "as_unary_path_permission")]
- read: Option<UnaryPermission<PathBuf>>,
+ #[serde(default, deserialize_with = "as_unary_read_permission")]
+ read: Option<UnaryPermission<ReadPermission>>,
#[serde(default, deserialize_with = "as_permission_state")]
run: Option<PermissionState>,
- #[serde(default, deserialize_with = "as_unary_path_permission")]
- write: Option<UnaryPermission<PathBuf>>,
+ #[serde(default, deserialize_with = "as_unary_write_permission")]
+ write: Option<UnaryPermission<WritePermission>>,
}
fn as_permission_state<'de, D>(
@@ -402,27 +470,50 @@ impl<'de> de::Visitor<'de> for ParseBooleanOrStringVec {
}
}
-fn as_unary_string_permission<'de, D>(
+fn as_unary_net_permission<'de, D>(
deserializer: D,
-) -> Result<Option<UnaryPermission<String>>, D::Error>
+) -> Result<Option<UnaryPermission<NetPermission>>, D::Error>
where
D: Deserializer<'de>,
{
let value: UnaryPermissionBase =
deserializer.deserialize_any(ParseBooleanOrStringVec)?;
- let allowed: HashSet<String> = value.paths.into_iter().collect();
+ let allowed: HashSet<NetPermission> = value
+ .paths
+ .into_iter()
+ .map(NetPermission::from_string)
+ .collect();
- Ok(Some(UnaryPermission::<String> {
+ Ok(Some(UnaryPermission::<NetPermission> {
global_state: value.global_state,
granted_list: allowed,
..Default::default()
}))
}
-fn as_unary_path_permission<'de, D>(
+fn as_unary_read_permission<'de, D>(
+ deserializer: D,
+) -> Result<Option<UnaryPermission<ReadPermission>>, 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::<ReadPermission> {
+ 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<PathBuf>>, D::Error>
+) -> Result<Option<UnaryPermission<WritePermission>>, D::Error>
where
D: Deserializer<'de>,
{
@@ -432,9 +523,9 @@ where
let paths: Vec<PathBuf> =
value.paths.into_iter().map(PathBuf::from).collect();
- Ok(Some(UnaryPermission::<PathBuf> {
+ Ok(Some(UnaryPermission::<WritePermission> {
global_state: value.global_state,
- granted_list: resolve_fs_allowlist(&Some(paths)),
+ granted_list: resolve_write_allowlist(&Some(paths)),
..Default::default()
}))
}