Classify plugin permission risk
This commit is contained in:
@@ -21,8 +21,8 @@ pub use error::DomainError;
|
|||||||
pub use history::HistoryEntry;
|
pub use history::HistoryEntry;
|
||||||
pub use identifiers::{DownloadId, ProfileId, SpaceId, SplitId, TabId, WebViewId};
|
pub use identifiers::{DownloadId, ProfileId, SpaceId, SplitId, TabId, WebViewId};
|
||||||
pub use plugin::{
|
pub use plugin::{
|
||||||
PluginContributionPoint, PluginId, PluginManifest, PluginPermission, PluginSignature,
|
PluginContributionPoint, PluginId, PluginManifest, PluginPermission, PluginPermissionRisk,
|
||||||
PluginSignatureAlgorithm,
|
PluginSignature, PluginSignatureAlgorithm,
|
||||||
};
|
};
|
||||||
pub use profile::{Profile, ProfileKind};
|
pub use profile::{Profile, ProfileKind};
|
||||||
pub use space::{ArchivePolicy, Space};
|
pub use space::{ArchivePolicy, Space};
|
||||||
|
|||||||
@@ -50,6 +50,12 @@ pub enum PluginPermission {
|
|||||||
UiContextMenu,
|
UiContextMenu,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
|
pub enum PluginPermissionRisk {
|
||||||
|
Standard,
|
||||||
|
High,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub enum PluginContributionPoint {
|
pub enum PluginContributionPoint {
|
||||||
CommandBarCommand,
|
CommandBarCommand,
|
||||||
@@ -166,6 +172,10 @@ impl PluginManifest {
|
|||||||
&self.permissions
|
&self.permissions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn high_risk_permissions(&self) -> impl Iterator<Item = &PluginPermission> {
|
||||||
|
self.permissions.iter().filter(|permission| permission.requires_separate_confirmation())
|
||||||
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn contributes(&self) -> &[PluginContributionPoint] {
|
pub fn contributes(&self) -> &[PluginContributionPoint] {
|
||||||
&self.contributes
|
&self.contributes
|
||||||
@@ -245,6 +255,40 @@ impl PluginPermission {
|
|||||||
Self::UiContextMenu => "ui:context_menu",
|
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 {
|
impl PluginContributionPoint {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use std::{error::Error, io};
|
use std::{error::Error, io};
|
||||||
|
|
||||||
use ely_domain::{
|
use ely_domain::{
|
||||||
DomainError, PluginContributionPoint, PluginManifest, PluginPermission,
|
DomainError, PluginContributionPoint, PluginManifest, PluginPermission, PluginPermissionRisk,
|
||||||
PluginSignatureAlgorithm,
|
PluginSignatureAlgorithm,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -33,6 +33,20 @@ fn parses_signed_plugin_manifest() -> Result<(), Box<dyn Error>> {
|
|||||||
Ok(())
|
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]
|
#[test]
|
||||||
fn rejects_unknown_plugin_permission() -> Result<(), Box<dyn Error>> {
|
fn rejects_unknown_plugin_permission() -> Result<(), Box<dyn Error>> {
|
||||||
let manifest = valid_manifest().replace("page:metadata", "tabs:admin");
|
let manifest = valid_manifest().replace("page:metadata", "tabs:admin");
|
||||||
|
|||||||
Reference in New Issue
Block a user