Skip to content
Permalink
Browse files

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

  • Loading branch information...
afinch7 authored and ry committed Mar 13, 2019
1 parent 58cc69f commit 7e092210312af337a118c70865c2eb2593c83192
Showing with 66 additions and 7 deletions.
  1. +1 −0 src/compiler.rs
  2. +5 −0 src/flags.rs
  3. +4 −0 src/ops.rs
  4. +22 −6 src/permissions.rs
  5. +34 −1 tools/permission_prompt_test.py
@@ -58,6 +58,7 @@ fn lazy_start(parent_state: &Arc<IsolateState>) -> Resource {
allow_env: AtomicBool::new(false),
allow_net: AtomicBool::new(true),
allow_run: AtomicBool::new(false),
..Default::default()
};
let rid = cell.get_or_insert_with(|| {
let resource = workers::spawn(
@@ -22,6 +22,7 @@ pub struct DenoFlags {
pub allow_net: bool,
pub allow_env: bool,
pub allow_run: bool,
pub no_prompts: bool,
pub types: bool,
pub prefetch: bool,
pub info: bool,
@@ -108,6 +109,9 @@ fn set_recognized_flags(
flags.allow_read = true;
flags.allow_write = true;
}
if matches.opt_present("no-prompt") {
flags.no_prompts = true;
}
if matches.opt_present("types") {
flags.types = true;
}
@@ -149,6 +153,7 @@ pub fn set_flags(
opts.optflag("", "allow-env", "Allow environment access");
opts.optflag("", "allow-run", "Allow running subprocesses");
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("h", "help", "Print this message");
opts.optflag("D", "log-debug", "Log debug output");
@@ -1899,6 +1899,7 @@ mod tests {
allow_env: AtomicBool::new(true),
allow_net: AtomicBool::new(true),
allow_run: AtomicBool::new(true),
..Default::default()
};
let isolate = Isolate::new(
IsolateInit {
@@ -1944,6 +1945,7 @@ mod tests {
allow_env: AtomicBool::new(true),
allow_net: AtomicBool::new(true),
allow_run: AtomicBool::new(true),
..Default::default()
};
let isolate = Isolate::new(
IsolateInit {
@@ -1989,6 +1991,7 @@ mod tests {
allow_env: AtomicBool::new(true),
allow_net: AtomicBool::new(false),
allow_run: AtomicBool::new(true),
..Default::default()
};
let isolate = Isolate::new(
IsolateInit {
@@ -2034,6 +2037,7 @@ mod tests {
allow_env: AtomicBool::new(false),
allow_net: AtomicBool::new(true),
allow_run: AtomicBool::new(false),
..Default::default()
};
let isolate = Isolate::new(
IsolateInit {
@@ -18,6 +18,7 @@ pub struct DenoPermissions {
pub allow_net: AtomicBool,
pub allow_env: AtomicBool,
pub allow_run: AtomicBool,
pub no_prompts: AtomicBool,
}

impl DenoPermissions {
@@ -28,6 +29,7 @@ impl DenoPermissions {
allow_env: AtomicBool::new(flags.allow_env),
allow_net: AtomicBool::new(flags.allow_net),
allow_run: AtomicBool::new(flags.allow_run),
no_prompts: AtomicBool::new(flags.no_prompts),
}
}

@@ -36,7 +38,7 @@ impl DenoPermissions {
return Ok(());
};
// 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() {
self.allow_run.store(true, Ordering::SeqCst);
}
@@ -48,7 +50,8 @@ impl DenoPermissions {
return Ok(());
};
// 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() {
self.allow_read.store(true, Ordering::SeqCst);
}
@@ -60,7 +63,8 @@ impl DenoPermissions {
return Ok(());
};
// 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() {
self.allow_write.store(true, Ordering::SeqCst);
}
@@ -72,8 +76,10 @@ impl DenoPermissions {
return Ok(());
};
// TODO get location (where access occurred)
let r =
permission_prompt(&format!("network access to \"{}\"", domain_name));
let r = self.try_permissions_prompt(&format!(
"network access to \"{}\"",
domain_name
));
if r.is_ok() {
self.allow_net.store(true, Ordering::SeqCst);
}
@@ -85,13 +91,22 @@ impl DenoPermissions {
return Ok(());
};
// 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() {
self.allow_env.store(true, Ordering::SeqCst);
}
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 {
return self.allow_run.load(Ordering::SeqCst);
}
@@ -144,6 +159,7 @@ impl DenoPermissions {
allow_env: AtomicBool::new(false),
allow_net: AtomicBool::new(false),
allow_run: AtomicBool::new(false),
..Default::default()
}
}
}
@@ -55,7 +55,8 @@ def run(self,
allow_write=False,
allow_net=False,
allow_env=False,
allow_run=False):
allow_run=False,
no_prompt=False):
"Returns (return_code, stdout, stderr)."
cmd = [self.deno_exe, PERMISSIONS_PROMPT_TEST_TS, arg]
if allow_read:
@@ -68,6 +69,8 @@ def run(self,
cmd.append("--allow-env")
if allow_run:
cmd.append("--allow-run")
if no_prompt:
cmd.append("--no-prompt")
return tty_capture(cmd, bytes_input)

def warm_up(self):
@@ -92,6 +95,11 @@ def test_read_no(self):
assert b'PermissionDenied: permission denied' 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):
code, stdout, stderr = self.run('needsWrite', b'y\n')
assert code == 0
@@ -110,6 +118,11 @@ def test_write_no(self):
assert b'PermissionDenied: permission denied' 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):
code, stdout, stderr = self.run('needsEnv', b'y\n')
assert code == 0
@@ -128,6 +141,11 @@ def test_env_no(self):
assert b'PermissionDenied: permission denied' 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):
code, stdout, stderr = self.run('needsEnv', b'y\n')
assert code == 0
@@ -146,6 +164,11 @@ def test_net_no(self):
assert b'PermissionDenied: permission denied' 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):
code, stdout, stderr = self.run('needsRun', b'y\n')
assert code == 0
@@ -164,25 +187,35 @@ def test_run_no(self):
assert b'PermissionDenied: permission denied' 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):
p = Prompt(deno_exe)
p.warm_up()
p.test_read_yes()
p.test_read_arg()
p.test_read_no()
p.test_read_no_prompt()
p.test_write_yes()
p.test_write_arg()
p.test_write_no()
p.test_write_no_prompt()
p.test_env_yes()
p.test_env_arg()
p.test_env_no()
p.test_env_no_prompt()
p.test_net_yes()
p.test_net_arg()
p.test_net_no()
p.test_net_no_prompt()
p.test_run_yes()
p.test_run_arg()
p.test_run_no()
p.test_run_no_prompt()


def main():

0 comments on commit 7e09221

Please sign in to comment.
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.