1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-22 15:06:54 -05:00

refactor(cli/permissions): Cleanup Flags to Permissions conversion (#8213)

This commit is contained in:
Nayeem Rahman 2020-10-31 22:44:42 +00:00 committed by GitHub
parent 07d23baa74
commit d9b8778c45
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -45,27 +45,6 @@ impl PermissionState {
} }
} }
impl From<usize> for PermissionState {
fn from(val: usize) -> Self {
match val {
0 => PermissionState::Granted,
1 => PermissionState::Prompt,
2 => PermissionState::Denied,
_ => unreachable!(),
}
}
}
impl From<bool> for PermissionState {
fn from(val: bool) -> Self {
if val {
PermissionState::Granted
} else {
PermissionState::Prompt
}
}
}
impl fmt::Display for PermissionState { impl fmt::Display for PermissionState {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self { match self {
@ -84,7 +63,7 @@ impl Default for PermissionState {
#[derive(Clone, Debug, Default, Deserialize, PartialEq)] #[derive(Clone, Debug, Default, Deserialize, PartialEq)]
pub struct UnaryPermission<T: Eq + Hash> { pub struct UnaryPermission<T: Eq + Hash> {
pub program_state: PermissionState, pub global_state: PermissionState,
pub granted_list: HashSet<T>, pub granted_list: HashSet<T>,
pub denied_list: HashSet<T>, pub denied_list: HashSet<T>,
} }
@ -109,26 +88,33 @@ fn resolve_fs_allowlist(allowlist: &[PathBuf]) -> HashSet<PathBuf> {
impl Permissions { impl Permissions {
pub fn from_flags(flags: &Flags) -> Self { pub fn from_flags(flags: &Flags) -> Self {
fn state_from_flag_bool(flag: bool) -> PermissionState {
if flag {
PermissionState::Granted
} else {
PermissionState::Prompt
}
}
Self { Self {
read: UnaryPermission::<PathBuf> { read: UnaryPermission::<PathBuf> {
program_state: PermissionState::from(flags.allow_read), global_state: state_from_flag_bool(flags.allow_read),
granted_list: resolve_fs_allowlist(&flags.read_allowlist), granted_list: resolve_fs_allowlist(&flags.read_allowlist),
..Default::default() ..Default::default()
}, },
write: UnaryPermission::<PathBuf> { write: UnaryPermission::<PathBuf> {
program_state: PermissionState::from(flags.allow_write), global_state: state_from_flag_bool(flags.allow_write),
granted_list: resolve_fs_allowlist(&flags.write_allowlist), granted_list: resolve_fs_allowlist(&flags.write_allowlist),
..Default::default() ..Default::default()
}, },
net: UnaryPermission::<String> { net: UnaryPermission::<String> {
program_state: PermissionState::from(flags.allow_net), global_state: state_from_flag_bool(flags.allow_net),
granted_list: flags.net_allowlist.iter().cloned().collect(), granted_list: flags.net_allowlist.iter().cloned().collect(),
..Default::default() ..Default::default()
}, },
env: PermissionState::from(flags.allow_env), env: state_from_flag_bool(flags.allow_env),
run: PermissionState::from(flags.allow_run), run: state_from_flag_bool(flags.allow_run),
plugin: PermissionState::from(flags.allow_plugin), plugin: state_from_flag_bool(flags.allow_plugin),
hrtime: PermissionState::from(flags.allow_hrtime), hrtime: state_from_flag_bool(flags.allow_hrtime),
} }
} }
@ -153,15 +139,15 @@ impl Permissions {
pub fn allow_all() -> Self { pub fn allow_all() -> Self {
Self { Self {
read: UnaryPermission { read: UnaryPermission {
program_state: PermissionState::Granted, global_state: PermissionState::Granted,
..Default::default() ..Default::default()
}, },
write: UnaryPermission { write: UnaryPermission {
program_state: PermissionState::Granted, global_state: PermissionState::Granted,
..Default::default() ..Default::default()
}, },
net: UnaryPermission { net: UnaryPermission {
program_state: PermissionState::Granted, global_state: PermissionState::Granted,
..Default::default() ..Default::default()
}, },
env: PermissionState::Granted, env: PermissionState::Granted,
@ -173,7 +159,7 @@ impl Permissions {
pub fn query_read(&self, path: &Option<&Path>) -> PermissionState { pub fn query_read(&self, path: &Option<&Path>) -> PermissionState {
let path = path.map(|p| resolve_from_cwd(p).unwrap()); let path = path.map(|p| resolve_from_cwd(p).unwrap());
if self.read.program_state == PermissionState::Denied if self.read.global_state == PermissionState::Denied
&& match path.as_ref() { && match path.as_ref() {
None => true, None => true,
Some(path) => check_path_blocklist(path, &self.read.denied_list), Some(path) => check_path_blocklist(path, &self.read.denied_list),
@ -181,7 +167,7 @@ impl Permissions {
{ {
return PermissionState::Denied; return PermissionState::Denied;
} }
if self.read.program_state == PermissionState::Granted if self.read.global_state == PermissionState::Granted
|| match path.as_ref() { || match path.as_ref() {
None => false, None => false,
Some(path) => check_path_allowlist(path, &self.read.granted_list), Some(path) => check_path_allowlist(path, &self.read.granted_list),
@ -194,7 +180,7 @@ impl Permissions {
pub fn query_write(&self, path: &Option<&Path>) -> PermissionState { pub fn query_write(&self, path: &Option<&Path>) -> PermissionState {
let path = path.map(|p| resolve_from_cwd(p).unwrap()); let path = path.map(|p| resolve_from_cwd(p).unwrap());
if self.write.program_state == PermissionState::Denied if self.write.global_state == PermissionState::Denied
&& match path.as_ref() { && match path.as_ref() {
None => true, None => true,
Some(path) => check_path_blocklist(path, &self.write.denied_list), Some(path) => check_path_blocklist(path, &self.write.denied_list),
@ -202,7 +188,7 @@ impl Permissions {
{ {
return PermissionState::Denied; return PermissionState::Denied;
} }
if self.write.program_state == PermissionState::Granted if self.write.global_state == PermissionState::Granted
|| match path.as_ref() { || match path.as_ref() {
None => false, None => false,
Some(path) => check_path_allowlist(path, &self.write.granted_list), Some(path) => check_path_allowlist(path, &self.write.granted_list),
@ -214,12 +200,12 @@ impl Permissions {
} }
pub fn query_net(&self, host: &str, port: Option<u16>) -> PermissionState { pub fn query_net(&self, host: &str, port: Option<u16>) -> PermissionState {
if self.net.program_state == PermissionState::Denied if self.net.global_state == PermissionState::Denied
|| check_host_and_port_list(host, port, &self.net.denied_list) || check_host_and_port_list(host, port, &self.net.denied_list)
{ {
return PermissionState::Denied; return PermissionState::Denied;
} }
if self.net.program_state == PermissionState::Granted if self.net.global_state == PermissionState::Granted
|| check_host_and_port_list(host, port, &self.net.granted_list) || check_host_and_port_list(host, port, &self.net.granted_list)
{ {
return PermissionState::Granted; return PermissionState::Granted;
@ -232,7 +218,7 @@ impl Permissions {
url: &Option<&str>, url: &Option<&str>,
) -> Result<PermissionState, AnyError> { ) -> Result<PermissionState, AnyError> {
if url.is_none() { if url.is_none() {
return Ok(self.net.program_state); return Ok(self.net.global_state);
} }
let url: &str = url.unwrap(); let url: &str = url.unwrap();
// If url is invalid, then throw a TypeError. // If url is invalid, then throw a TypeError.
@ -288,7 +274,7 @@ impl Permissions {
.denied_list .denied_list
.retain(|path| !resolved_path.starts_with(path)); .retain(|path| !resolved_path.starts_with(path));
self.read.denied_list.insert(resolved_path); self.read.denied_list.insert(resolved_path);
self.read.program_state = PermissionState::Denied; self.read.global_state = PermissionState::Denied;
return PermissionState::Denied; return PermissionState::Denied;
} }
} }
@ -298,10 +284,10 @@ impl Permissions {
if state == PermissionState::Prompt { if state == PermissionState::Prompt {
if permission_prompt("Deno requests read access") { if permission_prompt("Deno requests read access") {
self.read.granted_list.clear(); self.read.granted_list.clear();
self.read.program_state = PermissionState::Granted; self.read.global_state = PermissionState::Granted;
return PermissionState::Granted; return PermissionState::Granted;
} else { } else {
self.read.program_state = PermissionState::Denied; self.read.global_state = PermissionState::Denied;
return PermissionState::Denied; return PermissionState::Denied;
} }
} }
@ -330,7 +316,7 @@ impl Permissions {
.denied_list .denied_list
.retain(|path| !resolved_path.starts_with(path)); .retain(|path| !resolved_path.starts_with(path));
self.write.denied_list.insert(resolved_path); self.write.denied_list.insert(resolved_path);
self.write.program_state = PermissionState::Denied; self.write.global_state = PermissionState::Denied;
return PermissionState::Denied; return PermissionState::Denied;
} }
} }
@ -340,10 +326,10 @@ impl Permissions {
if state == PermissionState::Prompt { if state == PermissionState::Prompt {
if permission_prompt("Deno requests write access") { if permission_prompt("Deno requests write access") {
self.write.granted_list.clear(); self.write.granted_list.clear();
self.write.program_state = PermissionState::Granted; self.write.global_state = PermissionState::Granted;
return PermissionState::Granted; return PermissionState::Granted;
} else { } else {
self.write.program_state = PermissionState::Denied; self.write.global_state = PermissionState::Denied;
return PermissionState::Denied; return PermissionState::Denied;
} }
} }
@ -366,7 +352,7 @@ impl Permissions {
return Ok(PermissionState::Granted); return Ok(PermissionState::Granted);
} else { } else {
self.net.denied_list.insert(url.to_string()); self.net.denied_list.insert(url.to_string());
self.net.program_state = PermissionState::Denied; self.net.global_state = PermissionState::Denied;
return Ok(PermissionState::Denied); return Ok(PermissionState::Denied);
} }
} }
@ -376,10 +362,10 @@ impl Permissions {
if state == PermissionState::Prompt { if state == PermissionState::Prompt {
if permission_prompt("Deno requests network access") { if permission_prompt("Deno requests network access") {
self.net.granted_list.clear(); self.net.granted_list.clear();
self.net.program_state = PermissionState::Granted; self.net.global_state = PermissionState::Granted;
return Ok(PermissionState::Granted); return Ok(PermissionState::Granted);
} else { } else {
self.net.program_state = PermissionState::Denied; self.net.global_state = PermissionState::Denied;
return Ok(PermissionState::Denied); return Ok(PermissionState::Denied);
} }
} }
@ -440,8 +426,8 @@ impl Permissions {
.retain(|path_| !path_.starts_with(&path)); .retain(|path_| !path_.starts_with(&path));
} else { } else {
self.read.granted_list.clear(); self.read.granted_list.clear();
if self.read.program_state == PermissionState::Granted { if self.read.global_state == PermissionState::Granted {
self.read.program_state = PermissionState::Prompt; self.read.global_state = PermissionState::Prompt;
} }
} }
self.query_read(path) self.query_read(path)
@ -456,8 +442,8 @@ impl Permissions {
.retain(|path_| !path_.starts_with(&path)); .retain(|path_| !path_.starts_with(&path));
} else { } else {
self.write.granted_list.clear(); self.write.granted_list.clear();
if self.write.program_state == PermissionState::Granted { if self.write.global_state == PermissionState::Granted {
self.write.program_state = PermissionState::Prompt; self.write.global_state = PermissionState::Prompt;
} }
} }
self.query_write(path) self.query_write(path)
@ -471,8 +457,8 @@ impl Permissions {
self.net.granted_list.remove(*url); self.net.granted_list.remove(*url);
} else { } else {
self.net.granted_list.clear(); self.net.granted_list.clear();
if self.net.program_state == PermissionState::Granted { if self.net.global_state == PermissionState::Granted {
self.net.program_state = PermissionState::Prompt; self.net.global_state = PermissionState::Prompt;
} }
} }
self.query_net_url(url) self.query_net_url(url)
@ -902,17 +888,17 @@ mod tests {
let json_perms = r#" let json_perms = r#"
{ {
"read": { "read": {
"program_state": "Granted", "global_state": "Granted",
"granted_list": [], "granted_list": [],
"denied_list": [] "denied_list": []
}, },
"write": { "write": {
"program_state": "Granted", "global_state": "Granted",
"granted_list": [], "granted_list": [],
"denied_list": [] "denied_list": []
}, },
"net": { "net": {
"program_state": "Granted", "global_state": "Granted",
"granted_list": [], "granted_list": [],
"denied_list": [] "denied_list": []
}, },
@ -924,15 +910,15 @@ mod tests {
"#; "#;
let perms0 = Permissions { let perms0 = Permissions {
read: UnaryPermission { read: UnaryPermission {
program_state: PermissionState::Granted, global_state: PermissionState::Granted,
..Default::default() ..Default::default()
}, },
write: UnaryPermission { write: UnaryPermission {
program_state: PermissionState::Granted, global_state: PermissionState::Granted,
..Default::default() ..Default::default()
}, },
net: UnaryPermission { net: UnaryPermission {
program_state: PermissionState::Granted, global_state: PermissionState::Granted,
..Default::default() ..Default::default()
}, },
env: PermissionState::Granted, env: PermissionState::Granted,
@ -949,15 +935,15 @@ mod tests {
fn test_query() { fn test_query() {
let perms1 = Permissions { let perms1 = Permissions {
read: UnaryPermission { read: UnaryPermission {
program_state: PermissionState::Granted, global_state: PermissionState::Granted,
..Default::default() ..Default::default()
}, },
write: UnaryPermission { write: UnaryPermission {
program_state: PermissionState::Granted, global_state: PermissionState::Granted,
..Default::default() ..Default::default()
}, },
net: UnaryPermission { net: UnaryPermission {
program_state: PermissionState::Granted, global_state: PermissionState::Granted,
..Default::default() ..Default::default()
}, },
env: PermissionState::Granted, env: PermissionState::Granted,
@ -967,17 +953,17 @@ mod tests {
}; };
let perms2 = Permissions { let perms2 = Permissions {
read: UnaryPermission { read: UnaryPermission {
program_state: PermissionState::Prompt, global_state: PermissionState::Prompt,
granted_list: resolve_fs_allowlist(&[PathBuf::from("/foo")]), granted_list: resolve_fs_allowlist(&[PathBuf::from("/foo")]),
..Default::default() ..Default::default()
}, },
write: UnaryPermission { write: UnaryPermission {
program_state: PermissionState::Prompt, global_state: PermissionState::Prompt,
granted_list: resolve_fs_allowlist(&[PathBuf::from("/foo")]), granted_list: resolve_fs_allowlist(&[PathBuf::from("/foo")]),
..Default::default() ..Default::default()
}, },
net: UnaryPermission { net: UnaryPermission {
program_state: PermissionState::Prompt, global_state: PermissionState::Prompt,
granted_list: ["127.0.0.1:8000".to_string()].iter().cloned().collect(), granted_list: ["127.0.0.1:8000".to_string()].iter().cloned().collect(),
..Default::default() ..Default::default()
}, },
@ -1017,15 +1003,15 @@ mod tests {
fn test_request() { fn test_request() {
let mut perms = Permissions { let mut perms = Permissions {
read: UnaryPermission { read: UnaryPermission {
program_state: PermissionState::Prompt, global_state: PermissionState::Prompt,
..Default::default() ..Default::default()
}, },
write: UnaryPermission { write: UnaryPermission {
program_state: PermissionState::Prompt, global_state: PermissionState::Prompt,
..Default::default() ..Default::default()
}, },
net: UnaryPermission { net: UnaryPermission {
program_state: PermissionState::Prompt, global_state: PermissionState::Prompt,
..Default::default() ..Default::default()
}, },
env: PermissionState::Prompt, env: PermissionState::Prompt,
@ -1073,17 +1059,17 @@ mod tests {
fn test_revoke() { fn test_revoke() {
let mut perms = Permissions { let mut perms = Permissions {
read: UnaryPermission { read: UnaryPermission {
program_state: PermissionState::Prompt, global_state: PermissionState::Prompt,
granted_list: resolve_fs_allowlist(&[PathBuf::from("/foo")]), granted_list: resolve_fs_allowlist(&[PathBuf::from("/foo")]),
..Default::default() ..Default::default()
}, },
write: UnaryPermission { write: UnaryPermission {
program_state: PermissionState::Prompt, global_state: PermissionState::Prompt,
granted_list: resolve_fs_allowlist(&[PathBuf::from("/foo")]), granted_list: resolve_fs_allowlist(&[PathBuf::from("/foo")]),
..Default::default() ..Default::default()
}, },
net: UnaryPermission { net: UnaryPermission {
program_state: PermissionState::Denied, global_state: PermissionState::Denied,
..Default::default() ..Default::default()
}, },
env: PermissionState::Granted, env: PermissionState::Granted,