fix: don't save permission data in memory

This commit is contained in:
Jae-Heon Ji 2023-07-26 03:16:39 +09:00
parent 82b16da55f
commit 1e05d566b6
10 changed files with 104 additions and 104 deletions

View File

@ -13,7 +13,7 @@ use crate::ui::{
use crate::ClientId;
use std::cell::RefCell;
use std::rc::Rc;
use zellij_utils::data::{PermissionType, PluginPermission};
use zellij_utils::data::{PermissionStatus, PermissionType, PluginPermission};
use zellij_utils::pane_size::{Offset, SizeInPixels};
use zellij_utils::position::Position;
use zellij_utils::{
@ -228,9 +228,15 @@ impl Pane for PluginPane {
let permissions = requesting_permissions.permissions.clone();
match input_bytes.as_slice() {
// Y or y
&[89] | &[121] => Some(AdjustedInput::PermissionRequestResult(permissions, true)),
&[89] | &[121] => Some(AdjustedInput::PermissionRequestResult(
permissions,
PermissionStatus::Granted,
)),
// N or n
&[78] | &[110] => Some(AdjustedInput::PermissionRequestResult(permissions, false)),
&[78] | &[110] => Some(AdjustedInput::PermissionRequestResult(
permissions,
PermissionStatus::Denied,
)),
_ => None,
}
} else {

View File

@ -18,13 +18,11 @@ use crate::{pty::PtyInstruction, thread_bus::Bus, ClientId, ServerInstruction};
use wasm_bridge::WasmBridge;
use zellij_utils::{
consts::ZELLIJ_PLUGIN_PERMISSIONS_FILE,
data::{Event, EventType, PermissionType, PluginCapabilities},
data::{Event, EventType, PermissionStatus, PermissionType, PluginCapabilities},
errors::{prelude::*, ContextType, PluginContext},
input::{
command::TerminalAction,
layout::{FloatingPaneLayout, Layout, Run, RunPlugin, RunPluginLocation, TiledPaneLayout},
permission::GrantedPermission,
plugins::PluginsConfig,
},
ipc::ClientAttributes,
@ -81,7 +79,12 @@ pub enum PluginInstruction {
String, // serialized payload
),
PluginSubscribedToEvents(PluginId, ClientId, HashSet<EventType>),
PermissionRequestResult(PluginId, Option<ClientId>, Vec<PermissionType>, bool),
PermissionRequestResult(
PluginId,
Option<ClientId>,
Vec<PermissionType>,
PermissionStatus,
),
Exit,
}
@ -132,21 +135,11 @@ pub(crate) fn plugin_thread_main(
let plugin_dir = data_dir.join("plugins/");
let plugin_global_data_dir = plugin_dir.join("data");
let granted_permission =
match fs::read_to_string(plugin_dir.join(ZELLIJ_PLUGIN_PERMISSIONS_FILE)) {
Ok(s) => match GrantedPermission::from_string(s) {
Ok(p) => p,
Err(_) => GrantedPermission::default(),
},
Err(_) => GrantedPermission::default(),
};
let mut wasm_bridge = WasmBridge::new(
plugins,
bus.senders.clone(),
store,
plugin_dir,
granted_permission,
path_to_default_shell,
zellij_cwd,
capabilities,
@ -305,11 +298,15 @@ pub(crate) fn plugin_thread_main(
PluginInstruction::PermissionRequestResult(
plugin_id,
client_id,
permissions,
result,
plugin_permission,
status,
) => {
let permissions = if result { permissions } else { Vec::new() };
match wasm_bridge.caching_plugin_permissions(plugin_id, client_id, permissions) {
match wasm_bridge.caching_plugin_permissions(
plugin_id,
client_id,
plugin_permission,
status,
) {
Ok(_) => {},
Err(e) => log::error!("{}", e),
}
@ -317,7 +314,7 @@ pub(crate) fn plugin_thread_main(
let updates = vec![(
Some(plugin_id),
client_id,
Event::PermissionRequestResult(result),
Event::PermissionRequestResult(status),
)];
wasm_bridge.update_plugins(updates)?;
},

View File

@ -14,8 +14,6 @@ use std::{
use url::Url;
use wasmer::{ChainableNamedResolver, Instance, Module, Store};
use wasmer_wasi::{Pipe, WasiState};
use zellij_utils::data::PermissionType;
use zellij_utils::input::permission::GrantedPermission;
use crate::{
logging_pipe::LoggingPipe, screen::ScreenInstruction, thread_bus::ThreadSenders,
@ -165,7 +163,6 @@ pub struct PluginLoader<'a> {
store: Store,
plugin: PluginConfig,
plugin_dir: &'a PathBuf,
plugin_permissions: Option<Vec<PermissionType>>,
tab_index: usize,
plugin_own_data_dir: PathBuf,
size: Size,
@ -183,7 +180,6 @@ impl<'a> PluginLoader<'a> {
plugin_id: PluginId,
plugin_dir: PathBuf,
plugin_cache: Arc<Mutex<HashMap<PathBuf, Module>>>,
plugin_permissions: Option<Vec<PermissionType>>,
senders: ThreadSenders,
store: Store,
plugin_map: Arc<Mutex<PluginMap>>,
@ -213,7 +209,6 @@ impl<'a> PluginLoader<'a> {
first_client_id,
&store,
&plugin_dir,
plugin_permissions,
path_to_default_shell,
zellij_cwd,
capabilities,
@ -247,7 +242,6 @@ impl<'a> PluginLoader<'a> {
tab_index: usize,
plugin_dir: PathBuf,
plugin_cache: Arc<Mutex<HashMap<PathBuf, Module>>>,
plugin_permissions: Option<Vec<PermissionType>>,
senders: ThreadSenders,
store: Store,
plugin_map: Arc<Mutex<PluginMap>>,
@ -271,7 +265,6 @@ impl<'a> PluginLoader<'a> {
&store,
plugin.clone(),
&plugin_dir,
plugin_permissions,
tab_index,
size,
path_to_default_shell,
@ -309,7 +302,6 @@ impl<'a> PluginLoader<'a> {
client_id: ClientId,
plugin_dir: PathBuf,
plugin_cache: Arc<Mutex<HashMap<PathBuf, Module>>>,
granted_permission: &GrantedPermission,
senders: ThreadSenders,
store: Store,
plugin_map: Arc<Mutex<PluginMap>>,
@ -323,14 +315,10 @@ impl<'a> PluginLoader<'a> {
default_layout: Box<Layout>,
) -> Result<()> {
let mut new_plugins = HashSet::new();
for (plugin_id, _, running_plugin) in plugin_map.lock().unwrap().running_plugins() {
let running_plugin = running_plugin.lock().unwrap();
let plugin_permissions =
granted_permission.get(&running_plugin.plugin_env.plugin.location.to_string());
new_plugins.insert((plugin_id, client_id, plugin_permissions.cloned()));
for plugin_id in plugin_map.lock().unwrap().plugin_ids() {
new_plugins.insert((plugin_id, client_id));
}
for (plugin_id, existing_client_id, plugin_permissions) in new_plugins {
for (plugin_id, existing_client_id) in new_plugins {
let mut plugin_loader = PluginLoader::new_from_different_client_id(
&plugin_cache,
&plugin_map,
@ -340,7 +328,6 @@ impl<'a> PluginLoader<'a> {
existing_client_id,
&store,
&plugin_dir,
plugin_permissions,
path_to_default_shell.clone(),
zellij_cwd.clone(),
capabilities.clone(),
@ -368,7 +355,6 @@ impl<'a> PluginLoader<'a> {
plugin_id: PluginId,
plugin_dir: PathBuf,
plugin_cache: Arc<Mutex<HashMap<PathBuf, Module>>>,
plugin_permissions: Option<Vec<PermissionType>>,
senders: ThreadSenders,
store: Store,
plugin_map: Arc<Mutex<PluginMap>>,
@ -399,7 +385,6 @@ impl<'a> PluginLoader<'a> {
first_client_id,
&store,
&plugin_dir,
plugin_permissions,
path_to_default_shell,
zellij_cwd,
capabilities,
@ -434,7 +419,6 @@ impl<'a> PluginLoader<'a> {
store: &Store,
plugin: PluginConfig,
plugin_dir: &'a PathBuf,
plugin_permissions: Option<Vec<PermissionType>>,
tab_index: usize,
size: Size,
path_to_default_shell: PathBuf,
@ -459,7 +443,6 @@ impl<'a> PluginLoader<'a> {
store: store.clone(),
plugin,
plugin_dir,
plugin_permissions,
tab_index,
plugin_own_data_dir,
size,
@ -481,7 +464,6 @@ impl<'a> PluginLoader<'a> {
client_id: ClientId,
store: &Store,
plugin_dir: &'a PathBuf,
plugin_permissions: Option<Vec<PermissionType>>,
path_to_default_shell: PathBuf,
zellij_cwd: PathBuf,
capabilities: PluginCapabilities,
@ -513,7 +495,6 @@ impl<'a> PluginLoader<'a> {
store,
plugin_config,
plugin_dir,
plugin_permissions,
tab_index,
size,
path_to_default_shell,
@ -533,7 +514,6 @@ impl<'a> PluginLoader<'a> {
client_id: ClientId,
store: &Store,
plugin_dir: &'a PathBuf,
plugin_permissions: Option<Vec<PermissionType>>,
path_to_default_shell: PathBuf,
zellij_cwd: PathBuf,
capabilities: PluginCapabilities,
@ -566,7 +546,6 @@ impl<'a> PluginLoader<'a> {
store,
plugin_config,
plugin_dir,
plugin_permissions,
tab_index,
size,
path_to_default_shell,
@ -812,7 +791,6 @@ impl<'a> PluginLoader<'a> {
*client_id,
&self.store,
&self.plugin_dir,
self.plugin_permissions.clone(),
self.path_to_default_shell.clone(),
self.zellij_cwd.clone(),
self.capabilities.clone(),
@ -890,18 +868,13 @@ impl<'a> PluginLoader<'a> {
})
.with_context(err_context)?;
let wasi = wasi_env.import_object(&module).with_context(err_context)?;
let plugin_permissions = match &self.plugin_permissions {
Some(p) => Some(HashSet::from_iter(p.clone())),
None => None,
};
let mut mut_plugin = self.plugin.clone();
mut_plugin.set_tab_index(self.tab_index);
let plugin_env = PluginEnv {
plugin_id: self.plugin_id,
client_id: self.client_id,
plugin: mut_plugin,
plugin_permissions,
permissions: HashSet::default(),
senders: self.senders.clone(),
wasi_env,
plugin_own_data_dir: self.plugin_own_data_dir.clone(),

View File

@ -193,7 +193,7 @@ pub type Subscriptions = HashSet<EventType>;
pub struct PluginEnv {
pub plugin_id: PluginId,
pub plugin: PluginConfig,
pub plugin_permissions: Option<HashSet<PermissionType>>,
pub permissions: HashSet<PermissionType>,
pub senders: ThreadSenders,
pub wasi_env: WasiEnv,
pub tab_index: usize,
@ -217,11 +217,8 @@ impl PluginEnv {
)
}
pub fn merge_plugin_permissions(&mut self, permissions: HashSet<PermissionType>) {
match &mut self.plugin_permissions {
Some(p) => p.extend(permissions),
None => self.plugin_permissions = Some(permissions),
}
pub fn merge_permissions(&mut self, permissions: HashSet<PermissionType>) {
self.permissions.extend(permissions);
}
}

View File

@ -15,8 +15,8 @@ use std::{
};
use wasmer::{Instance, Module, Store, Value};
use zellij_utils::async_std::task::{self, JoinHandle};
use zellij_utils::consts::ZELLIJ_PLUGIN_PERMISSIONS_FILE;
use zellij_utils::data::PermissionType;
use zellij_utils::consts::{ZELLIJ_CACHE_DIR, ZELLIJ_PLUGIN_PERMISSIONS_FILE};
use zellij_utils::data::{PermissionStatus, PermissionType, PluginPermission};
use zellij_utils::input::permission::GrantedPermission;
use zellij_utils::notify_debouncer_full::{notify::RecommendedWatcher, Debouncer, FileIdMap};
@ -50,7 +50,6 @@ pub struct WasmBridge {
plugin_dir: PathBuf,
plugin_cache: Arc<Mutex<HashMap<PathBuf, Module>>>,
plugin_map: Arc<Mutex<PluginMap>>,
granted_permission: GrantedPermission,
next_plugin_id: PluginId,
cached_events_for_pending_plugins: HashMap<PluginId, Vec<Event>>,
cached_resizes_for_pending_plugins: HashMap<PluginId, (usize, usize)>, // (rows, columns)
@ -75,7 +74,6 @@ impl WasmBridge {
senders: ThreadSenders,
store: Store,
plugin_dir: PathBuf,
granted_permission: GrantedPermission,
path_to_default_shell: PathBuf,
zellij_cwd: PathBuf,
capabilities: PluginCapabilities,
@ -96,7 +94,6 @@ impl WasmBridge {
plugin_dir,
plugin_cache,
plugin_map,
granted_permission,
path_to_default_shell,
watcher,
next_plugin_id: 0,
@ -152,10 +149,6 @@ impl WasmBridge {
let load_plugin_task = task::spawn({
let plugin_dir = self.plugin_dir.clone();
let plugin_cache = self.plugin_cache.clone();
let plugin_permissions = self
.granted_permission
.get(&run.location.to_string())
.cloned();
let senders = self.senders.clone();
let store = self.store.clone();
let plugin_map = self.plugin_map.clone();
@ -177,7 +170,6 @@ impl WasmBridge {
tab_index,
plugin_dir,
plugin_cache,
plugin_permissions,
senders.clone(),
store,
plugin_map,
@ -245,10 +237,6 @@ impl WasmBridge {
let load_plugin_task = task::spawn({
let plugin_dir = self.plugin_dir.clone();
let plugin_cache = self.plugin_cache.clone();
let plugin_permissions = self
.granted_permission
.get(&run_plugin.location.to_string())
.cloned();
let senders = self.senders.clone();
let store = self.store.clone();
let plugin_map = self.plugin_map.clone();
@ -264,7 +252,6 @@ impl WasmBridge {
first_plugin_id,
plugin_dir.clone(),
plugin_cache.clone(),
plugin_permissions.clone(),
senders.clone(),
store.clone(),
plugin_map.clone(),
@ -289,7 +276,6 @@ impl WasmBridge {
*plugin_id,
plugin_dir.clone(),
plugin_cache.clone(),
plugin_permissions.clone(),
senders.clone(),
store.clone(),
plugin_map.clone(),
@ -336,7 +322,6 @@ impl WasmBridge {
client_id,
self.plugin_dir.clone(),
self.plugin_cache.clone(),
&self.granted_permission,
self.senders.clone(),
self.store.clone(),
self.plugin_map.clone(),
@ -734,6 +719,7 @@ impl WasmBridge {
plugin_id: PluginId,
client_id: Option<ClientId>,
permissions: Vec<PermissionType>,
status: PermissionStatus,
) -> Result<()> {
if let Some(running_plugin) = self
.plugin_map
@ -744,18 +730,33 @@ impl WasmBridge {
let err_context = || format!("Failed to write plugin permission {plugin_id}");
let mut running_plugin = running_plugin.lock().unwrap();
running_plugin
.plugin_env
.merge_plugin_permissions(HashSet::from_iter(permissions.clone()));
self.granted_permission.insert(
let permissions = HashSet::from_iter(permissions);
match status {
PermissionStatus::Granted => {
running_plugin.plugin_env.merge_permissions(permissions)
},
PermissionStatus::Denied => {
permissions.iter().for_each(|p| {
running_plugin.plugin_env.permissions.remove(p);
});
},
}
let mut granted_permission = GrantedPermission::from_default().unwrap_or_default();
granted_permission.insert(
running_plugin.plugin_env.plugin.location.to_string(),
permissions,
running_plugin
.plugin_env
.permissions
.clone()
.into_iter()
.collect(),
);
let mut f = File::create(self.plugin_dir.join(ZELLIJ_PLUGIN_PERMISSIONS_FILE))
let mut f = File::create(ZELLIJ_CACHE_DIR.join(ZELLIJ_PLUGIN_PERMISSIONS_FILE))
.with_context(err_context)?;
write!(f, "{}", self.granted_permission.to_string()).with_context(err_context)?;
write!(f, "{}", granted_permission.to_string()).with_context(err_context)?;
}
Ok(())
@ -788,10 +789,8 @@ fn check_permission(plugin_env: &PluginEnv, event: &Event) -> Permission {
_ => return Permission::Allowed,
};
if let Some(permissions) = &plugin_env.plugin_permissions {
if !permissions.contains(&permission) {
return Permission::Denied(permission);
}
if !plugin_env.permissions.contains(&permission) {
return Permission::Denied(permission);
}
Permission::Allowed

View File

@ -217,20 +217,11 @@ fn host_set_selectable(env: &ForeignFunctionEnv, selectable: i32) {
fn host_request_permission(env: &ForeignFunctionEnv) {
wasi_read_object::<Vec<PermissionType>>(&env.plugin_env.wasi_env)
.and_then(|permissions| {
if let Some(permissions) = &env.plugin_env.plugin_permissions {
if !permissions.is_empty() {
return Ok(());
}
}
env.plugin_env
.senders
.send_to_screen(ScreenInstruction::RequestPluginPermissions(
env.plugin_env.plugin_id,
PluginPermission::new(
env.plugin_env.plugin.path.display().to_string(),
permissions,
),
PluginPermission::new(env.plugin_env.plugin.location.to_string(), permissions),
))
})
.with_context(|| {

View File

@ -10,6 +10,7 @@ use zellij_utils::data::{Direction, PaneManifest, PluginPermission, Resize, Resi
use zellij_utils::errors::prelude::*;
use zellij_utils::input::command::RunCommand;
use zellij_utils::input::options::Clipboard;
use zellij_utils::input::permission::GrantedPermission;
use zellij_utils::pane_size::{Size, SizeInPixels};
use zellij_utils::{
input::command::TerminalAction,
@ -2823,6 +2824,18 @@ pub(crate) fn screen_thread_main(
screen.report_tab_state()?;
},
ScreenInstruction::RequestPluginPermissions(plugin_id, permissions) => {
let permissions = match GrantedPermission::from_default() {
Ok(granted_permission) => {
if let Some(p) = granted_permission.get(&permissions.name) {
// TODO: How to deal cached data?
permissions
} else {
permissions
}
},
Err(_) => permissions,
};
let all_tabs = screen.get_tabs_mut();
let found = all_tabs.values_mut().any(|tab| {
if tab.has_plugin(plugin_id) {

View File

@ -9,7 +9,9 @@ mod swap_layouts;
use copy_command::CopyCommand;
use std::env::temp_dir;
use uuid::Uuid;
use zellij_utils::data::{Direction, PaneInfo, PermissionType, PluginPermission, ResizeStrategy};
use zellij_utils::data::{
Direction, PaneInfo, PermissionStatus, PermissionType, PluginPermission, ResizeStrategy,
};
use zellij_utils::errors::prelude::*;
use zellij_utils::input::command::RunCommand;
use zellij_utils::position::{Column, Line};
@ -474,7 +476,7 @@ pub trait Pane {
pub enum AdjustedInput {
WriteBytesToTerminal(Vec<u8>),
ReRunCommandInThisPane(RunCommand),
PermissionRequestResult(Vec<PermissionType>, bool),
PermissionRequestResult(Vec<PermissionType>, PermissionStatus),
CloseThisPane,
}
pub fn get_next_terminal_position(
@ -1576,14 +1578,14 @@ impl Tab {
.send_to_plugin(PluginInstruction::Update(plugin_updates))
.with_context(err_context)?;
},
Some(AdjustedInput::PermissionRequestResult(permissions, result)) => {
Some(AdjustedInput::PermissionRequestResult(permissions, status)) => {
self.request_plugin_permissions(pid, None);
self.senders
.send_to_plugin(PluginInstruction::PermissionRequestResult(
pid,
client_id,
permissions,
result,
status,
))
.with_context(err_context)?;
should_update_ui = true;

View File

@ -494,7 +494,7 @@ pub enum Event {
/// A file was deleted somewhere in the Zellij CWD folder
FileSystemDelete(Vec<PathBuf>),
/// A Result of plugin permission request
PermissionRequestResult(bool),
PermissionRequestResult(PermissionStatus),
}
#[derive(Debug, Clone, PartialEq, EnumDiscriminants, ToString, Serialize, Deserialize)]
@ -840,3 +840,9 @@ pub enum CopyDestination {
Primary,
System,
}
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
pub enum PermissionStatus {
Granted,
Denied,
}

View File

@ -1,6 +1,13 @@
use std::collections::{hash_map::Iter, HashMap};
use std::{
collections::{hash_map::Iter, HashMap},
fs,
};
use crate::data::PermissionType;
use crate::{
consts::{ZELLIJ_CACHE_DIR, ZELLIJ_PLUGIN_PERMISSIONS_FILE},
data::PermissionType,
input::config::ConfigError,
};
#[derive(Default, Debug)]
pub struct GrantedPermission(HashMap<String, Vec<PermissionType>>);
@ -17,4 +24,13 @@ impl GrantedPermission {
pub fn iter(&self) -> Iter<String, Vec<PermissionType>> {
self.0.iter()
}
pub fn from_default() -> Result<Self, ConfigError> {
let default_permission = ZELLIJ_CACHE_DIR.join(ZELLIJ_PLUGIN_PERMISSIONS_FILE);
let raw_string = fs::read_to_string(&default_permission)
.map_err(|e| ConfigError::IoPath(e, default_permission.into()))?;
GrantedPermission::from_string(raw_string)
}
}