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

--no-prompt flag for non-interactive environments (#1913)

This commit is contained in:
andy finch 2019-03-13 12:43:47 -04:00 committed by Ryan Dahl
parent 58cc69f672
commit 7e09221031
5 changed files with 66 additions and 7 deletions

View file

@ -58,6 +58,7 @@ fn lazy_start(parent_state: &Arc<IsolateState>) -> Resource {
allow_env: AtomicBool::new(false), allow_env: AtomicBool::new(false),
allow_net: AtomicBool::new(true), allow_net: AtomicBool::new(true),
allow_run: AtomicBool::new(false), allow_run: AtomicBool::new(false),
..Default::default()
}; };
let rid = cell.get_or_insert_with(|| { let rid = cell.get_or_insert_with(|| {
let resource = workers::spawn( let resource = workers::spawn(

View file

@ -22,6 +22,7 @@ pub struct DenoFlags {
pub allow_net: bool, pub allow_net: bool,
pub allow_env: bool, pub allow_env: bool,
pub allow_run: bool, pub allow_run: bool,
pub no_prompts: bool,
pub types: bool, pub types: bool,
pub prefetch: bool, pub prefetch: bool,
pub info: bool, pub info: bool,
@ -108,6 +109,9 @@ fn set_recognized_flags(
flags.allow_read = true; flags.allow_read = true;
flags.allow_write = true; flags.allow_write = true;
} }
if matches.opt_present("no-prompt") {
flags.no_prompts = true;
}
if matches.opt_present("types") { if matches.opt_present("types") {
flags.types = true; flags.types = true;
} }
@ -149,6 +153,7 @@ pub fn set_flags(
opts.optflag("", "allow-env", "Allow environment access"); opts.optflag("", "allow-env", "Allow environment access");
opts.optflag("", "allow-run", "Allow running subprocesses"); opts.optflag("", "allow-run", "Allow running subprocesses");
opts.optflag("A", "allow-all", "Allow all permissions"); opts.optflag("A", "allow-all", "Allow all permissions");
opts.optflag("", "no-prompt", "Do not use prompts");
opts.optflag("", "recompile", "Force recompilation of TypeScript code"); opts.optflag("", "recompile", "Force recompilation of TypeScript code");
opts.optflag("h", "help", "Print this message"); opts.optflag("h", "help", "Print this message");
opts.optflag("D", "log-debug", "Log debug output"); opts.optflag("D", "log-debug", "Log debug output");

View file

@ -1899,6 +1899,7 @@ mod tests {
allow_env: AtomicBool::new(true), allow_env: AtomicBool::new(true),
allow_net: AtomicBool::new(true), allow_net: AtomicBool::new(true),
allow_run: AtomicBool::new(true), allow_run: AtomicBool::new(true),
..Default::default()
}; };
let isolate = Isolate::new( let isolate = Isolate::new(
IsolateInit { IsolateInit {
@ -1944,6 +1945,7 @@ mod tests {
allow_env: AtomicBool::new(true), allow_env: AtomicBool::new(true),
allow_net: AtomicBool::new(true), allow_net: AtomicBool::new(true),
allow_run: AtomicBool::new(true), allow_run: AtomicBool::new(true),
..Default::default()
}; };
let isolate = Isolate::new( let isolate = Isolate::new(
IsolateInit { IsolateInit {
@ -1989,6 +1991,7 @@ mod tests {
allow_env: AtomicBool::new(true), allow_env: AtomicBool::new(true),
allow_net: AtomicBool::new(false), allow_net: AtomicBool::new(false),
allow_run: AtomicBool::new(true), allow_run: AtomicBool::new(true),
..Default::default()
}; };
let isolate = Isolate::new( let isolate = Isolate::new(
IsolateInit { IsolateInit {
@ -2034,6 +2037,7 @@ mod tests {
allow_env: AtomicBool::new(false), allow_env: AtomicBool::new(false),
allow_net: AtomicBool::new(true), allow_net: AtomicBool::new(true),
allow_run: AtomicBool::new(false), allow_run: AtomicBool::new(false),
..Default::default()
}; };
let isolate = Isolate::new( let isolate = Isolate::new(
IsolateInit { IsolateInit {

View file

@ -18,6 +18,7 @@ pub struct DenoPermissions {
pub allow_net: AtomicBool, pub allow_net: AtomicBool,
pub allow_env: AtomicBool, pub allow_env: AtomicBool,
pub allow_run: AtomicBool, pub allow_run: AtomicBool,
pub no_prompts: AtomicBool,
} }
impl DenoPermissions { impl DenoPermissions {
@ -28,6 +29,7 @@ impl DenoPermissions {
allow_env: AtomicBool::new(flags.allow_env), allow_env: AtomicBool::new(flags.allow_env),
allow_net: AtomicBool::new(flags.allow_net), allow_net: AtomicBool::new(flags.allow_net),
allow_run: AtomicBool::new(flags.allow_run), allow_run: AtomicBool::new(flags.allow_run),
no_prompts: AtomicBool::new(flags.no_prompts),
} }
} }
@ -36,7 +38,7 @@ impl DenoPermissions {
return Ok(()); return Ok(());
}; };
// TODO get location (where access occurred) // TODO get location (where access occurred)
let r = permission_prompt("access to run a subprocess"); let r = self.try_permissions_prompt("access to run a subprocess");
if r.is_ok() { if r.is_ok() {
self.allow_run.store(true, Ordering::SeqCst); self.allow_run.store(true, Ordering::SeqCst);
} }
@ -48,7 +50,8 @@ impl DenoPermissions {
return Ok(()); return Ok(());
}; };
// TODO get location (where access occurred) // TODO get location (where access occurred)
let r = permission_prompt(&format!("read access to \"{}\"", filename));; let r =
self.try_permissions_prompt(&format!("read access to \"{}\"", filename));;
if r.is_ok() { if r.is_ok() {
self.allow_read.store(true, Ordering::SeqCst); self.allow_read.store(true, Ordering::SeqCst);
} }
@ -60,7 +63,8 @@ impl DenoPermissions {
return Ok(()); return Ok(());
}; };
// TODO get location (where access occurred) // TODO get location (where access occurred)
let r = permission_prompt(&format!("write access to \"{}\"", filename));; let r =
self.try_permissions_prompt(&format!("write access to \"{}\"", filename));;
if r.is_ok() { if r.is_ok() {
self.allow_write.store(true, Ordering::SeqCst); self.allow_write.store(true, Ordering::SeqCst);
} }
@ -72,8 +76,10 @@ impl DenoPermissions {
return Ok(()); return Ok(());
}; };
// TODO get location (where access occurred) // TODO get location (where access occurred)
let r = let r = self.try_permissions_prompt(&format!(
permission_prompt(&format!("network access to \"{}\"", domain_name)); "network access to \"{}\"",
domain_name
));
if r.is_ok() { if r.is_ok() {
self.allow_net.store(true, Ordering::SeqCst); self.allow_net.store(true, Ordering::SeqCst);
} }
@ -85,13 +91,22 @@ impl DenoPermissions {
return Ok(()); return Ok(());
}; };
// TODO get location (where access occurred) // TODO get location (where access occurred)
let r = permission_prompt(&"access to environment variables"); let r = self.try_permissions_prompt(&"access to environment variables");
if r.is_ok() { if r.is_ok() {
self.allow_env.store(true, Ordering::SeqCst); self.allow_env.store(true, Ordering::SeqCst);
} }
r r
} }
/// Try to present the user with a permission prompt
/// will error with permission_denied if no_prompts is enabled
fn try_permissions_prompt(&self, message: &str) -> DenoResult<()> {
if self.no_prompts.load(Ordering::SeqCst) {
return Err(permission_denied());
}
permission_prompt(message)
}
pub fn allows_run(&self) -> bool { pub fn allows_run(&self) -> bool {
return self.allow_run.load(Ordering::SeqCst); return self.allow_run.load(Ordering::SeqCst);
} }
@ -144,6 +159,7 @@ impl DenoPermissions {
allow_env: AtomicBool::new(false), allow_env: AtomicBool::new(false),
allow_net: AtomicBool::new(false), allow_net: AtomicBool::new(false),
allow_run: AtomicBool::new(false), allow_run: AtomicBool::new(false),
..Default::default()
} }
} }
} }

View file

@ -55,7 +55,8 @@ class Prompt(object):
allow_write=False, allow_write=False,
allow_net=False, allow_net=False,
allow_env=False, allow_env=False,
allow_run=False): allow_run=False,
no_prompt=False):
"Returns (return_code, stdout, stderr)." "Returns (return_code, stdout, stderr)."
cmd = [self.deno_exe, PERMISSIONS_PROMPT_TEST_TS, arg] cmd = [self.deno_exe, PERMISSIONS_PROMPT_TEST_TS, arg]
if allow_read: if allow_read:
@ -68,6 +69,8 @@ class Prompt(object):
cmd.append("--allow-env") cmd.append("--allow-env")
if allow_run: if allow_run:
cmd.append("--allow-run") cmd.append("--allow-run")
if no_prompt:
cmd.append("--no-prompt")
return tty_capture(cmd, bytes_input) return tty_capture(cmd, bytes_input)
def warm_up(self): def warm_up(self):
@ -92,6 +95,11 @@ class Prompt(object):
assert b'PermissionDenied: permission denied' in stderr assert b'PermissionDenied: permission denied' in stderr
assert b'⚠️ Deno requests read access' in stderr assert b'⚠️ Deno requests read access' in stderr
def test_read_no_prompt(self):
code, _stdout, stderr = self.run('needsRead', b'', no_prompt=True)
assert code == 1
assert b'PermissionDenied: permission denied' in stderr
def test_write_yes(self): def test_write_yes(self):
code, stdout, stderr = self.run('needsWrite', b'y\n') code, stdout, stderr = self.run('needsWrite', b'y\n')
assert code == 0 assert code == 0
@ -110,6 +118,11 @@ class Prompt(object):
assert b'PermissionDenied: permission denied' in stderr assert b'PermissionDenied: permission denied' in stderr
assert b'⚠️ Deno requests write access' in stderr assert b'⚠️ Deno requests write access' in stderr
def test_write_no_prompt(self):
code, _stdout, stderr = self.run('needsWrite', b'', no_prompt=True)
assert code == 1
assert b'PermissionDenied: permission denied' in stderr
def test_env_yes(self): def test_env_yes(self):
code, stdout, stderr = self.run('needsEnv', b'y\n') code, stdout, stderr = self.run('needsEnv', b'y\n')
assert code == 0 assert code == 0
@ -128,6 +141,11 @@ class Prompt(object):
assert b'PermissionDenied: permission denied' in stderr assert b'PermissionDenied: permission denied' in stderr
assert b'⚠️ Deno requests access to environment' in stderr assert b'⚠️ Deno requests access to environment' in stderr
def test_env_no_prompt(self):
code, _stdout, stderr = self.run('needsEnv', b'', no_prompt=True)
assert code == 1
assert b'PermissionDenied: permission denied' in stderr
def test_net_yes(self): def test_net_yes(self):
code, stdout, stderr = self.run('needsEnv', b'y\n') code, stdout, stderr = self.run('needsEnv', b'y\n')
assert code == 0 assert code == 0
@ -146,6 +164,11 @@ class Prompt(object):
assert b'PermissionDenied: permission denied' in stderr assert b'PermissionDenied: permission denied' in stderr
assert b'⚠️ Deno requests network access' in stderr assert b'⚠️ Deno requests network access' in stderr
def test_net_no_prompt(self):
code, _stdout, stderr = self.run('needsNet', b'', no_prompt=True)
assert code == 1
assert b'PermissionDenied: permission denied' in stderr
def test_run_yes(self): def test_run_yes(self):
code, stdout, stderr = self.run('needsRun', b'y\n') code, stdout, stderr = self.run('needsRun', b'y\n')
assert code == 0 assert code == 0
@ -164,6 +187,11 @@ class Prompt(object):
assert b'PermissionDenied: permission denied' in stderr assert b'PermissionDenied: permission denied' in stderr
assert b'⚠️ Deno requests access to run' in stderr assert b'⚠️ Deno requests access to run' in stderr
def test_run_no_prompt(self):
code, _stdout, stderr = self.run('needsRun', b'', no_prompt=True)
assert code == 1
assert b'PermissionDenied: permission denied' in stderr
def permission_prompt_test(deno_exe): def permission_prompt_test(deno_exe):
p = Prompt(deno_exe) p = Prompt(deno_exe)
@ -171,18 +199,23 @@ def permission_prompt_test(deno_exe):
p.test_read_yes() p.test_read_yes()
p.test_read_arg() p.test_read_arg()
p.test_read_no() p.test_read_no()
p.test_read_no_prompt()
p.test_write_yes() p.test_write_yes()
p.test_write_arg() p.test_write_arg()
p.test_write_no() p.test_write_no()
p.test_write_no_prompt()
p.test_env_yes() p.test_env_yes()
p.test_env_arg() p.test_env_arg()
p.test_env_no() p.test_env_no()
p.test_env_no_prompt()
p.test_net_yes() p.test_net_yes()
p.test_net_arg() p.test_net_arg()
p.test_net_no() p.test_net_no()
p.test_net_no_prompt()
p.test_run_yes() p.test_run_yes()
p.test_run_arg() p.test_run_arg()
p.test_run_no() p.test_run_no()
p.test_run_no_prompt()
def main(): def main():