Skip to content

Commit e673854

Browse files
authored
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
1 parent 490a6b4 commit e673854

File tree

7 files changed

+120
-35
lines changed

7 files changed

+120
-35
lines changed

.changes/fix-remote-domain-url.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"tauri": patch:bug
3+
---
4+
5+
Fixes capability remote domain not allowing subpaths, query parameters and hash when those values are empty.

core/tauri-config-schema/schema.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1141,7 +1141,7 @@
11411141
],
11421142
"properties": {
11431143
"urls": {
1144-
"description": "Remote domains this capability refers to using the [URLPattern standard](https://urlpattern.spec.whatwg.org/).",
1144+
"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",
11451145
"type": "array",
11461146
"items": {
11471147
"type": "string"

core/tauri-utils/src/acl/capability.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,11 @@ fn default_capability_local() -> bool {
9090
#[serde(rename_all = "camelCase")]
9191
pub struct CapabilityRemote {
9292
/// Remote domains this capability refers to using the [URLPattern standard](https://urlpattern.spec.whatwg.org/).
93+
///
94+
/// # Examples
95+
///
96+
/// - "https://*.mydomain.dev": allows subdomains of mydomain.dev
97+
/// - "https://mydomain.dev/api/*": allows any subpath of mydomain.dev/api
9398
pub urls: Vec<String>,
9499
}
95100

core/tauri-utils/src/acl/mod.rs

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,21 @@ impl FromStr for RemoteUrlPattern {
202202
type Err = urlpattern::quirks::Error;
203203

204204
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
205-
let init = urlpattern::UrlPatternInit::parse_constructor_string::<regex::Regex>(s, None)?;
205+
let mut init = urlpattern::UrlPatternInit::parse_constructor_string::<regex::Regex>(s, None)?;
206+
if init.search.as_ref().map(|p| p.is_empty()).unwrap_or(true) {
207+
init.search.replace("*".to_string());
208+
}
209+
if init.hash.as_ref().map(|p| p.is_empty()).unwrap_or(true) {
210+
init.hash.replace("*".to_string());
211+
}
212+
if init
213+
.pathname
214+
.as_ref()
215+
.map(|p| p.is_empty() || p == "/")
216+
.unwrap_or(true)
217+
{
218+
init.pathname.replace("*".to_string());
219+
}
206220
let pattern = urlpattern::UrlPattern::parse(init)?;
207221
Ok(Self(Arc::new(pattern), s.to_string()))
208222
}
@@ -251,6 +265,46 @@ pub enum ExecutionContext {
251265
},
252266
}
253267

268+
#[cfg(test)]
269+
mod tests {
270+
use crate::acl::RemoteUrlPattern;
271+
272+
#[test]
273+
fn url_pattern_domain_wildcard() {
274+
let pattern: RemoteUrlPattern = "http://*".parse().unwrap();
275+
276+
assert!(pattern.test(&"http://tauri.app/path".parse().unwrap()));
277+
assert!(pattern.test(&"http://tauri.app/path?q=1".parse().unwrap()));
278+
279+
assert!(pattern.test(&"http://localhost/path".parse().unwrap()));
280+
assert!(pattern.test(&"http://localhost/path?q=1".parse().unwrap()));
281+
282+
let pattern: RemoteUrlPattern = "http://*.tauri.app".parse().unwrap();
283+
284+
assert!(!pattern.test(&"http://tauri.app/path".parse().unwrap()));
285+
assert!(!pattern.test(&"http://tauri.app/path?q=1".parse().unwrap()));
286+
assert!(pattern.test(&"http://api.tauri.app/path".parse().unwrap()));
287+
assert!(pattern.test(&"http://api.tauri.app/path?q=1".parse().unwrap()));
288+
assert!(!pattern.test(&"http://localhost/path".parse().unwrap()));
289+
assert!(!pattern.test(&"http://localhost/path?q=1".parse().unwrap()));
290+
}
291+
292+
#[test]
293+
fn url_pattern_path_wildcard() {
294+
let pattern: RemoteUrlPattern = "http://localhost/*".parse().unwrap();
295+
assert!(pattern.test(&"http://localhost/path".parse().unwrap()));
296+
assert!(pattern.test(&"http://localhost/path?q=1".parse().unwrap()));
297+
}
298+
299+
#[test]
300+
fn url_pattern_scheme_wildcard() {
301+
let pattern: RemoteUrlPattern = "*://localhost".parse().unwrap();
302+
assert!(pattern.test(&"http://localhost/path".parse().unwrap()));
303+
assert!(pattern.test(&"https://localhost/path?q=1".parse().unwrap()));
304+
assert!(pattern.test(&"custom://localhost/path".parse().unwrap()));
305+
}
306+
}
307+
254308
#[cfg(feature = "build")]
255309
mod build_ {
256310
use std::convert::identity;

core/tests/acl/fixtures/snapshots/acl_tests__tests__file-explorer-remote.snap

Lines changed: 48 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -90,50 +90,59 @@ Resolved {
9090
},
9191
},
9292
pathname: Component {
93-
pattern_string: "/",
93+
pattern_string: "*",
9494
regexp: Ok(
9595
Regex(
96-
"^/$",
96+
"^(.*)$",
9797
),
9898
),
99-
group_name_list: [],
99+
group_name_list: [
100+
"0",
101+
],
100102
matcher: Matcher {
101103
prefix: "",
102104
suffix: "",
103-
inner: Literal {
104-
literal: "/",
105+
inner: SingleCapture {
106+
filter: None,
107+
allow_empty: true,
105108
},
106109
},
107110
},
108111
search: Component {
109-
pattern_string: "",
112+
pattern_string: "*",
110113
regexp: Ok(
111114
Regex(
112-
"^$",
115+
"^(.*)$",
113116
),
114117
),
115-
group_name_list: [],
118+
group_name_list: [
119+
"0",
120+
],
116121
matcher: Matcher {
117122
prefix: "",
118123
suffix: "",
119-
inner: Literal {
120-
literal: "",
124+
inner: SingleCapture {
125+
filter: None,
126+
allow_empty: true,
121127
},
122128
},
123129
},
124130
hash: Component {
125-
pattern_string: "",
131+
pattern_string: "*",
126132
regexp: Ok(
127133
Regex(
128-
"^$",
134+
"^(.*)$",
129135
),
130136
),
131-
group_name_list: [],
137+
group_name_list: [
138+
"0",
139+
],
132140
matcher: Matcher {
133141
prefix: "",
134142
suffix: "",
135-
inner: Literal {
136-
literal: "",
143+
inner: SingleCapture {
144+
filter: None,
145+
allow_empty: true,
137146
},
138147
},
139148
},
@@ -251,50 +260,59 @@ Resolved {
251260
},
252261
},
253262
pathname: Component {
254-
pattern_string: "/",
263+
pattern_string: "*",
255264
regexp: Ok(
256265
Regex(
257-
"^/$",
266+
"^(.*)$",
258267
),
259268
),
260-
group_name_list: [],
269+
group_name_list: [
270+
"0",
271+
],
261272
matcher: Matcher {
262273
prefix: "",
263274
suffix: "",
264-
inner: Literal {
265-
literal: "/",
275+
inner: SingleCapture {
276+
filter: None,
277+
allow_empty: true,
266278
},
267279
},
268280
},
269281
search: Component {
270-
pattern_string: "",
282+
pattern_string: "*",
271283
regexp: Ok(
272284
Regex(
273-
"^$",
285+
"^(.*)$",
274286
),
275287
),
276-
group_name_list: [],
288+
group_name_list: [
289+
"0",
290+
],
277291
matcher: Matcher {
278292
prefix: "",
279293
suffix: "",
280-
inner: Literal {
281-
literal: "",
294+
inner: SingleCapture {
295+
filter: None,
296+
allow_empty: true,
282297
},
283298
},
284299
},
285300
hash: Component {
286-
pattern_string: "",
301+
pattern_string: "*",
287302
regexp: Ok(
288303
Regex(
289-
"^$",
304+
"^(.*)$",
290305
),
291306
),
292-
group_name_list: [],
307+
group_name_list: [
308+
"0",
309+
],
293310
matcher: Matcher {
294311
prefix: "",
295312
suffix: "",
296-
inner: Literal {
297-
literal: "",
313+
inner: SingleCapture {
314+
filter: None,
315+
allow_empty: true,
298316
},
299317
},
300318
},

examples/api/src-tauri/capabilities/run-app.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22
"$schema": "../gen/schemas/desktop-schema.json",
33
"identifier": "run-app",
44
"description": "permissions to run the app",
5-
"windows": ["main", "main-*"],
5+
"windows": [
6+
"main",
7+
"main-*"
8+
],
69
"permissions": [
710
{
811
"identifier": "allow-log-operation",
@@ -96,4 +99,4 @@
9699
"tray:allow-set-icon-as-template",
97100
"tray:allow-set-show-menu-on-left-click"
98101
]
99-
}
102+
}

tooling/cli/schema.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1141,7 +1141,7 @@
11411141
],
11421142
"properties": {
11431143
"urls": {
1144-
"description": "Remote domains this capability refers to using the [URLPattern standard](https://urlpattern.spec.whatwg.org/).",
1144+
"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",
11451145
"type": "array",
11461146
"items": {
11471147
"type": "string"

0 commit comments

Comments
 (0)