mirror of
https://github.com/denoland/deno.git
synced 2024-11-26 16:09:27 -05:00
refactor(cli/permissions): Cleanup Flags to Permissions conversion (#8213)
This commit is contained in:
parent
07d23baa74
commit
d9b8778c45
1 changed files with 58 additions and 72 deletions
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue