Skip to content

Commit

Permalink
feat: Add hint to permission prompt to display allow flag (denoland#1…
Browse files Browse the repository at this point in the history
  • Loading branch information
ry committed Feb 16, 2022
1 parent 53088e1 commit 57f4b0e
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 45 deletions.
14 changes: 7 additions & 7 deletions cli/tests/integration/run_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -521,9 +521,9 @@ fn _090_run_permissions_request() {
let args = "run --quiet 090_run_permissions_request.ts";
use util::PtyData::*;
util::test_pty2(args, vec![
Output("⚠️ ️Deno requests run access to \"ls\". Allow? [y/n (y = yes allow, n = no deny)] "),
Output("⚠️ ️Deno requests run access to \"ls\". Run again with --allow-run to bypass this prompt.\r\n Allow? [y/n (y = yes allow, n = no deny)]"),
Input("y\n"),
Output("⚠️ ️Deno requests run access to \"cat\". Allow? [y/n (y = yes allow, n = no deny)] "),
Output("⚠️ ️Deno requests run access to \"cat\". Run again with --allow-run to bypass this prompt.\r\n Allow? [y/n (y = yes allow, n = no deny)]"),
Input("n\n"),
Output("granted\r\n"),
Output("prompt\r\n"),
Expand Down Expand Up @@ -2197,9 +2197,9 @@ mod permissions {
let args = "run --quiet 061_permissions_request.ts";
use util::PtyData::*;
util::test_pty2(args, vec![
Output("⚠️ ️Deno requests read access to \"foo\". Allow? [y/n (y = yes allow, n = no deny)] "),
Output("⚠️ ️Deno requests read access to \"foo\". Run again with --allow-read to bypass this prompt.\r\n Allow? [y/n (y = yes allow, n = no deny)] "),
Input("y\n"),
Output("⚠️ ️Deno requests read access to \"bar\". Allow? [y/n (y = yes allow, n = no deny)] "),
Output("⚠️ ️Deno requests read access to \"bar\". Run again with --allow-read to bypass this prompt.\r\n Allow? [y/n (y = yes allow, n = no deny)]"),
Input("n\n"),
Output("granted\r\n"),
Output("prompt\r\n"),
Expand All @@ -2212,7 +2212,7 @@ mod permissions {
let args = "run --quiet 062_permissions_request_global.ts";
use util::PtyData::*;
util::test_pty2(args, vec![
Output("⚠️ ️Deno requests read access. Allow? [y/n (y = yes allow, n = no deny)] "),
Output("⚠️ ️Deno requests read access. Run again with --allow-read to bypass this prompt.\r\n Allow? [y/n (y = yes allow, n = no deny)] "),
Input("y\n"),
Output("PermissionStatus { state: \"granted\", onchange: null }\r\n"),
Output("PermissionStatus { state: \"granted\", onchange: null }\r\n"),
Expand Down Expand Up @@ -2332,9 +2332,9 @@ fn issue9750() {
vec![
Output("Enter 'yy':\r\n"),
Input("yy\n"),
Output("⚠️ ️Deno requests env access. Allow? [y/n (y = yes allow, n = no deny)] "),
Output("⚠️ ️Deno requests env access. Run again with --allow-env to bypass this prompt.\r\n Allow? [y/n (y = yes allow, n = no deny)]"),
Input("n\n"),
Output("⚠️ ️Deno requests env access to \"SECRET\". Allow? [y/n (y = yes allow, n = no deny)] "),
Output("⚠️ ️Deno requests env access to \"SECRET\". Run again with --allow-run to bypass this prompt.\r\n Allow? [y/n (y = yes allow, n = no deny)]"),
Input("n\n"),
Output("error: Uncaught (in promise) PermissionDenied: Requires env access to \"SECRET\", run again with the --allow-env flag\r\n"),
],
Expand Down
106 changes: 68 additions & 38 deletions runtime/permissions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ impl PermissionState {
name: &str,
info: Option<&str>,
prompt: bool,
flag: &str,
) -> (Result<(), AnyError>, bool) {
match self {
PermissionState::Granted => {
Expand All @@ -92,7 +93,7 @@ impl PermissionState {
}
PermissionState::Prompt if prompt => {
let msg = Self::fmt_access(name, info);
if permission_prompt(&msg) {
if permission_prompt(&msg, flag) {
Self::log_perm_access(name, info);
(Ok(()), true)
} else {
Expand Down Expand Up @@ -135,7 +136,10 @@ impl UnitPermission {

pub fn request(&mut self) -> PermissionState {
if self.state == PermissionState::Prompt {
if permission_prompt(&format!("access to {}", self.description)) {
if permission_prompt(
&format!("access to {}", self.description),
self.name,
) {
self.state = PermissionState::Granted;
} else {
self.state = PermissionState::Denied;
Expand All @@ -152,7 +156,8 @@ impl UnitPermission {
}

pub fn check(&mut self) -> Result<(), AnyError> {
let (result, prompted) = self.state.check(self.name, None, self.prompt);
let (result, prompted) =
self.state.check(self.name, None, self.prompt, self.name);
if prompted {
if result.is_ok() {
self.state = PermissionState::Granted;
Expand Down Expand Up @@ -311,10 +316,10 @@ impl UnaryPermission<ReadDescriptor> {
let (resolved_path, display_path) = resolved_and_display_path(path);
let state = self.query(Some(&resolved_path));
if state == PermissionState::Prompt {
if permission_prompt(&format!(
"read access to \"{}\"",
display_path.display()
)) {
if permission_prompt(
&format!("read access to \"{}\"", display_path.display()),
self.name,
) {
self.granted_list.insert(ReadDescriptor(resolved_path));
PermissionState::Granted
} else {
Expand All @@ -331,7 +336,7 @@ impl UnaryPermission<ReadDescriptor> {
} else {
let state = self.query(None);
if state == PermissionState::Prompt {
if permission_prompt("read access") {
if permission_prompt("read access", self.name) {
self.granted_list.clear();
self.global_state = PermissionState::Granted;
PermissionState::Granted
Expand Down Expand Up @@ -366,6 +371,7 @@ impl UnaryPermission<ReadDescriptor> {
self.name,
Some(&format!("\"{}\"", display_path.display())),
self.prompt,
self.name,
);
if prompted {
if result.is_ok() {
Expand All @@ -390,6 +396,7 @@ impl UnaryPermission<ReadDescriptor> {
self.name,
Some(&format!("<{}>", display)),
self.prompt,
self.name,
);
if prompted {
if result.is_ok() {
Expand All @@ -404,7 +411,9 @@ impl UnaryPermission<ReadDescriptor> {

pub fn check_all(&mut self) -> Result<(), AnyError> {
let (result, prompted) =
self.query(None).check(self.name, Some("all"), self.prompt);
self
.query(None)
.check(self.name, Some("all"), self.prompt, self.name);
if prompted {
if result.is_ok() {
self.global_state = PermissionState::Granted;
Expand Down Expand Up @@ -462,10 +471,10 @@ impl UnaryPermission<WriteDescriptor> {
let (resolved_path, display_path) = resolved_and_display_path(path);
let state = self.query(Some(&resolved_path));
if state == PermissionState::Prompt {
if permission_prompt(&format!(
"write access to \"{}\"",
display_path.display()
)) {
if permission_prompt(
&format!("write access to \"{}\"", display_path.display()),
self.name,
) {
self.granted_list.insert(WriteDescriptor(resolved_path));
PermissionState::Granted
} else {
Expand All @@ -482,7 +491,7 @@ impl UnaryPermission<WriteDescriptor> {
} else {
let state = self.query(None);
if state == PermissionState::Prompt {
if permission_prompt("write access") {
if permission_prompt("write access", self.name) {
self.granted_list.clear();
self.global_state = PermissionState::Granted;
PermissionState::Granted
Expand Down Expand Up @@ -517,6 +526,7 @@ impl UnaryPermission<WriteDescriptor> {
self.name,
Some(&format!("\"{}\"", display_path.display())),
self.prompt,
self.name,
);
if prompted {
if result.is_ok() {
Expand All @@ -531,7 +541,9 @@ impl UnaryPermission<WriteDescriptor> {

pub fn check_all(&mut self) -> Result<(), AnyError> {
let (result, prompted) =
self.query(None).check(self.name, Some("all"), self.prompt);
self
.query(None)
.check(self.name, Some("all"), self.prompt, self.name);
if prompted {
if result.is_ok() {
self.global_state = PermissionState::Granted;
Expand Down Expand Up @@ -600,7 +612,10 @@ impl UnaryPermission<NetDescriptor> {
let state = self.query(Some(host));
let host = NetDescriptor::new(&host);
if state == PermissionState::Prompt {
if permission_prompt(&format!("network access to \"{}\"", host)) {
if permission_prompt(
&format!("network access to \"{}\"", host),
self.name,
) {
self.granted_list.insert(host);
PermissionState::Granted
} else {
Expand All @@ -617,7 +632,7 @@ impl UnaryPermission<NetDescriptor> {
} else {
let state = self.query::<&str>(None);
if state == PermissionState::Prompt {
if permission_prompt("network access") {
if permission_prompt("network access", self.name) {
self.granted_list.clear();
self.global_state = PermissionState::Granted;
PermissionState::Granted
Expand Down Expand Up @@ -662,6 +677,7 @@ impl UnaryPermission<NetDescriptor> {
self.name,
Some(&format!("\"{}\"", new_host)),
self.prompt,
self.name,
);
if prompted {
if result.is_ok() {
Expand All @@ -688,6 +704,7 @@ impl UnaryPermission<NetDescriptor> {
self.name,
Some(&format!("\"{}\"", display_host)),
self.prompt,
self.name,
);
if prompted {
if result.is_ok() {
Expand All @@ -701,10 +718,12 @@ impl UnaryPermission<NetDescriptor> {
}

pub fn check_all(&mut self) -> Result<(), AnyError> {
let (result, prompted) =
self
.query::<&str>(None)
.check(self.name, Some("all"), self.prompt);
let (result, prompted) = self.query::<&str>(None).check(
self.name,
Some("all"),
self.prompt,
self.name,
);
if prompted {
if result.is_ok() {
self.global_state = PermissionState::Granted;
Expand Down Expand Up @@ -755,7 +774,7 @@ impl UnaryPermission<EnvDescriptor> {
if let Some(env) = env {
let state = self.query(Some(env));
if state == PermissionState::Prompt {
if permission_prompt(&format!("env access to \"{}\"", env)) {
if permission_prompt(&format!("env access to \"{}\"", env), self.name) {
self.granted_list.insert(EnvDescriptor::new(env));
PermissionState::Granted
} else {
Expand All @@ -772,7 +791,7 @@ impl UnaryPermission<EnvDescriptor> {
} else {
let state = self.query(None);
if state == PermissionState::Prompt {
if permission_prompt("env access") {
if permission_prompt("env access", self.name) {
self.granted_list.clear();
self.global_state = PermissionState::Granted;
PermissionState::Granted
Expand Down Expand Up @@ -803,6 +822,7 @@ impl UnaryPermission<EnvDescriptor> {
self.name,
Some(&format!("\"{}\"", env)),
self.prompt,
self.name,
);
if prompted {
if result.is_ok() {
Expand All @@ -817,7 +837,9 @@ impl UnaryPermission<EnvDescriptor> {

pub fn check_all(&mut self) -> Result<(), AnyError> {
let (result, prompted) =
self.query(None).check(self.name, Some("all"), self.prompt);
self
.query(None)
.check(self.name, Some("all"), self.prompt, self.name);
if prompted {
if result.is_ok() {
self.global_state = PermissionState::Granted;
Expand Down Expand Up @@ -871,7 +893,7 @@ impl UnaryPermission<RunDescriptor> {
if let Some(cmd) = cmd {
let state = self.query(Some(cmd));
if state == PermissionState::Prompt {
if permission_prompt(&format!("run access to \"{}\"", cmd)) {
if permission_prompt(&format!("run access to \"{}\"", cmd), self.name) {
self
.granted_list
.insert(RunDescriptor::from_str(cmd).unwrap());
Expand All @@ -894,7 +916,7 @@ impl UnaryPermission<RunDescriptor> {
} else {
let state = self.query(None);
if state == PermissionState::Prompt {
if permission_prompt("run access") {
if permission_prompt("run access", self.name) {
self.granted_list.clear();
self.global_state = PermissionState::Granted;
PermissionState::Granted
Expand Down Expand Up @@ -927,6 +949,7 @@ impl UnaryPermission<RunDescriptor> {
self.name,
Some(&format!("\"{}\"", cmd)),
self.prompt,
self.name,
);
if prompted {
if result.is_ok() {
Expand All @@ -945,7 +968,9 @@ impl UnaryPermission<RunDescriptor> {

pub fn check_all(&mut self) -> Result<(), AnyError> {
let (result, prompted) =
self.query(None).check(self.name, Some("all"), self.prompt);
self
.query(None)
.check(self.name, Some("all"), self.prompt, self.name);
if prompted {
if result.is_ok() {
self.global_state = PermissionState::Granted;
Expand Down Expand Up @@ -997,10 +1022,10 @@ impl UnaryPermission<FfiDescriptor> {
let (resolved_path, display_path) = resolved_and_display_path(path);
let state = self.query(Some(&resolved_path));
if state == PermissionState::Prompt {
if permission_prompt(&format!(
"ffi access to \"{}\"",
display_path.display()
)) {
if permission_prompt(
&format!("ffi access to \"{}\"", display_path.display()),
self.name,
) {
self.granted_list.insert(FfiDescriptor(resolved_path));
PermissionState::Granted
} else {
Expand All @@ -1017,7 +1042,7 @@ impl UnaryPermission<FfiDescriptor> {
} else {
let state = self.query(None);
if state == PermissionState::Prompt {
if permission_prompt("ffi access") {
if permission_prompt("ffi access", self.name) {
self.granted_list.clear();
self.global_state = PermissionState::Granted;
PermissionState::Granted
Expand Down Expand Up @@ -1051,6 +1076,7 @@ impl UnaryPermission<FfiDescriptor> {
self.name,
Some(&format!("\"{}\"", display_path.display())),
self.prompt,
self.name,
);

if prompted {
Expand All @@ -1065,7 +1091,9 @@ impl UnaryPermission<FfiDescriptor> {
result
} else {
let (result, prompted) =
self.query(None).check(self.name, None, self.prompt);
self
.query(None)
.check(self.name, None, self.prompt, self.name);

if prompted {
if result.is_ok() {
Expand All @@ -1081,7 +1109,9 @@ impl UnaryPermission<FfiDescriptor> {

pub fn check_all(&mut self) -> Result<(), AnyError> {
let (result, prompted) =
self.query(None).check(self.name, Some("all"), self.prompt);
self
.query(None)
.check(self.name, Some("all"), self.prompt, self.name);
if prompted {
if result.is_ok() {
self.global_state = PermissionState::Granted;
Expand Down Expand Up @@ -1867,7 +1897,7 @@ pub fn create_child_permissions(
/// Shows the permission prompt and returns the answer according to the user input.
/// This loops until the user gives the proper input.
#[cfg(not(test))]
fn permission_prompt(message: &str) -> bool {
fn permission_prompt(message: &str, name: &str) -> bool {
if !atty::is(atty::Stream::Stdin) || !atty::is(atty::Stream::Stderr) {
return false;
};
Expand Down Expand Up @@ -1978,8 +2008,8 @@ fn permission_prompt(message: &str) -> bool {

let opts = "[y/n (y = yes allow, n = no deny)] ";
let msg = format!(
"{} ️Deno requests {}. Allow? {}",
PERMISSION_EMOJI, message, opts
"{} ️Deno requests {}. Run again with --allow-{} to bypass this prompt.\n Allow? {} ",
PERMISSION_EMOJI, message, name, opts
);
// print to stderr so that if deno is > to a file this is still displayed.
eprint!("{}", colors::bold(&msg));
Expand Down Expand Up @@ -2009,7 +2039,7 @@ fn permission_prompt(message: &str) -> bool {
// When testing, permission prompt returns the value of STUB_PROMPT_VALUE
// which we set from the test functions.
#[cfg(test)]
fn permission_prompt(_message: &str) -> bool {
fn permission_prompt(_message: &str, _flag: &str) -> bool {
STUB_PROMPT_VALUE.load(Ordering::SeqCst)
}

Expand Down

0 comments on commit 57f4b0e

Please sign in to comment.