-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(permission): support suffix wildcards in --allow-env
flag
#25255
Changes from 12 commits
085b111
5e463d3
1dae2e4
849e194
574f292
8ae53a6
7d0b807
32af9f7
ac39fc9
8603674
981a9ce
a7469b9
7a93a1a
8df48c3
7ed8376
4c31cdd
b5c8bb8
24e2ac5
3076ca9
e49e0ef
6a368f9
afff2c8
22b568f
6153314
9ef3509
c828c7c
525cdbc
63b3e22
37c49be
372266b
600d042
4b2b357
365525e
6d12ba3
522a4f3
78d9617
0bc4cd7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -18,6 +18,7 @@ use deno_core::url::Url; | |||||||||||||
use deno_core::ModuleSpecifier; | ||||||||||||||
use deno_terminal::colors; | ||||||||||||||
use fqdn::FQDN; | ||||||||||||||
use log::error; | ||||||||||||||
use once_cell::sync::Lazy; | ||||||||||||||
use std::borrow::Cow; | ||||||||||||||
use std::collections::HashSet; | ||||||||||||||
|
@@ -32,6 +33,7 @@ use std::path::PathBuf; | |||||||||||||
use std::str::FromStr; | ||||||||||||||
use std::string::ToString; | ||||||||||||||
use std::sync::Arc; | ||||||||||||||
use std::sync::RwLock; | ||||||||||||||
|
||||||||||||||
pub mod prompter; | ||||||||||||||
use prompter::permission_prompt; | ||||||||||||||
|
@@ -181,6 +183,29 @@ impl PermissionState { | |||||||||||||
.map(|info| { format!(" to {info}") }) | ||||||||||||||
.unwrap_or_default(), | ||||||||||||||
); | ||||||||||||||
|
||||||||||||||
if name == "env" { | ||||||||||||||
let env_var_name = info() | ||||||||||||||
.map(|info| { | ||||||||||||||
let info_str = info.trim_start_matches('"').trim_end_matches('"'); | ||||||||||||||
info_str.to_string() | ||||||||||||||
}) | ||||||||||||||
.unwrap_or_default(); | ||||||||||||||
for env_var in crate::get_wildcard_permissions() { | ||||||||||||||
if let Some(suffix) = env_var.strip_prefix('*') { | ||||||||||||||
if env_var_name.ends_with(suffix) { | ||||||||||||||
return (Ok(()), true, false); | ||||||||||||||
} | ||||||||||||||
} else if let Some(prefix) = env_var.strip_suffix('*') { | ||||||||||||||
if env_var_name.starts_with(prefix) { | ||||||||||||||
return (Ok(()), true, false); | ||||||||||||||
} | ||||||||||||||
} else if env_var.contains('*') { | ||||||||||||||
return (Ok(()), true, false); | ||||||||||||||
} | ||||||||||||||
} | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
match permission_prompt(&msg, name, api_name, true) { | ||||||||||||||
PromptResponse::Allow => { | ||||||||||||||
Self::log_perm_access(name, info); | ||||||||||||||
|
@@ -2317,6 +2342,36 @@ pub fn is_standalone() -> bool { | |||||||||||||
IS_STANDALONE.is_raised() | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
static WILDCARD_PERMISSIONS: Lazy<RwLock<Vec<String>>> = | ||||||||||||||
Lazy::new(|| RwLock::new(Vec::new())); | ||||||||||||||
|
||||||||||||||
pub fn add_wildcard_permission(permission: &str) -> Result<(), String> { | ||||||||||||||
let mut permissions = WILDCARD_PERMISSIONS.write().map_err(|e| { | ||||||||||||||
error!("Failed to acquire write lock: {}", e); | ||||||||||||||
"Failed to add wildcard permission".to_string() | ||||||||||||||
})?; | ||||||||||||||
if !permissions.contains(&permission.to_string()) { | ||||||||||||||
permissions.push(permission.to_string()); | ||||||||||||||
} | ||||||||||||||
Ok(()) | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
pub fn get_wildcard_permissions() -> Vec<String> { | ||||||||||||||
let permissions = WILDCARD_PERMISSIONS | ||||||||||||||
.read() | ||||||||||||||
.expect("Failed to acquire read lock"); | ||||||||||||||
permissions.clone() | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
pub fn clear_wildcard_permissions() -> Result<(), String> { | ||||||||||||||
let mut permissions = WILDCARD_PERMISSIONS.write().map_err(|e| { | ||||||||||||||
error!("Failed to acquire write lock: {}", e); | ||||||||||||||
"Failed to clear wildcard permissions".to_string() | ||||||||||||||
})?; | ||||||||||||||
permissions.clear(); | ||||||||||||||
Ok(()) | ||||||||||||||
} | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you explain the purpose of this code? What's the reason for having a static with a lock just to match permissions? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The code uses a RwLock to handle wildcard permissions dynamically. When a wildcard is passed (e.g., There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That is not correct. You want to solve the same way So you need to update
and then There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @bartlomieju , There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You store one element in a single enum - then multiple enums are stored here: deno/runtime/permissions/lib.rs Lines 338 to 340 in b01578a
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
@bartlomieju |
||||||||||||||
|
||||||||||||||
#[cfg(test)] | ||||||||||||||
mod tests { | ||||||||||||||
use super::*; | ||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
{ | ||
"tempDir": true, | ||
"tests": { | ||
"deno_env_wildcard_tests": { | ||
"envs": { | ||
"MYAPP_HELLO": "Hello\tworld,", | ||
"MYAPP_GOODBYE": "farewell", | ||
"OTHER_VAR": "ignore" | ||
}, | ||
"steps": [ | ||
{ | ||
"args": "run --allow-env=MYAPP_* main.js", | ||
"output": "Hello\tworld,\nfarewell\ndone\n" | ||
}, | ||
{ | ||
"args": "run --allow-env=*_HELLO,*_GOODBYE,*_DONE,*_TEST main.js", | ||
"output": "Hello\tworld,\nfarewell\ndone\n" | ||
}, | ||
{ | ||
"args": "run --allow-env=* main.js", | ||
"output": "Hello\tworld,\nfarewell\ndone\n" | ||
}, | ||
{ | ||
"args": "run --allow-env main.js", | ||
"output": "Hello\tworld,\nfarewell\ndone\n" | ||
}, | ||
{ | ||
"args": "run --allow-env=MYAPP_HELLO,MYAPP_GOODBYE,MYAPP_TEST,MYAPP_DONE main.js", | ||
"output": "Hello\tworld,\nfarewell\ndone\n" | ||
} | ||
] | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
console.log(Deno.env.get("MYAPP_HELLO")); | ||
console.log(Deno.env.get("MYAPP_GOODBYE")); | ||
Deno.env.set("MYAPP_TEST", "done"); | ||
Deno.env.set("MYAPP_DONE", "done"); | ||
console.log(Deno.env.get("MYAPP_DONE")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
--allow-env=*
makes no sense because it's equal to--allow-env
. If we are to support "wildcards" in env var names it should only be at the begging or end (AWS_*
,*_DENO
)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK I will remove it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done