mirror of https://github.com/tauri-apps/tauri
refactor(core): allow configuring both local and remote URLs on capability (#8950)
This commit is contained in:
parent
e538ba586c
commit
a76fb118ce
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
"tauri-utils": patch:breaking
|
||||||
|
"tauri-cli": patch:breaking
|
||||||
|
"@tauri-apps/cli": patch:breaking
|
||||||
|
---
|
||||||
|
|
||||||
|
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.
|
|
@ -1085,15 +1085,22 @@
|
||||||
"default": "",
|
"default": "",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"context": {
|
"remote": {
|
||||||
"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.",
|
"description": "Configure remote URLs that can use the capability permissions.",
|
||||||
"default": "local",
|
"anyOf": [
|
||||||
"allOf": [
|
|
||||||
{
|
{
|
||||||
"$ref": "#/definitions/CapabilityContext"
|
"$ref": "#/definitions/CapabilityRemote"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"local": {
|
||||||
|
"description": "Whether this capability is enabled for local app URLs or not. Defaults to `true`.",
|
||||||
|
"default": true,
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"windows": {
|
"windows": {
|
||||||
"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.",
|
"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.",
|
||||||
"type": "array",
|
"type": "array",
|
||||||
|
@ -1131,42 +1138,21 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"CapabilityContext": {
|
"CapabilityRemote": {
|
||||||
"description": "Context of the capability.",
|
"description": "Configuration for remote URLs that are associated with the capability.",
|
||||||
"oneOf": [
|
"type": "object",
|
||||||
{
|
"required": [
|
||||||
"description": "Capability refers to local URL usage.",
|
"urls"
|
||||||
"type": "string",
|
],
|
||||||
"enum": [
|
"properties": {
|
||||||
"local"
|
"urls": {
|
||||||
]
|
"description": "Remote domains this capability refers to. Can use glob patterns.",
|
||||||
},
|
"type": "array",
|
||||||
{
|
"items": {
|
||||||
"description": "Capability refers to remote usage.",
|
"type": "string"
|
||||||
"type": "object",
|
}
|
||||||
"required": [
|
|
||||||
"remote"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"remote": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"urls"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"urls": {
|
|
||||||
"description": "Remote domains this capability refers to. Can use glob patterns.",
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
},
|
},
|
||||||
"PermissionEntry": {
|
"PermissionEntry": {
|
||||||
"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.",
|
"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.",
|
||||||
|
|
|
@ -56,11 +56,11 @@ pub struct Capability {
|
||||||
/// Description of the capability.
|
/// Description of the capability.
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub description: String,
|
pub description: String,
|
||||||
/// Execution context of the capability.
|
/// Configure remote URLs that can use the capability permissions.
|
||||||
///
|
pub remote: Option<CapabilityRemote>,
|
||||||
/// At runtime, Tauri filters the IPC command together with the context to determine whether it is allowed or not and its scope.
|
/// Whether this capability is enabled for local app URLs or not. Defaults to `true`.
|
||||||
#[serde(default)]
|
#[serde(default = "default_capability_local")]
|
||||||
pub context: CapabilityContext,
|
pub local: bool,
|
||||||
/// List of windows that uses this capability. Can be a glob pattern.
|
/// List of windows that uses this capability. Can be a glob pattern.
|
||||||
///
|
///
|
||||||
/// On multiwebview windows, prefer [`Self::webviews`] for a fine grained access control.
|
/// On multiwebview windows, prefer [`Self::webviews`] for a fine grained access control.
|
||||||
|
@ -78,6 +78,10 @@ pub struct Capability {
|
||||||
pub platforms: Vec<Target>,
|
pub platforms: Vec<Target>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn default_capability_local() -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
fn default_platforms() -> Vec<Target> {
|
fn default_platforms() -> Vec<Target> {
|
||||||
vec![
|
vec![
|
||||||
Target::Linux,
|
Target::Linux,
|
||||||
|
@ -88,19 +92,13 @@ fn default_platforms() -> Vec<Target> {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Context of the capability.
|
/// Configuration for remote URLs that are associated with the capability.
|
||||||
#[derive(Debug, Default, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Default, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub enum CapabilityContext {
|
pub struct CapabilityRemote {
|
||||||
/// Capability refers to local URL usage.
|
/// Remote domains this capability refers to. Can use glob patterns.
|
||||||
#[default]
|
pub urls: Vec<String>,
|
||||||
Local,
|
|
||||||
/// Capability refers to remote usage.
|
|
||||||
Remote {
|
|
||||||
/// Remote domains this capability refers to. Can use glob patterns.
|
|
||||||
urls: Vec<String>,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Capability formats accepted in a capability file.
|
/// Capability formats accepted in a capability file.
|
||||||
|
@ -154,19 +152,14 @@ mod build {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{literal_struct, tokens::*};
|
use crate::{literal_struct, tokens::*};
|
||||||
|
|
||||||
impl ToTokens for CapabilityContext {
|
impl ToTokens for CapabilityRemote {
|
||||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||||
let prefix = quote! { ::tauri::utils::acl::capability::CapabilityContext };
|
let urls = vec_lit(&self.urls, str_lit);
|
||||||
|
literal_struct!(
|
||||||
tokens.append_all(match self {
|
tokens,
|
||||||
Self::Remote { urls } => {
|
::tauri::utils::acl::capability::CapabilityRemote,
|
||||||
let urls = vec_lit(urls, str_lit);
|
urls
|
||||||
quote! { #prefix::Remote { urls: #urls } }
|
);
|
||||||
}
|
|
||||||
Self::Local => {
|
|
||||||
quote! { #prefix::Local }
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,7 +185,8 @@ mod build {
|
||||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||||
let identifier = str_lit(&self.identifier);
|
let identifier = str_lit(&self.identifier);
|
||||||
let description = str_lit(&self.description);
|
let description = str_lit(&self.description);
|
||||||
let context = &self.context;
|
let remote = &self.remote;
|
||||||
|
let local = self.local;
|
||||||
let windows = vec_lit(&self.windows, str_lit);
|
let windows = vec_lit(&self.windows, str_lit);
|
||||||
let permissions = vec_lit(&self.permissions, identity);
|
let permissions = vec_lit(&self.permissions, identity);
|
||||||
let platforms = vec_lit(&self.platforms, identity);
|
let platforms = vec_lit(&self.platforms, identity);
|
||||||
|
@ -202,7 +196,8 @@ mod build {
|
||||||
::tauri::utils::acl::capability::Capability,
|
::tauri::utils::acl::capability::Capability,
|
||||||
identifier,
|
identifier,
|
||||||
description,
|
description,
|
||||||
context,
|
remote,
|
||||||
|
local,
|
||||||
windows,
|
windows,
|
||||||
permissions,
|
permissions,
|
||||||
platforms
|
platforms
|
||||||
|
|
|
@ -15,7 +15,7 @@ use glob::Pattern;
|
||||||
use crate::platform::Target;
|
use crate::platform::Target;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
capability::{Capability, CapabilityContext, PermissionEntry},
|
capability::{Capability, PermissionEntry},
|
||||||
plugin::Manifest,
|
plugin::Manifest,
|
||||||
Commands, Error, ExecutionContext, Permission, PermissionSet, Scopes, Value,
|
Commands, Error, ExecutionContext, Permission, PermissionSet, Scopes, Value,
|
||||||
};
|
};
|
||||||
|
@ -346,18 +346,18 @@ fn resolve_command(
|
||||||
scope_id: Option<ScopeKey>,
|
scope_id: Option<ScopeKey>,
|
||||||
#[cfg(debug_assertions)] referenced_by_permission_identifier: String,
|
#[cfg(debug_assertions)] referenced_by_permission_identifier: String,
|
||||||
) {
|
) {
|
||||||
let contexts = match &capability.context {
|
let mut contexts = Vec::new();
|
||||||
CapabilityContext::Local => {
|
if capability.local {
|
||||||
vec![ExecutionContext::Local]
|
contexts.push(ExecutionContext::Local);
|
||||||
}
|
}
|
||||||
CapabilityContext::Remote { urls } => urls
|
if let Some(remote) = &capability.remote {
|
||||||
.iter()
|
contexts.extend(remote.urls.iter().map(|url| {
|
||||||
.map(|url| ExecutionContext::Remote {
|
ExecutionContext::Remote {
|
||||||
url: Pattern::new(url)
|
url: Pattern::new(url)
|
||||||
.unwrap_or_else(|e| panic!("invalid glob pattern for remote URL {url}: {e}")),
|
.unwrap_or_else(|e| panic!("invalid glob pattern for remote URL {url}: {e}")),
|
||||||
})
|
}
|
||||||
.collect(),
|
}));
|
||||||
};
|
}
|
||||||
|
|
||||||
for context in contexts {
|
for context in contexts {
|
||||||
let resolved = commands
|
let resolved = commands
|
||||||
|
|
|
@ -2,5 +2,6 @@ identifier = "run-app"
|
||||||
description = "app capability"
|
description = "app capability"
|
||||||
windows = ["main"]
|
windows = ["main"]
|
||||||
permissions = ["fs:read", "fs:allow-app"]
|
permissions = ["fs:read", "fs:allow-app"]
|
||||||
[context.remote]
|
local = false
|
||||||
|
[remote]
|
||||||
urls = ["https://tauri.app"]
|
urls = ["https://tauri.app"]
|
||||||
|
|
|
@ -1085,15 +1085,22 @@
|
||||||
"default": "",
|
"default": "",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"context": {
|
"remote": {
|
||||||
"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.",
|
"description": "Configure remote URLs that can use the capability permissions.",
|
||||||
"default": "local",
|
"anyOf": [
|
||||||
"allOf": [
|
|
||||||
{
|
{
|
||||||
"$ref": "#/definitions/CapabilityContext"
|
"$ref": "#/definitions/CapabilityRemote"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"local": {
|
||||||
|
"description": "Whether this capability is enabled for local app URLs or not. Defaults to `true`.",
|
||||||
|
"default": true,
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"windows": {
|
"windows": {
|
||||||
"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.",
|
"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.",
|
||||||
"type": "array",
|
"type": "array",
|
||||||
|
@ -1131,42 +1138,21 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"CapabilityContext": {
|
"CapabilityRemote": {
|
||||||
"description": "Context of the capability.",
|
"description": "Configuration for remote URLs that are associated with the capability.",
|
||||||
"oneOf": [
|
"type": "object",
|
||||||
{
|
"required": [
|
||||||
"description": "Capability refers to local URL usage.",
|
"urls"
|
||||||
"type": "string",
|
],
|
||||||
"enum": [
|
"properties": {
|
||||||
"local"
|
"urls": {
|
||||||
]
|
"description": "Remote domains this capability refers to. Can use glob patterns.",
|
||||||
},
|
"type": "array",
|
||||||
{
|
"items": {
|
||||||
"description": "Capability refers to remote usage.",
|
"type": "string"
|
||||||
"type": "object",
|
}
|
||||||
"required": [
|
|
||||||
"remote"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"remote": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"urls"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"urls": {
|
|
||||||
"description": "Remote domains this capability refers to. Can use glob patterns.",
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
},
|
},
|
||||||
"PermissionEntry": {
|
"PermissionEntry": {
|
||||||
"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.",
|
"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.",
|
||||||
|
|
|
@ -7,7 +7,7 @@ use crate::Result;
|
||||||
use serde_json::{Map, Value};
|
use serde_json::{Map, Value};
|
||||||
use tauri_utils::{
|
use tauri_utils::{
|
||||||
acl::{
|
acl::{
|
||||||
capability::{Capability, CapabilityContext, PermissionEntry},
|
capability::{Capability, PermissionEntry},
|
||||||
Scopes, Value as AclValue,
|
Scopes, Value as AclValue,
|
||||||
},
|
},
|
||||||
platform::Target,
|
platform::Target,
|
||||||
|
@ -59,7 +59,8 @@ pub fn migrate(tauri_dir: &Path) -> Result<()> {
|
||||||
serde_json::to_string_pretty(&Capability {
|
serde_json::to_string_pretty(&Capability {
|
||||||
identifier: "migrated".to_string(),
|
identifier: "migrated".to_string(),
|
||||||
description: "permissions that were migrated from v1".into(),
|
description: "permissions that were migrated from v1".into(),
|
||||||
context: CapabilityContext::Local,
|
local: true,
|
||||||
|
remote: None,
|
||||||
windows: vec!["main".into()],
|
windows: vec!["main".into()],
|
||||||
webviews: vec![],
|
webviews: vec![],
|
||||||
permissions,
|
permissions,
|
||||||
|
|
Loading…
Reference in New Issue