From f38b91471a23fac144cc1bea44961803f39ea169 Mon Sep 17 00:00:00 2001 From: Jae-Heon Ji Date: Mon, 7 Aug 2023 18:49:54 +0900 Subject: [PATCH] refactor: permission cache --- zellij-server/src/plugins/mod.rs | 5 +- .../src/plugins/unit/plugin_tests.rs | 16 ++++-- zellij-server/src/plugins/wasm_bridge.rs | 16 ++---- zellij-server/src/plugins/zellij_exports.rs | 25 ++++----- zellij-server/src/tab/mod.rs | 1 + zellij-utils/src/input/permission.rs | 56 ++++++++++++++----- zellij-utils/src/kdl/mod.rs | 10 ++-- 7 files changed, 81 insertions(+), 48 deletions(-) diff --git a/zellij-server/src/plugins/mod.rs b/zellij-server/src/plugins/mod.rs index fb23072c95..4bef0683d1 100644 --- a/zellij-server/src/plugins/mod.rs +++ b/zellij-server/src/plugins/mod.rs @@ -84,6 +84,7 @@ pub enum PluginInstruction { Option, Vec, PermissionStatus, + Option, ), Exit, } @@ -301,12 +302,14 @@ pub(crate) fn plugin_thread_main( client_id, permissions, status, + cache_path, ) => { - if let Err(e) = wasm_bridge.caching_plugin_permissions( + if let Err(e) = wasm_bridge.cache_plugin_permissions( plugin_id, client_id, permissions, status, + cache_path, ) { log::error!("{}", e); } diff --git a/zellij-server/src/plugins/unit/plugin_tests.rs b/zellij-server/src/plugins/unit/plugin_tests.rs index ff9c59788f..5906695572 100644 --- a/zellij-server/src/plugins/unit/plugin_tests.rs +++ b/zellij-server/src/plugins/unit/plugin_tests.rs @@ -9,7 +9,7 @@ use wasmer::Store; use zellij_utils::data::{Event, Key, PermissionStatus, PermissionType, PluginCapabilities}; use zellij_utils::errors::ErrorContext; use zellij_utils::input::layout::{Layout, PluginUserConfiguration, RunPlugin, RunPluginLocation}; -use zellij_utils::input::permission::GrantedPermission; +use zellij_utils::input::permission::PermissionCache; use zellij_utils::input::plugins::PluginsConfig; use zellij_utils::ipc::ClientAttributes; use zellij_utils::lazy_static::lazy_static; @@ -4291,6 +4291,8 @@ pub fn request_plugin_permissions() { pub fn granted_permission_request_result() { let temp_folder = tempdir().unwrap(); let plugin_host_folder = PathBuf::from(temp_folder.path()); + let cache_path = plugin_host_folder.join("permissions_test.kdl"); + let (plugin_thread_sender, _, mut teardown) = create_plugin_thread(Some(plugin_host_folder)); let plugin_should_float = Some(false); let plugin_title = Some("test_plugin".to_owned()); @@ -4321,12 +4323,13 @@ pub fn granted_permission_request_result() { Some(client_id), vec![PermissionType::KeyboardInput], PermissionStatus::Granted, + Some(cache_path.clone()), )); teardown(); - let granted_permission = GrantedPermission::from_cache_or_default(); - let permissions = granted_permission.get(&run_plugin.location.to_string()); + let permission_cache = PermissionCache::from_path_or_default(Some(cache_path)); + let permissions = permission_cache.get_permissions(run_plugin.location.to_string()); assert_snapshot!(format!("{:#?}", permissions)); } @@ -4336,6 +4339,8 @@ pub fn granted_permission_request_result() { pub fn denied_permission_request_result() { let temp_folder = tempdir().unwrap(); let plugin_host_folder = PathBuf::from(temp_folder.path()); + let cache_path = plugin_host_folder.join("permissions_test.kdl"); + let (plugin_thread_sender, _, mut teardown) = create_plugin_thread(Some(plugin_host_folder)); let plugin_should_float = Some(false); let plugin_title = Some("test_plugin".to_owned()); @@ -4366,12 +4371,13 @@ pub fn denied_permission_request_result() { Some(client_id), vec![PermissionType::KeyboardInput], PermissionStatus::Denied, + Some(cache_path.clone()), )); teardown(); - let granted_permission = GrantedPermission::from_cache_or_default(); - let permissions = granted_permission.get(&run_plugin.location.to_string()); + let permission_cache = PermissionCache::from_path_or_default(Some(cache_path)); + let permissions = permission_cache.get_permissions(run_plugin.location.to_string()); assert_snapshot!(format!("{:#?}", permissions)); } diff --git a/zellij-server/src/plugins/wasm_bridge.rs b/zellij-server/src/plugins/wasm_bridge.rs index cc5b33c552..e64ba9deca 100644 --- a/zellij-server/src/plugins/wasm_bridge.rs +++ b/zellij-server/src/plugins/wasm_bridge.rs @@ -5,8 +5,6 @@ use crate::plugins::plugin_worker::MessageToWorker; use crate::plugins::watch_filesystem::watch_filesystem; use crate::plugins::zellij_exports::{wasi_read_string, wasi_write_object}; use log::info; -use std::fs::File; -use std::io::Write; use std::{ collections::{HashMap, HashSet}, path::PathBuf, @@ -15,9 +13,8 @@ use std::{ }; use wasmer::{Instance, Module, Store, Value}; use zellij_utils::async_std::task::{self, JoinHandle}; -use zellij_utils::consts::ZELLIJ_PLUGIN_PERMISSIONS_CACHE; use zellij_utils::data::{PermissionStatus, PermissionType}; -use zellij_utils::input::permission::GrantedPermission; +use zellij_utils::input::permission::PermissionCache; use zellij_utils::notify_debouncer_full::{notify::RecommendedWatcher, Debouncer, FileIdMap}; use crate::{ @@ -714,12 +711,13 @@ impl WasmBridge { }; } } - pub fn caching_plugin_permissions( + pub fn cache_plugin_permissions( &mut self, plugin_id: PluginId, client_id: Option, permissions: Vec, status: PermissionStatus, + cache_path: Option, ) -> Result<()> { if let Some(running_plugin) = self .plugin_map @@ -740,15 +738,13 @@ impl WasmBridge { .plugin_env .set_permissions(HashSet::from_iter(permissions.clone())); - let mut granted_permission = GrantedPermission::from_cache_or_default(); - granted_permission.insert( + let mut permission_cache = PermissionCache::from_path_or_default(cache_path); + permission_cache.cache( running_plugin.plugin_env.plugin.location.to_string(), permissions, ); - let mut f = File::create(ZELLIJ_PLUGIN_PERMISSIONS_CACHE.as_path()) - .with_context(err_context)?; - write!(f, "{}", granted_permission.to_string()).with_context(err_context)?; + permission_cache.write_to_file().with_context(err_context)?; } Ok(()) diff --git a/zellij-server/src/plugins/zellij_exports.rs b/zellij-server/src/plugins/zellij_exports.rs index 26d252ede2..1ea99eadca 100644 --- a/zellij-server/src/plugins/zellij_exports.rs +++ b/zellij-server/src/plugins/zellij_exports.rs @@ -15,7 +15,7 @@ use std::{ use wasmer::{imports, Function, ImportObject, Store, WasmerEnv}; use wasmer_wasi::WasiEnv; use zellij_utils::data::{PermissionType, PluginPermission}; -use zellij_utils::input::permission::GrantedPermission; +use zellij_utils::input::permission::PermissionCache; use url::Url; @@ -218,19 +218,18 @@ fn host_set_selectable(env: &ForeignFunctionEnv, selectable: i32) { fn host_request_permission(env: &ForeignFunctionEnv) { wasi_read_object::>(&env.plugin_env.wasi_env) .and_then(|permissions| { - if let Some(p) = GrantedPermission::from_cache_or_default() - .get(&env.plugin_env.plugin.location.to_string()) + if PermissionCache::from_path_or_default(None) + .check_permissions(env.plugin_env.plugin.location.to_string(), &permissions) { - if p.to_vec() == permissions { - return env.plugin_env.senders.send_to_plugin( - PluginInstruction::PermissionRequestResult( - env.plugin_env.plugin_id, - Some(env.plugin_env.client_id), - permissions.to_vec(), - zellij_utils::data::PermissionStatus::Granted, - ), - ); - } + return env.plugin_env.senders.send_to_plugin( + PluginInstruction::PermissionRequestResult( + env.plugin_env.plugin_id, + Some(env.plugin_env.client_id), + permissions.to_vec(), + zellij_utils::data::PermissionStatus::Granted, + None, + ), + ); } env.plugin_env diff --git a/zellij-server/src/tab/mod.rs b/zellij-server/src/tab/mod.rs index 8599e9301b..fb6d4e170f 100644 --- a/zellij-server/src/tab/mod.rs +++ b/zellij-server/src/tab/mod.rs @@ -1586,6 +1586,7 @@ impl Tab { client_id, permissions, status, + None, )) .with_context(err_context)?; should_update_ui = true; diff --git a/zellij-utils/src/input/permission.rs b/zellij-utils/src/input/permission.rs index abfbef5e5a..1755fe1e66 100644 --- a/zellij-utils/src/input/permission.rs +++ b/zellij-utils/src/input/permission.rs @@ -1,32 +1,60 @@ use std::{ - collections::{hash_map::Iter, HashMap}, - fs, + collections::HashMap, + fs::{self, File}, + io::Write, + path::PathBuf, }; use crate::{consts::ZELLIJ_PLUGIN_PERMISSIONS_CACHE, data::PermissionType}; +pub type GrantedPermission = HashMap>; + #[derive(Default, Debug)] -pub struct GrantedPermission(HashMap>); +pub struct PermissionCache { + path: PathBuf, + granted: GrantedPermission, +} -impl GrantedPermission { - pub fn insert(&mut self, k: String, v: Vec) { - self.0.insert(k, v); +impl PermissionCache { + pub fn cache(&mut self, plugin_name: String, permissions: Vec) { + self.granted.insert(plugin_name, permissions); } - pub fn get(&self, k: &String) -> Option<&Vec> { - self.0.get(k) + pub fn get_permissions(&self, plugin_name: String) -> Option<&Vec> { + self.granted.get(&plugin_name) } - pub fn iter(&self) -> Iter> { - self.0.iter() + pub fn check_permissions( + &self, + plugin_name: String, + permissions: &Vec, + ) -> bool { + if let Some(target) = self.granted.get(&plugin_name) { + if target == permissions { + return true; + } + } + + false } - pub fn from_cache_or_default() -> Self { - let default_permission = ZELLIJ_PLUGIN_PERMISSIONS_CACHE.to_path_buf(); + pub fn from_path_or_default(cache_path: Option) -> Self { + let cache_path = cache_path.unwrap_or(ZELLIJ_PLUGIN_PERMISSIONS_CACHE.to_path_buf()); - match fs::read_to_string(&default_permission) { - Ok(s) => GrantedPermission::from_string(s).unwrap_or_default(), + let granted = match fs::read_to_string(cache_path.clone()) { + Ok(raw_string) => PermissionCache::from_string(raw_string).unwrap_or_default(), Err(_) => GrantedPermission::default(), + }; + + PermissionCache { + path: cache_path, + granted, } } + + pub fn write_to_file(&self) -> std::io::Result<()> { + let mut f = File::create(&self.path)?; + write!(f, "{}", PermissionCache::to_string(&self.granted))?; + Ok(()) + } } diff --git a/zellij-utils/src/kdl/mod.rs b/zellij-utils/src/kdl/mod.rs index 4fa7f76dba..13a03ad15d 100644 --- a/zellij-utils/src/kdl/mod.rs +++ b/zellij-utils/src/kdl/mod.rs @@ -5,7 +5,7 @@ use crate::input::config::{Config, ConfigError, KdlError}; use crate::input::keybinds::Keybinds; use crate::input::layout::{Layout, PluginUserConfiguration, RunPlugin, RunPluginLocation}; use crate::input::options::{Clipboard, OnForceClose, Options}; -use crate::input::permission::GrantedPermission; +use crate::input::permission::{GrantedPermission, PermissionCache}; use crate::input::plugins::{PluginConfig, PluginTag, PluginType, PluginsConfig}; use crate::input::theme::{FrameConfig, Theme, Themes, UiConfig}; use crate::setup::{find_default_config_dir, get_layout_dir}; @@ -1794,8 +1794,8 @@ impl Themes { } } -impl GrantedPermission { - pub fn from_string(raw_string: String) -> Result { +impl PermissionCache { + pub fn from_string(raw_string: String) -> Result { let kdl_document: KdlDocument = raw_string.parse()?; let mut granted_permission = GrantedPermission::default(); @@ -1819,10 +1819,10 @@ impl GrantedPermission { Ok(granted_permission) } - pub fn to_string(&self) -> String { + pub fn to_string(granted: &GrantedPermission) -> String { let mut kdl_doucment = KdlDocument::new(); - self.iter().for_each(|(k, v)| { + granted.iter().for_each(|(k, v)| { let mut node = KdlNode::new(k.as_str()); let mut children = KdlDocument::new();