1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-11 16:42:21 -05:00

refactor(runtime/ops/worker_host): simplify worker perms handling (#9835)

This commit is contained in:
crowlKats 2021-03-19 18:27:41 +01:00 committed by GitHub
parent 91ca58fb26
commit 2d55090d8c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 75 additions and 257 deletions

View file

@ -109,285 +109,103 @@ pub fn init(
} }
fn merge_boolean_permission( fn merge_boolean_permission(
target: &BooleanPermission, mut main: BooleanPermission,
incoming: Option<PermissionState>, worker: Option<PermissionState>,
) -> Result<BooleanPermission, AnyError> { ) -> Result<BooleanPermission, AnyError> {
let mut perm = target.clone(); if let Some(worker) = worker {
perm.state = match target.state { if worker < main.state {
PermissionState::Granted => match incoming { return Err(custom_error(
Some(state) => state, "PermissionDenied",
None => perm.state, "Can't escalate parent thread permissions",
}, ));
_ => match incoming { } else {
Some(state) => match state { main.state = worker;
PermissionState::Denied => state, }
_ => { }
return Err(custom_error( Ok(main)
"PermissionDenied",
"Can't escalate parent thread permissions",
))
}
},
None => perm.state,
},
};
Ok(perm)
} }
fn check_net_permission_contains( fn merge_net_permission(
a: &HashSet<NetPermission>, mut main: UnaryPermission<NetPermission>,
b: &HashSet<NetPermission>, worker: Option<UnaryPermission<NetPermission>>,
) -> bool {
b.iter().all(|x| a.contains(x))
}
fn merge_net_permissions(
target: &UnaryPermission<NetPermission>,
incoming: Option<UnaryPermission<NetPermission>>,
) -> Result<UnaryPermission<NetPermission>, AnyError> { ) -> Result<UnaryPermission<NetPermission>, AnyError> {
if incoming.is_none() { if let Some(worker) = worker {
return Ok(target.clone()); if (worker.global_state < main.global_state)
}; || !worker
.granted_list
let new_permissions = incoming.unwrap(); .iter()
match &target.global_state { .all(|x| main.check(&(&x.0, x.1)).is_ok())
PermissionState::Granted => Ok(UnaryPermission::<NetPermission> { {
global_state: new_permissions.global_state, return Err(custom_error(
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(
"PermissionDenied", "PermissionDenied",
"Can't escalate parent thread permissions", "Can't escalate parent thread permissions",
)), ));
//Merge } else {
PermissionState::Prompt => { main.global_state = worker.global_state;
if check_net_permission_contains( main.granted_list = worker.granted_list;
&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",
)),
},
} }
Ok(main)
} }
fn check_read_permissions( fn merge_read_permission(
allow_list: &HashSet<ReadPermission>, mut main: UnaryPermission<ReadPermission>,
current_permissions: &Permissions, worker: Option<UnaryPermission<ReadPermission>>,
) -> 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,
) -> Result<UnaryPermission<ReadPermission>, AnyError> { ) -> Result<UnaryPermission<ReadPermission>, AnyError> {
if incoming.is_none() { if let Some(worker) = worker {
return Ok(target.clone()); if (worker.global_state < main.global_state)
}; || !worker
.granted_list
let new_permissions = incoming.unwrap(); .iter()
match &target.global_state { .all(|x| main.check(x.0.as_path()).is_ok())
PermissionState::Granted => Ok(UnaryPermission::<ReadPermission> { {
global_state: new_permissions.global_state, return Err(custom_error(
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", "PermissionDenied",
"Can't escalate parent thread permissions", "Can't escalate parent thread permissions",
)), ));
//Merge } else {
PermissionState::Prompt => { main.global_state = worker.global_state;
if check_read_permissions( main.granted_list = worker.granted_list;
&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",
)),
},
} }
Ok(main)
} }
fn merge_write_permissions( fn merge_write_permission(
target: &UnaryPermission<WritePermission>, mut main: UnaryPermission<WritePermission>,
incoming: Option<UnaryPermission<WritePermission>>, worker: Option<UnaryPermission<WritePermission>>,
current_permissions: &Permissions,
) -> Result<UnaryPermission<WritePermission>, AnyError> { ) -> Result<UnaryPermission<WritePermission>, AnyError> {
if incoming.is_none() { if let Some(worker) = worker {
return Ok(target.clone()); if (worker.global_state < main.global_state)
}; || !worker
.granted_list
let new_permissions = incoming.unwrap(); .iter()
match &target.global_state { .all(|x| main.check(x.0.as_path()).is_ok())
PermissionState::Granted => Ok(UnaryPermission::<WritePermission> { {
global_state: new_permissions.global_state, return Err(custom_error(
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(
"PermissionDenied", "PermissionDenied",
"Can't escalate parent thread permissions", "Can't escalate parent thread permissions",
)), ));
//Merge } else {
PermissionState::Prompt => { main.global_state = worker.global_state;
if check_write_permissions( main.granted_list = worker.granted_list;
&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",
)),
},
} }
Ok(main)
} }
fn create_worker_permissions( fn create_worker_permissions(
main_thread_permissions: &Permissions, main_perms: Permissions,
permission_args: PermissionsArg, worker_perms: PermissionsArg,
) -> Result<Permissions, AnyError> { ) -> Result<Permissions, AnyError> {
Ok(Permissions { Ok(Permissions {
env: merge_boolean_permission( env: merge_boolean_permission(main_perms.env, worker_perms.env)?,
&main_thread_permissions.env, hrtime: merge_boolean_permission(main_perms.hrtime, worker_perms.hrtime)?,
permission_args.env, net: merge_net_permission(main_perms.net, worker_perms.net)?,
)?, plugin: merge_boolean_permission(main_perms.plugin, worker_perms.plugin)?,
hrtime: merge_boolean_permission( read: merge_read_permission(main_perms.read, worker_perms.read)?,
&main_thread_permissions.hrtime, run: merge_boolean_permission(main_perms.run, worker_perms.run)?,
permission_args.hrtime, write: merge_write_permission(main_perms.write, worker_perms.write)?,
)?,
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,
)?,
}) })
} }
@ -559,7 +377,7 @@ fn op_create_worker(
let parent_permissions = state.borrow::<Permissions>().clone(); let parent_permissions = state.borrow::<Permissions>().clone();
let worker_permissions = if let Some(permissions) = args.permissions { let worker_permissions = if let Some(permissions) = args.permissions {
super::check_unstable(state, "Worker.deno.permissions"); super::check_unstable(state, "Worker.deno.permissions");
create_worker_permissions(&parent_permissions, permissions)? create_worker_permissions(parent_permissions.clone(), permissions)?
} else { } else {
parent_permissions.clone() parent_permissions.clone()
}; };

View file

@ -25,7 +25,7 @@ use std::sync::Mutex;
const PERMISSION_EMOJI: &str = "⚠️"; const PERMISSION_EMOJI: &str = "⚠️";
/// Tri-state value for storing permission state /// Tri-state value for storing permission state
#[derive(PartialEq, Debug, Clone, Copy, Deserialize)] #[derive(PartialEq, Debug, Clone, Copy, Deserialize, PartialOrd)]
pub enum PermissionState { pub enum PermissionState {
Granted = 0, Granted = 0,
Prompt = 1, Prompt = 1,