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:
parent
53088e16de
commit
57f4b0e5af
2 changed files with 75 additions and 45 deletions
|
@ -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"),
|
||||
],
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue