mirror of
https://github.com/tauri-apps/tauri.git
synced 2024-08-17 11:50:26 +03:00
fix(acl): inconsistencies on urlpattern usage for remote domain URL (#9133)
* fix(acl): inconsistencies on urlpattern usage for remote domain URL * remove println! * typo * fix tests
This commit is contained in:
parent
490a6b424e
commit
e673854c83
5
.changes/fix-remote-domain-url.md
Normal file
5
.changes/fix-remote-domain-url.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
"tauri": patch:bug
|
||||
---
|
||||
|
||||
Fixes capability remote domain not allowing subpaths, query parameters and hash when those values are empty.
|
@ -1141,7 +1141,7 @@
|
||||
],
|
||||
"properties": {
|
||||
"urls": {
|
||||
"description": "Remote domains this capability refers to using the [URLPattern standard](https://urlpattern.spec.whatwg.org/).",
|
||||
"description": "Remote domains this capability refers to using the [URLPattern standard](https://urlpattern.spec.whatwg.org/).\n\n# Examples\n\n- \"https://*.mydomain.dev\": allows subdomains of mydomain.dev - \"https://mydomain.dev/api/*\": allows any subpath of mydomain.dev/api",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
|
@ -90,6 +90,11 @@ fn default_capability_local() -> bool {
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CapabilityRemote {
|
||||
/// Remote domains this capability refers to using the [URLPattern standard](https://urlpattern.spec.whatwg.org/).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// - "https://*.mydomain.dev": allows subdomains of mydomain.dev
|
||||
/// - "https://mydomain.dev/api/*": allows any subpath of mydomain.dev/api
|
||||
pub urls: Vec<String>,
|
||||
}
|
||||
|
||||
|
@ -202,7 +202,21 @@ impl FromStr for RemoteUrlPattern {
|
||||
type Err = urlpattern::quirks::Error;
|
||||
|
||||
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
|
||||
let init = urlpattern::UrlPatternInit::parse_constructor_string::<regex::Regex>(s, None)?;
|
||||
let mut init = urlpattern::UrlPatternInit::parse_constructor_string::<regex::Regex>(s, None)?;
|
||||
if init.search.as_ref().map(|p| p.is_empty()).unwrap_or(true) {
|
||||
init.search.replace("*".to_string());
|
||||
}
|
||||
if init.hash.as_ref().map(|p| p.is_empty()).unwrap_or(true) {
|
||||
init.hash.replace("*".to_string());
|
||||
}
|
||||
if init
|
||||
.pathname
|
||||
.as_ref()
|
||||
.map(|p| p.is_empty() || p == "/")
|
||||
.unwrap_or(true)
|
||||
{
|
||||
init.pathname.replace("*".to_string());
|
||||
}
|
||||
let pattern = urlpattern::UrlPattern::parse(init)?;
|
||||
Ok(Self(Arc::new(pattern), s.to_string()))
|
||||
}
|
||||
@ -251,6 +265,46 @@ pub enum ExecutionContext {
|
||||
},
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::acl::RemoteUrlPattern;
|
||||
|
||||
#[test]
|
||||
fn url_pattern_domain_wildcard() {
|
||||
let pattern: RemoteUrlPattern = "http://*".parse().unwrap();
|
||||
|
||||
assert!(pattern.test(&"http://tauri.app/path".parse().unwrap()));
|
||||
assert!(pattern.test(&"http://tauri.app/path?q=1".parse().unwrap()));
|
||||
|
||||
assert!(pattern.test(&"http://localhost/path".parse().unwrap()));
|
||||
assert!(pattern.test(&"http://localhost/path?q=1".parse().unwrap()));
|
||||
|
||||
let pattern: RemoteUrlPattern = "http://*.tauri.app".parse().unwrap();
|
||||
|
||||
assert!(!pattern.test(&"http://tauri.app/path".parse().unwrap()));
|
||||
assert!(!pattern.test(&"http://tauri.app/path?q=1".parse().unwrap()));
|
||||
assert!(pattern.test(&"http://api.tauri.app/path".parse().unwrap()));
|
||||
assert!(pattern.test(&"http://api.tauri.app/path?q=1".parse().unwrap()));
|
||||
assert!(!pattern.test(&"http://localhost/path".parse().unwrap()));
|
||||
assert!(!pattern.test(&"http://localhost/path?q=1".parse().unwrap()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn url_pattern_path_wildcard() {
|
||||
let pattern: RemoteUrlPattern = "http://localhost/*".parse().unwrap();
|
||||
assert!(pattern.test(&"http://localhost/path".parse().unwrap()));
|
||||
assert!(pattern.test(&"http://localhost/path?q=1".parse().unwrap()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn url_pattern_scheme_wildcard() {
|
||||
let pattern: RemoteUrlPattern = "*://localhost".parse().unwrap();
|
||||
assert!(pattern.test(&"http://localhost/path".parse().unwrap()));
|
||||
assert!(pattern.test(&"https://localhost/path?q=1".parse().unwrap()));
|
||||
assert!(pattern.test(&"custom://localhost/path".parse().unwrap()));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "build")]
|
||||
mod build_ {
|
||||
use std::convert::identity;
|
||||
|
@ -90,50 +90,59 @@ Resolved {
|
||||
},
|
||||
},
|
||||
pathname: Component {
|
||||
pattern_string: "/",
|
||||
pattern_string: "*",
|
||||
regexp: Ok(
|
||||
Regex(
|
||||
"^/$",
|
||||
"^(.*)$",
|
||||
),
|
||||
),
|
||||
group_name_list: [],
|
||||
group_name_list: [
|
||||
"0",
|
||||
],
|
||||
matcher: Matcher {
|
||||
prefix: "",
|
||||
suffix: "",
|
||||
inner: Literal {
|
||||
literal: "/",
|
||||
inner: SingleCapture {
|
||||
filter: None,
|
||||
allow_empty: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
search: Component {
|
||||
pattern_string: "",
|
||||
pattern_string: "*",
|
||||
regexp: Ok(
|
||||
Regex(
|
||||
"^$",
|
||||
"^(.*)$",
|
||||
),
|
||||
),
|
||||
group_name_list: [],
|
||||
group_name_list: [
|
||||
"0",
|
||||
],
|
||||
matcher: Matcher {
|
||||
prefix: "",
|
||||
suffix: "",
|
||||
inner: Literal {
|
||||
literal: "",
|
||||
inner: SingleCapture {
|
||||
filter: None,
|
||||
allow_empty: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
hash: Component {
|
||||
pattern_string: "",
|
||||
pattern_string: "*",
|
||||
regexp: Ok(
|
||||
Regex(
|
||||
"^$",
|
||||
"^(.*)$",
|
||||
),
|
||||
),
|
||||
group_name_list: [],
|
||||
group_name_list: [
|
||||
"0",
|
||||
],
|
||||
matcher: Matcher {
|
||||
prefix: "",
|
||||
suffix: "",
|
||||
inner: Literal {
|
||||
literal: "",
|
||||
inner: SingleCapture {
|
||||
filter: None,
|
||||
allow_empty: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -251,50 +260,59 @@ Resolved {
|
||||
},
|
||||
},
|
||||
pathname: Component {
|
||||
pattern_string: "/",
|
||||
pattern_string: "*",
|
||||
regexp: Ok(
|
||||
Regex(
|
||||
"^/$",
|
||||
"^(.*)$",
|
||||
),
|
||||
),
|
||||
group_name_list: [],
|
||||
group_name_list: [
|
||||
"0",
|
||||
],
|
||||
matcher: Matcher {
|
||||
prefix: "",
|
||||
suffix: "",
|
||||
inner: Literal {
|
||||
literal: "/",
|
||||
inner: SingleCapture {
|
||||
filter: None,
|
||||
allow_empty: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
search: Component {
|
||||
pattern_string: "",
|
||||
pattern_string: "*",
|
||||
regexp: Ok(
|
||||
Regex(
|
||||
"^$",
|
||||
"^(.*)$",
|
||||
),
|
||||
),
|
||||
group_name_list: [],
|
||||
group_name_list: [
|
||||
"0",
|
||||
],
|
||||
matcher: Matcher {
|
||||
prefix: "",
|
||||
suffix: "",
|
||||
inner: Literal {
|
||||
literal: "",
|
||||
inner: SingleCapture {
|
||||
filter: None,
|
||||
allow_empty: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
hash: Component {
|
||||
pattern_string: "",
|
||||
pattern_string: "*",
|
||||
regexp: Ok(
|
||||
Regex(
|
||||
"^$",
|
||||
"^(.*)$",
|
||||
),
|
||||
),
|
||||
group_name_list: [],
|
||||
group_name_list: [
|
||||
"0",
|
||||
],
|
||||
matcher: Matcher {
|
||||
prefix: "",
|
||||
suffix: "",
|
||||
inner: Literal {
|
||||
literal: "",
|
||||
inner: SingleCapture {
|
||||
filter: None,
|
||||
allow_empty: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -2,7 +2,10 @@
|
||||
"$schema": "../gen/schemas/desktop-schema.json",
|
||||
"identifier": "run-app",
|
||||
"description": "permissions to run the app",
|
||||
"windows": ["main", "main-*"],
|
||||
"windows": [
|
||||
"main",
|
||||
"main-*"
|
||||
],
|
||||
"permissions": [
|
||||
{
|
||||
"identifier": "allow-log-operation",
|
||||
|
@ -1141,7 +1141,7 @@
|
||||
],
|
||||
"properties": {
|
||||
"urls": {
|
||||
"description": "Remote domains this capability refers to using the [URLPattern standard](https://urlpattern.spec.whatwg.org/).",
|
||||
"description": "Remote domains this capability refers to using the [URLPattern standard](https://urlpattern.spec.whatwg.org/).\n\n# Examples\n\n- \"https://*.mydomain.dev\": allows subdomains of mydomain.dev - \"https://mydomain.dev/api/*\": allows any subpath of mydomain.dev/api",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
|
Loading…
Reference in New Issue
Block a user