mirror of
https://github.com/tauri-apps/plugins-workspace.git
synced 2026-04-23 11:36:13 +02:00
refactor: move deleted tauri APIs, prepare for next release (#355)
This commit is contained in:
committed by
GitHub
parent
937e6a5be6
commit
702b7b36bd
@@ -0,0 +1,148 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use serde::{de::Error as DeError, Deserialize, Deserializer};
|
||||
|
||||
/// Allowlist for the shell APIs.
|
||||
///
|
||||
/// See more: https://tauri.app/v1/api/config#shellallowlistconfig
|
||||
#[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize)]
|
||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||
pub struct Config {
|
||||
/// Access scope for the binary execution APIs.
|
||||
/// Sidecars are automatically enabled.
|
||||
#[serde(default)]
|
||||
pub scope: ShellAllowlistScope,
|
||||
/// Open URL with the user's default application.
|
||||
#[serde(default)]
|
||||
pub open: ShellAllowlistOpen,
|
||||
}
|
||||
|
||||
/// A command allowed to be executed by the webview API.
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub struct ShellAllowedCommand {
|
||||
/// The name for this allowed shell command configuration.
|
||||
///
|
||||
/// This name will be used inside of the webview API to call this command along with
|
||||
/// any specified arguments.
|
||||
pub name: String,
|
||||
|
||||
/// The command name.
|
||||
/// It can start with a variable that resolves to a system base directory.
|
||||
/// The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`,
|
||||
/// `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`,
|
||||
/// `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`,
|
||||
/// `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.
|
||||
// use default just so the schema doesn't flag it as required
|
||||
pub command: PathBuf,
|
||||
|
||||
/// The allowed arguments for the command execution.
|
||||
pub args: ShellAllowedArgs,
|
||||
|
||||
/// If this command is a sidecar command.
|
||||
pub sidecar: bool,
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for ShellAllowedCommand {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
#[derive(Deserialize)]
|
||||
struct InnerShellAllowedCommand {
|
||||
name: String,
|
||||
#[serde(rename = "cmd")]
|
||||
command: Option<PathBuf>,
|
||||
#[serde(default)]
|
||||
args: ShellAllowedArgs,
|
||||
#[serde(default)]
|
||||
sidecar: bool,
|
||||
}
|
||||
|
||||
let config = InnerShellAllowedCommand::deserialize(deserializer)?;
|
||||
|
||||
if !config.sidecar && config.command.is_none() {
|
||||
return Err(DeError::custom(
|
||||
"The shell scope `command` value is required.",
|
||||
));
|
||||
}
|
||||
|
||||
Ok(ShellAllowedCommand {
|
||||
name: config.name,
|
||||
command: config.command.unwrap_or_default(),
|
||||
args: config.args,
|
||||
sidecar: config.sidecar,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// A set of command arguments allowed to be executed by the webview API.
|
||||
///
|
||||
/// A value of `true` will allow any arguments to be passed to the command. `false` will disable all
|
||||
/// arguments. A list of [`ShellAllowedArg`] will set those arguments as the only valid arguments to
|
||||
/// be passed to the attached command configuration.
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Deserialize)]
|
||||
#[serde(untagged, deny_unknown_fields)]
|
||||
#[non_exhaustive]
|
||||
pub enum ShellAllowedArgs {
|
||||
/// Use a simple boolean to allow all or disable all arguments to this command configuration.
|
||||
Flag(bool),
|
||||
|
||||
/// A specific set of [`ShellAllowedArg`] that are valid to call for the command configuration.
|
||||
List(Vec<ShellAllowedArg>),
|
||||
}
|
||||
|
||||
impl Default for ShellAllowedArgs {
|
||||
fn default() -> Self {
|
||||
Self::Flag(false)
|
||||
}
|
||||
}
|
||||
|
||||
/// A command argument allowed to be executed by the webview API.
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Deserialize)]
|
||||
#[serde(untagged, deny_unknown_fields)]
|
||||
#[non_exhaustive]
|
||||
pub enum ShellAllowedArg {
|
||||
/// A non-configurable argument that is passed to the command in the order it was specified.
|
||||
Fixed(String),
|
||||
|
||||
/// A variable that is set while calling the command from the webview API.
|
||||
///
|
||||
Var {
|
||||
/// [regex] validator to require passed values to conform to an expected input.
|
||||
///
|
||||
/// This will require the argument value passed to this variable to match the `validator` regex
|
||||
/// before it will be executed.
|
||||
///
|
||||
/// [regex]: https://docs.rs/regex/latest/regex/#syntax
|
||||
validator: String,
|
||||
},
|
||||
}
|
||||
|
||||
/// Shell scope definition.
|
||||
/// It is a list of command names and associated CLI arguments that restrict the API access from the webview.
|
||||
#[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize)]
|
||||
|
||||
pub struct ShellAllowlistScope(pub Vec<ShellAllowedCommand>);
|
||||
|
||||
/// Defines the `shell > open` api scope.
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Deserialize)]
|
||||
#[serde(untagged, deny_unknown_fields)]
|
||||
#[non_exhaustive]
|
||||
pub enum ShellAllowlistOpen {
|
||||
/// If the shell open API should be enabled.
|
||||
///
|
||||
/// If enabled, the default validation regex (`^((mailto:\w+)|(tel:\w+)|(https?://\w+)).+`) is used.
|
||||
Flag(bool),
|
||||
|
||||
/// Enable the shell open API, with a custom regex that the opened path must match against.
|
||||
///
|
||||
/// If using a custom regex to support a non-http(s) schema, care should be used to prevent values
|
||||
/// that allow flag-like strings to pass validation. e.g. `--enable-debugging`, `-i`, `/R`.
|
||||
Validate(String),
|
||||
}
|
||||
|
||||
impl Default for ShellAllowlistOpen {
|
||||
fn default() -> Self {
|
||||
Self::Flag(false)
|
||||
}
|
||||
}
|
||||
@@ -8,16 +8,17 @@ use regex::Regex;
|
||||
use scope::{Scope, ScopeAllowedCommand, ScopeConfig};
|
||||
use tauri::{
|
||||
plugin::{Builder, TauriPlugin},
|
||||
utils::config::{ShellAllowedArg, ShellAllowedArgs, ShellAllowlistOpen, ShellAllowlistScope},
|
||||
AppHandle, Manager, RunEvent, Runtime,
|
||||
};
|
||||
|
||||
mod commands;
|
||||
mod config;
|
||||
mod error;
|
||||
mod open;
|
||||
pub mod process;
|
||||
mod scope;
|
||||
|
||||
use config::{Config, ShellAllowedArg, ShellAllowedArgs, ShellAllowlistOpen, ShellAllowlistScope};
|
||||
pub use error::Error;
|
||||
type Result<T> = std::result::Result<T, Error>;
|
||||
type ChildStore = Arc<Mutex<HashMap<u32, CommandChild>>>;
|
||||
@@ -61,25 +62,21 @@ impl<R: Runtime, T: Manager<R>> ShellExt<R> for T {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init<R: Runtime>() -> TauriPlugin<R> {
|
||||
Builder::new("shell")
|
||||
pub fn init<R: Runtime>() -> TauriPlugin<R, Option<Config>> {
|
||||
Builder::<R, Option<Config>>::new("shell")
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
commands::execute,
|
||||
commands::stdin_write,
|
||||
commands::kill,
|
||||
commands::open
|
||||
])
|
||||
.setup(|app, _api| {
|
||||
.setup(|app, api| {
|
||||
let default_config = Config::default();
|
||||
let config = api.config().as_ref().unwrap_or(&default_config);
|
||||
app.manage(Shell {
|
||||
app: app.clone(),
|
||||
children: Default::default(),
|
||||
scope: Scope::new(
|
||||
app,
|
||||
shell_scope(
|
||||
app.config().tauri.allowlist.shell.scope.clone(),
|
||||
&app.config().tauri.allowlist.shell.open,
|
||||
),
|
||||
),
|
||||
scope: Scope::new(app, shell_scope(config.scope.clone(), &config.open)),
|
||||
});
|
||||
Ok(())
|
||||
})
|
||||
@@ -111,7 +108,6 @@ fn shell_scope(scope: ShellAllowlistScope, open: &ShellAllowlistOpen) -> ScopeCo
|
||||
Regex::new(validator).unwrap_or_else(|e| panic!("invalid regex {validator}: {e}"));
|
||||
Some(validator)
|
||||
}
|
||||
_ => panic!("unknown shell open format, unable to prepare"),
|
||||
};
|
||||
|
||||
ScopeConfig {
|
||||
@@ -136,11 +132,9 @@ fn get_allowed_clis(scope: ShellAllowlistScope) -> HashMap<String, ScopeAllowedC
|
||||
.unwrap_or_else(|e| panic!("invalid regex {validator}: {e}"));
|
||||
scope::ScopeAllowedArg::Var { validator }
|
||||
}
|
||||
_ => panic!("unknown shell scope arg, unable to prepare"),
|
||||
});
|
||||
Some(list.collect())
|
||||
}
|
||||
_ => panic!("unknown shell scope command, unable to prepare"),
|
||||
};
|
||||
|
||||
(
|
||||
|
||||
Reference in New Issue
Block a user