diff options
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/js/10_permissions.js | 7 | ||||
-rw-r--r-- | runtime/ops/os.rs | 45 | ||||
-rw-r--r-- | runtime/ops/permissions.rs | 21 | ||||
-rw-r--r-- | runtime/permissions.rs | 238 |
4 files changed, 300 insertions, 11 deletions
diff --git a/runtime/js/10_permissions.js b/runtime/js/10_permissions.js index 2573816df..6aad0677d 100644 --- a/runtime/js/10_permissions.js +++ b/runtime/js/10_permissions.js @@ -32,12 +32,13 @@ * @property {PermissionStatus} status */ - /** @type {ReadonlyArray<"read" | "write" | "net" | "env" | "run" | "ffi" | "hrtime">} */ + /** @type {ReadonlyArray<"read" | "write" | "net" | "env" | "sys" | "run" | "ffi" | "hrtime">} */ const permissionNames = [ "read", "write", "net", "env", + "sys", "run", "ffi", "hrtime", @@ -132,6 +133,8 @@ key += `-${desc.command}&`; } else if (desc.name === "env" && desc.variable) { key += `-${desc.variable}&`; + } else if (desc.name === "sys" && desc.kind) { + key += `-${desc.kind}&`; } else { key += "$"; } @@ -242,7 +245,7 @@ serializedPermissions[key] = permissions[key]; } } - for (const key of ["env", "hrtime", "net"]) { + for (const key of ["env", "hrtime", "net", "sys"]) { if (ArrayIsArray(permissions[key])) { serializedPermissions[key] = ArrayPrototypeSlice(permissions[key]); } else { diff --git a/runtime/ops/os.rs b/runtime/ops/os.rs index 14c4229a1..0e51e3120 100644 --- a/runtime/ops/os.rs +++ b/runtime/ops/os.rs @@ -161,7 +161,10 @@ fn op_exit(state: &mut OpState) { #[op] fn op_loadavg(state: &mut OpState) -> Result<(f64, f64, f64), AnyError> { super::check_unstable(state, "Deno.loadavg"); - state.borrow_mut::<Permissions>().env.check_all()?; + state + .borrow_mut::<Permissions>() + .sys + .check("loadavg", Some("Deno.loadavg()"))?; match sys_info::loadavg() { Ok(loadavg) => Ok((loadavg.one, loadavg.five, loadavg.fifteen)), Err(_) => Ok((0.0, 0.0, 0.0)), @@ -171,7 +174,10 @@ fn op_loadavg(state: &mut OpState) -> Result<(f64, f64, f64), AnyError> { #[op] fn op_hostname(state: &mut OpState) -> Result<String, AnyError> { super::check_unstable(state, "Deno.hostname"); - state.borrow_mut::<Permissions>().env.check_all()?; + state + .borrow_mut::<Permissions>() + .sys + .check("hostname", Some("Deno.hostname()"))?; let hostname = sys_info::hostname().unwrap_or_else(|_| "".to_string()); Ok(hostname) } @@ -179,7 +185,10 @@ fn op_hostname(state: &mut OpState) -> Result<String, AnyError> { #[op] fn op_os_release(state: &mut OpState) -> Result<String, AnyError> { super::check_unstable(state, "Deno.osRelease"); - state.borrow_mut::<Permissions>().env.check_all()?; + state + .borrow_mut::<Permissions>() + .sys + .check("osRelease", Some("Deno.osRelease()"))?; let release = sys_info::os_release().unwrap_or_else(|_| "".to_string()); Ok(release) } @@ -189,7 +198,10 @@ fn op_network_interfaces( state: &mut OpState, ) -> Result<Vec<NetworkInterface>, AnyError> { super::check_unstable(state, "Deno.networkInterfaces"); - state.borrow_mut::<Permissions>().env.check_all()?; + state + .borrow_mut::<Permissions>() + .sys + .check("networkInterfaces", Some("Deno.networkInterfaces()"))?; Ok(netif::up()?.map(NetworkInterface::from).collect()) } @@ -255,7 +267,10 @@ fn op_system_memory_info( state: &mut OpState, ) -> Result<Option<MemInfo>, AnyError> { super::check_unstable(state, "Deno.systemMemoryInfo"); - state.borrow_mut::<Permissions>().env.check_all()?; + state + .borrow_mut::<Permissions>() + .sys + .check("systemMemoryInfo", Some("Deno.systemMemoryInfo()"))?; match sys_info::mem_info() { Ok(info) => Ok(Some(MemInfo { total: info.total, @@ -274,7 +289,10 @@ fn op_system_memory_info( #[op] fn op_getgid(state: &mut OpState) -> Result<Option<u32>, AnyError> { super::check_unstable(state, "Deno.getGid"); - state.borrow_mut::<Permissions>().env.check_all()?; + state + .borrow_mut::<Permissions>() + .sys + .check("getGid", Some("Deno.getGid()"))?; // TODO(bartlomieju): #[allow(clippy::undocumented_unsafe_blocks)] unsafe { @@ -286,7 +304,10 @@ fn op_getgid(state: &mut OpState) -> Result<Option<u32>, AnyError> { #[op] fn op_getgid(state: &mut OpState) -> Result<Option<u32>, AnyError> { super::check_unstable(state, "Deno.getGid"); - state.borrow_mut::<Permissions>().env.check_all()?; + state + .borrow_mut::<Permissions>() + .sys + .check("getGid", Some("Deno.getGid()"))?; Ok(None) } @@ -294,7 +315,10 @@ fn op_getgid(state: &mut OpState) -> Result<Option<u32>, AnyError> { #[op] fn op_getuid(state: &mut OpState) -> Result<Option<u32>, AnyError> { super::check_unstable(state, "Deno.getUid"); - state.borrow_mut::<Permissions>().env.check_all()?; + state + .borrow_mut::<Permissions>() + .sys + .check("getUid", Some("Deno.getUid()"))?; // TODO(bartlomieju): #[allow(clippy::undocumented_unsafe_blocks)] unsafe { @@ -306,6 +330,9 @@ fn op_getuid(state: &mut OpState) -> Result<Option<u32>, AnyError> { #[op] fn op_getuid(state: &mut OpState) -> Result<Option<u32>, AnyError> { super::check_unstable(state, "Deno.getUid"); - state.borrow_mut::<Permissions>().env.check_all()?; + state + .borrow_mut::<Permissions>() + .sys + .check("getUid", Some("Deno.getUid()"))?; Ok(None) } diff --git a/runtime/ops/permissions.rs b/runtime/ops/permissions.rs index ed1797701..b79330f7f 100644 --- a/runtime/ops/permissions.rs +++ b/runtime/ops/permissions.rs @@ -2,6 +2,7 @@ use crate::permissions::Permissions; use deno_core::error::custom_error; +use deno_core::error::type_error; use deno_core::error::uri_error; use deno_core::error::AnyError; use deno_core::op; @@ -27,6 +28,7 @@ pub struct PermissionArgs { path: Option<String>, host: Option<String>, variable: Option<String>, + kind: Option<String>, command: Option<String>, } @@ -48,6 +50,7 @@ pub fn op_query_permission( .as_ref(), ), "env" => permissions.env.query(args.variable.as_deref()), + "sys" => permissions.sys.query(parse_sys_kind(args.kind.as_deref())?), "run" => permissions.run.query(args.command.as_deref()), "ffi" => permissions.ffi.query(args.path.as_deref().map(Path::new)), "hrtime" => permissions.hrtime.query(), @@ -79,6 +82,9 @@ pub fn op_revoke_permission( .as_ref(), ), "env" => permissions.env.revoke(args.variable.as_deref()), + "sys" => permissions + .sys + .revoke(parse_sys_kind(args.kind.as_deref())?), "run" => permissions.run.revoke(args.command.as_deref()), "ffi" => permissions.ffi.revoke(args.path.as_deref().map(Path::new)), "hrtime" => permissions.hrtime.revoke(), @@ -110,6 +116,9 @@ pub fn op_request_permission( .as_ref(), ), "env" => permissions.env.request(args.variable.as_deref()), + "sys" => permissions + .sys + .request(parse_sys_kind(args.kind.as_deref())?), "run" => permissions.run.request(args.command.as_deref()), "ffi" => permissions.ffi.request(args.path.as_deref().map(Path::new)), "hrtime" => permissions.hrtime.request(), @@ -132,3 +141,15 @@ fn parse_host(host_str: &str) -> Result<(String, Option<u16>), AnyError> { let hostname = url.host_str().unwrap(); Ok((hostname.to_string(), url.port())) } + +fn parse_sys_kind(kind: Option<&str>) -> Result<Option<&str>, AnyError> { + if let Some(kind) = kind { + match kind { + "hostname" | "osRelease" | "loadavg" | "networkInterfaces" + | "systemMemoryInfo" | "getUid" | "getGid" => Ok(Some(kind)), + _ => Err(type_error(format!("unknown system info kind \"{}\"", kind))), + } + } else { + Ok(kind) + } +} diff --git a/runtime/permissions.rs b/runtime/permissions.rs index a50295910..84ff286b4 100644 --- a/runtime/permissions.rs +++ b/runtime/permissions.rs @@ -302,6 +302,9 @@ impl ToString for RunDescriptor { } #[derive(Clone, Eq, PartialEq, Hash, Debug)] +pub struct SysDescriptor(pub String); + +#[derive(Clone, Eq, PartialEq, Hash, Debug)] pub struct FfiDescriptor(pub PathBuf); impl UnaryPermission<ReadDescriptor> { @@ -928,6 +931,128 @@ impl Default for UnaryPermission<EnvDescriptor> { } } +impl UnaryPermission<SysDescriptor> { + pub fn query(&self, kind: Option<&str>) -> PermissionState { + if self.global_state == PermissionState::Denied + && match kind { + None => true, + Some(kind) => { + self.denied_list.contains(&SysDescriptor(kind.to_string())) + } + } + { + PermissionState::Denied + } else if self.global_state == PermissionState::Granted + || match kind { + None => false, + Some(kind) => { + self.granted_list.contains(&SysDescriptor(kind.to_string())) + } + } + { + PermissionState::Granted + } else { + PermissionState::Prompt + } + } + + pub fn request(&mut self, kind: Option<&str>) -> PermissionState { + let state = self.query(kind); + if state != PermissionState::Prompt { + return state; + } + if let Some(kind) = kind { + let desc = SysDescriptor(kind.to_string()); + if permission_prompt( + &format!("sys access to \"{}\"", kind), + self.name, + Some("Deno.permissions.query()"), + ) { + self.granted_list.insert(desc); + PermissionState::Granted + } else { + self.denied_list.insert(desc); + self.global_state = PermissionState::Denied; + PermissionState::Denied + } + } else { + if permission_prompt( + "sys access", + self.name, + Some("Deno.permissions.query()"), + ) { + self.global_state = PermissionState::Granted; + } else { + self.granted_list.clear(); + self.global_state = PermissionState::Denied; + } + self.global_state + } + } + + pub fn revoke(&mut self, kind: Option<&str>) -> PermissionState { + if let Some(kind) = kind { + self.granted_list.remove(&SysDescriptor(kind.to_string())); + } else { + self.granted_list.clear(); + } + if self.global_state == PermissionState::Granted { + self.global_state = PermissionState::Prompt; + } + self.query(kind) + } + + pub fn check( + &mut self, + kind: &str, + api_name: Option<&str>, + ) -> Result<(), AnyError> { + let (result, prompted) = self.query(Some(kind)).check( + self.name, + api_name, + Some(&format!("\"{}\"", kind)), + self.prompt, + ); + if prompted { + if result.is_ok() { + self.granted_list.insert(SysDescriptor(kind.to_string())); + } else { + self.denied_list.insert(SysDescriptor(kind.to_string())); + self.global_state = PermissionState::Denied; + } + } + result + } + + pub fn check_all(&mut self) -> Result<(), AnyError> { + let (result, prompted) = + self + .query(None) + .check(self.name, None, Some("all"), self.prompt); + if prompted { + if result.is_ok() { + self.global_state = PermissionState::Granted; + } else { + self.global_state = PermissionState::Denied; + } + } + result + } +} + +impl Default for UnaryPermission<SysDescriptor> { + fn default() -> Self { + UnaryPermission::<SysDescriptor> { + name: "sys", + description: "system information", + global_state: Default::default(), + granted_list: Default::default(), + denied_list: Default::default(), + prompt: false, + } + } +} + impl UnaryPermission<RunDescriptor> { pub fn query(&self, cmd: Option<&str>) -> PermissionState { if self.global_state == PermissionState::Denied @@ -1221,6 +1346,7 @@ pub struct Permissions { pub write: UnaryPermission<WriteDescriptor>, pub net: UnaryPermission<NetDescriptor>, pub env: UnaryPermission<EnvDescriptor>, + pub sys: UnaryPermission<SysDescriptor>, pub run: UnaryPermission<RunDescriptor>, pub ffi: UnaryPermission<FfiDescriptor>, pub hrtime: UnitPermission, @@ -1233,6 +1359,7 @@ impl Default for Permissions { write: Permissions::new_write(&None, false).unwrap(), net: Permissions::new_net(&None, false).unwrap(), env: Permissions::new_env(&None, false).unwrap(), + sys: Permissions::new_sys(&None, false).unwrap(), run: Permissions::new_run(&None, false).unwrap(), ffi: Permissions::new_ffi(&None, false).unwrap(), hrtime: Permissions::new_hrtime(false), @@ -1248,6 +1375,7 @@ pub struct PermissionsOptions { pub allow_ffi: Option<Vec<PathBuf>>, pub allow_read: Option<Vec<PathBuf>>, pub allow_run: Option<Vec<String>>, + pub allow_sys: Option<Vec<String>>, pub allow_write: Option<Vec<PathBuf>>, pub prompt: bool, } @@ -1321,6 +1449,31 @@ impl Permissions { }) } + pub fn new_sys( + state: &Option<Vec<String>>, + prompt: bool, + ) -> Result<UnaryPermission<SysDescriptor>, AnyError> { + Ok(UnaryPermission::<SysDescriptor> { + global_state: global_state_from_option(state), + granted_list: state.as_ref().map_or_else( + || Ok(HashSet::new()), + |v| { + v.iter() + .map(|x| { + if x.is_empty() { + Err(AnyError::msg("emtpy")) + } else { + Ok(SysDescriptor(x.to_string())) + } + }) + .collect() + }, + )?, + prompt, + ..Default::default() + }) + } + pub fn new_run( state: &Option<Vec<String>>, prompt: bool, @@ -1373,6 +1526,7 @@ impl Permissions { write: Permissions::new_write(&opts.allow_write, opts.prompt)?, net: Permissions::new_net(&opts.allow_net, opts.prompt)?, env: Permissions::new_env(&opts.allow_env, opts.prompt)?, + sys: Permissions::new_sys(&opts.allow_sys, opts.prompt)?, run: Permissions::new_run(&opts.allow_run, opts.prompt)?, ffi: Permissions::new_ffi(&opts.allow_ffi, opts.prompt)?, hrtime: Permissions::new_hrtime(opts.allow_hrtime), @@ -1385,6 +1539,7 @@ impl Permissions { write: Permissions::new_write(&Some(vec![]), false).unwrap(), net: Permissions::new_net(&Some(vec![]), false).unwrap(), env: Permissions::new_env(&Some(vec![]), false).unwrap(), + sys: Permissions::new_sys(&Some(vec![]), false).unwrap(), run: Permissions::new_run(&Some(vec![]), false).unwrap(), ffi: Permissions::new_ffi(&Some(vec![]), false).unwrap(), hrtime: Permissions::new_hrtime(true), @@ -1722,6 +1877,7 @@ pub struct ChildPermissionsArg { ffi: ChildUnaryPermissionArg, read: ChildUnaryPermissionArg, run: ChildUnaryPermissionArg, + sys: ChildUnaryPermissionArg, write: ChildUnaryPermissionArg, } @@ -1734,6 +1890,7 @@ impl ChildPermissionsArg { ffi: ChildUnaryPermissionArg::Inherit, read: ChildUnaryPermissionArg::Inherit, run: ChildUnaryPermissionArg::Inherit, + sys: ChildUnaryPermissionArg::Inherit, write: ChildUnaryPermissionArg::Inherit, } } @@ -1746,6 +1903,7 @@ impl ChildPermissionsArg { ffi: ChildUnaryPermissionArg::NotGranted, read: ChildUnaryPermissionArg::NotGranted, run: ChildUnaryPermissionArg::NotGranted, + sys: ChildUnaryPermissionArg::NotGranted, write: ChildUnaryPermissionArg::NotGranted, } } @@ -1822,6 +1980,11 @@ impl<'de> Deserialize<'de> for ChildPermissionsArg { child_permissions_arg.run = arg.map_err(|e| { de::Error::custom(format!("(deno.permissions.run) {}", e)) })?; + } else if key == "sys" { + let arg = serde_json::from_value::<ChildUnaryPermissionArg>(value); + child_permissions_arg.sys = arg.map_err(|e| { + de::Error::custom(format!("(deno.permissions.sys) {}", e)) + })?; } else if key == "write" { let arg = serde_json::from_value::<ChildUnaryPermissionArg>(value); child_permissions_arg.write = arg.map_err(|e| { @@ -1872,6 +2035,35 @@ pub fn create_child_permissions( worker_perms.env.global_state = PermissionState::Denied; } worker_perms.env.prompt = main_perms.env.prompt; + match child_permissions_arg.sys { + ChildUnaryPermissionArg::Inherit => { + worker_perms.sys = main_perms.sys.clone(); + } + ChildUnaryPermissionArg::Granted => { + if main_perms.sys.check_all().is_err() { + return Err(escalation_error()); + } + worker_perms.sys.global_state = PermissionState::Granted; + } + ChildUnaryPermissionArg::NotGranted => {} + ChildUnaryPermissionArg::GrantedList(granted_list) => { + worker_perms.sys.granted_list = + Permissions::new_sys(&Some(granted_list), false)?.granted_list; + if !worker_perms + .sys + .granted_list + .iter() + .all(|desc| main_perms.sys.check(&desc.0, None).is_ok()) + { + return Err(escalation_error()); + } + } + } + worker_perms.sys.denied_list = main_perms.sys.denied_list.clone(); + if main_perms.sys.global_state == PermissionState::Denied { + worker_perms.sys.global_state = PermissionState::Denied; + } + worker_perms.sys.prompt = main_perms.sys.prompt; match child_permissions_arg.hrtime { ChildUnitPermissionArg::Inherit => { worker_perms.hrtime = main_perms.hrtime.clone(); @@ -2608,6 +2800,10 @@ mod tests { global_state: PermissionState::Prompt, ..Permissions::new_env(&Some(svec!["HOME"]), false).unwrap() }, + sys: UnaryPermission { + global_state: PermissionState::Prompt, + ..Permissions::new_sys(&Some(svec!["hostname"]), false).unwrap() + }, run: UnaryPermission { global_state: PermissionState::Prompt, ..Permissions::new_run(&Some(svec!["deno"]), false).unwrap() @@ -2642,6 +2838,10 @@ mod tests { assert_eq!(perms1.env.query(Some("HOME")), PermissionState::Granted); assert_eq!(perms2.env.query(None), PermissionState::Prompt); assert_eq!(perms2.env.query(Some("HOME")), PermissionState::Granted); + assert_eq!(perms1.sys.query(None), PermissionState::Granted); + assert_eq!(perms1.sys.query(Some("HOME")), PermissionState::Granted); + assert_eq!(perms2.env.query(None), PermissionState::Prompt); + assert_eq!(perms2.sys.query(Some("hostname")), PermissionState::Granted); assert_eq!(perms1.run.query(None), PermissionState::Granted); assert_eq!(perms1.run.query(Some("deno")), PermissionState::Granted); assert_eq!(perms2.run.query(None), PermissionState::Prompt); @@ -2681,6 +2881,11 @@ mod tests { prompt_value.set(false); assert_eq!(perms.env.request(Some("HOME")), PermissionState::Granted); prompt_value.set(true); + assert_eq!(perms.sys.request(Some("hostname")), PermissionState::Granted); + assert_eq!(perms.sys.query(None), PermissionState::Prompt); + prompt_value.set(false); + assert_eq!(perms.sys.request(Some("hostname")), PermissionState::Granted); + prompt_value.set(true); assert_eq!(perms.run.request(Some("deno")), PermissionState::Granted); assert_eq!(perms.run.query(None), PermissionState::Prompt); prompt_value.set(false); @@ -2728,6 +2933,10 @@ mod tests { global_state: PermissionState::Prompt, ..Permissions::new_env(&Some(svec!["HOME"]), false).unwrap() }, + sys: UnaryPermission { + global_state: PermissionState::Prompt, + ..Permissions::new_sys(&Some(svec!["hostname"]), false).unwrap() + }, run: UnaryPermission { global_state: PermissionState::Prompt, ..Permissions::new_run(&Some(svec!["deno"]), false).unwrap() @@ -2754,6 +2963,7 @@ mod tests { assert_eq!(perms.net.query(Some(&("127.0.0.1", None))), PermissionState::Prompt); assert_eq!(perms.net.query(Some(&("127.0.0.1", Some(8000)))), PermissionState::Granted); assert_eq!(perms.env.revoke(Some("HOME")), PermissionState::Prompt); + assert_eq!(perms.env.revoke(Some("hostname")), PermissionState::Prompt); assert_eq!(perms.run.revoke(Some("deno")), PermissionState::Prompt); assert_eq!(perms.ffi.revoke(Some(Path::new("deno"))), PermissionState::Prompt); assert_eq!(perms.hrtime.revoke(), PermissionState::Denied); @@ -2767,6 +2977,7 @@ mod tests { write: Permissions::new_write(&None, true).unwrap(), net: Permissions::new_net(&None, true).unwrap(), env: Permissions::new_env(&None, true).unwrap(), + sys: Permissions::new_sys(&None, true).unwrap(), run: Permissions::new_run(&None, true).unwrap(), ffi: Permissions::new_ffi(&None, true).unwrap(), hrtime: Permissions::new_hrtime(false), @@ -2807,6 +3018,12 @@ mod tests { assert!(perms.env.check("HOME").is_ok()); assert!(perms.env.check("PATH").is_err()); + prompt_value.set(true); + assert!(perms.env.check("hostname").is_ok()); + prompt_value.set(false); + assert!(perms.env.check("hostname").is_ok()); + assert!(perms.env.check("osRelease").is_err()); + assert!(perms.hrtime.check().is_err()); } @@ -2817,6 +3034,7 @@ mod tests { write: Permissions::new_write(&None, true).unwrap(), net: Permissions::new_net(&None, true).unwrap(), env: Permissions::new_env(&None, true).unwrap(), + sys: Permissions::new_sys(&None, true).unwrap(), run: Permissions::new_run(&None, true).unwrap(), ffi: Permissions::new_ffi(&None, true).unwrap(), hrtime: Permissions::new_hrtime(false), @@ -2867,6 +3085,14 @@ mod tests { assert!(perms.env.check("PATH").is_ok()); prompt_value.set(false); + assert!(perms.sys.check("hostname", None).is_err()); + prompt_value.set(true); + assert!(perms.sys.check("hostname", None).is_err()); + assert!(perms.sys.check("osRelease", None).is_ok()); + prompt_value.set(false); + assert!(perms.sys.check("osRelease", None).is_ok()); + + prompt_value.set(false); assert!(perms.hrtime.check().is_err()); prompt_value.set(true); assert!(perms.hrtime.check().is_err()); @@ -2902,6 +3128,7 @@ mod tests { ffi: ChildUnaryPermissionArg::Inherit, read: ChildUnaryPermissionArg::Inherit, run: ChildUnaryPermissionArg::Inherit, + sys: ChildUnaryPermissionArg::Inherit, write: ChildUnaryPermissionArg::Inherit, } ); @@ -2914,6 +3141,7 @@ mod tests { ffi: ChildUnaryPermissionArg::NotGranted, read: ChildUnaryPermissionArg::NotGranted, run: ChildUnaryPermissionArg::NotGranted, + sys: ChildUnaryPermissionArg::NotGranted, write: ChildUnaryPermissionArg::NotGranted, } ); @@ -2966,6 +3194,7 @@ mod tests { "ffi": true, "read": true, "run": true, + "sys": true, "write": true, })) .unwrap(), @@ -2975,6 +3204,7 @@ mod tests { ffi: ChildUnaryPermissionArg::Granted, read: ChildUnaryPermissionArg::Granted, run: ChildUnaryPermissionArg::Granted, + sys: ChildUnaryPermissionArg::Granted, write: ChildUnaryPermissionArg::Granted, ..ChildPermissionsArg::none() } @@ -2986,6 +3216,7 @@ mod tests { "ffi": false, "read": false, "run": false, + "sys": false, "write": false, })) .unwrap(), @@ -2995,6 +3226,7 @@ mod tests { ffi: ChildUnaryPermissionArg::NotGranted, read: ChildUnaryPermissionArg::NotGranted, run: ChildUnaryPermissionArg::NotGranted, + sys: ChildUnaryPermissionArg::NotGranted, write: ChildUnaryPermissionArg::NotGranted, ..ChildPermissionsArg::none() } @@ -3006,6 +3238,7 @@ mod tests { "ffi": ["foo", "file:///bar/baz"], "read": ["foo", "file:///bar/baz"], "run": ["foo", "file:///bar/baz", "./qux"], + "sys": ["hostname", "osRelease"], "write": ["foo", "file:///bar/baz"], })) .unwrap(), @@ -3025,6 +3258,10 @@ mod tests { "file:///bar/baz", "./qux" ]), + sys: ChildUnaryPermissionArg::GrantedList(svec![ + "hostname", + "osRelease" + ]), write: ChildUnaryPermissionArg::GrantedList(svec![ "foo", "file:///bar/baz" @@ -3129,6 +3366,7 @@ mod tests { fn test_handle_empty_value() { assert!(Permissions::new_read(&Some(vec![PathBuf::new()]), false).is_err()); assert!(Permissions::new_env(&Some(vec![String::new()]), false).is_err()); + assert!(Permissions::new_sys(&Some(vec![String::new()]), false).is_err()); assert!(Permissions::new_run(&Some(vec![String::new()]), false).is_err()); assert!(Permissions::new_ffi(&Some(vec![PathBuf::new()]), false).is_err()); assert!(Permissions::new_net(&Some(svec![String::new()]), false).is_err()); |