0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-03-03 09:31:22 -05:00

feat: Add hint to permission prompt to display allow flag (#13695)

This commit is contained in:
Ryan Dahl 2022-02-16 18:14:46 -05:00 committed by GitHub
parent 53088e16de
commit 57f4b0e5af
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 75 additions and 45 deletions

View file

@ -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"),
@ -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"),
@ -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"),
@ -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"),
],

View file

@ -84,6 +84,7 @@ impl PermissionState {
name: &str,
info: Option<&str>,
prompt: bool,
flag: &str,
) -> (Result<(), AnyError>, bool) {
match self {
PermissionState::Granted => {
@ -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 {
@ -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;
@ -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;
@ -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 {
@ -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
@ -366,6 +371,7 @@ impl UnaryPermission<ReadDescriptor> {
self.name,
Some(&format!("\"{}\"", display_path.display())),
self.prompt,
self.name,
);
if prompted {
if result.is_ok() {
@ -390,6 +396,7 @@ impl UnaryPermission<ReadDescriptor> {
self.name,
Some(&format!("<{}>", display)),
self.prompt,
self.name,
);
if prompted {
if result.is_ok() {
@ -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;
@ -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 {
@ -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
@ -517,6 +526,7 @@ impl UnaryPermission<WriteDescriptor> {
self.name,
Some(&format!("\"{}\"", display_path.display())),
self.prompt,
self.name,
);
if prompted {
if result.is_ok() {
@ -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;
@ -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 {
@ -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
@ -662,6 +677,7 @@ impl UnaryPermission<NetDescriptor> {
self.name,
Some(&format!("\"{}\"", new_host)),
self.prompt,
self.name,
);
if prompted {
if result.is_ok() {
@ -688,6 +704,7 @@ impl UnaryPermission<NetDescriptor> {
self.name,
Some(&format!("\"{}\"", display_host)),
self.prompt,
self.name,
);
if prompted {
if result.is_ok() {
@ -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;
@ -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 {
@ -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
@ -803,6 +822,7 @@ impl UnaryPermission<EnvDescriptor> {
self.name,
Some(&format!("\"{}\"", env)),
self.prompt,
self.name,
);
if prompted {
if result.is_ok() {
@ -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;
@ -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());
@ -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
@ -927,6 +949,7 @@ impl UnaryPermission<RunDescriptor> {
self.name,
Some(&format!("\"{}\"", cmd)),
self.prompt,
self.name,
);
if prompted {
if result.is_ok() {
@ -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;
@ -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 {
@ -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
@ -1051,6 +1076,7 @@ impl UnaryPermission<FfiDescriptor> {
self.name,
Some(&format!("\"{}\"", display_path.display())),
self.prompt,
self.name,
);
if prompted {
@ -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() {
@ -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;
@ -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;
};
@ -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));
@ -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)
}