summaryrefslogtreecommitdiffstats
path: root/zellij-utils
diff options
context:
space:
mode:
authorJae-Heon Ji <32578710+jaeheonji@users.noreply.github.com>2023-08-12 22:35:42 +0900
committerGitHub <noreply@github.com>2023-08-12 15:35:42 +0200
commitc8ddb23297e2f4fc900b8286d57e2808ae6a4fdb (patch)
treec96d26c8bfc24172374aefe88624b78c6890663f /zellij-utils
parenta1903b6b048f8257fc16ffd09e19c825248cb9d6 (diff)
feat: add plugin permission system (#2624)
* WIP: add exaple of permission ui * feat: add request permission ui * feat: add caching permission in memory * feat: add permission check * feat: add file caching * fix: changes request * feat(ui): new status bar mode (#2619) * supermode prototype * fix integration tests * fix tests * style(fmt): rustfmt * docs(changelog): status-bar supermode * fix(rendering): occasional glitches while resizing (#2621) * docs(changelog): resize glitches fix * chore(version): bump development version * Fix colored pane frames in mirrored sessions (#2625) * server/panes/tiled: Fix colored frames in mirrored sessions. Colored frames were previously ignored because they were treated like floating panes when rendering tiled panes. * CHANGELOG: Add PR #2625 * server/tab/unit: Fix unit tests for server. * fix(sessions): use custom lists of adjectives and nouns for generating session names (#2122) * Create custom lists of adjectives and nouns for generating session names * move word lists to const slices * add logic to retry name generation * refactor - reuse the name generator - iterator instead of for loop --------- Co-authored-by: Thomas Linford <linford.t@gmail.com> * docs(changelog): generate session names with custom words list * feat(plugins): make plugins configurable (#2646) * work * make every plugin entry point configurable * make integration tests pass * make e2e tests pass * add test for plugin configuration * add test snapshot * add plugin config parsing test * cleanups * style(fmt): rustfmt * style(comment): remove commented code * docs(changelog): configurable plugins * style(fmt): rustfmt * touch up ui * fix: don't save permission data in memory * feat: load cached permission * test: add example test (WIP) * fix: issue event are always denied * test: update snapshot * apply formatting * refactor: update default cache function * test: add more new test * apply formatting * Revert "apply formatting" This reverts commit a4e93703fbfdb6865131daa1c8b90fc5c36ab25e. * apply format * fix: update cache path * apply format * fix: cache path * fix: update log level * test for github workflow * Revert "test for github workflow" This reverts commit 01eff3bc5d1627a4e60bc6dac8ebe5500bc5b56e. * refactor: permission cache * fix(test): permission grant/deny race condition * style(fmt): rustfmt * style(fmt): rustfmt * configure permissions * permission denied test * snapshot * add ui for small plugins * style(fmt): rustfmt * some cleanups --------- Co-authored-by: Aram Drevekenin <aram@poor.dev> Co-authored-by: har7an <99636919+har7an@users.noreply.github.com> Co-authored-by: Kyle Sutherland-Cash <kyle.sutherlandcash@gmail.com> Co-authored-by: Thomas Linford <linford.t@gmail.com> Co-authored-by: Thomas Linford <tlinford@users.noreply.github.com>
Diffstat (limited to 'zellij-utils')
-rwxr-xr-xzellij-utils/assets/plugins/compact-bar.wasmbin526730 -> 806599 bytes
-rwxr-xr-xzellij-utils/assets/plugins/fixture-plugin-for-tests.wasmbin469401 -> 768790 bytes
-rwxr-xr-xzellij-utils/assets/plugins/status-bar.wasmbin656048 -> 961879 bytes
-rwxr-xr-xzellij-utils/assets/plugins/strider.wasmbin1718164 -> 2025837 bytes
-rwxr-xr-xzellij-utils/assets/plugins/tab-bar.wasmbin497583 -> 781434 bytes
-rw-r--r--zellij-utils/src/consts.rs2
-rw-r--r--zellij-utils/src/data.rs70
-rw-r--r--zellij-utils/src/errors.rs2
-rw-r--r--zellij-utils/src/input/mod.rs1
-rw-r--r--zellij-utils/src/input/permission.rs60
-rw-r--r--zellij-utils/src/kdl/mod.rs52
-rw-r--r--zellij-utils/src/plugin_api/event.proto6
-rw-r--r--zellij-utils/src/plugin_api/event.rs30
-rw-r--r--zellij-utils/src/plugin_api/mod.rs1
-rw-r--r--zellij-utils/src/plugin_api/plugin_command.proto7
-rw-r--r--zellij-utils/src/plugin_api/plugin_command.rs34
-rw-r--r--zellij-utils/src/plugin_api/plugin_permission.proto12
-rw-r--r--zellij-utils/src/plugin_api/plugin_permission.rs44
18 files changed, 311 insertions, 10 deletions
diff --git a/zellij-utils/assets/plugins/compact-bar.wasm b/zellij-utils/assets/plugins/compact-bar.wasm
index f38c500fc..9e2112cf9 100755
--- a/zellij-utils/assets/plugins/compact-bar.wasm
+++ b/zellij-utils/assets/plugins/compact-bar.wasm
Binary files differ
diff --git a/zellij-utils/assets/plugins/fixture-plugin-for-tests.wasm b/zellij-utils/assets/plugins/fixture-plugin-for-tests.wasm
index 80a6776e9..ff13cefd0 100755
--- a/zellij-utils/assets/plugins/fixture-plugin-for-tests.wasm
+++ b/zellij-utils/assets/plugins/fixture-plugin-for-tests.wasm
Binary files differ
diff --git a/zellij-utils/assets/plugins/status-bar.wasm b/zellij-utils/assets/plugins/status-bar.wasm
index 58beaacc8..e18d4edf9 100755
--- a/zellij-utils/assets/plugins/status-bar.wasm
+++ b/zellij-utils/assets/plugins/status-bar.wasm
Binary files differ
diff --git a/zellij-utils/assets/plugins/strider.wasm b/zellij-utils/assets/plugins/strider.wasm
index db61209a8..3aff9cc30 100755
--- a/zellij-utils/assets/plugins/strider.wasm
+++ b/zellij-utils/assets/plugins/strider.wasm
Binary files differ
diff --git a/zellij-utils/assets/plugins/tab-bar.wasm b/zellij-utils/assets/plugins/tab-bar.wasm
index 1a2919f6f..ee53ba180 100755
--- a/zellij-utils/assets/plugins/tab-bar.wasm
+++ b/zellij-utils/assets/plugins/tab-bar.wasm
Binary files differ
diff --git a/zellij-utils/src/consts.rs b/zellij-utils/src/consts.rs
index 50600a934..a2c3a42a5 100644
--- a/zellij-utils/src/consts.rs
+++ b/zellij-utils/src/consts.rs
@@ -36,6 +36,8 @@ lazy_static! {
.cache_dir()
.to_path_buf()
.join(format!("{}", Uuid::new_v4()));
+ pub static ref ZELLIJ_PLUGIN_PERMISSIONS_CACHE: PathBuf =
+ ZELLIJ_CACHE_DIR.join("permissions.kdl");
}
pub const FEATURES: &[&str] = &[
diff --git a/zellij-utils/src/data.rs b/zellij-utils/src/data.rs
index 9c1c8e2f6..a08e642f9 100644
--- a/zellij-utils/src/data.rs
+++ b/zellij-utils/src/data.rs
@@ -6,7 +6,7 @@ use std::collections::{HashMap, HashSet};
use std::fmt;
use std::path::{Path, PathBuf};
use std::str::FromStr;
-use strum_macros::{EnumDiscriminants, EnumIter, EnumString, ToString};
+use strum_macros::{Display, EnumDiscriminants, EnumIter, EnumString, ToString};
pub type ClientId = u16; // TODO: merge with crate type?
@@ -493,6 +493,63 @@ pub enum Event {
FileSystemUpdate(Vec<PathBuf>),
/// A file was deleted somewhere in the Zellij CWD folder
FileSystemDelete(Vec<PathBuf>),
+ /// A Result of plugin permission request
+ PermissionRequestResult(PermissionStatus),
+}
+
+#[derive(
+ Debug,
+ PartialEq,
+ Eq,
+ Hash,
+ Copy,
+ Clone,
+ EnumDiscriminants,
+ ToString,
+ Serialize,
+ Deserialize,
+ PartialOrd,
+ Ord,
+)]
+#[strum_discriminants(derive(EnumString, Hash, Serialize, Deserialize, Display, PartialOrd, Ord))]
+#[strum_discriminants(name(PermissionType))]
+#[non_exhaustive]
+pub enum Permission {
+ ReadApplicationState,
+ ChangeApplicationState,
+ OpenFiles,
+ RunCommands,
+ OpenTerminalsOrPlugins,
+ WriteToStdin,
+}
+
+impl PermissionType {
+ pub fn display_name(&self) -> String {
+ match self {
+ PermissionType::ReadApplicationState => {
+ "Access Zellij state (Panes, Tabs and UI)".to_owned()
+ },
+ PermissionType::ChangeApplicationState => {
+ "Change Zellij state (Panes, Tabs and UI)".to_owned()
+ },
+ PermissionType::OpenFiles => "Open files (eg. for editing)".to_owned(),
+ PermissionType::RunCommands => "Run commands".to_owned(),
+ PermissionType::OpenTerminalsOrPlugins => "Start new terminals and plugins".to_owned(),
+ PermissionType::WriteToStdin => "Write to standard input (STDIN)".to_owned(),
+ }
+ }
+}
+
+#[derive(Debug, Clone)]
+pub struct PluginPermission {
+ pub name: String,
+ pub permissions: Vec<PermissionType>,
+}
+
+impl PluginPermission {
+ pub fn new(name: String, permissions: Vec<PermissionType>) -> Self {
+ PluginPermission { name, permissions }
+ }
}
/// Describes the different input modes, which change the way that keystrokes will be interpreted.
@@ -811,6 +868,12 @@ pub enum CopyDestination {
System,
}
+#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
+pub enum PermissionStatus {
+ Granted,
+ Denied,
+}
+
#[derive(Debug, Default, Clone)]
pub struct FileToOpen {
pub path: PathBuf,
@@ -882,7 +945,9 @@ impl PluginMessage {
}
}
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, EnumDiscriminants, ToString)]
+#[strum_discriminants(derive(EnumString, Hash, Serialize, Deserialize))]
+#[strum_discriminants(name(CommandType))]
pub enum PluginCommand {
Subscribe(HashSet<EventType>),
Unsubscribe(HashSet<EventType>),
@@ -950,4 +1015,5 @@ pub enum PluginCommand {
RenamePluginPane(u32, String), // plugin pane id, new name
RenameTab(u32, String), // tab index, new name
ReportPanic(String), // stringified panic
+ RequestPluginPermissions(Vec<PermissionType>),
}
diff --git a/zellij-utils/src/errors.rs b/zellij-utils/src/errors.rs
index df5d02782..306db448c 100644
--- a/zellij-utils/src/errors.rs
+++ b/zellij-utils/src/errors.rs
@@ -338,6 +338,7 @@ pub enum ScreenContext {
FocusPaneWithId,
RenamePane,
RenameTab,
+ RequestPluginPermissions,
BreakPane,
BreakPaneRight,
BreakPaneLeft,
@@ -377,6 +378,7 @@ pub enum PluginContext {
PostMessageToPluginWorker,
PostMessageToPlugin,
PluginSubscribedToEvents,
+ PermissionRequestResult,
}
/// Stack call representations corresponding to the different types of [`ClientInstruction`]s.
diff --git a/zellij-utils/src/input/mod.rs b/zellij-utils/src/input/mod.rs
index 6722cfd88..1c95f348b 100644
--- a/zellij-utils/src/input/mod.rs
+++ b/zellij-utils/src/input/mod.rs
@@ -4,6 +4,7 @@ pub mod config;
pub mod keybinds;
pub mod layout;
pub mod options;
+pub mod permission;
pub mod plugins;
pub mod theme;
diff --git a/zellij-utils/src/input/permission.rs b/zellij-utils/src/input/permission.rs
new file mode 100644
index 000000000..1755fe1e6
--- /dev/null
+++ b/zellij-utils/src/input/permission.rs
@@ -0,0 +1,60 @@
+use std::{
+ collections::HashMap,
+ fs::{self, File},
+ io::Write,
+ path::PathBuf,
+};
+
+use crate::{consts::ZELLIJ_PLUGIN_PERMISSIONS_CACHE, data::PermissionType};
+
+pub type GrantedPermission = HashMap<String, Vec<PermissionType>>;
+
+#[derive(Default, Debug)]
+pub struct PermissionCache {
+ path: PathBuf,
+ granted: GrantedPermission,
+}
+
+impl PermissionCache {
+ pub fn cache(&mut self, plugin_name: String, permissions: Vec<PermissionType>) {
+ self.granted.insert(plugin_name, permissions);
+ }
+
+ pub fn get_permissions(&self, plugin_name: String) -> Option<&Vec<PermissionType>> {
+ self.granted.get(&plugin_name)
+ }
+
+ pub fn check_permissions(
+ &self,
+ plugin_name: String,
+ permissions: &Vec<PermissionType>,
+ ) -> bool {
+ if let Some(target) = self.granted.get(&plugin_name) {
+ if target == permissions {
+ return true;
+ }
+ }
+
+ false
+ }
+
+ pub fn from_path_or_default(cache_path: Option<PathBuf>) -> Self {
+ let cache_path = cache_path.unwrap_or(ZELLIJ_PLUGIN_PERMISSIONS_CACHE.to_path_buf());
+
+ 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 a75a4a638..13a03ad15 100644
--- a/zellij-utils/src/kdl/mod.rs
+++ b/zellij-utils/src/kdl/mod.rs
@@ -1,15 +1,16 @@
mod kdl_layout_parser;
-use crate::data::{Direction, InputMode, Key, Palette, PaletteColor, Resize};
+use crate::data::{Direction, InputMode, Key, Palette, PaletteColor, PermissionType, Resize};
use crate::envs::EnvironmentVariables;
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, 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};
use kdl_layout_parser::KdlLayoutParser;
-use std::collections::{BTreeMap, HashMap};
+use std::collections::{BTreeMap, HashMap, HashSet};
use strum::IntoEnumIterator;
use miette::NamedSource;
@@ -1793,6 +1794,53 @@ impl Themes {
}
}
+impl PermissionCache {
+ pub fn from_string(raw_string: String) -> Result<GrantedPermission, ConfigError> {
+ let kdl_document: KdlDocument = raw_string.parse()?;
+
+ let mut granted_permission = GrantedPermission::default();
+
+ for node in kdl_document.nodes() {
+ if let Some(children) = node.children() {
+ let key = kdl_name!(node);
+ let permissions: Vec<PermissionType> = children
+ .nodes()
+ .iter()
+ .filter_map(|p| {
+ let v = kdl_name!(p);
+ PermissionType::from_str(v).ok()
+ })
+ .collect();
+
+ granted_permission.insert(key.into(), permissions);
+ }
+ }
+
+ Ok(granted_permission)
+ }
+
+ pub fn to_string(granted: &GrantedPermission) -> String {
+ let mut kdl_doucment = KdlDocument::new();
+
+ granted.iter().for_each(|(k, v)| {
+ let mut node = KdlNode::new(k.as_str());
+ let mut children = KdlDocument::new();
+
+ let permissions: HashSet<PermissionType> = v.clone().into_iter().collect();
+ permissions.iter().for_each(|f| {
+ let n = KdlNode::new(f.to_string().as_str());
+ children.nodes_mut().push(n);
+ });
+
+ node.set_children(children);
+ kdl_doucment.nodes_mut().push(node);
+ });
+
+ kdl_doucment.fmt();
+ kdl_doucment.to_string()
+ }
+}
+
pub fn parse_plugin_user_configuration(
plugin_block: &KdlNode,
) -> Result<BTreeMap<String, String>, ConfigError> {
diff --git a/zellij-utils/src/plugin_api/event.proto b/zellij-utils/src/plugin_api/event.proto
index 95928ae3b..3a9838fa8 100644
--- a/zellij-utils/src/plugin_api/event.proto
+++ b/zellij-utils/src/plugin_api/event.proto
@@ -38,6 +38,7 @@ enum EventType {
FileSystemUpdate = 13;
/// A file was deleted somewhere in the Zellij CWD folder
FileSystemDelete = 14;
+ PermissionRequestResult = 15;
}
message EventNameList {
@@ -57,9 +58,14 @@ message Event {
bool visible_payload = 9;
CustomMessagePayload custom_message_payload = 10;
FileListPayload file_list_payload = 11;
+ PermissionRequestResultPayload permission_request_result_payload = 12;
}
}
+message PermissionRequestResultPayload {
+ bool granted = 1;
+}
+
message FileListPayload {
repeated string paths = 1;
}
diff --git a/zellij-utils/src/plugin_api/event.rs b/zellij-utils/src/plugin_api/event.rs
index 315fa54b8..6115fe1e8 100644
--- a/zellij-utils/src/plugin_api/event.rs
+++ b/zellij-utils/src/plugin_api/event.rs
@@ -13,9 +13,10 @@ pub use super::generated_api::api::{
style::Style as ProtobufStyle,
};
use crate::data::{
- CopyDestination, Direction, Event, EventType, InputMode, Key, ModeInfo, Mouse, Palette,
- PaletteColor, PaneInfo, PaneManifest, PluginCapabilities, Style, TabInfo, ThemeHue,
+ CopyDestination, Event, EventType, InputMode, Key, ModeInfo, Mouse, PaneInfo, PaneManifest,
+ PermissionStatus, PluginCapabilities, Style, TabInfo,
};
+
use crate::errors::prelude::*;
use crate::input::actions::Action;
@@ -160,6 +161,16 @@ impl TryFrom<ProtobufEvent> for Event {
},
_ => Err("Malformed payload for the file system delete Event"),
},
+ Some(ProtobufEventType::PermissionRequestResult) => match protobuf_event.payload {
+ Some(ProtobufEventPayload::PermissionRequestResultPayload(payload)) => {
+ if payload.granted {
+ Ok(Event::PermissionRequestResult(PermissionStatus::Granted))
+ } else {
+ Ok(Event::PermissionRequestResult(PermissionStatus::Denied))
+ }
+ },
+ _ => Err("Malformed payload for the file system delete Event"),
+ },
None => Err("Unknown Protobuf Event"),
}
}
@@ -290,6 +301,18 @@ impl TryFrom<Event> for ProtobufEvent {
payload: Some(event::Payload::FileListPayload(file_list_payload)),
})
},
+ Event::PermissionRequestResult(permission_status) => {
+ let granted = match permission_status {
+ PermissionStatus::Granted => true,
+ PermissionStatus::Denied => false,
+ };
+ Ok(ProtobufEvent {
+ name: ProtobufEventType::PermissionRequestResult as i32,
+ payload: Some(event::Payload::PermissionRequestResultPayload(
+ PermissionRequestResultPayload { granted },
+ )),
+ })
+ },
}
}
}
@@ -673,6 +696,7 @@ impl TryFrom<ProtobufEventType> for EventType {
ProtobufEventType::FileSystemRead => EventType::FileSystemRead,
ProtobufEventType::FileSystemUpdate => EventType::FileSystemUpdate,
ProtobufEventType::FileSystemDelete => EventType::FileSystemDelete,
+ ProtobufEventType::PermissionRequestResult => EventType::PermissionRequestResult,
})
}
}
@@ -696,6 +720,7 @@ impl TryFrom<EventType> for ProtobufEventType {
EventType::FileSystemRead => ProtobufEventType::FileSystemRead,
EventType::FileSystemUpdate => ProtobufEventType::FileSystemUpdate,
EventType::FileSystemDelete => ProtobufEventType::FileSystemDelete,
+ EventType::PermissionRequestResult => ProtobufEventType::PermissionRequestResult,
})
}
}
@@ -717,6 +742,7 @@ fn serialize_mode_update_event() {
#[test]
fn serialize_mode_update_event_with_non_default_values() {
+ use crate::data::{Direction, Palette, PaletteColor, ThemeHue};
use prost::Message;
let mode_update_event = Event::ModeUpdate(ModeInfo {
mode: InputMode::Locked,
diff --git a/zellij-utils/src/plugin_api/mod.rs b/zellij-utils/src/plugin_api/mod.rs
index 55ace5007..4812d468c 100644
--- a/zellij-utils/src/plugin_api/mod.rs
+++ b/zellij-utils/src/plugin_api/mod.rs
@@ -7,6 +7,7 @@ pub mod key;
pub mod message;
pub mod plugin_command;
pub mod plugin_ids;
+pub mod plugin_permission;
pub mod resize;
pub mod style;
pub mod generated_api {
diff --git a/zellij-utils/src/plugin_api/plugin_command.proto b/zellij-utils/src/plugin_api/plugin_command.proto
index f09ccf4b1..9ba8bb7f4 100644
--- a/zellij-utils/src/plugin_api/plugin_command.proto
+++ b/zellij-utils/src/plugin_api/plugin_command.proto
@@ -6,6 +6,7 @@ import "command.proto";
import "message.proto";
import "input_mode.proto";
import "resize.proto";
+import "plugin_permission.proto";
package api.plugin_command;
@@ -76,6 +77,7 @@ enum CommandName {
RenamePluginPane = 63;
RenameTab = 64;
ReportCrash = 65;
+ RequestPluginPermissions = 66;
}
message PluginCommand {
@@ -117,9 +119,14 @@ message PluginCommand {
IdAndNewName rename_plugin_pane_payload = 35;
IdAndNewName rename_tab_payload = 36;
string report_crash_payload = 37;
+ RequestPluginPermissionPayload request_plugin_permission_payload = 38;
}
}
+message RequestPluginPermissionPayload {
+ repeated plugin_permission.PermissionType permissions = 1;
+}
+
message SubscribePayload {
event.EventNameList subscriptions = 1;
}
diff --git a/zellij-utils/src/plugin_api/plugin_command.rs b/zellij-utils/src/plugin_api/plugin_command.rs
index bf359dd20..ff50a6a76 100644
--- a/zellij-utils/src/plugin_api/plugin_command.rs
+++ b/zellij-utils/src/plugin_api/plugin_command.rs
@@ -3,14 +3,15 @@ pub use super::generated_api::api::{
plugin_command::{
plugin_command::Payload, CommandName, ExecCmdPayload, IdAndNewName, MovePayload,
OpenCommandPanePayload, OpenFilePayload, PaneIdAndShouldFloat,
- PluginCommand as ProtobufPluginCommand, PluginMessagePayload, ResizePayload,
- SetTimeoutPayload, SubscribePayload, SwitchTabToPayload, SwitchToModePayload,
- UnsubscribePayload,
+ PluginCommand as ProtobufPluginCommand, PluginMessagePayload,
+ RequestPluginPermissionPayload, ResizePayload, SetTimeoutPayload, SubscribePayload,
+ SwitchTabToPayload, SwitchToModePayload, UnsubscribePayload,
},
+ plugin_permission::PermissionType as ProtobufPermissionType,
resize::ResizeAction as ProtobufResizeAction,
};
-use crate::data::PluginCommand;
+use crate::data::{PermissionType, PluginCommand};
use std::convert::TryFrom;
@@ -486,6 +487,19 @@ impl TryFrom<ProtobufPluginCommand> for PluginCommand {
},
_ => Err("Mismatched payload for ReportCrash"),
},
+ Some(CommandName::RequestPluginPermissions) => match protobuf_plugin_command.payload {
+ Some(Payload::RequestPluginPermissionPayload(payload)) => {
+ Ok(PluginCommand::RequestPluginPermissions(
+ payload
+ .permissions
+ .iter()
+ .filter_map(|p| ProtobufPermissionType::from_i32(*p))
+ .filter_map(|p| PermissionType::try_from(p).ok())
+ .collect(),
+ ))
+ },
+ _ => Err("Mismatched payload for RequestPluginPermission"),
+ },
None => Err("Unrecognized plugin command"),
}
}
@@ -820,6 +834,18 @@ impl TryFrom<PluginCommand> for ProtobufPluginCommand {
name: CommandName::ReportCrash as i32,
payload: Some(Payload::ReportCrashPayload(payload)),
}),
+ Pl