Skip to content

Commit a76fb11

Browse files
authored
refactor(core): allow configuring both local and remote URLs on capability (#8950)
1 parent e538ba5 commit a76fb11

File tree

7 files changed

+99
-123
lines changed

7 files changed

+99
-123
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"tauri-utils": patch:breaking
3+
"tauri-cli": patch:breaking
4+
"@tauri-apps/cli": patch:breaking
5+
---
6+
7+
Changed the capability format to allow configuring both `remote: { urls: Vec<String> }` and `local: bool (default: true)` instead of choosing one on the `context` field.

core/tauri-config-schema/schema.json

Lines changed: 26 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,15 +1085,22 @@
10851085
"default": "",
10861086
"type": "string"
10871087
},
1088-
"context": {
1089-
"description": "Execution context of the capability.\n\nAt runtime, Tauri filters the IPC command together with the context to determine whether it is allowed or not and its scope.",
1090-
"default": "local",
1091-
"allOf": [
1088+
"remote": {
1089+
"description": "Configure remote URLs that can use the capability permissions.",
1090+
"anyOf": [
10921091
{
1093-
"$ref": "#/definitions/CapabilityContext"
1092+
"$ref": "#/definitions/CapabilityRemote"
1093+
},
1094+
{
1095+
"type": "null"
10941096
}
10951097
]
10961098
},
1099+
"local": {
1100+
"description": "Whether this capability is enabled for local app URLs or not. Defaults to `true`.",
1101+
"default": true,
1102+
"type": "boolean"
1103+
},
10971104
"windows": {
10981105
"description": "List of windows that uses this capability. Can be a glob pattern.\n\nOn multiwebview windows, prefer [`Self::webviews`] for a fine grained access control.",
10991106
"type": "array",
@@ -1131,42 +1138,21 @@
11311138
}
11321139
}
11331140
},
1134-
"CapabilityContext": {
1135-
"description": "Context of the capability.",
1136-
"oneOf": [
1137-
{
1138-
"description": "Capability refers to local URL usage.",
1139-
"type": "string",
1140-
"enum": [
1141-
"local"
1142-
]
1143-
},
1144-
{
1145-
"description": "Capability refers to remote usage.",
1146-
"type": "object",
1147-
"required": [
1148-
"remote"
1149-
],
1150-
"properties": {
1151-
"remote": {
1152-
"type": "object",
1153-
"required": [
1154-
"urls"
1155-
],
1156-
"properties": {
1157-
"urls": {
1158-
"description": "Remote domains this capability refers to. Can use glob patterns.",
1159-
"type": "array",
1160-
"items": {
1161-
"type": "string"
1162-
}
1163-
}
1164-
}
1165-
}
1166-
},
1167-
"additionalProperties": false
1141+
"CapabilityRemote": {
1142+
"description": "Configuration for remote URLs that are associated with the capability.",
1143+
"type": "object",
1144+
"required": [
1145+
"urls"
1146+
],
1147+
"properties": {
1148+
"urls": {
1149+
"description": "Remote domains this capability refers to. Can use glob patterns.",
1150+
"type": "array",
1151+
"items": {
1152+
"type": "string"
1153+
}
11681154
}
1169-
]
1155+
}
11701156
},
11711157
"PermissionEntry": {
11721158
"description": "An entry for a permission value in a [`Capability`] can be either a raw permission [`Identifier`] or an object that references a permission and extends its scope.",

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

Lines changed: 24 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,11 @@ pub struct Capability {
5656
/// Description of the capability.
5757
#[serde(default)]
5858
pub description: String,
59-
/// Execution context of the capability.
60-
///
61-
/// At runtime, Tauri filters the IPC command together with the context to determine whether it is allowed or not and its scope.
62-
#[serde(default)]
63-
pub context: CapabilityContext,
59+
/// Configure remote URLs that can use the capability permissions.
60+
pub remote: Option<CapabilityRemote>,
61+
/// Whether this capability is enabled for local app URLs or not. Defaults to `true`.
62+
#[serde(default = "default_capability_local")]
63+
pub local: bool,
6464
/// List of windows that uses this capability. Can be a glob pattern.
6565
///
6666
/// On multiwebview windows, prefer [`Self::webviews`] for a fine grained access control.
@@ -78,6 +78,10 @@ pub struct Capability {
7878
pub platforms: Vec<Target>,
7979
}
8080

81+
fn default_capability_local() -> bool {
82+
true
83+
}
84+
8185
fn default_platforms() -> Vec<Target> {
8286
vec![
8387
Target::Linux,
@@ -88,19 +92,13 @@ fn default_platforms() -> Vec<Target> {
8892
]
8993
}
9094

91-
/// Context of the capability.
95+
/// Configuration for remote URLs that are associated with the capability.
9296
#[derive(Debug, Default, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord, Hash)]
9397
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
9498
#[serde(rename_all = "camelCase")]
95-
pub enum CapabilityContext {
96-
/// Capability refers to local URL usage.
97-
#[default]
98-
Local,
99-
/// Capability refers to remote usage.
100-
Remote {
101-
/// Remote domains this capability refers to. Can use glob patterns.
102-
urls: Vec<String>,
103-
},
99+
pub struct CapabilityRemote {
100+
/// Remote domains this capability refers to. Can use glob patterns.
101+
pub urls: Vec<String>,
104102
}
105103

106104
/// Capability formats accepted in a capability file.
@@ -154,19 +152,14 @@ mod build {
154152
use super::*;
155153
use crate::{literal_struct, tokens::*};
156154

157-
impl ToTokens for CapabilityContext {
155+
impl ToTokens for CapabilityRemote {
158156
fn to_tokens(&self, tokens: &mut TokenStream) {
159-
let prefix = quote! { ::tauri::utils::acl::capability::CapabilityContext };
160-
161-
tokens.append_all(match self {
162-
Self::Remote { urls } => {
163-
let urls = vec_lit(urls, str_lit);
164-
quote! { #prefix::Remote { urls: #urls } }
165-
}
166-
Self::Local => {
167-
quote! { #prefix::Local }
168-
}
169-
});
157+
let urls = vec_lit(&self.urls, str_lit);
158+
literal_struct!(
159+
tokens,
160+
::tauri::utils::acl::capability::CapabilityRemote,
161+
urls
162+
);
170163
}
171164
}
172165

@@ -192,7 +185,8 @@ mod build {
192185
fn to_tokens(&self, tokens: &mut TokenStream) {
193186
let identifier = str_lit(&self.identifier);
194187
let description = str_lit(&self.description);
195-
let context = &self.context;
188+
let remote = &self.remote;
189+
let local = self.local;
196190
let windows = vec_lit(&self.windows, str_lit);
197191
let permissions = vec_lit(&self.permissions, identity);
198192
let platforms = vec_lit(&self.platforms, identity);
@@ -202,7 +196,8 @@ mod build {
202196
::tauri::utils::acl::capability::Capability,
203197
identifier,
204198
description,
205-
context,
199+
remote,
200+
local,
206201
windows,
207202
permissions,
208203
platforms

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

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use glob::Pattern;
1515
use crate::platform::Target;
1616

1717
use super::{
18-
capability::{Capability, CapabilityContext, PermissionEntry},
18+
capability::{Capability, PermissionEntry},
1919
plugin::Manifest,
2020
Commands, Error, ExecutionContext, Permission, PermissionSet, Scopes, Value,
2121
};
@@ -346,18 +346,18 @@ fn resolve_command(
346346
scope_id: Option<ScopeKey>,
347347
#[cfg(debug_assertions)] referenced_by_permission_identifier: String,
348348
) {
349-
let contexts = match &capability.context {
350-
CapabilityContext::Local => {
351-
vec![ExecutionContext::Local]
352-
}
353-
CapabilityContext::Remote { urls } => urls
354-
.iter()
355-
.map(|url| ExecutionContext::Remote {
349+
let mut contexts = Vec::new();
350+
if capability.local {
351+
contexts.push(ExecutionContext::Local);
352+
}
353+
if let Some(remote) = &capability.remote {
354+
contexts.extend(remote.urls.iter().map(|url| {
355+
ExecutionContext::Remote {
356356
url: Pattern::new(url)
357357
.unwrap_or_else(|e| panic!("invalid glob pattern for remote URL {url}: {e}")),
358-
})
359-
.collect(),
360-
};
358+
}
359+
}));
360+
}
361361

362362
for context in contexts {
363363
let resolved = commands

core/tests/acl/fixtures/capabilities/file-explorer-remote/cap.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@ identifier = "run-app"
22
description = "app capability"
33
windows = ["main"]
44
permissions = ["fs:read", "fs:allow-app"]
5-
[context.remote]
5+
local = false
6+
[remote]
67
urls = ["https://tauri.app"]

tooling/cli/schema.json

Lines changed: 26 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,15 +1085,22 @@
10851085
"default": "",
10861086
"type": "string"
10871087
},
1088-
"context": {
1089-
"description": "Execution context of the capability.\n\nAt runtime, Tauri filters the IPC command together with the context to determine whether it is allowed or not and its scope.",
1090-
"default": "local",
1091-
"allOf": [
1088+
"remote": {
1089+
"description": "Configure remote URLs that can use the capability permissions.",
1090+
"anyOf": [
10921091
{
1093-
"$ref": "#/definitions/CapabilityContext"
1092+
"$ref": "#/definitions/CapabilityRemote"
1093+
},
1094+
{
1095+
"type": "null"
10941096
}
10951097
]
10961098
},
1099+
"local": {
1100+
"description": "Whether this capability is enabled for local app URLs or not. Defaults to `true`.",
1101+
"default": true,
1102+
"type": "boolean"
1103+
},
10971104
"windows": {
10981105
"description": "List of windows that uses this capability. Can be a glob pattern.\n\nOn multiwebview windows, prefer [`Self::webviews`] for a fine grained access control.",
10991106
"type": "array",
@@ -1131,42 +1138,21 @@
11311138
}
11321139
}
11331140
},
1134-
"CapabilityContext": {
1135-
"description": "Context of the capability.",
1136-
"oneOf": [
1137-
{
1138-
"description": "Capability refers to local URL usage.",
1139-
"type": "string",
1140-
"enum": [
1141-
"local"
1142-
]
1143-
},
1144-
{
1145-
"description": "Capability refers to remote usage.",
1146-
"type": "object",
1147-
"required": [
1148-
"remote"
1149-
],
1150-
"properties": {
1151-
"remote": {
1152-
"type": "object",
1153-
"required": [
1154-
"urls"
1155-
],
1156-
"properties": {
1157-
"urls": {
1158-
"description": "Remote domains this capability refers to. Can use glob patterns.",
1159-
"type": "array",
1160-
"items": {
1161-
"type": "string"
1162-
}
1163-
}
1164-
}
1165-
}
1166-
},
1167-
"additionalProperties": false
1141+
"CapabilityRemote": {
1142+
"description": "Configuration for remote URLs that are associated with the capability.",
1143+
"type": "object",
1144+
"required": [
1145+
"urls"
1146+
],
1147+
"properties": {
1148+
"urls": {
1149+
"description": "Remote domains this capability refers to. Can use glob patterns.",
1150+
"type": "array",
1151+
"items": {
1152+
"type": "string"
1153+
}
11681154
}
1169-
]
1155+
}
11701156
},
11711157
"PermissionEntry": {
11721158
"description": "An entry for a permission value in a [`Capability`] can be either a raw permission [`Identifier`] or an object that references a permission and extends its scope.",

tooling/cli/src/migrate/config.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::Result;
77
use serde_json::{Map, Value};
88
use tauri_utils::{
99
acl::{
10-
capability::{Capability, CapabilityContext, PermissionEntry},
10+
capability::{Capability, PermissionEntry},
1111
Scopes, Value as AclValue,
1212
},
1313
platform::Target,
@@ -59,7 +59,8 @@ pub fn migrate(tauri_dir: &Path) -> Result<()> {
5959
serde_json::to_string_pretty(&Capability {
6060
identifier: "migrated".to_string(),
6161
description: "permissions that were migrated from v1".into(),
62-
context: CapabilityContext::Local,
62+
local: true,
63+
remote: None,
6364
windows: vec!["main".into()],
6465
webviews: vec![],
6566
permissions,

0 commit comments

Comments
 (0)