From 2d55090d8cb506305b9d485d927d2de7a20dc87d Mon Sep 17 00:00:00 2001 From: crowlKats <13135287+crowlKats@users.noreply.github.com> Date: Fri, 19 Mar 2021 18:27:41 +0100 Subject: [PATCH] refactor(runtime/ops/worker_host): simplify worker perms handling (#9835) --- runtime/ops/worker_host.rs | 330 +++++++++---------------------------- runtime/permissions.rs | 2 +- 2 files changed, 75 insertions(+), 257 deletions(-) diff --git a/runtime/ops/worker_host.rs b/runtime/ops/worker_host.rs index da580af1ec..a56c460f32 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, + mut main: BooleanPermission, + worker: Option, ) -> Result { - 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) + 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 check_net_permission_contains( - a: &HashSet, - b: &HashSet, -) -> bool { - b.iter().all(|x| a.contains(x)) -} - -fn merge_net_permissions( - target: &UnaryPermission, - incoming: Option>, +fn merge_net_permission( + mut main: UnaryPermission, + worker: Option>, ) -> Result, AnyError> { - if incoming.is_none() { - return Ok(target.clone()); - }; - - let new_permissions = incoming.unwrap(); - match &target.global_state { - PermissionState::Granted => Ok(UnaryPermission:: { - 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:: { - 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:: { - 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:: { - 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, - current_permissions: &Permissions, -) -> bool { - allow_list - .iter() - .all(|x| current_permissions.read.check(&x.0).is_ok()) -} - -fn check_write_permissions( - allow_list: &HashSet, - current_permissions: &Permissions, -) -> bool { - allow_list - .iter() - .all(|x| current_permissions.write.check(&x.0).is_ok()) -} - -fn merge_read_permissions( - target: &UnaryPermission, - incoming: Option>, - current_permissions: &Permissions, +fn merge_read_permission( + mut main: UnaryPermission, + worker: Option>, ) -> Result, AnyError> { - if incoming.is_none() { - return Ok(target.clone()); - }; - - let new_permissions = incoming.unwrap(); - match &target.global_state { - PermissionState::Granted => Ok(UnaryPermission:: { - 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:: { - 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:: { - 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:: { - 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, - incoming: Option>, - current_permissions: &Permissions, +fn merge_write_permission( + mut main: UnaryPermission, + worker: Option>, ) -> Result, AnyError> { - if incoming.is_none() { - return Ok(target.clone()); - }; - - let new_permissions = incoming.unwrap(); - match &target.global_state { - PermissionState::Granted => Ok(UnaryPermission:: { - 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:: { - 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:: { - 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:: { - 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 { 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::().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 5d28a06404..5cd2280024 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,