fix persisted-scope plugin (ouchie)

pull/468/head
FabianLars 2 years ago
parent b5d50843a7
commit 57701f1f9c
No known key found for this signature in database
GPG Key ID: 3B12BC1DEBF61125

@ -15,11 +15,12 @@ use aho_corasick::AhoCorasick;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tauri::{ use tauri::{
plugin::{Builder, TauriPlugin}, plugin::{Builder, TauriPlugin},
FsScope, FsScopeEvent, Manager, Runtime, FsScope, FsScopeEvent, GlobPattern, Manager, Runtime,
}; };
use tauri_plugin_fs::{FsExt, ScopeEvent as FsScopeEvent}; use tauri_plugin_fs::{FsExt, Scope as FsPluginScope, ScopeEvent as FsPluginScopeEvent};
use std::{ use std::{
collections::HashSet,
fs::{create_dir_all, File}, fs::{create_dir_all, File},
io::Write, io::Write,
path::Path, path::Path,
@ -43,6 +44,70 @@ const PATTERNS: &[&str] = &[
]; ];
const REPLACE_WITH: &[&str] = &[r"[", r"]", r"?", r"*", r"\?", r"\\?\", r"\\?\"]; const REPLACE_WITH: &[&str] = &[r"[", r"]", r"?", r"*", r"\?", r"\\?\", r"\\?\"];
trait ScopeExt {
fn allow_file_(&self, path: &Path);
fn allow_directory_(&self, path: &Path, recursive: bool);
fn forbid_file_(&self, path: &Path);
fn forbid_directory_(&self, path: &Path, recursive: bool);
fn allowed_patterns_(&self) -> HashSet<GlobPattern>;
fn forbidden_patterns_(&self) -> HashSet<GlobPattern>;
}
impl ScopeExt for &FsPluginScope {
fn allow_file_(&self, path: &Path) {
let _ = self.allow_file(path);
}
fn allow_directory_(&self, path: &Path, recursive: bool) {
let _ = self.allow_directory(path, recursive);
}
fn forbid_file_(&self, path: &Path) {
let _ = self.forbid_file(path);
}
fn forbid_directory_(&self, path: &Path, recursive: bool) {
let _ = self.forbid_directory(path, recursive);
}
fn allowed_patterns_(&self) -> HashSet<GlobPattern> {
self.allowed_patterns()
}
fn forbidden_patterns_(&self) -> HashSet<GlobPattern> {
self.forbidden_patterns()
}
}
#[cfg(feature = "protocol-asset")]
impl ScopeExt for &FsScope {
fn allow_file_(&self, path: &Path) {
let _ = self.allow_file(path);
}
fn allow_directory_(&self, path: &Path, recursive: bool) {
let _ = self.allow_directory(path, recursive);
}
fn forbid_file_(&self, path: &Path) {
let _ = self.forbid_file(path);
}
fn forbid_directory_(&self, path: &Path, recursive: bool) {
let _ = self.forbid_directory(path, recursive);
}
fn allowed_patterns_(&self) -> HashSet<GlobPattern> {
self.allowed_patterns()
}
fn forbidden_patterns_(&self) -> HashSet<GlobPattern> {
self.forbidden_patterns()
}
}
#[derive(Debug, thiserror::Error)] #[derive(Debug, thiserror::Error)]
enum Error { enum Error {
#[error(transparent)] #[error(transparent)]
@ -105,49 +170,49 @@ fn fix_directory(path_str: &str) -> &Path {
path path
} }
fn allow_path(scope: &FsScope, path: &str) { fn allow_path(scope: impl ScopeExt, path: &str) {
let target_type = detect_scope_type(path); let target_type = detect_scope_type(path);
match target_type { match target_type {
TargetType::File => { TargetType::File => {
let _ = scope.allow_file(path); scope.allow_file_(Path::new(path));
} }
TargetType::Directory => { TargetType::Directory => {
// We remove the '*' at the end of it, else it will be escaped by the pattern. // We remove the '*' at the end of it, else it will be escaped by the pattern.
let _ = scope.allow_directory(fix_directory(path), false); scope.allow_directory_(fix_directory(path), false);
} }
TargetType::RecursiveDirectory => { TargetType::RecursiveDirectory => {
// We remove the '**' at the end of it, else it will be escaped by the pattern. // We remove the '**' at the end of it, else it will be escaped by the pattern.
let _ = scope.allow_directory(fix_directory(path), true); scope.allow_directory_(fix_directory(path), true);
} }
} }
} }
fn forbid_path(scope: &FsScope, path: &str) { fn forbid_path(scope: impl ScopeExt, path: &str) {
let target_type = detect_scope_type(path); let target_type = detect_scope_type(path);
match target_type { match target_type {
TargetType::File => { TargetType::File => {
let _ = scope.forbid_file(path); scope.forbid_file_(Path::new(path));
} }
TargetType::Directory => { TargetType::Directory => {
let _ = scope.forbid_directory(fix_directory(path), false); scope.forbid_directory_(fix_directory(path), false);
} }
TargetType::RecursiveDirectory => { TargetType::RecursiveDirectory => {
let _ = scope.forbid_directory(fix_directory(path), true); scope.forbid_directory_(fix_directory(path), true);
} }
} }
} }
fn save_scopes(scope: &FsScope, app_dir: &Path, scope_state_path: &Path) { fn save_scopes(scope: impl ScopeExt, app_dir: &Path, scope_state_path: &Path) {
let scope = Scope { let scope = Scope {
allowed_paths: scope allowed_paths: scope
.allowed_patterns() .allowed_patterns_()
.into_iter() .into_iter()
.map(|p| p.to_string()) .map(|p| p.to_string())
.collect(), .collect(),
forbidden_patterns: scope forbidden_patterns: scope
.forbidden_patterns() .forbidden_patterns_()
.into_iter() .into_iter()
.map(|p| p.to_string()) .map(|p| p.to_string())
.collect(), .collect(),
@ -166,16 +231,17 @@ pub fn init<R: Runtime>() -> TauriPlugin<R> {
Builder::new("persisted-scope") Builder::new("persisted-scope")
.setup(|app, _api| { .setup(|app, _api| {
let fs_scope = app.try_fs_scope(); let fs_scope = app.try_fs_scope();
let core_scopes = app.state::<tauri::scope::Scopes>(); let asset_protocol_scope = app.asset_protocol_scope();
let app = app.clone(); let app = app.clone();
let app_dir = app.path().app_data_dir(); let app_dir = app.path().app_data_dir();
if let Some(app_dir) = app_dir { if let Ok(app_dir) = app_dir {
let fs_scope_state_path = app_dir.join(SCOPE_STATE_FILENAME); let fs_scope_state_path = app_dir.join(SCOPE_STATE_FILENAME);
#[cfg(feature = "protocol-asset")] #[cfg(feature = "protocol-asset")]
let asset_scope_state_path = app_dir.join(ASSET_SCOPE_STATE_FILENAME); let asset_scope_state_path = app_dir.join(ASSET_SCOPE_STATE_FILENAME);
let _ = fs_scope.forbid_file(&fs_scope_state_path); if let Some(fs_scope) = fs_scope {
let _ = fs_scope.forbid_file(&fs_scope_state_path);}
#[cfg(feature = "protocol-asset")] #[cfg(feature = "protocol-asset")]
let _ = asset_protocol_scope.forbid_file(&asset_scope_state_path); let _ = asset_protocol_scope.forbid_file(&asset_scope_state_path);
@ -183,7 +249,8 @@ pub fn init<R: Runtime>() -> TauriPlugin<R> {
// We will still save some semi-broken values because the scope events are quite spammy and we don't want to reduce runtime performance any further. // We will still save some semi-broken values because the scope events are quite spammy and we don't want to reduce runtime performance any further.
let ac = AhoCorasick::new(PATTERNS).unwrap(/* This should be impossible to fail since we're using a small static input */); let ac = AhoCorasick::new(PATTERNS).unwrap(/* This should be impossible to fail since we're using a small static input */);
if fs_scope_state_path.exists() { if let Some(fs_scope) = fs_scope {
if fs_scope_state_path.exists() {
let scope: Scope = tauri::api::file::read_binary(&fs_scope_state_path) let scope: Scope = tauri::api::file::read_binary(&fs_scope_state_path)
.map_err(Error::from) .map_err(Error::from)
.and_then(|scope| bincode::deserialize(&scope).map_err(Into::into)) .and_then(|scope| bincode::deserialize(&scope).map_err(Into::into))
@ -191,16 +258,17 @@ pub fn init<R: Runtime>() -> TauriPlugin<R> {
for allowed in &scope.allowed_paths { for allowed in &scope.allowed_paths {
let allowed = fix_pattern(&ac, allowed); let allowed = fix_pattern(&ac, allowed);
allow_path(&fs_scope, &allowed); allow_path(fs_scope, &allowed);
} }
for forbidden in &scope.forbidden_patterns { for forbidden in &scope.forbidden_patterns {
let forbidden = fix_pattern(&ac, forbidden); let forbidden = fix_pattern(&ac, forbidden);
forbid_path(&fs_scope, &forbidden); forbid_path(fs_scope, &forbidden);
} }
// Manually save the fixed scopes to disk once. // Manually save the fixed scopes to disk once.
// This is needed to fix broken .peristed-scope files in case the app doesn't update the scope itself. // This is needed to fix broken .peristed-scope files in case the app doesn't update the scope itself.
save_scopes(&fs_scope, &app_dir, &fs_scope_state_path); save_scopes(fs_scope, &app_dir, &fs_scope_state_path);
}
} }
#[cfg(feature = "protocol-asset")] #[cfg(feature = "protocol-asset")]
@ -225,12 +293,15 @@ pub fn init<R: Runtime>() -> TauriPlugin<R> {
#[cfg(feature = "protocol-asset")] #[cfg(feature = "protocol-asset")]
let app_dir_ = app_dir.clone(); let app_dir_ = app_dir.clone();
let fs_scope_ = fs_scope.clone(); if let Some(fs_scope) = fs_scope {
fs_scope.listen(move |event| { let fs_scope_ = fs_scope.clone();
if let FsScopeEvent::PathAllowed(_) = event { fs_scope.listen(move |event| {
save_scopes(&fs_scope_, &app_dir, &fs_scope_state_path); if let FsPluginScopeEvent::PathAllowed(_) = event {
} save_scopes(&fs_scope_, &app_dir, &fs_scope_state_path);
}); }
});
}
#[cfg(feature = "protocol-asset")] #[cfg(feature = "protocol-asset")]
{ {
let asset_protocol_scope_ = asset_protocol_scope.clone(); let asset_protocol_scope_ = asset_protocol_scope.clone();

Loading…
Cancel
Save