mirror of
https://github.com/denoland/deno.git
synced 2024-11-28 16:20:57 -05:00
fix(permissions): ignore empty values (#15447)
This commit is contained in:
parent
08061b60d9
commit
d0ffa0beb5
7 changed files with 180 additions and 123 deletions
|
@ -261,7 +261,7 @@ pub async fn watch_func2<T: Clone, O, F>(
|
||||||
print_config: PrintConfig,
|
print_config: PrintConfig,
|
||||||
) -> Result<(), AnyError>
|
) -> Result<(), AnyError>
|
||||||
where
|
where
|
||||||
O: FnMut(T) -> F,
|
O: FnMut(T) -> Result<F, AnyError>,
|
||||||
F: Future<Output = Result<(), AnyError>>,
|
F: Future<Output = Result<(), AnyError>>,
|
||||||
{
|
{
|
||||||
let (watcher_sender, mut watcher_receiver) =
|
let (watcher_sender, mut watcher_receiver) =
|
||||||
|
@ -306,7 +306,7 @@ where
|
||||||
add_paths_to_watcher(&mut watcher, &maybe_paths.unwrap());
|
add_paths_to_watcher(&mut watcher, &maybe_paths.unwrap());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let operation_future = error_handler(operation(operation_args.clone()));
|
let operation_future = error_handler(operation(operation_args.clone())?);
|
||||||
|
|
||||||
select! {
|
select! {
|
||||||
_ = receiver_future => {},
|
_ = receiver_future => {},
|
||||||
|
|
|
@ -282,7 +282,7 @@ impl TestRun {
|
||||||
let flags = flags_from_vec(args.into_iter().map(String::from).collect())?;
|
let flags = flags_from_vec(args.into_iter().map(String::from).collect())?;
|
||||||
let ps = proc_state::ProcState::build(flags).await?;
|
let ps = proc_state::ProcState::build(flags).await?;
|
||||||
let permissions =
|
let permissions =
|
||||||
Permissions::from_options(&ps.options.permissions_options());
|
Permissions::from_options(&ps.options.permissions_options())?;
|
||||||
test::check_specifiers(
|
test::check_specifiers(
|
||||||
&ps,
|
&ps,
|
||||||
permissions.clone(),
|
permissions.clone(),
|
||||||
|
|
16
cli/main.rs
16
cli/main.rs
|
@ -472,7 +472,7 @@ async fn install_command(
|
||||||
preload_flags.inspect = None;
|
preload_flags.inspect = None;
|
||||||
preload_flags.inspect_brk = None;
|
preload_flags.inspect_brk = None;
|
||||||
let permissions =
|
let permissions =
|
||||||
Permissions::from_options(&preload_flags.permissions_options());
|
Permissions::from_options(&preload_flags.permissions_options())?;
|
||||||
let ps = ProcState::build(preload_flags).await?;
|
let ps = ProcState::build(preload_flags).await?;
|
||||||
let main_module = resolve_url_or_path(&install_flags.module_url)?;
|
let main_module = resolve_url_or_path(&install_flags.module_url)?;
|
||||||
let mut worker = create_main_worker(
|
let mut worker = create_main_worker(
|
||||||
|
@ -562,7 +562,7 @@ async fn eval_command(
|
||||||
// type, and so our "fake" specifier needs to have the proper extension.
|
// type, and so our "fake" specifier needs to have the proper extension.
|
||||||
let main_module =
|
let main_module =
|
||||||
resolve_url_or_path(&format!("./$deno$eval.{}", eval_flags.ext))?;
|
resolve_url_or_path(&format!("./$deno$eval.{}", eval_flags.ext))?;
|
||||||
let permissions = Permissions::from_options(&flags.permissions_options());
|
let permissions = Permissions::from_options(&flags.permissions_options())?;
|
||||||
let ps = ProcState::build(flags).await?;
|
let ps = ProcState::build(flags).await?;
|
||||||
let mut worker = create_main_worker(
|
let mut worker = create_main_worker(
|
||||||
&ps,
|
&ps,
|
||||||
|
@ -862,7 +862,7 @@ async fn repl_command(
|
||||||
let mut worker = create_main_worker(
|
let mut worker = create_main_worker(
|
||||||
&ps,
|
&ps,
|
||||||
main_module.clone(),
|
main_module.clone(),
|
||||||
Permissions::from_options(&ps.options.permissions_options()),
|
Permissions::from_options(&ps.options.permissions_options())?,
|
||||||
vec![],
|
vec![],
|
||||||
Default::default(),
|
Default::default(),
|
||||||
);
|
);
|
||||||
|
@ -883,7 +883,7 @@ async fn run_from_stdin(flags: Flags) -> Result<i32, AnyError> {
|
||||||
let mut worker = create_main_worker(
|
let mut worker = create_main_worker(
|
||||||
&ps.clone(),
|
&ps.clone(),
|
||||||
main_module.clone(),
|
main_module.clone(),
|
||||||
Permissions::from_options(&ps.options.permissions_options()),
|
Permissions::from_options(&ps.options.permissions_options())?,
|
||||||
vec![],
|
vec![],
|
||||||
Default::default(),
|
Default::default(),
|
||||||
);
|
);
|
||||||
|
@ -994,8 +994,8 @@ async fn run_with_watch(flags: Flags, script: String) -> Result<i32, AnyError> {
|
||||||
ModuleSpecifier,
|
ModuleSpecifier,
|
||||||
)| {
|
)| {
|
||||||
let flags = flags.clone();
|
let flags = flags.clone();
|
||||||
let permissions = Permissions::from_options(&flags.permissions_options());
|
let permissions = Permissions::from_options(&flags.permissions_options())?;
|
||||||
async move {
|
Ok(async move {
|
||||||
let ps =
|
let ps =
|
||||||
ProcState::build_for_file_watcher((*flags).clone(), sender.clone())
|
ProcState::build_for_file_watcher((*flags).clone(), sender.clone())
|
||||||
.await?;
|
.await?;
|
||||||
|
@ -1015,7 +1015,7 @@ async fn run_with_watch(flags: Flags, script: String) -> Result<i32, AnyError> {
|
||||||
executor.execute(&main_module).await?;
|
executor.execute(&main_module).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
file_watcher::watch_func2(
|
file_watcher::watch_func2(
|
||||||
|
@ -1053,7 +1053,7 @@ async fn run_command(
|
||||||
let main_module = resolve_url_or_path(&run_flags.script)?;
|
let main_module = resolve_url_or_path(&run_flags.script)?;
|
||||||
let ps = ProcState::build(flags).await?;
|
let ps = ProcState::build(flags).await?;
|
||||||
let permissions =
|
let permissions =
|
||||||
Permissions::from_options(&ps.options.permissions_options());
|
Permissions::from_options(&ps.options.permissions_options())?;
|
||||||
let mut worker = create_main_worker(
|
let mut worker = create_main_worker(
|
||||||
&ps,
|
&ps,
|
||||||
main_module.clone(),
|
main_module.clone(),
|
||||||
|
|
|
@ -224,7 +224,7 @@ pub async fn run(
|
||||||
let flags = metadata_to_flags(&metadata);
|
let flags = metadata_to_flags(&metadata);
|
||||||
let main_module = &metadata.entrypoint;
|
let main_module = &metadata.entrypoint;
|
||||||
let ps = ProcState::build(flags).await?;
|
let ps = ProcState::build(flags).await?;
|
||||||
let permissions = Permissions::from_options(&metadata.permissions);
|
let permissions = Permissions::from_options(&metadata.permissions)?;
|
||||||
let blob_store = BlobStore::default();
|
let blob_store = BlobStore::default();
|
||||||
let broadcast_channel = InMemoryBroadcastChannel::default();
|
let broadcast_channel = InMemoryBroadcastChannel::default();
|
||||||
let module_loader = Rc::new(EmbeddedModuleLoader {
|
let module_loader = Rc::new(EmbeddedModuleLoader {
|
||||||
|
|
|
@ -524,7 +524,7 @@ pub async fn run_benchmarks(
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), AnyError> {
|
||||||
let ps = ProcState::build(flags).await?;
|
let ps = ProcState::build(flags).await?;
|
||||||
let permissions =
|
let permissions =
|
||||||
Permissions::from_options(&ps.options.permissions_options());
|
Permissions::from_options(&ps.options.permissions_options())?;
|
||||||
let specifiers = collect_specifiers(
|
let specifiers = collect_specifiers(
|
||||||
bench_flags.include.unwrap_or_else(|| vec![".".to_string()]),
|
bench_flags.include.unwrap_or_else(|| vec![".".to_string()]),
|
||||||
&bench_flags.ignore.clone(),
|
&bench_flags.ignore.clone(),
|
||||||
|
@ -559,7 +559,7 @@ pub async fn run_benchmarks_with_watch(
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), AnyError> {
|
||||||
let ps = ProcState::build(flags).await?;
|
let ps = ProcState::build(flags).await?;
|
||||||
let permissions =
|
let permissions =
|
||||||
Permissions::from_options(&ps.options.permissions_options());
|
Permissions::from_options(&ps.options.permissions_options())?;
|
||||||
|
|
||||||
let include = bench_flags.include.unwrap_or_else(|| vec![".".to_string()]);
|
let include = bench_flags.include.unwrap_or_else(|| vec![".".to_string()]);
|
||||||
let ignore = bench_flags.ignore.clone();
|
let ignore = bench_flags.ignore.clone();
|
||||||
|
|
|
@ -1385,7 +1385,7 @@ pub async fn run_tests(
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), AnyError> {
|
||||||
let ps = ProcState::build(flags).await?;
|
let ps = ProcState::build(flags).await?;
|
||||||
let permissions =
|
let permissions =
|
||||||
Permissions::from_options(&ps.options.permissions_options());
|
Permissions::from_options(&ps.options.permissions_options())?;
|
||||||
let specifiers_with_mode = fetch_specifiers_with_test_mode(
|
let specifiers_with_mode = fetch_specifiers_with_test_mode(
|
||||||
&ps,
|
&ps,
|
||||||
test_flags.include,
|
test_flags.include,
|
||||||
|
@ -1430,7 +1430,7 @@ pub async fn run_tests_with_watch(
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), AnyError> {
|
||||||
let ps = ProcState::build(flags).await?;
|
let ps = ProcState::build(flags).await?;
|
||||||
let permissions =
|
let permissions =
|
||||||
Permissions::from_options(&ps.options.permissions_options());
|
Permissions::from_options(&ps.options.permissions_options())?;
|
||||||
|
|
||||||
let include = test_flags.include;
|
let include = test_flags.include;
|
||||||
let ignore = test_flags.ignore.clone();
|
let ignore = test_flags.ignore.clone();
|
||||||
|
|
|
@ -215,12 +215,16 @@ impl NetDescriptor {
|
||||||
fn new<T: AsRef<str>>(host: &&(T, Option<u16>)) -> Self {
|
fn new<T: AsRef<str>>(host: &&(T, Option<u16>)) -> Self {
|
||||||
NetDescriptor(host.0.as_ref().to_string(), host.1)
|
NetDescriptor(host.0.as_ref().to_string(), host.1)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn from_string(host: String) -> Self {
|
impl FromStr for NetDescriptor {
|
||||||
let url = url::Url::parse(&format!("http://{}", host)).unwrap();
|
type Err = AnyError;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
let url = url::Url::parse(&format!("http://{s}"))?;
|
||||||
let hostname = url.host_str().unwrap().to_string();
|
let hostname = url.host_str().unwrap().to_string();
|
||||||
|
|
||||||
NetDescriptor(hostname, url.port())
|
Ok(NetDescriptor(hostname, url.port()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1126,12 +1130,12 @@ pub struct Permissions {
|
||||||
impl Default for Permissions {
|
impl Default for Permissions {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
read: Permissions::new_read(&None, false),
|
read: Permissions::new_read(&None, false).unwrap(),
|
||||||
write: Permissions::new_write(&None, false),
|
write: Permissions::new_write(&None, false).unwrap(),
|
||||||
net: Permissions::new_net(&None, false),
|
net: Permissions::new_net(&None, false).unwrap(),
|
||||||
env: Permissions::new_env(&None, false),
|
env: Permissions::new_env(&None, false).unwrap(),
|
||||||
run: Permissions::new_run(&None, false),
|
run: Permissions::new_run(&None, false).unwrap(),
|
||||||
ffi: Permissions::new_ffi(&None, false),
|
ffi: Permissions::new_ffi(&None, false).unwrap(),
|
||||||
hrtime: Permissions::new_hrtime(false),
|
hrtime: Permissions::new_hrtime(false),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1153,90 +1157,106 @@ impl Permissions {
|
||||||
pub fn new_read(
|
pub fn new_read(
|
||||||
state: &Option<Vec<PathBuf>>,
|
state: &Option<Vec<PathBuf>>,
|
||||||
prompt: bool,
|
prompt: bool,
|
||||||
) -> UnaryPermission<ReadDescriptor> {
|
) -> Result<UnaryPermission<ReadDescriptor>, AnyError> {
|
||||||
UnaryPermission::<ReadDescriptor> {
|
Ok(UnaryPermission::<ReadDescriptor> {
|
||||||
global_state: global_state_from_option(state),
|
global_state: global_state_from_option(state),
|
||||||
granted_list: resolve_read_allowlist(state),
|
granted_list: resolve_read_allowlist(state)?,
|
||||||
prompt,
|
prompt,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_write(
|
pub fn new_write(
|
||||||
state: &Option<Vec<PathBuf>>,
|
state: &Option<Vec<PathBuf>>,
|
||||||
prompt: bool,
|
prompt: bool,
|
||||||
) -> UnaryPermission<WriteDescriptor> {
|
) -> Result<UnaryPermission<WriteDescriptor>, AnyError> {
|
||||||
UnaryPermission::<WriteDescriptor> {
|
Ok(UnaryPermission::<WriteDescriptor> {
|
||||||
global_state: global_state_from_option(state),
|
global_state: global_state_from_option(state),
|
||||||
granted_list: resolve_write_allowlist(state),
|
granted_list: resolve_write_allowlist(state)?,
|
||||||
prompt,
|
prompt,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_net(
|
pub fn new_net(
|
||||||
state: &Option<Vec<String>>,
|
state: &Option<Vec<String>>,
|
||||||
prompt: bool,
|
prompt: bool,
|
||||||
) -> UnaryPermission<NetDescriptor> {
|
) -> Result<UnaryPermission<NetDescriptor>, AnyError> {
|
||||||
UnaryPermission::<NetDescriptor> {
|
Ok(UnaryPermission::<NetDescriptor> {
|
||||||
global_state: global_state_from_option(state),
|
global_state: global_state_from_option(state),
|
||||||
granted_list: state
|
granted_list: state.as_ref().map_or_else(
|
||||||
.as_ref()
|
|| Ok(HashSet::new()),
|
||||||
.map(|v| {
|
|v| {
|
||||||
v.iter()
|
v.iter()
|
||||||
.map(|x| NetDescriptor::from_string(x.clone()))
|
.map(|x| NetDescriptor::from_str(x))
|
||||||
.collect()
|
.collect::<Result<HashSet<NetDescriptor>, AnyError>>()
|
||||||
})
|
},
|
||||||
.unwrap_or_else(HashSet::new),
|
)?,
|
||||||
prompt,
|
prompt,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_env(
|
pub fn new_env(
|
||||||
state: &Option<Vec<String>>,
|
state: &Option<Vec<String>>,
|
||||||
prompt: bool,
|
prompt: bool,
|
||||||
) -> UnaryPermission<EnvDescriptor> {
|
) -> Result<UnaryPermission<EnvDescriptor>, AnyError> {
|
||||||
UnaryPermission::<EnvDescriptor> {
|
Ok(UnaryPermission::<EnvDescriptor> {
|
||||||
global_state: global_state_from_option(state),
|
global_state: global_state_from_option(state),
|
||||||
granted_list: state
|
granted_list: state.as_ref().map_or_else(
|
||||||
.as_ref()
|
|| Ok(HashSet::new()),
|
||||||
.map(|v| v.iter().map(EnvDescriptor::new).collect())
|
|v| {
|
||||||
.unwrap_or_else(HashSet::new),
|
v.iter()
|
||||||
|
.map(|x| {
|
||||||
|
if x.is_empty() {
|
||||||
|
Err(AnyError::msg("Empty path is not allowed"))
|
||||||
|
} else {
|
||||||
|
Ok(EnvDescriptor::new(x))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
},
|
||||||
|
)?,
|
||||||
prompt,
|
prompt,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_run(
|
pub fn new_run(
|
||||||
state: &Option<Vec<String>>,
|
state: &Option<Vec<String>>,
|
||||||
prompt: bool,
|
prompt: bool,
|
||||||
) -> UnaryPermission<RunDescriptor> {
|
) -> Result<UnaryPermission<RunDescriptor>, AnyError> {
|
||||||
UnaryPermission::<RunDescriptor> {
|
Ok(UnaryPermission::<RunDescriptor> {
|
||||||
global_state: global_state_from_option(state),
|
global_state: global_state_from_option(state),
|
||||||
granted_list: state
|
granted_list: state.as_ref().map_or_else(
|
||||||
.as_ref()
|
|| Ok(HashSet::new()),
|
||||||
.map(|v| {
|
|v| {
|
||||||
v.iter()
|
v.iter()
|
||||||
.map(|x| RunDescriptor::from_str(x).unwrap())
|
.map(|x| {
|
||||||
|
if x.is_empty() {
|
||||||
|
Err(AnyError::msg("Empty path is not allowed"))
|
||||||
|
} else {
|
||||||
|
Ok(RunDescriptor::from_str(x).unwrap())
|
||||||
|
}
|
||||||
|
})
|
||||||
.collect()
|
.collect()
|
||||||
})
|
},
|
||||||
.unwrap_or_else(HashSet::new),
|
)?,
|
||||||
prompt,
|
prompt,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_ffi(
|
pub fn new_ffi(
|
||||||
state: &Option<Vec<PathBuf>>,
|
state: &Option<Vec<PathBuf>>,
|
||||||
prompt: bool,
|
prompt: bool,
|
||||||
) -> UnaryPermission<FfiDescriptor> {
|
) -> Result<UnaryPermission<FfiDescriptor>, AnyError> {
|
||||||
UnaryPermission::<FfiDescriptor> {
|
Ok(UnaryPermission::<FfiDescriptor> {
|
||||||
global_state: global_state_from_option(state),
|
global_state: global_state_from_option(state),
|
||||||
granted_list: resolve_ffi_allowlist(state),
|
granted_list: resolve_ffi_allowlist(state)?,
|
||||||
prompt,
|
prompt,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_hrtime(state: bool) -> UnitPermission {
|
pub fn new_hrtime(state: bool) -> UnitPermission {
|
||||||
|
@ -1248,26 +1268,26 @@ impl Permissions {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_options(opts: &PermissionsOptions) -> Self {
|
pub fn from_options(opts: &PermissionsOptions) -> Result<Self, AnyError> {
|
||||||
Self {
|
Ok(Self {
|
||||||
read: Permissions::new_read(&opts.allow_read, opts.prompt),
|
read: Permissions::new_read(&opts.allow_read, opts.prompt)?,
|
||||||
write: Permissions::new_write(&opts.allow_write, opts.prompt),
|
write: Permissions::new_write(&opts.allow_write, opts.prompt)?,
|
||||||
net: Permissions::new_net(&opts.allow_net, opts.prompt),
|
net: Permissions::new_net(&opts.allow_net, opts.prompt)?,
|
||||||
env: Permissions::new_env(&opts.allow_env, opts.prompt),
|
env: Permissions::new_env(&opts.allow_env, opts.prompt)?,
|
||||||
run: Permissions::new_run(&opts.allow_run, opts.prompt),
|
run: Permissions::new_run(&opts.allow_run, opts.prompt)?,
|
||||||
ffi: Permissions::new_ffi(&opts.allow_ffi, opts.prompt),
|
ffi: Permissions::new_ffi(&opts.allow_ffi, opts.prompt)?,
|
||||||
hrtime: Permissions::new_hrtime(opts.allow_hrtime),
|
hrtime: Permissions::new_hrtime(opts.allow_hrtime),
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn allow_all() -> Self {
|
pub fn allow_all() -> Self {
|
||||||
Self {
|
Self {
|
||||||
read: Permissions::new_read(&Some(vec![]), false),
|
read: Permissions::new_read(&Some(vec![]), false).unwrap(),
|
||||||
write: Permissions::new_write(&Some(vec![]), false),
|
write: Permissions::new_write(&Some(vec![]), false).unwrap(),
|
||||||
net: Permissions::new_net(&Some(vec![]), false),
|
net: Permissions::new_net(&Some(vec![]), false).unwrap(),
|
||||||
env: Permissions::new_env(&Some(vec![]), false),
|
env: Permissions::new_env(&Some(vec![]), false).unwrap(),
|
||||||
run: Permissions::new_run(&Some(vec![]), false),
|
run: Permissions::new_run(&Some(vec![]), false).unwrap(),
|
||||||
ffi: Permissions::new_ffi(&Some(vec![]), false),
|
ffi: Permissions::new_ffi(&Some(vec![]), false).unwrap(),
|
||||||
hrtime: Permissions::new_hrtime(true),
|
hrtime: Permissions::new_hrtime(true),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1370,43 +1390,55 @@ fn global_state_from_option<T>(flag: &Option<Vec<T>>) -> PermissionState {
|
||||||
|
|
||||||
pub fn resolve_read_allowlist(
|
pub fn resolve_read_allowlist(
|
||||||
allow: &Option<Vec<PathBuf>>,
|
allow: &Option<Vec<PathBuf>>,
|
||||||
) -> HashSet<ReadDescriptor> {
|
) -> Result<HashSet<ReadDescriptor>, AnyError> {
|
||||||
if let Some(v) = allow {
|
if let Some(v) = allow {
|
||||||
v.iter()
|
v.iter()
|
||||||
.map(|raw_path| {
|
.map(|raw_path| {
|
||||||
ReadDescriptor(resolve_from_cwd(Path::new(&raw_path)).unwrap())
|
if raw_path.as_os_str().is_empty() {
|
||||||
|
Err(AnyError::msg("Empty path is not allowed"))
|
||||||
|
} else {
|
||||||
|
resolve_from_cwd(Path::new(&raw_path)).map(ReadDescriptor)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
} else {
|
} else {
|
||||||
HashSet::new()
|
Ok(HashSet::new())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve_write_allowlist(
|
pub fn resolve_write_allowlist(
|
||||||
allow: &Option<Vec<PathBuf>>,
|
allow: &Option<Vec<PathBuf>>,
|
||||||
) -> HashSet<WriteDescriptor> {
|
) -> Result<HashSet<WriteDescriptor>, AnyError> {
|
||||||
if let Some(v) = allow {
|
if let Some(v) = allow {
|
||||||
v.iter()
|
v.iter()
|
||||||
.map(|raw_path| {
|
.map(|raw_path| {
|
||||||
WriteDescriptor(resolve_from_cwd(Path::new(&raw_path)).unwrap())
|
if raw_path.as_os_str().is_empty() {
|
||||||
|
Err(AnyError::msg("Empty path is not allowed"))
|
||||||
|
} else {
|
||||||
|
resolve_from_cwd(Path::new(&raw_path)).map(WriteDescriptor)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
} else {
|
} else {
|
||||||
HashSet::new()
|
Ok(HashSet::new())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve_ffi_allowlist(
|
pub fn resolve_ffi_allowlist(
|
||||||
allow: &Option<Vec<PathBuf>>,
|
allow: &Option<Vec<PathBuf>>,
|
||||||
) -> HashSet<FfiDescriptor> {
|
) -> Result<HashSet<FfiDescriptor>, AnyError> {
|
||||||
if let Some(v) = allow {
|
if let Some(v) = allow {
|
||||||
v.iter()
|
v.iter()
|
||||||
.map(|raw_path| {
|
.map(|raw_path| {
|
||||||
FfiDescriptor(resolve_from_cwd(Path::new(&raw_path)).unwrap())
|
if raw_path.as_os_str().is_empty() {
|
||||||
|
Err(AnyError::msg("Empty path is not allowed"))
|
||||||
|
} else {
|
||||||
|
resolve_from_cwd(Path::new(&raw_path)).map(FfiDescriptor)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
} else {
|
} else {
|
||||||
HashSet::new()
|
Ok(HashSet::new())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1687,7 +1719,7 @@ pub fn create_child_permissions(
|
||||||
ChildUnaryPermissionArg::NotGranted => {}
|
ChildUnaryPermissionArg::NotGranted => {}
|
||||||
ChildUnaryPermissionArg::GrantedList(granted_list) => {
|
ChildUnaryPermissionArg::GrantedList(granted_list) => {
|
||||||
worker_perms.env.granted_list =
|
worker_perms.env.granted_list =
|
||||||
Permissions::new_env(&Some(granted_list), false).granted_list;
|
Permissions::new_env(&Some(granted_list), false)?.granted_list;
|
||||||
if !worker_perms
|
if !worker_perms
|
||||||
.env
|
.env
|
||||||
.granted_list
|
.granted_list
|
||||||
|
@ -1732,7 +1764,7 @@ pub fn create_child_permissions(
|
||||||
ChildUnaryPermissionArg::NotGranted => {}
|
ChildUnaryPermissionArg::NotGranted => {}
|
||||||
ChildUnaryPermissionArg::GrantedList(granted_list) => {
|
ChildUnaryPermissionArg::GrantedList(granted_list) => {
|
||||||
worker_perms.net.granted_list =
|
worker_perms.net.granted_list =
|
||||||
Permissions::new_net(&Some(granted_list), false).granted_list;
|
Permissions::new_net(&Some(granted_list), false)?.granted_list;
|
||||||
if !worker_perms
|
if !worker_perms
|
||||||
.net
|
.net
|
||||||
.granted_list
|
.granted_list
|
||||||
|
@ -1763,7 +1795,7 @@ pub fn create_child_permissions(
|
||||||
worker_perms.ffi.granted_list = Permissions::new_ffi(
|
worker_perms.ffi.granted_list = Permissions::new_ffi(
|
||||||
&Some(granted_list.iter().map(PathBuf::from).collect()),
|
&Some(granted_list.iter().map(PathBuf::from).collect()),
|
||||||
false,
|
false,
|
||||||
)
|
)?
|
||||||
.granted_list;
|
.granted_list;
|
||||||
if !worker_perms
|
if !worker_perms
|
||||||
.ffi
|
.ffi
|
||||||
|
@ -1795,7 +1827,7 @@ pub fn create_child_permissions(
|
||||||
worker_perms.read.granted_list = Permissions::new_read(
|
worker_perms.read.granted_list = Permissions::new_read(
|
||||||
&Some(granted_list.iter().map(PathBuf::from).collect()),
|
&Some(granted_list.iter().map(PathBuf::from).collect()),
|
||||||
false,
|
false,
|
||||||
)
|
)?
|
||||||
.granted_list;
|
.granted_list;
|
||||||
if !worker_perms
|
if !worker_perms
|
||||||
.read
|
.read
|
||||||
|
@ -1825,7 +1857,7 @@ pub fn create_child_permissions(
|
||||||
ChildUnaryPermissionArg::NotGranted => {}
|
ChildUnaryPermissionArg::NotGranted => {}
|
||||||
ChildUnaryPermissionArg::GrantedList(granted_list) => {
|
ChildUnaryPermissionArg::GrantedList(granted_list) => {
|
||||||
worker_perms.run.granted_list =
|
worker_perms.run.granted_list =
|
||||||
Permissions::new_run(&Some(granted_list), false).granted_list;
|
Permissions::new_run(&Some(granted_list), false)?.granted_list;
|
||||||
if !worker_perms
|
if !worker_perms
|
||||||
.run
|
.run
|
||||||
.granted_list
|
.granted_list
|
||||||
|
@ -1856,7 +1888,7 @@ pub fn create_child_permissions(
|
||||||
worker_perms.write.granted_list = Permissions::new_write(
|
worker_perms.write.granted_list = Permissions::new_write(
|
||||||
&Some(granted_list.iter().map(PathBuf::from).collect()),
|
&Some(granted_list.iter().map(PathBuf::from).collect()),
|
||||||
false,
|
false,
|
||||||
)
|
)?
|
||||||
.granted_list;
|
.granted_list;
|
||||||
if !worker_perms
|
if !worker_perms
|
||||||
.write
|
.write
|
||||||
|
@ -2080,7 +2112,8 @@ mod tests {
|
||||||
allow_read: Some(allowlist.clone()),
|
allow_read: Some(allowlist.clone()),
|
||||||
allow_write: Some(allowlist),
|
allow_write: Some(allowlist),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
// Inside of /a/specific and /a/specific/dir/name
|
// Inside of /a/specific and /a/specific/dir/name
|
||||||
assert!(perms.read.check(Path::new("/a/specific/dir/name")).is_ok());
|
assert!(perms.read.check(Path::new("/a/specific/dir/name")).is_ok());
|
||||||
|
@ -2146,7 +2179,8 @@ mod tests {
|
||||||
"www.github.com:443"
|
"www.github.com:443"
|
||||||
]),
|
]),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let domain_tests = vec![
|
let domain_tests = vec![
|
||||||
("localhost", 1234, true),
|
("localhost", 1234, true),
|
||||||
|
@ -2181,7 +2215,8 @@ mod tests {
|
||||||
let mut perms = Permissions::from_options(&PermissionsOptions {
|
let mut perms = Permissions::from_options(&PermissionsOptions {
|
||||||
allow_net: Some(svec![]), // this means `--allow-net` is present without values following `=` sign
|
allow_net: Some(svec![]), // this means `--allow-net` is present without values following `=` sign
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let domain_tests = vec![
|
let domain_tests = vec![
|
||||||
("localhost", 1234),
|
("localhost", 1234),
|
||||||
|
@ -2215,7 +2250,8 @@ mod tests {
|
||||||
let mut perms = Permissions::from_options(&PermissionsOptions {
|
let mut perms = Permissions::from_options(&PermissionsOptions {
|
||||||
allow_net: None,
|
allow_net: None,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let domain_tests = vec![
|
let domain_tests = vec![
|
||||||
("localhost", 1234),
|
("localhost", 1234),
|
||||||
|
@ -2256,7 +2292,8 @@ mod tests {
|
||||||
"www.github.com:443"
|
"www.github.com:443"
|
||||||
]),
|
]),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let url_tests = vec![
|
let url_tests = vec![
|
||||||
// Any protocol + port for localhost should be ok, since we don't specify
|
// Any protocol + port for localhost should be ok, since we don't specify
|
||||||
|
@ -2314,7 +2351,8 @@ mod tests {
|
||||||
allow_read: Some(read_allowlist),
|
allow_read: Some(read_allowlist),
|
||||||
allow_net: Some(svec!["localhost"]),
|
allow_net: Some(svec!["localhost"]),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let mut fixtures = vec![
|
let mut fixtures = vec![
|
||||||
(
|
(
|
||||||
|
@ -2373,26 +2411,29 @@ mod tests {
|
||||||
read: UnaryPermission {
|
read: UnaryPermission {
|
||||||
global_state: PermissionState::Prompt,
|
global_state: PermissionState::Prompt,
|
||||||
..Permissions::new_read(&Some(vec![PathBuf::from("/foo")]), false)
|
..Permissions::new_read(&Some(vec![PathBuf::from("/foo")]), false)
|
||||||
|
.unwrap()
|
||||||
},
|
},
|
||||||
write: UnaryPermission {
|
write: UnaryPermission {
|
||||||
global_state: PermissionState::Prompt,
|
global_state: PermissionState::Prompt,
|
||||||
..Permissions::new_write(&Some(vec![PathBuf::from("/foo")]), false)
|
..Permissions::new_write(&Some(vec![PathBuf::from("/foo")]), false)
|
||||||
|
.unwrap()
|
||||||
},
|
},
|
||||||
net: UnaryPermission {
|
net: UnaryPermission {
|
||||||
global_state: PermissionState::Prompt,
|
global_state: PermissionState::Prompt,
|
||||||
..Permissions::new_net(&Some(svec!["127.0.0.1:8000"]), false)
|
..Permissions::new_net(&Some(svec!["127.0.0.1:8000"]), false).unwrap()
|
||||||
},
|
},
|
||||||
env: UnaryPermission {
|
env: UnaryPermission {
|
||||||
global_state: PermissionState::Prompt,
|
global_state: PermissionState::Prompt,
|
||||||
..Permissions::new_env(&Some(svec!["HOME"]), false)
|
..Permissions::new_env(&Some(svec!["HOME"]), false).unwrap()
|
||||||
},
|
},
|
||||||
run: UnaryPermission {
|
run: UnaryPermission {
|
||||||
global_state: PermissionState::Prompt,
|
global_state: PermissionState::Prompt,
|
||||||
..Permissions::new_run(&Some(svec!["deno"]), false)
|
..Permissions::new_run(&Some(svec!["deno"]), false).unwrap()
|
||||||
},
|
},
|
||||||
ffi: UnaryPermission {
|
ffi: UnaryPermission {
|
||||||
global_state: PermissionState::Prompt,
|
global_state: PermissionState::Prompt,
|
||||||
..Permissions::new_ffi(&Some(vec![PathBuf::from("deno")]), false)
|
..Permissions::new_ffi(&Some(vec![PathBuf::from("deno")]), false)
|
||||||
|
.unwrap()
|
||||||
},
|
},
|
||||||
hrtime: UnitPermission {
|
hrtime: UnitPermission {
|
||||||
state: PermissionState::Prompt,
|
state: PermissionState::Prompt,
|
||||||
|
@ -2483,6 +2524,7 @@ mod tests {
|
||||||
&Some(vec![PathBuf::from("/foo"), PathBuf::from("/foo/baz")]),
|
&Some(vec![PathBuf::from("/foo"), PathBuf::from("/foo/baz")]),
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
|
.unwrap()
|
||||||
},
|
},
|
||||||
write: UnaryPermission {
|
write: UnaryPermission {
|
||||||
global_state: PermissionState::Prompt,
|
global_state: PermissionState::Prompt,
|
||||||
|
@ -2490,6 +2532,7 @@ mod tests {
|
||||||
&Some(vec![PathBuf::from("/foo"), PathBuf::from("/foo/baz")]),
|
&Some(vec![PathBuf::from("/foo"), PathBuf::from("/foo/baz")]),
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
|
.unwrap()
|
||||||
},
|
},
|
||||||
net: UnaryPermission {
|
net: UnaryPermission {
|
||||||
global_state: PermissionState::Prompt,
|
global_state: PermissionState::Prompt,
|
||||||
|
@ -2497,18 +2540,20 @@ mod tests {
|
||||||
&Some(svec!["127.0.0.1", "127.0.0.1:8000"]),
|
&Some(svec!["127.0.0.1", "127.0.0.1:8000"]),
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
|
.unwrap()
|
||||||
},
|
},
|
||||||
env: UnaryPermission {
|
env: UnaryPermission {
|
||||||
global_state: PermissionState::Prompt,
|
global_state: PermissionState::Prompt,
|
||||||
..Permissions::new_env(&Some(svec!["HOME"]), false)
|
..Permissions::new_env(&Some(svec!["HOME"]), false).unwrap()
|
||||||
},
|
},
|
||||||
run: UnaryPermission {
|
run: UnaryPermission {
|
||||||
global_state: PermissionState::Prompt,
|
global_state: PermissionState::Prompt,
|
||||||
..Permissions::new_run(&Some(svec!["deno"]), false)
|
..Permissions::new_run(&Some(svec!["deno"]), false).unwrap()
|
||||||
},
|
},
|
||||||
ffi: UnaryPermission {
|
ffi: UnaryPermission {
|
||||||
global_state: PermissionState::Prompt,
|
global_state: PermissionState::Prompt,
|
||||||
..Permissions::new_ffi(&Some(vec![PathBuf::from("deno")]), false)
|
..Permissions::new_ffi(&Some(vec![PathBuf::from("deno")]), false)
|
||||||
|
.unwrap()
|
||||||
},
|
},
|
||||||
hrtime: UnitPermission {
|
hrtime: UnitPermission {
|
||||||
state: PermissionState::Denied,
|
state: PermissionState::Denied,
|
||||||
|
@ -2536,12 +2581,12 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_check() {
|
fn test_check() {
|
||||||
let mut perms = Permissions {
|
let mut perms = Permissions {
|
||||||
read: Permissions::new_read(&None, true),
|
read: Permissions::new_read(&None, true).unwrap(),
|
||||||
write: Permissions::new_write(&None, true),
|
write: Permissions::new_write(&None, true).unwrap(),
|
||||||
net: Permissions::new_net(&None, true),
|
net: Permissions::new_net(&None, true).unwrap(),
|
||||||
env: Permissions::new_env(&None, true),
|
env: Permissions::new_env(&None, true).unwrap(),
|
||||||
run: Permissions::new_run(&None, true),
|
run: Permissions::new_run(&None, true).unwrap(),
|
||||||
ffi: Permissions::new_ffi(&None, true),
|
ffi: Permissions::new_ffi(&None, true).unwrap(),
|
||||||
hrtime: Permissions::new_hrtime(false),
|
hrtime: Permissions::new_hrtime(false),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2586,12 +2631,12 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_check_fail() {
|
fn test_check_fail() {
|
||||||
let mut perms = Permissions {
|
let mut perms = Permissions {
|
||||||
read: Permissions::new_read(&None, true),
|
read: Permissions::new_read(&None, true).unwrap(),
|
||||||
write: Permissions::new_write(&None, true),
|
write: Permissions::new_write(&None, true).unwrap(),
|
||||||
net: Permissions::new_net(&None, true),
|
net: Permissions::new_net(&None, true).unwrap(),
|
||||||
env: Permissions::new_env(&None, true),
|
env: Permissions::new_env(&None, true).unwrap(),
|
||||||
run: Permissions::new_run(&None, true),
|
run: Permissions::new_run(&None, true).unwrap(),
|
||||||
ffi: Permissions::new_ffi(&None, true),
|
ffi: Permissions::new_ffi(&None, true).unwrap(),
|
||||||
hrtime: Permissions::new_hrtime(false),
|
hrtime: Permissions::new_hrtime(false),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2652,7 +2697,7 @@ mod tests {
|
||||||
let mut perms = Permissions::allow_all();
|
let mut perms = Permissions::allow_all();
|
||||||
perms.env = UnaryPermission {
|
perms.env = UnaryPermission {
|
||||||
global_state: PermissionState::Prompt,
|
global_state: PermissionState::Prompt,
|
||||||
..Permissions::new_env(&Some(svec!["HOME"]), false)
|
..Permissions::new_env(&Some(svec!["HOME"]), false).unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
prompt_value.set(true);
|
prompt_value.set(true);
|
||||||
|
@ -2810,9 +2855,9 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_create_child_permissions() {
|
fn test_create_child_permissions() {
|
||||||
let mut main_perms = Permissions {
|
let mut main_perms = Permissions {
|
||||||
env: Permissions::new_env(&Some(vec![]), false),
|
env: Permissions::new_env(&Some(vec![]), false).unwrap(),
|
||||||
hrtime: Permissions::new_hrtime(true),
|
hrtime: Permissions::new_hrtime(true),
|
||||||
net: Permissions::new_net(&Some(svec!["foo", "bar"]), false),
|
net: Permissions::new_net(&Some(svec!["foo", "bar"]), false).unwrap(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -2828,8 +2873,8 @@ mod tests {
|
||||||
)
|
)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
Permissions {
|
Permissions {
|
||||||
env: Permissions::new_env(&Some(vec![]), false),
|
env: Permissions::new_env(&Some(vec![]), false).unwrap(),
|
||||||
net: Permissions::new_net(&Some(svec!["foo"]), false),
|
net: Permissions::new_net(&Some(svec!["foo"]), false).unwrap(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -2865,7 +2910,8 @@ mod tests {
|
||||||
let mut main_perms = Permissions::from_options(&PermissionsOptions {
|
let mut main_perms = Permissions::from_options(&PermissionsOptions {
|
||||||
prompt: true,
|
prompt: true,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
})
|
||||||
|
.unwrap();
|
||||||
prompt_value.set(true);
|
prompt_value.set(true);
|
||||||
let worker_perms = create_child_permissions(
|
let worker_perms = create_child_permissions(
|
||||||
&mut main_perms,
|
&mut main_perms,
|
||||||
|
@ -2885,7 +2931,8 @@ mod tests {
|
||||||
let mut main_perms = Permissions::from_options(&PermissionsOptions {
|
let mut main_perms = Permissions::from_options(&PermissionsOptions {
|
||||||
prompt: true,
|
prompt: true,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
})
|
||||||
|
.unwrap();
|
||||||
prompt_value.set(false);
|
prompt_value.set(false);
|
||||||
assert!(main_perms.write.check(&PathBuf::from("foo")).is_err());
|
assert!(main_perms.write.check(&PathBuf::from("foo")).is_err());
|
||||||
let worker_perms = create_child_permissions(
|
let worker_perms = create_child_permissions(
|
||||||
|
@ -2895,4 +2942,14 @@ mod tests {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(worker_perms.write.denied_list, main_perms.write.denied_list);
|
assert_eq!(worker_perms.write.denied_list, main_perms.write.denied_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_handle_empty_value() {
|
||||||
|
assert!(Permissions::new_read(&Some(vec![PathBuf::new()]), false).is_err());
|
||||||
|
assert!(Permissions::new_env(&Some(vec![String::new()]), false).is_err());
|
||||||
|
assert!(Permissions::new_run(&Some(vec![String::new()]), false).is_err());
|
||||||
|
assert!(Permissions::new_ffi(&Some(vec![PathBuf::new()]), false).is_err());
|
||||||
|
assert!(Permissions::new_net(&Some(svec![String::new()]), false).is_err());
|
||||||
|
assert!(Permissions::new_write(&Some(vec![PathBuf::new()]), false).is_err());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue