Classify plugin permission risk
This commit is contained in:
@@ -21,8 +21,8 @@ pub use error::DomainError;
|
||||
pub use history::HistoryEntry;
|
||||
pub use identifiers::{DownloadId, ProfileId, SpaceId, SplitId, TabId, WebViewId};
|
||||
pub use plugin::{
|
||||
PluginContributionPoint, PluginId, PluginManifest, PluginPermission, PluginSignature,
|
||||
PluginSignatureAlgorithm,
|
||||
PluginContributionPoint, PluginId, PluginManifest, PluginPermission, PluginPermissionRisk,
|
||||
PluginSignature, PluginSignatureAlgorithm,
|
||||
};
|
||||
pub use profile::{Profile, ProfileKind};
|
||||
pub use space::{ArchivePolicy, Space};
|
||||
|
||||
@@ -50,6 +50,12 @@ pub enum PluginPermission {
|
||||
UiContextMenu,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub enum PluginPermissionRisk {
|
||||
Standard,
|
||||
High,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub enum PluginContributionPoint {
|
||||
CommandBarCommand,
|
||||
@@ -166,6 +172,10 @@ impl PluginManifest {
|
||||
&self.permissions
|
||||
}
|
||||
|
||||
pub fn high_risk_permissions(&self) -> impl Iterator<Item = &PluginPermission> {
|
||||
self.permissions.iter().filter(|permission| permission.requires_separate_confirmation())
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn contributes(&self) -> &[PluginContributionPoint] {
|
||||
&self.contributes
|
||||
@@ -245,6 +255,40 @@ impl PluginPermission {
|
||||
Self::UiContextMenu => "ui:context_menu",
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn risk(&self) -> PluginPermissionRisk {
|
||||
match self {
|
||||
Self::TabsRead
|
||||
| Self::SpacesRead
|
||||
| Self::PageMetadata
|
||||
| Self::SettingsRead
|
||||
| Self::UiPanel
|
||||
| Self::UiCommand
|
||||
| Self::UiContextMenu => PluginPermissionRisk::Standard,
|
||||
Self::TabsWrite
|
||||
| Self::SpacesWrite
|
||||
| Self::BookmarksRead
|
||||
| Self::BookmarksWrite
|
||||
| Self::HistoryRead
|
||||
| Self::DownloadsRead
|
||||
| Self::DownloadsWrite
|
||||
| Self::PageScreenshot
|
||||
| Self::PageScript
|
||||
| Self::ClipboardRead
|
||||
| Self::ClipboardWrite
|
||||
| Self::FilesystemRead
|
||||
| Self::FilesystemWrite
|
||||
| Self::NetworkFetch
|
||||
| Self::SettingsWrite
|
||||
| Self::SyncPlugin => PluginPermissionRisk::High,
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn requires_separate_confirmation(&self) -> bool {
|
||||
self.risk() == PluginPermissionRisk::High
|
||||
}
|
||||
}
|
||||
|
||||
impl PluginContributionPoint {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::{error::Error, io};
|
||||
|
||||
use ely_domain::{
|
||||
DomainError, PluginContributionPoint, PluginManifest, PluginPermission,
|
||||
DomainError, PluginContributionPoint, PluginManifest, PluginPermission, PluginPermissionRisk,
|
||||
PluginSignatureAlgorithm,
|
||||
};
|
||||
|
||||
@@ -33,6 +33,20 @@ fn parses_signed_plugin_manifest() -> Result<(), Box<dyn Error>> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_plugin_permission_risk_for_separate_confirmation() -> Result<(), Box<dyn Error>> {
|
||||
let manifest = PluginManifest::from_toml(valid_manifest().as_str())?;
|
||||
let high_risk_permissions = manifest.high_risk_permissions().collect::<Vec<_>>();
|
||||
|
||||
assert!(high_risk_permissions.is_empty());
|
||||
assert_eq!(PluginPermission::PageMetadata.risk(), PluginPermissionRisk::Standard);
|
||||
assert_eq!(PluginPermission::UiCommand.risk(), PluginPermissionRisk::Standard);
|
||||
assert_eq!(PluginPermission::HistoryRead.risk(), PluginPermissionRisk::High);
|
||||
assert!(PluginPermission::PageScript.requires_separate_confirmation());
|
||||
assert!(PluginPermission::FilesystemWrite.requires_separate_confirmation());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rejects_unknown_plugin_permission() -> Result<(), Box<dyn Error>> {
|
||||
let manifest = valid_manifest().replace("page:metadata", "tabs:admin");
|
||||
|
||||
Reference in New Issue
Block a user