mirror of https://github.com/tauri-apps/tauri
feat: Add option to generate default permissions for inlined plugins (#10559)
* feat: Add option to allow all commands by default * option to use a list of permissions, move logic to tauri-build * fix plugin * add utils change file --------- Co-authored-by: Lucas Nogueira <lucas@tauri.app>
This commit is contained in:
parent
213c0b1b8e
commit
0bb7b0f352
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
"tauri-build": patch:feat
|
||||
---
|
||||
|
||||
Added `InlinedPlugin::default_permission` to autogenerate the default permission of an inlined plugin.
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
"tauri-utils": patch:enhance
|
||||
---
|
||||
|
||||
Return autogenerated permissions from `autogenerate_command_permissions`.
|
|
@ -42,6 +42,19 @@ const ACL_MANIFESTS_FILE_NAME: &str = "acl-manifests.json";
|
|||
pub struct InlinedPlugin {
|
||||
commands: &'static [&'static str],
|
||||
permissions_path_pattern: Option<&'static str>,
|
||||
default: Option<DefaultPermissionRule>,
|
||||
}
|
||||
|
||||
/// Variants of a generated default permission that can be used on an [`InlinedPlugin`].
|
||||
#[derive(Debug)]
|
||||
pub enum DefaultPermissionRule {
|
||||
/// Allow all commands from [`InlinedPlugin::commands`].
|
||||
AllowAllCommands,
|
||||
/// Allow the given list of permissions.
|
||||
///
|
||||
/// Note that the list refers to permissions instead of command names,
|
||||
/// so for example a command called `execute` would need to be allowed as `allow-execute`.
|
||||
Allow(Vec<String>),
|
||||
}
|
||||
|
||||
impl InlinedPlugin {
|
||||
|
@ -65,6 +78,14 @@ impl InlinedPlugin {
|
|||
self.permissions_path_pattern.replace(pattern);
|
||||
self
|
||||
}
|
||||
|
||||
/// Creates a default permission for the plugin using the given rule.
|
||||
///
|
||||
/// Alternatively you can pull a permission in the filesystem in the permissions directory, see [`Self::permissions_path_pattern`].
|
||||
pub fn default_permission(mut self, default: DefaultPermissionRule) -> Self {
|
||||
self.default.replace(default);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// Tauri application permission manifest.
|
||||
|
@ -337,12 +358,35 @@ pub fn inline_plugins(
|
|||
let mut permission_files = if plugin.commands.is_empty() {
|
||||
Vec::new()
|
||||
} else {
|
||||
tauri_utils::acl::build::autogenerate_command_permissions(
|
||||
let autogenerated = tauri_utils::acl::build::autogenerate_command_permissions(
|
||||
&plugin_out_dir,
|
||||
plugin.commands,
|
||||
"",
|
||||
false,
|
||||
);
|
||||
|
||||
let default_permissions = plugin.default.map(|default| match default {
|
||||
DefaultPermissionRule::AllowAllCommands => autogenerated.allowed,
|
||||
DefaultPermissionRule::Allow(permissions) => permissions,
|
||||
});
|
||||
if let Some(default_permissions) = default_permissions {
|
||||
let default_permission_toml = format!(
|
||||
r###"# Automatically generated - DO NOT EDIT!
|
||||
[default]
|
||||
permissions = [{default_permissions}]
|
||||
"###,
|
||||
default_permissions = default_permissions
|
||||
.iter()
|
||||
.map(|p| format!("\"{p}\""))
|
||||
.collect::<Vec<String>>()
|
||||
.join(",")
|
||||
);
|
||||
|
||||
let default_permission_toml_path = plugin_out_dir.join("default.toml");
|
||||
|
||||
write_if_changed(&default_permission_toml, &default_permission_toml_path);
|
||||
}
|
||||
|
||||
tauri_utils::acl::build::define_permissions(
|
||||
&plugin_out_dir.join("*").to_string_lossy(),
|
||||
name,
|
||||
|
@ -384,6 +428,12 @@ pub fn inline_plugins(
|
|||
Ok(acl_manifests)
|
||||
}
|
||||
|
||||
fn write_if_changed(content: &str, path: &Path) {
|
||||
if content != read_to_string(path).unwrap_or_default() {
|
||||
std::fs::write(path, content).unwrap_or_else(|_| panic!("unable to autogenerate {path:?}"));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn app_manifest_permissions(
|
||||
out_dir: &Path,
|
||||
manifest: AppManifest,
|
||||
|
|
|
@ -373,6 +373,17 @@ impl Attributes {
|
|||
self
|
||||
}
|
||||
|
||||
/// Adds the given list of plugins to the list of inlined plugins (a plugin that is part of your application).
|
||||
///
|
||||
/// See [`InlinedPlugin`] for more information.
|
||||
pub fn plugins<I>(mut self, plugins: I) -> Self
|
||||
where
|
||||
I: IntoIterator<Item = (&'static str, InlinedPlugin)>,
|
||||
{
|
||||
self.inlined_plugins.extend(plugins);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the application manifest for the Access Control List.
|
||||
///
|
||||
/// See [`AppManifest`] for more information.
|
||||
|
|
|
@ -388,13 +388,21 @@ fn parse_permissions(paths: Vec<PathBuf>) -> Result<Vec<PermissionFile>, Error>
|
|||
Ok(permissions)
|
||||
}
|
||||
|
||||
/// Permissions that are generated from commands using [`autogenerate_command_permissions`].
|
||||
pub struct AutogeneratedPermissions {
|
||||
/// The allow permissions generated from commands.
|
||||
pub allowed: Vec<String>,
|
||||
/// The deny permissions generated from commands.
|
||||
pub denied: Vec<String>,
|
||||
}
|
||||
|
||||
/// Autogenerate permission files for a list of commands.
|
||||
pub fn autogenerate_command_permissions(
|
||||
path: &Path,
|
||||
commands: &[&str],
|
||||
license_header: &str,
|
||||
schema_ref: bool,
|
||||
) {
|
||||
) -> AutogeneratedPermissions {
|
||||
if !path.exists() {
|
||||
create_dir_all(path).expect("unable to create autogenerated commands dir");
|
||||
}
|
||||
|
@ -418,8 +426,14 @@ pub fn autogenerate_command_permissions(
|
|||
"".to_string()
|
||||
};
|
||||
|
||||
let mut autogenerated = AutogeneratedPermissions {
|
||||
allowed: Vec::new(),
|
||||
denied: Vec::new(),
|
||||
};
|
||||
|
||||
for command in commands {
|
||||
let slugified_command = command.replace('_', "-");
|
||||
|
||||
let toml = format!(
|
||||
r###"{license_header}# Automatically generated - DO NOT EDIT!
|
||||
{schema_entry}
|
||||
|
@ -436,9 +450,21 @@ commands.deny = ["{command}"]
|
|||
);
|
||||
|
||||
let out_path = path.join(format!("{command}.toml"));
|
||||
if toml != read_to_string(&out_path).unwrap_or_default() {
|
||||
std::fs::write(out_path, toml)
|
||||
.unwrap_or_else(|_| panic!("unable to autogenerate ${command}.toml"));
|
||||
}
|
||||
write_if_changed(&toml, &out_path);
|
||||
|
||||
autogenerated
|
||||
.allowed
|
||||
.push(format!("allow-{slugified_command}"));
|
||||
autogenerated
|
||||
.denied
|
||||
.push(format!("deny-{slugified_command}"));
|
||||
}
|
||||
|
||||
autogenerated
|
||||
}
|
||||
|
||||
fn write_if_changed(content: &str, path: &Path) {
|
||||
if content != read_to_string(path).unwrap_or_default() {
|
||||
std::fs::write(path, content).unwrap_or_else(|_| panic!("unable to autogenerate {path:?}"));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue