summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/ops/worker_host.rs330
-rw-r--r--runtime/permissions.rs2
2 files changed, 75 insertions, 257 deletions
diff --git a/runtime/ops/worker_host.rs b/runtime/ops/worker_host.rs
index da580af1e..a56c460f3 100644
--- a/runtime/ops/worker_host.rs
+++ b/runtime/ops/worker_host.rs
@@ -109,285 +109,103 @@ pub fn init(
}
fn merge_boolean_permission(
- target: &BooleanPermission,
- incoming: Option<PermissionState>,
+ mut main: BooleanPermission,
+ worker: Option<PermissionState>,
) -> Result<BooleanPermission, AnyError> {
- let mut perm = target.clone();
- perm.state = match target.state {
- PermissionState::Granted => match incoming {
- Some(state) => state,
- None => perm.state,
- },
- _ => match incoming {
- Some(state) => match state {
- PermissionState::Denied => state,
- _ => {
- return Err(custom_error(
- "PermissionDenied",
- "Can't escalate parent thread permissions",
- ))
- }
- },
- None => perm.state,
- },
- };
- Ok(perm)
-}
-
-fn check_net_permission_contains(
- a: &HashSet<NetPermission>,
- b: &HashSet<NetPermission>,
-) -> bool {
- b.iter().all(|x| a.contains(x))
+ 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_permissions(
- target: &UnaryPermission<NetPermission>,
- incoming: Option<UnaryPermission<NetPermission>>,
+fn merge_net_permission(
+ mut main: UnaryPermission<NetPermission>,
+ worker: 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::<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
- PermissionState::Granted => Err(custom_error(
+ 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",
- )),
- //Merge
- PermissionState::Prompt => {
- if check_net_permission_contains(
- &target.granted_list,
- &new_permissions.granted_list,
- ) {
- 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(
- "PermissionDenied",
- "Can't escalate parent thread permissions",
- ))
- }
- }
- //Copy
- 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::<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",
- "Can't escalate parent thread permissions",
- )),
- },
+ ));
+ } else {
+ main.global_state = worker.global_state;
+ main.granted_list = worker.granted_list;
+ }
}
+ Ok(main)
}
-fn check_read_permissions(
- allow_list: &HashSet<ReadPermission>,
- current_permissions: &Permissions,
-) -> bool {
- allow_list
- .iter()
- .all(|x| current_permissions.read.check(&x.0).is_ok())
-}
-
-fn check_write_permissions(
- allow_list: &HashSet<WritePermission>,
- current_permissions: &Permissions,
-) -> bool {
- allow_list
- .iter()
- .all(|x| current_permissions.write.check(&x.0).is_ok())
-}
-
-fn merge_read_permissions(
- target: &UnaryPermission<ReadPermission>,
- incoming: Option<UnaryPermission<ReadPermission>>,
- current_permissions: &Permissions,
+fn merge_read_permission(
+ mut main: UnaryPermission<ReadPermission>,
+ worker: Option<UnaryPermission<ReadPermission>>,
) -> 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(
+ 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",
- )),
- //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",
- )),
- },
+ ));
+ } else {
+ main.global_state = worker.global_state;
+ main.granted_list = worker.granted_list;
+ }
}
+ Ok(main)
}
-fn merge_write_permissions(
- target: &UnaryPermission<WritePermission>,
- incoming: Option<UnaryPermission<WritePermission>>,
- current_permissions: &Permissions,
+fn merge_write_permission(
+ mut main: UnaryPermission<WritePermission>,
+ worker: Option<UnaryPermission<WritePermission>>,
) -> 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::<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
- PermissionState::Granted => Err(custom_error(
+ 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",
- )),
- //Merge
- PermissionState::Prompt => {
- 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(
- "PermissionDenied",
- "Can't escalate parent thread permissions",
- ))
- }
- }
- //Copy
- 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::<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",
- "Can't escalate parent thread permissions",
- )),
- },
+ ));
+ } else {
+ main.global_state = worker.global_state;
+ main.granted_list = worker.granted_list;
+ }
}
+ Ok(main)
}
fn create_worker_permissions(
- main_thread_permissions: &Permissions,
- permission_args: PermissionsArg,
+ main_perms: Permissions,
+ worker_perms: PermissionsArg,
) -> Result<Permissions, AnyError> {
Ok(Permissions {
- env: merge_boolean_permission(
- &main_thread_permissions.env,
- permission_args.env,
- )?,
- hrtime: merge_boolean_permission(
- &main_thread_permissions.hrtime,
- permission_args.hrtime,
- )?,
- net: merge_net_permissions(
- &main_thread_permissions.net,
- permission_args.net,
- )?,
- plugin: merge_boolean_permission(
- &main_thread_permissions.plugin,
- permission_args.plugin,
- )?,
- read: merge_read_permissions(
- &main_thread_permissions.read,
- permission_args.read,
- &main_thread_permissions,
- )?,
- run: merge_boolean_permission(
- &main_thread_permissions.run,
- permission_args.run,
- )?,
- write: merge_write_permissions(
- &main_thread_permissions.write,
- permission_args.write,
- &main_thread_permissions,
- )?,
+ env: merge_boolean_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)?,
+ plugin: merge_boolean_permission(main_perms.plugin, worker_perms.plugin)?,
+ read: merge_read_permission(main_perms.read, worker_perms.read)?,
+ run: merge_boolean_permission(main_perms.run, worker_perms.run)?,
+ write: merge_write_permission(main_perms.write, worker_perms.write)?,
})
}
@@ -559,7 +377,7 @@ fn op_create_worker(
let parent_permissions = state.borrow::<Permissions>().clone();
let worker_permissions = if let Some(permissions) = args.permissions {
super::check_unstable(state, "Worker.deno.permissions");
- create_worker_permissions(&parent_permissions, permissions)?
+ create_worker_permissions(parent_permissions.clone(), permissions)?
} else {
parent_permissions.clone()
};
diff --git a/runtime/permissions.rs b/runtime/permissions.rs
index 5d28a0640..5cd228002 100644
--- a/runtime/permissions.rs
+++ b/runtime/permissions.rs
@@ -25,7 +25,7 @@ use std::sync::Mutex;
const PERMISSION_EMOJI: &str = "⚠️";
/// Tri-state value for storing permission state
-#[derive(PartialEq, Debug, Clone, Copy, Deserialize)]
+#[derive(PartialEq, Debug, Clone, Copy, Deserialize, PartialOrd)]
pub enum PermissionState {
Granted = 0,
Prompt = 1,