From 9499018bb78b8d3272ac4e7d962b7195f69cde20 Mon Sep 17 00:00:00 2001 From: FabianLars Date: Fri, 30 Jun 2023 15:39:13 +0200 Subject: [PATCH] fix(persisted-scope): separately save asset protocol patterns --- .changes/persisted-scope-save-asset.md | 5 ++ Cargo.lock | 2 +- plugins/persisted-scope/src/lib.rs | 64 +++++++++++++++++++------- 3 files changed, 53 insertions(+), 18 deletions(-) create mode 100644 .changes/persisted-scope-save-asset.md diff --git a/.changes/persisted-scope-save-asset.md b/.changes/persisted-scope-save-asset.md new file mode 100644 index 0000000000..5b4b933a47 --- /dev/null +++ b/.changes/persisted-scope-save-asset.md @@ -0,0 +1,5 @@ +--- +"persisted-scope": patch +--- + +Split up fs and asset scopes. **This will reset the asset protocol scope once!** diff --git a/Cargo.lock b/Cargo.lock index 500fcca353..28500762b2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4392,7 +4392,7 @@ dependencies = [ [[package]] name = "tauri-plugin-persisted-scope" -version = "0.1.1" +version = "0.1.2" dependencies = [ "aho-corasick 1.0.1", "bincode", diff --git a/plugins/persisted-scope/src/lib.rs b/plugins/persisted-scope/src/lib.rs index af4891862a..7ff99a60c7 100644 --- a/plugins/persisted-scope/src/lib.rs +++ b/plugins/persisted-scope/src/lib.rs @@ -6,7 +6,7 @@ use aho_corasick::AhoCorasick; use serde::{Deserialize, Serialize}; use tauri::{ plugin::{Builder, TauriPlugin}, - AppHandle, FsScope, FsScopeEvent, Manager, Runtime, + FsScope, FsScopeEvent, Manager, Runtime, }; use std::{ @@ -15,7 +15,10 @@ use std::{ path::Path, }; +// Using 2 separate files so that we don't have to think about write conflicts and not break backwards compat. const SCOPE_STATE_FILENAME: &str = ".persisted-scope"; +#[cfg(feature = "protocol-asset")] +const ASSET_SCOPE_STATE_FILENAME: &str = ".persisted-scope-asset"; // Most of these patterns are just added to try to fix broken files in the wild. // After a while we can hopefully reduce it to something like [r"[?]", r"[*]", r"\\?\\\?\"] @@ -126,16 +129,14 @@ fn forbid_path(scope: &FsScope, path: &str) { } } -fn save_scopes(app: &AppHandle, app_dir: &Path, scope_state_path: &Path) { - let fs_scope = app.fs_scope(); - +fn save_scopes(scope: &FsScope, app_dir: &Path, scope_state_path: &Path) { let scope = Scope { - allowed_paths: fs_scope + allowed_paths: scope .allowed_patterns() .into_iter() .map(|p| p.to_string()) .collect(), - forbidden_patterns: fs_scope + forbidden_patterns: scope .forbidden_patterns() .into_iter() .map(|p| p.to_string()) @@ -161,18 +162,20 @@ pub fn init() -> TauriPlugin { let app_dir = app.path_resolver().app_data_dir(); if let Some(app_dir) = app_dir { - let scope_state_path = app_dir.join(SCOPE_STATE_FILENAME); + let fs_scope_state_path = app_dir.join(SCOPE_STATE_FILENAME); + #[cfg(feature = "protocol-asset")] + let asset_scope_state_path = app_dir.join(ASSET_SCOPE_STATE_FILENAME); - let _ = fs_scope.forbid_file(&scope_state_path); + let _ = fs_scope.forbid_file(&fs_scope_state_path); #[cfg(feature = "protocol-asset")] - let _ = asset_protocol_scope.forbid_file(&scope_state_path); + let _ = asset_protocol_scope.forbid_file(&asset_scope_state_path); // We're trying to fix broken .persisted-scope files seamlessly, so we'll be running this on the values read on the saved file. // 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 */); - if scope_state_path.exists() { - let scope: Scope = tauri::api::file::read_binary(&scope_state_path) + if fs_scope_state_path.exists() { + let scope: Scope = tauri::api::file::read_binary(&fs_scope_state_path) .map_err(Error::from) .and_then(|scope| bincode::deserialize(&scope).map_err(Into::into)) .unwrap_or_default(); @@ -180,26 +183,53 @@ pub fn init() -> TauriPlugin { for allowed in &scope.allowed_paths { let allowed = fix_pattern(&ac, allowed); allow_path(&fs_scope, &allowed); - #[cfg(feature = "protocol-asset")] - allow_path(&asset_protocol_scope, &allowed); } for forbidden in &scope.forbidden_patterns { let forbidden = fix_pattern(&ac, forbidden); forbid_path(&fs_scope, &forbidden); - #[cfg(feature = "protocol-asset")] - forbid_path(&asset_protocol_scope, &forbidden); } // 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. - save_scopes(&app, &app_dir, &scope_state_path); + save_scopes(&fs_scope, &app_dir, &fs_scope_state_path); } + #[cfg(feature = "protocol-asset")] + if asset_scope_state_path.exists() { + let scope: Scope = tauri::api::file::read_binary(&asset_scope_state_path) + .map_err(Error::from) + .and_then(|scope| bincode::deserialize(&scope).map_err(Into::into)) + .unwrap_or_default(); + + for allowed in &scope.allowed_paths { + let allowed = fix_pattern(&ac, allowed); + allow_path(&asset_protocol_scope, &allowed); + } + for forbidden in &scope.forbidden_patterns { + let forbidden = fix_pattern(&ac, forbidden); + forbid_path(&asset_protocol_scope, &forbidden); + } + + // Manually save the fixed scopes to disk once. + save_scopes(&asset_protocol_scope, &app_dir, &asset_scope_state_path); + } + + #[cfg(feature = "protocol-asset")] + let app_dir_ = app_dir.clone(); + let fs_scope_ = fs_scope.clone(); fs_scope.listen(move |event| { if let FsScopeEvent::PathAllowed(_) = event { - save_scopes(&app, &app_dir, &scope_state_path); + save_scopes(&fs_scope_, &app_dir, &fs_scope_state_path); } }); + #[cfg(feature = "protocol-asset")] + { + let asset_protocol_scope_ = asset_protocol_scope.clone(); + asset_protocol_scope.listen(move |event| { + if let FsScopeEvent::PathAllowed(_) = event { + save_scopes(&asset_protocol_scope_, &app_dir_, &asset_scope_state_path); + } + });} } Ok(()) })