mirror of
https://github.com/denoland/deno.git
synced 2025-09-26 20:29:11 +00:00
feat(unstable): --allow-net subdomain wildcards (#29327)
This commit is contained in:
parent
cb23193f74
commit
ab9673dcc1
15 changed files with 377 additions and 54 deletions
|
@ -6121,6 +6121,8 @@ fn unstable_args_parse(
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(bartlomieju): this should be factored out since these are configured via UNSTABLE_FEATURES
|
// TODO(bartlomieju): this should be factored out since these are configured via UNSTABLE_FEATURES
|
||||||
|
flags.unstable_config.subdomain_wildcards =
|
||||||
|
matches.get_flag("unstable-subdomain-wildcards");
|
||||||
flags.unstable_config.bare_node_builtins =
|
flags.unstable_config.bare_node_builtins =
|
||||||
matches.get_flag("unstable-bare-node-builtins");
|
matches.get_flag("unstable-bare-node-builtins");
|
||||||
flags.unstable_config.detect_cjs = matches.get_flag("unstable-detect-cjs");
|
flags.unstable_config.detect_cjs = matches.get_flag("unstable-detect-cjs");
|
||||||
|
|
|
@ -5,6 +5,7 @@ use std::str::FromStr;
|
||||||
|
|
||||||
use deno_core::url::Url;
|
use deno_core::url::Url;
|
||||||
use deno_runtime::deno_permissions::NetDescriptor;
|
use deno_runtime::deno_permissions::NetDescriptor;
|
||||||
|
use deno_runtime::deno_permissions::UnstableSubdomainWildcards;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct ParsePortError(String);
|
pub struct ParsePortError(String);
|
||||||
|
@ -32,7 +33,11 @@ pub fn validator(host_and_port: &str) -> Result<String, String> {
|
||||||
if Url::parse(&format!("internal://{host_and_port}")).is_ok()
|
if Url::parse(&format!("internal://{host_and_port}")).is_ok()
|
||||||
|| host_and_port.parse::<IpAddr>().is_ok()
|
|| host_and_port.parse::<IpAddr>().is_ok()
|
||||||
|| host_and_port.parse::<BarePort>().is_ok()
|
|| host_and_port.parse::<BarePort>().is_ok()
|
||||||
|| NetDescriptor::parse(host_and_port).is_ok()
|
|| NetDescriptor::parse_for_list(
|
||||||
|
host_and_port,
|
||||||
|
UnstableSubdomainWildcards::Enabled,
|
||||||
|
)
|
||||||
|
.is_ok()
|
||||||
{
|
{
|
||||||
Ok(host_and_port.to_string())
|
Ok(host_and_port.to_string())
|
||||||
} else {
|
} else {
|
||||||
|
@ -52,7 +57,11 @@ pub fn parse(paths: Vec<String>) -> clap::error::Result<Vec<String>> {
|
||||||
out.push(format!("{}:{}", host, port.0));
|
out.push(format!("{}:{}", host, port.0));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
NetDescriptor::parse(&host_and_port).map_err(|e| {
|
NetDescriptor::parse_for_list(
|
||||||
|
&host_and_port,
|
||||||
|
UnstableSubdomainWildcards::Enabled,
|
||||||
|
)
|
||||||
|
.map_err(|e| {
|
||||||
clap::Error::raw(clap::error::ErrorKind::InvalidValue, e.to_string())
|
clap::Error::raw(clap::error::ErrorKind::InvalidValue, e.to_string())
|
||||||
})?;
|
})?;
|
||||||
out.push(host_and_port)
|
out.push(host_and_port)
|
||||||
|
@ -120,6 +129,7 @@ mod tests {
|
||||||
let entries = svec![
|
let entries = svec![
|
||||||
"deno.land",
|
"deno.land",
|
||||||
"deno.land:80",
|
"deno.land:80",
|
||||||
|
"*.deno.land",
|
||||||
"[::]",
|
"[::]",
|
||||||
"[::1]",
|
"[::1]",
|
||||||
"127.0.0.1",
|
"127.0.0.1",
|
||||||
|
@ -141,6 +151,7 @@ mod tests {
|
||||||
let expected = svec![
|
let expected = svec![
|
||||||
"deno.land",
|
"deno.land",
|
||||||
"deno.land:80",
|
"deno.land:80",
|
||||||
|
"*.deno.land",
|
||||||
"[::]",
|
"[::]",
|
||||||
"[::1]",
|
"[::1]",
|
||||||
"127.0.0.1",
|
"127.0.0.1",
|
||||||
|
|
|
@ -993,6 +993,11 @@ impl CliOptions {
|
||||||
&self.flags.unsafely_ignore_certificate_errors
|
&self.flags.unsafely_ignore_certificate_errors
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn unstable_subdomain_wildcards(&self) -> bool {
|
||||||
|
self.flags.unstable_config.subdomain_wildcards
|
||||||
|
|| self.workspace().has_unstable("subdomain-wildcards")
|
||||||
|
}
|
||||||
|
|
||||||
pub fn unstable_bare_node_builtins(&self) -> bool {
|
pub fn unstable_bare_node_builtins(&self) -> bool {
|
||||||
self.flags.unstable_config.bare_node_builtins
|
self.flags.unstable_config.bare_node_builtins
|
||||||
|| self.workspace().has_unstable("bare-node-builtins")
|
|| self.workspace().has_unstable("bare-node-builtins")
|
||||||
|
|
|
@ -45,6 +45,7 @@ use deno_runtime::deno_fs;
|
||||||
use deno_runtime::deno_fs::RealFs;
|
use deno_runtime::deno_fs::RealFs;
|
||||||
use deno_runtime::deno_permissions::Permissions;
|
use deno_runtime::deno_permissions::Permissions;
|
||||||
use deno_runtime::deno_permissions::PermissionsContainer;
|
use deno_runtime::deno_permissions::PermissionsContainer;
|
||||||
|
use deno_runtime::deno_permissions::UnstableSubdomainWildcards;
|
||||||
use deno_runtime::deno_tls::rustls::RootCertStore;
|
use deno_runtime::deno_tls::rustls::RootCertStore;
|
||||||
use deno_runtime::deno_tls::RootCertStoreProvider;
|
use deno_runtime::deno_tls::RootCertStoreProvider;
|
||||||
use deno_runtime::deno_web::BlobStore;
|
use deno_runtime::deno_web::BlobStore;
|
||||||
|
@ -930,7 +931,14 @@ impl CliFactory {
|
||||||
&self,
|
&self,
|
||||||
) -> Result<&Arc<RuntimePermissionDescriptorParser<CliSys>>, AnyError> {
|
) -> Result<&Arc<RuntimePermissionDescriptorParser<CliSys>>, AnyError> {
|
||||||
self.services.permission_desc_parser.get_or_try_init(|| {
|
self.services.permission_desc_parser.get_or_try_init(|| {
|
||||||
Ok(Arc::new(RuntimePermissionDescriptorParser::new(self.sys())))
|
Ok(Arc::new(RuntimePermissionDescriptorParser::new(
|
||||||
|
self.sys(),
|
||||||
|
if self.cli_options()?.unstable_subdomain_wildcards() {
|
||||||
|
UnstableSubdomainWildcards::Enabled
|
||||||
|
} else {
|
||||||
|
UnstableSubdomainWildcards::Disabled
|
||||||
|
},
|
||||||
|
)))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -190,6 +190,7 @@ pub fn resolve_npm_resolution_snapshot(
|
||||||
pub struct UnstableConfig {
|
pub struct UnstableConfig {
|
||||||
// TODO(bartlomieju): remove in Deno 2.5
|
// TODO(bartlomieju): remove in Deno 2.5
|
||||||
pub legacy_flag_enabled: bool, // --unstable
|
pub legacy_flag_enabled: bool, // --unstable
|
||||||
|
pub subdomain_wildcards: bool,
|
||||||
pub bare_node_builtins: bool,
|
pub bare_node_builtins: bool,
|
||||||
pub detect_cjs: bool,
|
pub detect_cjs: bool,
|
||||||
pub lazy_dynamic_imports: bool,
|
pub lazy_dynamic_imports: bool,
|
||||||
|
@ -206,6 +207,10 @@ impl UnstableConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
maybe_set(
|
||||||
|
&mut self.subdomain_wildcards,
|
||||||
|
UNSTABLE_ENV_VAR_NAMES.subdomain_wildcards,
|
||||||
|
);
|
||||||
maybe_set(
|
maybe_set(
|
||||||
&mut self.bare_node_builtins,
|
&mut self.bare_node_builtins,
|
||||||
UNSTABLE_ENV_VAR_NAMES.bare_node_builtins,
|
UNSTABLE_ENV_VAR_NAMES.bare_node_builtins,
|
||||||
|
|
|
@ -66,6 +66,7 @@ use deno_runtime::deno_node::create_host_defined_options;
|
||||||
use deno_runtime::deno_node::NodeRequireLoader;
|
use deno_runtime::deno_node::NodeRequireLoader;
|
||||||
use deno_runtime::deno_permissions::Permissions;
|
use deno_runtime::deno_permissions::Permissions;
|
||||||
use deno_runtime::deno_permissions::PermissionsContainer;
|
use deno_runtime::deno_permissions::PermissionsContainer;
|
||||||
|
use deno_runtime::deno_permissions::UnstableSubdomainWildcards;
|
||||||
use deno_runtime::deno_tls::rustls::RootCertStore;
|
use deno_runtime::deno_tls::rustls::RootCertStore;
|
||||||
use deno_runtime::deno_tls::RootCertStoreProvider;
|
use deno_runtime::deno_tls::RootCertStoreProvider;
|
||||||
use deno_runtime::deno_web::BlobStore;
|
use deno_runtime::deno_web::BlobStore;
|
||||||
|
@ -924,8 +925,14 @@ pub async fn run(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let desc_parser =
|
let desc_parser = Arc::new(RuntimePermissionDescriptorParser::new(
|
||||||
Arc::new(RuntimePermissionDescriptorParser::new(sys.clone()));
|
sys.clone(),
|
||||||
|
if metadata.unstable_config.subdomain_wildcards {
|
||||||
|
UnstableSubdomainWildcards::Enabled
|
||||||
|
} else {
|
||||||
|
UnstableSubdomainWildcards::Disabled
|
||||||
|
},
|
||||||
|
));
|
||||||
let permissions =
|
let permissions =
|
||||||
Permissions::from_options(desc_parser.as_ref(), &permissions)?;
|
Permissions::from_options(desc_parser.as_ref(), &permissions)?;
|
||||||
PermissionsContainer::new(desc_parser, permissions)
|
PermissionsContainer::new(desc_parser, permissions)
|
||||||
|
|
|
@ -709,6 +709,7 @@ impl<'a> DenoCompileBinaryWriter<'a> {
|
||||||
node_modules,
|
node_modules,
|
||||||
unstable_config: UnstableConfig {
|
unstable_config: UnstableConfig {
|
||||||
legacy_flag_enabled: false,
|
legacy_flag_enabled: false,
|
||||||
|
subdomain_wildcards: self.cli_options.unstable_subdomain_wildcards(),
|
||||||
bare_node_builtins: self.cli_options.unstable_bare_node_builtins(),
|
bare_node_builtins: self.cli_options.unstable_bare_node_builtins(),
|
||||||
detect_cjs: self.cli_options.unstable_detect_cjs(),
|
detect_cjs: self.cli_options.unstable_detect_cjs(),
|
||||||
features: self.cli_options.unstable_features(),
|
features: self.cli_options.unstable_features(),
|
||||||
|
|
|
@ -492,6 +492,7 @@ mod tests {
|
||||||
use deno_resolver::npm::DenoInNpmPackageChecker;
|
use deno_resolver::npm::DenoInNpmPackageChecker;
|
||||||
use deno_runtime::deno_fs::RealFs;
|
use deno_runtime::deno_fs::RealFs;
|
||||||
use deno_runtime::deno_permissions::Permissions;
|
use deno_runtime::deno_permissions::Permissions;
|
||||||
|
use deno_runtime::deno_permissions::UnstableSubdomainWildcards;
|
||||||
use deno_runtime::permissions::RuntimePermissionDescriptorParser;
|
use deno_runtime::permissions::RuntimePermissionDescriptorParser;
|
||||||
use deno_runtime::worker::WorkerOptions;
|
use deno_runtime::worker::WorkerOptions;
|
||||||
use deno_runtime::worker::WorkerServiceOptions;
|
use deno_runtime::worker::WorkerServiceOptions;
|
||||||
|
@ -502,9 +503,11 @@ mod tests {
|
||||||
let main_module =
|
let main_module =
|
||||||
resolve_path("./hello.js", &std::env::current_dir().unwrap()).unwrap();
|
resolve_path("./hello.js", &std::env::current_dir().unwrap()).unwrap();
|
||||||
let fs = Arc::new(RealFs);
|
let fs = Arc::new(RealFs);
|
||||||
let permission_desc_parser = Arc::new(
|
let permission_desc_parser =
|
||||||
RuntimePermissionDescriptorParser::new(crate::sys::CliSys::default()),
|
Arc::new(RuntimePermissionDescriptorParser::new(
|
||||||
);
|
crate::sys::CliSys::default(),
|
||||||
|
UnstableSubdomainWildcards::Enabled,
|
||||||
|
));
|
||||||
let options = WorkerOptions {
|
let options = WorkerOptions {
|
||||||
startup_snapshot: deno_snapshots::CLI_SNAPSHOT,
|
startup_snapshot: deno_snapshots::CLI_SNAPSHOT,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
|
|
@ -12,6 +12,7 @@ use deno_core::op2;
|
||||||
use deno_core::FsModuleLoader;
|
use deno_core::FsModuleLoader;
|
||||||
use deno_core::ModuleSpecifier;
|
use deno_core::ModuleSpecifier;
|
||||||
use deno_fs::RealFs;
|
use deno_fs::RealFs;
|
||||||
|
use deno_permissions::UnstableSubdomainWildcards;
|
||||||
use deno_resolver::npm::DenoInNpmPackageChecker;
|
use deno_resolver::npm::DenoInNpmPackageChecker;
|
||||||
use deno_resolver::npm::NpmResolver;
|
use deno_resolver::npm::NpmResolver;
|
||||||
use deno_runtime::deno_permissions::PermissionsContainer;
|
use deno_runtime::deno_permissions::PermissionsContainer;
|
||||||
|
@ -39,9 +40,11 @@ async fn main() -> Result<(), AnyError> {
|
||||||
let main_module = ModuleSpecifier::from_file_path(js_path).unwrap();
|
let main_module = ModuleSpecifier::from_file_path(js_path).unwrap();
|
||||||
eprintln!("Running {main_module}...");
|
eprintln!("Running {main_module}...");
|
||||||
let fs = Arc::new(RealFs);
|
let fs = Arc::new(RealFs);
|
||||||
let permission_desc_parser = Arc::new(
|
let permission_desc_parser =
|
||||||
RuntimePermissionDescriptorParser::new(sys_traits::impls::RealSys),
|
Arc::new(RuntimePermissionDescriptorParser::new(
|
||||||
);
|
sys_traits::impls::RealSys,
|
||||||
|
UnstableSubdomainWildcards::Enabled,
|
||||||
|
));
|
||||||
let mut worker = MainWorker::bootstrap_from_options(
|
let mut worker = MainWorker::bootstrap_from_options(
|
||||||
&main_module,
|
&main_module,
|
||||||
WorkerServiceOptions::<
|
WorkerServiceOptions::<
|
||||||
|
|
|
@ -168,6 +168,14 @@ pub static FEATURE_DESCRIPTIONS: &[UnstableFeatureDescription] = &[
|
||||||
config_option: ConfigFileOption::SameAsFlagName,
|
config_option: ConfigFileOption::SameAsFlagName,
|
||||||
env_var: Some("DENO_UNSTABLE_SLOPPY_IMPORTS"),
|
env_var: Some("DENO_UNSTABLE_SLOPPY_IMPORTS"),
|
||||||
},
|
},
|
||||||
|
UnstableFeatureDescription {
|
||||||
|
name: "subdomain-wildcards",
|
||||||
|
help_text: "Enable subdomain wildcards support for the `--allow-net` flag",
|
||||||
|
show_in_help: true,
|
||||||
|
kind: UnstableFeatureKind::Cli,
|
||||||
|
config_option: ConfigFileOption::SameAsFlagName,
|
||||||
|
env_var: Some("DENO_UNSTABLE_SUBDOMAIN_WILDCARDS"),
|
||||||
|
},
|
||||||
UnstableFeatureDescription {
|
UnstableFeatureDescription {
|
||||||
name: "temporal",
|
name: "temporal",
|
||||||
help_text: "Enable unstable Temporal API",
|
help_text: "Enable unstable Temporal API",
|
||||||
|
|
|
@ -18,9 +18,9 @@ export const unstableIds = {
|
||||||
nodeGlobals: 13,
|
nodeGlobals: 13,
|
||||||
otel: 15,
|
otel: 15,
|
||||||
process: 16,
|
process: 16,
|
||||||
temporal: 18,
|
temporal: 19,
|
||||||
unsafeProto: 19,
|
unsafeProto: 20,
|
||||||
vsock: 20,
|
vsock: 21,
|
||||||
webgpu: 21,
|
webgpu: 22,
|
||||||
workerOptions: 22,
|
workerOptions: 23,
|
||||||
};
|
};
|
||||||
|
|
|
@ -168,12 +168,21 @@ pub static UNSTABLE_FEATURES: &[UnstableFeatureDefinition] = &[ UnstableFeature
|
||||||
kind: UnstableFeatureKind::Cli,
|
kind: UnstableFeatureKind::Cli,
|
||||||
config_file_option: "sloppy-imports",
|
config_file_option: "sloppy-imports",
|
||||||
},
|
},
|
||||||
|
UnstableFeatureDefinition {
|
||||||
|
name: "subdomain-wildcards",
|
||||||
|
flag_name: "unstable-subdomain-wildcards",
|
||||||
|
help_text: "Enable subdomain wildcards support for the `--allow-net` flag",
|
||||||
|
show_in_help: true,
|
||||||
|
id: 18,
|
||||||
|
kind: UnstableFeatureKind::Cli,
|
||||||
|
config_file_option: "subdomain-wildcards",
|
||||||
|
},
|
||||||
UnstableFeatureDefinition {
|
UnstableFeatureDefinition {
|
||||||
name: "temporal",
|
name: "temporal",
|
||||||
flag_name: "unstable-temporal",
|
flag_name: "unstable-temporal",
|
||||||
help_text: "Enable unstable Temporal API",
|
help_text: "Enable unstable Temporal API",
|
||||||
show_in_help: true,
|
show_in_help: true,
|
||||||
id: 18,
|
id: 19,
|
||||||
kind: UnstableFeatureKind::Runtime,
|
kind: UnstableFeatureKind::Runtime,
|
||||||
config_file_option: "temporal",
|
config_file_option: "temporal",
|
||||||
},
|
},
|
||||||
|
@ -182,7 +191,7 @@ pub static UNSTABLE_FEATURES: &[UnstableFeatureDefinition] = &[ UnstableFeature
|
||||||
flag_name: "unstable-unsafe-proto",
|
flag_name: "unstable-unsafe-proto",
|
||||||
help_text: "Enable unsafe __proto__ support. This is a security risk.",
|
help_text: "Enable unsafe __proto__ support. This is a security risk.",
|
||||||
show_in_help: true,
|
show_in_help: true,
|
||||||
id: 19,
|
id: 20,
|
||||||
kind: UnstableFeatureKind::Runtime,
|
kind: UnstableFeatureKind::Runtime,
|
||||||
config_file_option: "unsafe-proto",
|
config_file_option: "unsafe-proto",
|
||||||
},
|
},
|
||||||
|
@ -191,7 +200,7 @@ pub static UNSTABLE_FEATURES: &[UnstableFeatureDefinition] = &[ UnstableFeature
|
||||||
flag_name: "unstable-vsock",
|
flag_name: "unstable-vsock",
|
||||||
help_text: "Enable unstable VSOCK APIs",
|
help_text: "Enable unstable VSOCK APIs",
|
||||||
show_in_help: false,
|
show_in_help: false,
|
||||||
id: 20,
|
id: 21,
|
||||||
kind: UnstableFeatureKind::Runtime,
|
kind: UnstableFeatureKind::Runtime,
|
||||||
config_file_option: "vsock",
|
config_file_option: "vsock",
|
||||||
},
|
},
|
||||||
|
@ -200,7 +209,7 @@ pub static UNSTABLE_FEATURES: &[UnstableFeatureDefinition] = &[ UnstableFeature
|
||||||
flag_name: "unstable-webgpu",
|
flag_name: "unstable-webgpu",
|
||||||
help_text: "Enable unstable WebGPU APIs",
|
help_text: "Enable unstable WebGPU APIs",
|
||||||
show_in_help: true,
|
show_in_help: true,
|
||||||
id: 21,
|
id: 22,
|
||||||
kind: UnstableFeatureKind::Runtime,
|
kind: UnstableFeatureKind::Runtime,
|
||||||
config_file_option: "webgpu",
|
config_file_option: "webgpu",
|
||||||
},
|
},
|
||||||
|
@ -209,7 +218,7 @@ pub static UNSTABLE_FEATURES: &[UnstableFeatureDefinition] = &[ UnstableFeature
|
||||||
flag_name: "unstable-worker-options",
|
flag_name: "unstable-worker-options",
|
||||||
help_text: "Enable unstable Web Worker APIs",
|
help_text: "Enable unstable Web Worker APIs",
|
||||||
show_in_help: true,
|
show_in_help: true,
|
||||||
id: 22,
|
id: 23,
|
||||||
kind: UnstableFeatureKind::Runtime,
|
kind: UnstableFeatureKind::Runtime,
|
||||||
config_file_option: "worker-options",
|
config_file_option: "worker-options",
|
||||||
},
|
},
|
||||||
|
@ -220,6 +229,7 @@ pub struct UnstableEnvVarNames {
|
||||||
pub lockfile_v5: &'static str,
|
pub lockfile_v5: &'static str,
|
||||||
pub npm_lazy_caching: &'static str,
|
pub npm_lazy_caching: &'static str,
|
||||||
pub sloppy_imports: &'static str,
|
pub sloppy_imports: &'static str,
|
||||||
|
pub subdomain_wildcards: &'static str,
|
||||||
}
|
}
|
||||||
pub static UNSTABLE_ENV_VAR_NAMES: UnstableEnvVarNames = UnstableEnvVarNames {
|
pub static UNSTABLE_ENV_VAR_NAMES: UnstableEnvVarNames = UnstableEnvVarNames {
|
||||||
bare_node_builtins: "DENO_UNSTABLE_BARE_NODE_BUILTINS",
|
bare_node_builtins: "DENO_UNSTABLE_BARE_NODE_BUILTINS",
|
||||||
|
@ -227,4 +237,5 @@ pub static UNSTABLE_ENV_VAR_NAMES: UnstableEnvVarNames = UnstableEnvVarNames {
|
||||||
lockfile_v5: "DENO_UNSTABLE_LOCKFILE_V5",
|
lockfile_v5: "DENO_UNSTABLE_LOCKFILE_V5",
|
||||||
npm_lazy_caching: "DENO_UNSTABLE_NPM_LAZY_CACHING",
|
npm_lazy_caching: "DENO_UNSTABLE_NPM_LAZY_CACHING",
|
||||||
sloppy_imports: "DENO_UNSTABLE_SLOPPY_IMPORTS",
|
sloppy_imports: "DENO_UNSTABLE_SLOPPY_IMPORTS",
|
||||||
|
subdomain_wildcards: "DENO_UNSTABLE_SUBDOMAIN_WILDCARDS",
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,6 +18,7 @@ use deno_permissions::RunDescriptorParseError;
|
||||||
use deno_permissions::RunQueryDescriptor;
|
use deno_permissions::RunQueryDescriptor;
|
||||||
use deno_permissions::SysDescriptor;
|
use deno_permissions::SysDescriptor;
|
||||||
use deno_permissions::SysDescriptorParseError;
|
use deno_permissions::SysDescriptorParseError;
|
||||||
|
use deno_permissions::UnstableSubdomainWildcards;
|
||||||
use deno_permissions::WriteDescriptor;
|
use deno_permissions::WriteDescriptor;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -25,13 +26,20 @@ pub struct RuntimePermissionDescriptorParser<
|
||||||
TSys: deno_permissions::which::WhichSys + Send + Sync,
|
TSys: deno_permissions::which::WhichSys + Send + Sync,
|
||||||
> {
|
> {
|
||||||
sys: TSys,
|
sys: TSys,
|
||||||
|
unstable_subdomain_wildcards: UnstableSubdomainWildcards,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<TSys: deno_permissions::which::WhichSys + Send + Sync>
|
impl<TSys: deno_permissions::which::WhichSys + Send + Sync>
|
||||||
RuntimePermissionDescriptorParser<TSys>
|
RuntimePermissionDescriptorParser<TSys>
|
||||||
{
|
{
|
||||||
pub fn new(sys: TSys) -> Self {
|
pub fn new(
|
||||||
Self { sys }
|
sys: TSys,
|
||||||
|
unstable_subdomain_wildcards: UnstableSubdomainWildcards,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
sys,
|
||||||
|
unstable_subdomain_wildcards,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_from_cwd(&self, path: &str) -> Result<PathBuf, PathResolveError> {
|
fn resolve_from_cwd(&self, path: &str) -> Result<PathBuf, PathResolveError> {
|
||||||
|
@ -77,14 +85,14 @@ impl<TSys: deno_permissions::which::WhichSys + Send + Sync + std::fmt::Debug>
|
||||||
&self,
|
&self,
|
||||||
text: &str,
|
text: &str,
|
||||||
) -> Result<NetDescriptor, deno_permissions::NetDescriptorParseError> {
|
) -> Result<NetDescriptor, deno_permissions::NetDescriptorParseError> {
|
||||||
NetDescriptor::parse(text)
|
NetDescriptor::parse_for_list(text, self.unstable_subdomain_wildcards)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_import_descriptor(
|
fn parse_import_descriptor(
|
||||||
&self,
|
&self,
|
||||||
text: &str,
|
text: &str,
|
||||||
) -> Result<ImportDescriptor, deno_permissions::NetDescriptorParseError> {
|
) -> Result<ImportDescriptor, deno_permissions::NetDescriptorParseError> {
|
||||||
ImportDescriptor::parse(text)
|
ImportDescriptor::parse_for_list(text, self.unstable_subdomain_wildcards)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_env_descriptor(
|
fn parse_env_descriptor(
|
||||||
|
@ -146,6 +154,13 @@ impl<TSys: deno_permissions::which::WhichSys + Send + Sync + std::fmt::Debug>
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_net_query(
|
||||||
|
&self,
|
||||||
|
text: &str,
|
||||||
|
) -> Result<NetDescriptor, deno_permissions::NetDescriptorParseError> {
|
||||||
|
NetDescriptor::parse_for_query(text)
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_run_query(
|
fn parse_run_query(
|
||||||
&self,
|
&self,
|
||||||
requested: &str,
|
requested: &str,
|
||||||
|
@ -166,14 +181,17 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_handle_empty_value() {
|
fn test_handle_empty_value() {
|
||||||
let parser =
|
let parser = RuntimePermissionDescriptorParser::new(
|
||||||
RuntimePermissionDescriptorParser::new(sys_traits::impls::RealSys);
|
sys_traits::impls::RealSys,
|
||||||
|
UnstableSubdomainWildcards::Enabled,
|
||||||
|
);
|
||||||
assert!(parser.parse_read_descriptor("").is_err());
|
assert!(parser.parse_read_descriptor("").is_err());
|
||||||
assert!(parser.parse_write_descriptor("").is_err());
|
assert!(parser.parse_write_descriptor("").is_err());
|
||||||
assert!(parser.parse_env_descriptor("").is_err());
|
assert!(parser.parse_env_descriptor("").is_err());
|
||||||
assert!(parser.parse_net_descriptor("").is_err());
|
assert!(parser.parse_net_descriptor("").is_err());
|
||||||
assert!(parser.parse_ffi_descriptor("").is_err());
|
assert!(parser.parse_ffi_descriptor("").is_err());
|
||||||
assert!(parser.parse_path_query("").is_err());
|
assert!(parser.parse_path_query("").is_err());
|
||||||
|
assert!(parser.parse_net_query("").is_err());
|
||||||
assert!(parser.parse_run_query("").is_err());
|
assert!(parser.parse_run_query("").is_err());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -818,9 +818,19 @@ impl QueryDescriptor for WriteQueryDescriptor {
|
||||||
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
|
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
|
||||||
pub struct WriteDescriptor(pub PathBuf);
|
pub struct WriteDescriptor(pub PathBuf);
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone, Copy, Eq, PartialEq)]
|
||||||
|
pub enum SubdomainWildcards {
|
||||||
|
Enabled,
|
||||||
|
#[default]
|
||||||
|
Disabled,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type UnstableSubdomainWildcards = SubdomainWildcards;
|
||||||
|
|
||||||
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
|
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
|
||||||
pub enum Host {
|
pub enum Host {
|
||||||
Fqdn(FQDN),
|
Fqdn(FQDN),
|
||||||
|
FqdnWithSubdomainWildcard(FQDN),
|
||||||
Ip(IpAddr),
|
Ip(IpAddr),
|
||||||
Vsock(u32),
|
Vsock(u32),
|
||||||
}
|
}
|
||||||
|
@ -843,7 +853,19 @@ pub enum HostParseError {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Host {
|
impl Host {
|
||||||
fn parse(s: &str) -> Result<Self, HostParseError> {
|
fn parse_for_query(s: &str) -> Result<Self, HostParseError> {
|
||||||
|
Self::parse_inner(s, SubdomainWildcards::Disabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
fn parse_for_list(s: &str) -> Result<Self, HostParseError> {
|
||||||
|
Self::parse_inner(s, SubdomainWildcards::Enabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_inner(
|
||||||
|
s: &str,
|
||||||
|
subdomain_wildcards: SubdomainWildcards,
|
||||||
|
) -> Result<Self, HostParseError> {
|
||||||
if s.starts_with('[') && s.ends_with(']') {
|
if s.starts_with('[') && s.ends_with(']') {
|
||||||
let ip = s[1..s.len() - 1]
|
let ip = s[1..s.len() - 1]
|
||||||
.parse::<Ipv6Addr>()
|
.parse::<Ipv6Addr>()
|
||||||
|
@ -865,9 +887,17 @@ impl Host {
|
||||||
} else {
|
} else {
|
||||||
Cow::Owned(s.to_ascii_lowercase())
|
Cow::Owned(s.to_ascii_lowercase())
|
||||||
};
|
};
|
||||||
|
let mut host_or_suffix = lower.as_ref();
|
||||||
|
let mut has_subdomain_wildcard = false;
|
||||||
|
if matches!(subdomain_wildcards, SubdomainWildcards::Enabled) {
|
||||||
|
if let Some(suffix) = lower.strip_prefix("*.") {
|
||||||
|
host_or_suffix = suffix;
|
||||||
|
has_subdomain_wildcard = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
let fqdn = {
|
let fqdn = {
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
FQDN::from_str(&lower).map_err(|e| HostParseError::Fqdn {
|
FQDN::from_str(host_or_suffix).map_err(|e| HostParseError::Fqdn {
|
||||||
error: e,
|
error: e,
|
||||||
host: s.to_string(),
|
host: s.to_string(),
|
||||||
})?
|
})?
|
||||||
|
@ -875,14 +905,18 @@ impl Host {
|
||||||
if fqdn.is_root() {
|
if fqdn.is_root() {
|
||||||
return Err(HostParseError::InvalidEmptyHost(s.to_string()));
|
return Err(HostParseError::InvalidEmptyHost(s.to_string()));
|
||||||
}
|
}
|
||||||
|
if has_subdomain_wildcard {
|
||||||
|
Ok(Host::FqdnWithSubdomainWildcard(fqdn))
|
||||||
|
} else {
|
||||||
Ok(Host::Fqdn(fqdn))
|
Ok(Host::Fqdn(fqdn))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
fn must_parse(s: &str) -> Self {
|
fn must_parse(s: &str) -> Self {
|
||||||
Self::parse(s).unwrap()
|
Self::parse_for_list(s).unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -923,11 +957,26 @@ impl QueryDescriptor for NetDescriptor {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn matches_allow(&self, other: &Self::AllowDesc) -> bool {
|
fn matches_allow(&self, other: &Self::AllowDesc) -> bool {
|
||||||
self.0 == other.0 && (other.1.is_none() || self.1 == other.1)
|
if other.1.is_some() && self.1 != other.1 {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
match (&other.0, &self.0) {
|
||||||
|
(Host::Fqdn(a), Host::Fqdn(b)) => a == b,
|
||||||
|
(Host::FqdnWithSubdomainWildcard(a), Host::Fqdn(b)) => {
|
||||||
|
b.is_subdomain_of(a)
|
||||||
|
}
|
||||||
|
(
|
||||||
|
Host::FqdnWithSubdomainWildcard(a),
|
||||||
|
Host::FqdnWithSubdomainWildcard(b),
|
||||||
|
) => a == b,
|
||||||
|
(Host::Ip(a), Host::Ip(b)) => a == b,
|
||||||
|
(Host::Vsock(a), Host::Vsock(b)) => a == b,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn matches_deny(&self, other: &Self::DenyDesc) -> bool {
|
fn matches_deny(&self, other: &Self::DenyDesc) -> bool {
|
||||||
self.0 == other.0 && (other.1.is_none() || self.1 == other.1)
|
self.matches_allow(other)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn revokes(&self, other: &Self::AllowDesc) -> bool {
|
fn revokes(&self, other: &Self::AllowDesc) -> bool {
|
||||||
|
@ -974,7 +1023,23 @@ pub enum NetDescriptorFromUrlParseError {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NetDescriptor {
|
impl NetDescriptor {
|
||||||
pub fn parse(hostname: &str) -> Result<Self, NetDescriptorParseError> {
|
pub fn parse_for_query(
|
||||||
|
hostname: &str,
|
||||||
|
) -> Result<Self, NetDescriptorParseError> {
|
||||||
|
Self::parse_inner(hostname, SubdomainWildcards::Disabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse_for_list(
|
||||||
|
hostname: &str,
|
||||||
|
unstable_subdomain_wildcards: UnstableSubdomainWildcards,
|
||||||
|
) -> Result<Self, NetDescriptorParseError> {
|
||||||
|
Self::parse_inner(hostname, unstable_subdomain_wildcards)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_inner(
|
||||||
|
hostname: &str,
|
||||||
|
subdomain_wildcards: SubdomainWildcards,
|
||||||
|
) -> Result<Self, NetDescriptorParseError> {
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
if let Some(vsock) = hostname.strip_prefix("vsock:") {
|
if let Some(vsock) = hostname.strip_prefix("vsock:") {
|
||||||
let mut split = vsock.split(':');
|
let mut split = vsock.split(':');
|
||||||
|
@ -1038,7 +1103,7 @@ impl NetDescriptor {
|
||||||
Some((host, port)) => (host, port),
|
Some((host, port)) => (host, port),
|
||||||
None => (hostname, ""),
|
None => (hostname, ""),
|
||||||
};
|
};
|
||||||
let host = Host::parse(host)?;
|
let host = Host::parse_inner(host, subdomain_wildcards)?;
|
||||||
|
|
||||||
let port = if port.is_empty() {
|
let port = if port.is_empty() {
|
||||||
None
|
None
|
||||||
|
@ -1068,7 +1133,7 @@ impl NetDescriptor {
|
||||||
let host = url.host_str().ok_or_else(|| {
|
let host = url.host_str().ok_or_else(|| {
|
||||||
NetDescriptorFromUrlParseError::MissingHost(url.clone())
|
NetDescriptorFromUrlParseError::MissingHost(url.clone())
|
||||||
})?;
|
})?;
|
||||||
let host = Host::parse(host)?;
|
let host = Host::parse_for_query(host)?;
|
||||||
let port = url.port_or_known_default();
|
let port = url.port_or_known_default();
|
||||||
Ok(NetDescriptor(host, port.map(Into::into)))
|
Ok(NetDescriptor(host, port.map(Into::into)))
|
||||||
}
|
}
|
||||||
|
@ -1085,6 +1150,7 @@ impl fmt::Display for NetDescriptor {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match &self.0 {
|
match &self.0 {
|
||||||
Host::Fqdn(fqdn) => write!(f, "{fqdn}"),
|
Host::Fqdn(fqdn) => write!(f, "{fqdn}"),
|
||||||
|
Host::FqdnWithSubdomainWildcard(fqdn) => write!(f, "*.{fqdn}"),
|
||||||
Host::Ip(IpAddr::V4(ip)) => write!(f, "{ip}"),
|
Host::Ip(IpAddr::V4(ip)) => write!(f, "{ip}"),
|
||||||
Host::Ip(IpAddr::V6(ip)) => write!(f, "[{ip}]"),
|
Host::Ip(IpAddr::V6(ip)) => write!(f, "[{ip}]"),
|
||||||
Host::Vsock(cid) => write!(f, "vsock:{cid}"),
|
Host::Vsock(cid) => write!(f, "vsock:{cid}"),
|
||||||
|
@ -1154,8 +1220,14 @@ impl QueryDescriptor for ImportDescriptor {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ImportDescriptor {
|
impl ImportDescriptor {
|
||||||
pub fn parse(specifier: &str) -> Result<Self, NetDescriptorParseError> {
|
pub fn parse_for_list(
|
||||||
Ok(ImportDescriptor(NetDescriptor::parse(specifier)?))
|
specifier: &str,
|
||||||
|
unstable_subdomain_wildcards: UnstableSubdomainWildcards,
|
||||||
|
) -> Result<Self, NetDescriptorParseError> {
|
||||||
|
Ok(ImportDescriptor(NetDescriptor::parse_for_list(
|
||||||
|
specifier,
|
||||||
|
unstable_subdomain_wildcards,
|
||||||
|
)?))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_url(url: &Url) -> Result<Self, NetDescriptorFromUrlParseError> {
|
pub fn from_url(url: &Url) -> Result<Self, NetDescriptorFromUrlParseError> {
|
||||||
|
@ -2981,7 +3053,7 @@ impl PermissionsContainer {
|
||||||
let mut inner = self.inner.lock();
|
let mut inner = self.inner.lock();
|
||||||
let inner = &mut inner.net;
|
let inner = &mut inner.net;
|
||||||
skip_check_if_is_permission_fully_granted!(inner);
|
skip_check_if_is_permission_fully_granted!(inner);
|
||||||
let hostname = Host::parse(host.0.as_ref())?;
|
let hostname = Host::parse_for_query(host.0.as_ref())?;
|
||||||
let descriptor = NetDescriptor(hostname, host.1.map(Into::into));
|
let descriptor = NetDescriptor(hostname, host.1.map(Into::into));
|
||||||
inner.check(&descriptor, Some(api_name))?;
|
inner.check(&descriptor, Some(api_name))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -3113,7 +3185,7 @@ impl PermissionsContainer {
|
||||||
permission.query(
|
permission.query(
|
||||||
match host {
|
match host {
|
||||||
None => None,
|
None => None,
|
||||||
Some(h) => Some(self.descriptor_parser.parse_net_descriptor(h)?),
|
Some(h) => Some(self.descriptor_parser.parse_net_query(h)?),
|
||||||
}
|
}
|
||||||
.as_ref(),
|
.as_ref(),
|
||||||
),
|
),
|
||||||
|
@ -3243,7 +3315,7 @@ impl PermissionsContainer {
|
||||||
self.inner.lock().net.revoke(
|
self.inner.lock().net.revoke(
|
||||||
match host {
|
match host {
|
||||||
None => None,
|
None => None,
|
||||||
Some(h) => Some(self.descriptor_parser.parse_net_descriptor(h)?),
|
Some(h) => Some(self.descriptor_parser.parse_net_query(h)?),
|
||||||
}
|
}
|
||||||
.as_ref(),
|
.as_ref(),
|
||||||
),
|
),
|
||||||
|
@ -3353,7 +3425,7 @@ impl PermissionsContainer {
|
||||||
self.inner.lock().net.request(
|
self.inner.lock().net.request(
|
||||||
match host {
|
match host {
|
||||||
None => None,
|
None => None,
|
||||||
Some(h) => Some(self.descriptor_parser.parse_net_descriptor(h)?),
|
Some(h) => Some(self.descriptor_parser.parse_net_query(h)?),
|
||||||
}
|
}
|
||||||
.as_ref(),
|
.as_ref(),
|
||||||
),
|
),
|
||||||
|
@ -3767,6 +3839,11 @@ pub trait PermissionDescriptorParser: Debug + Send + Sync {
|
||||||
path: &str,
|
path: &str,
|
||||||
) -> Result<PathQueryDescriptor, PathResolveError>;
|
) -> Result<PathQueryDescriptor, PathResolveError>;
|
||||||
|
|
||||||
|
fn parse_net_query(
|
||||||
|
&self,
|
||||||
|
text: &str,
|
||||||
|
) -> Result<NetDescriptor, NetDescriptorParseError>;
|
||||||
|
|
||||||
fn parse_run_query(
|
fn parse_run_query(
|
||||||
&self,
|
&self,
|
||||||
requested: &str,
|
requested: &str,
|
||||||
|
@ -3830,14 +3907,17 @@ mod tests {
|
||||||
&self,
|
&self,
|
||||||
text: &str,
|
text: &str,
|
||||||
) -> Result<NetDescriptor, NetDescriptorParseError> {
|
) -> Result<NetDescriptor, NetDescriptorParseError> {
|
||||||
NetDescriptor::parse(text)
|
NetDescriptor::parse_for_list(text, UnstableSubdomainWildcards::Enabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_import_descriptor(
|
fn parse_import_descriptor(
|
||||||
&self,
|
&self,
|
||||||
text: &str,
|
text: &str,
|
||||||
) -> Result<ImportDescriptor, NetDescriptorParseError> {
|
) -> Result<ImportDescriptor, NetDescriptorParseError> {
|
||||||
ImportDescriptor::parse(text)
|
ImportDescriptor::parse_for_list(
|
||||||
|
text,
|
||||||
|
UnstableSubdomainWildcards::Enabled,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_env_descriptor(
|
fn parse_env_descriptor(
|
||||||
|
@ -3891,6 +3971,13 @@ mod tests {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_net_query(
|
||||||
|
&self,
|
||||||
|
text: &str,
|
||||||
|
) -> Result<NetDescriptor, NetDescriptorParseError> {
|
||||||
|
NetDescriptor::parse_for_query(text)
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_run_query(
|
fn parse_run_query(
|
||||||
&self,
|
&self,
|
||||||
requested: &str,
|
requested: &str,
|
||||||
|
@ -3961,7 +4048,8 @@ mod tests {
|
||||||
"172.16.0.2:8000",
|
"172.16.0.2:8000",
|
||||||
"www.github.com:443",
|
"www.github.com:443",
|
||||||
"80.example.com:80",
|
"80.example.com:80",
|
||||||
"443.example.com:443"
|
"443.example.com:443",
|
||||||
|
"*.discord.gg"
|
||||||
]),
|
]),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
|
@ -3989,13 +4077,15 @@ mod tests {
|
||||||
("443.example.com", 444, false),
|
("443.example.com", 444, false),
|
||||||
("80.example.com", 81, false),
|
("80.example.com", 81, false),
|
||||||
("80.example.com", 80, true),
|
("80.example.com", 80, true),
|
||||||
|
("discord.gg", 0, true),
|
||||||
|
("foo.discord.gg", 0, true),
|
||||||
// Just some random hosts that should err
|
// Just some random hosts that should err
|
||||||
("somedomain", 0, false),
|
("somedomain", 0, false),
|
||||||
("192.168.0.1", 0, false),
|
("192.168.0.1", 0, false),
|
||||||
];
|
];
|
||||||
|
|
||||||
for (host, port, is_ok) in domain_tests {
|
for (host, port, is_ok) in domain_tests {
|
||||||
let host = Host::parse(host).unwrap();
|
let host = Host::parse_for_query(host).unwrap();
|
||||||
let descriptor = NetDescriptor(host, Some(port));
|
let descriptor = NetDescriptor(host, Some(port));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
is_ok,
|
is_ok,
|
||||||
|
@ -4041,7 +4131,7 @@ mod tests {
|
||||||
];
|
];
|
||||||
|
|
||||||
for (host_str, port) in domain_tests {
|
for (host_str, port) in domain_tests {
|
||||||
let host = Host::parse(host_str).unwrap();
|
let host = Host::parse_for_query(host_str).unwrap();
|
||||||
let descriptor = NetDescriptor(host, Some(port));
|
let descriptor = NetDescriptor(host, Some(port));
|
||||||
assert!(
|
assert!(
|
||||||
perms.net.check(&descriptor, None).is_ok(),
|
perms.net.check(&descriptor, None).is_ok(),
|
||||||
|
@ -4086,7 +4176,7 @@ mod tests {
|
||||||
];
|
];
|
||||||
|
|
||||||
for (host_str, port) in domain_tests {
|
for (host_str, port) in domain_tests {
|
||||||
let host = Host::parse(host_str).unwrap();
|
let host = Host::parse_for_query(host_str).unwrap();
|
||||||
let descriptor = NetDescriptor(host, Some(port));
|
let descriptor = NetDescriptor(host, Some(port));
|
||||||
assert!(
|
assert!(
|
||||||
perms.net.check(&descriptor, None).is_err(),
|
perms.net.check(&descriptor, None).is_err(),
|
||||||
|
@ -5058,7 +5148,7 @@ mod tests {
|
||||||
&parser,
|
&parser,
|
||||||
&PermissionsOptions {
|
&PermissionsOptions {
|
||||||
allow_env: Some(vec![]),
|
allow_env: Some(vec![]),
|
||||||
allow_net: Some(svec!["foo", "bar"]),
|
allow_net: Some(svec!["*.foo", "bar"]),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -5079,7 +5169,11 @@ mod tests {
|
||||||
Permissions {
|
Permissions {
|
||||||
env: Permissions::new_unary(Some(HashSet::new()), None, false),
|
env: Permissions::new_unary(Some(HashSet::new()), None, false),
|
||||||
net: Permissions::new_unary(
|
net: Permissions::new_unary(
|
||||||
Some(HashSet::from([NetDescriptor::parse("foo").unwrap()])),
|
Some(HashSet::from([NetDescriptor::parse_for_list(
|
||||||
|
"foo",
|
||||||
|
UnstableSubdomainWildcards::Enabled
|
||||||
|
)
|
||||||
|
.unwrap()])),
|
||||||
None,
|
None,
|
||||||
false
|
false
|
||||||
),
|
),
|
||||||
|
@ -5175,7 +5269,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_host_parse() {
|
fn test_host_parse_for_query() {
|
||||||
let hosts = &[
|
let hosts = &[
|
||||||
("deno.land", Some(Host::Fqdn(fqdn!("deno.land")))),
|
("deno.land", Some(Host::Fqdn(fqdn!("deno.land")))),
|
||||||
("DENO.land", Some(Host::Fqdn(fqdn!("deno.land")))),
|
("DENO.land", Some(Host::Fqdn(fqdn!("deno.land")))),
|
||||||
|
@ -5200,6 +5294,54 @@ mod tests {
|
||||||
("1::1.", None),
|
("1::1.", None),
|
||||||
("deno.land.", Some(Host::Fqdn(fqdn!("deno.land")))),
|
("deno.land.", Some(Host::Fqdn(fqdn!("deno.land")))),
|
||||||
(".deno.land", None),
|
(".deno.land", None),
|
||||||
|
("*.deno.land", None),
|
||||||
|
(
|
||||||
|
"::ffff:1.1.1.1",
|
||||||
|
Some(Host::Ip(IpAddr::V6(Ipv6Addr::new(
|
||||||
|
0, 0, 0, 0, 0, 0xffff, 0x0101, 0x0101,
|
||||||
|
)))),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
for (host_str, expected) in hosts {
|
||||||
|
assert_eq!(
|
||||||
|
Host::parse_for_query(host_str).ok(),
|
||||||
|
*expected,
|
||||||
|
"{host_str}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_host_parse_for_list() {
|
||||||
|
let hosts = &[
|
||||||
|
("deno.land", Some(Host::Fqdn(fqdn!("deno.land")))),
|
||||||
|
(
|
||||||
|
"*.deno.land",
|
||||||
|
Some(Host::FqdnWithSubdomainWildcard(fqdn!("deno.land"))),
|
||||||
|
),
|
||||||
|
("DENO.land", Some(Host::Fqdn(fqdn!("deno.land")))),
|
||||||
|
("deno.land.", Some(Host::Fqdn(fqdn!("deno.land")))),
|
||||||
|
(
|
||||||
|
"1.1.1.1",
|
||||||
|
Some(Host::Ip(IpAddr::V4(Ipv4Addr::new(1, 1, 1, 1)))),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"::1",
|
||||||
|
Some(Host::Ip(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)))),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"[::1]",
|
||||||
|
Some(Host::Ip(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)))),
|
||||||
|
),
|
||||||
|
("[::1", None),
|
||||||
|
("::1]", None),
|
||||||
|
("deno. land", None),
|
||||||
|
("1. 1.1.1", None),
|
||||||
|
("1.1.1.1.", None),
|
||||||
|
("1::1.", None),
|
||||||
|
("deno.land.", Some(Host::Fqdn(fqdn!("deno.land")))),
|
||||||
|
(".deno.land", None),
|
||||||
(
|
(
|
||||||
"::ffff:1.1.1.1",
|
"::ffff:1.1.1.1",
|
||||||
Some(Host::Ip(IpAddr::V6(Ipv6Addr::new(
|
Some(Host::Ip(IpAddr::V6(Ipv6Addr::new(
|
||||||
|
@ -5209,12 +5351,12 @@ mod tests {
|
||||||
];
|
];
|
||||||
|
|
||||||
for (host_str, expected) in hosts {
|
for (host_str, expected) in hosts {
|
||||||
assert_eq!(Host::parse(host_str).ok(), *expected, "{host_str}");
|
assert_eq!(Host::parse_for_list(host_str).ok(), *expected, "{host_str}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_net_descriptor_parse() {
|
fn test_net_descriptor_parse_for_query() {
|
||||||
let cases = &[
|
let cases = &[
|
||||||
(
|
(
|
||||||
"deno.land",
|
"deno.land",
|
||||||
|
@ -5228,6 +5370,84 @@ mod tests {
|
||||||
"deno.land:8000",
|
"deno.land:8000",
|
||||||
Some(NetDescriptor(Host::Fqdn(fqdn!("deno.land")), Some(8000))),
|
Some(NetDescriptor(Host::Fqdn(fqdn!("deno.land")), Some(8000))),
|
||||||
),
|
),
|
||||||
|
("*.deno.land", None),
|
||||||
|
("deno.land:", None),
|
||||||
|
("deno.land:a", None),
|
||||||
|
("deno. land:a", None),
|
||||||
|
("deno.land.: a", None),
|
||||||
|
(
|
||||||
|
"1.1.1.1",
|
||||||
|
Some(NetDescriptor(
|
||||||
|
Host::Ip(IpAddr::V4(Ipv4Addr::new(1, 1, 1, 1))),
|
||||||
|
None,
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
("1.1.1.1.", None),
|
||||||
|
("1.1.1.1..", None),
|
||||||
|
(
|
||||||
|
"1.1.1.1:8000",
|
||||||
|
Some(NetDescriptor(
|
||||||
|
Host::Ip(IpAddr::V4(Ipv4Addr::new(1, 1, 1, 1))),
|
||||||
|
Some(8000),
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
("::", None),
|
||||||
|
(":::80", None),
|
||||||
|
("::80", None),
|
||||||
|
(
|
||||||
|
"[::]",
|
||||||
|
Some(NetDescriptor(
|
||||||
|
Host::Ip(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0))),
|
||||||
|
None,
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
("[::1", None),
|
||||||
|
("::1]", None),
|
||||||
|
("::1]", None),
|
||||||
|
("[::1]:", None),
|
||||||
|
("[::1]:a", None),
|
||||||
|
(
|
||||||
|
"[::1]:443",
|
||||||
|
Some(NetDescriptor(
|
||||||
|
Host::Ip(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1))),
|
||||||
|
Some(443),
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
("", None),
|
||||||
|
("deno.land..", None),
|
||||||
|
];
|
||||||
|
|
||||||
|
for (input, expected) in cases {
|
||||||
|
assert_eq!(
|
||||||
|
NetDescriptor::parse_for_query(input).ok(),
|
||||||
|
*expected,
|
||||||
|
"'{input}'"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_net_descriptor_parse_for_list() {
|
||||||
|
let cases = &[
|
||||||
|
(
|
||||||
|
"deno.land",
|
||||||
|
Some(NetDescriptor(Host::Fqdn(fqdn!("deno.land")), None)),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"DENO.land",
|
||||||
|
Some(NetDescriptor(Host::Fqdn(fqdn!("deno.land")), None)),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"deno.land:8000",
|
||||||
|
Some(NetDescriptor(Host::Fqdn(fqdn!("deno.land")), Some(8000))),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"*.deno.land",
|
||||||
|
Some(NetDescriptor(
|
||||||
|
Host::FqdnWithSubdomainWildcard(fqdn!("deno.land")),
|
||||||
|
None,
|
||||||
|
)),
|
||||||
|
),
|
||||||
("deno.land:", None),
|
("deno.land:", None),
|
||||||
("deno.land:a", None),
|
("deno.land:a", None),
|
||||||
("deno. land:a", None),
|
("deno. land:a", None),
|
||||||
|
@ -5275,7 +5495,15 @@ mod tests {
|
||||||
];
|
];
|
||||||
|
|
||||||
for (input, expected) in cases {
|
for (input, expected) in cases {
|
||||||
assert_eq!(NetDescriptor::parse(input).ok(), *expected, "'{input}'");
|
assert_eq!(
|
||||||
|
NetDescriptor::parse_for_list(
|
||||||
|
input,
|
||||||
|
UnstableSubdomainWildcards::Enabled
|
||||||
|
)
|
||||||
|
.ok(),
|
||||||
|
*expected,
|
||||||
|
"'{input}'"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1444,6 +1444,19 @@ mod permissions {
|
||||||
assert!(!err.contains(util::PERMISSION_DENIED_PATTERN));
|
assert!(!err.contains(util::PERMISSION_DENIED_PATTERN));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn net_fetch_localhost_subdomain() {
|
||||||
|
let _http_guard = util::http_server();
|
||||||
|
let (_, err) = util::run_and_collect_output(
|
||||||
|
true,
|
||||||
|
"run --unstable-subdomain-wildcards --allow-net=*.localhost run/complex_permissions_test.ts netFetch http://localhost:4545/ http://localhost:4546/ http://localhost:4547/",
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
assert!(!err.contains(util::PERMISSION_DENIED_PATTERN));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn net_connect_allow_localhost_ip_4555() {
|
fn net_connect_allow_localhost_ip_4555() {
|
||||||
let _http_guard = util::http_server();
|
let _http_guard = util::http_server();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue