From 778d316f34c0ae0c66d3ab8be5123f2d4f07367e Mon Sep 17 00:00:00 2001 From: Lucas Nogueira Date: Wed, 26 Jun 2024 15:54:58 -0300 Subject: [PATCH] use a hashset --- .changes/capability-hashset.md | 5 ++++ core/tauri-utils/src/acl/capability.rs | 36 ++++++++++++-------------- core/tauri-utils/src/acl/identifier.rs | 2 +- core/tauri/src/ipc/authority.rs | 8 +++--- 4 files changed, 27 insertions(+), 24 deletions(-) create mode 100644 .changes/capability-hashset.md diff --git a/.changes/capability-hashset.md b/.changes/capability-hashset.md new file mode 100644 index 000000000..183d73f2a --- /dev/null +++ b/.changes/capability-hashset.md @@ -0,0 +1,5 @@ +--- +"tauri-utils": patch:breaking +--- + +`acl::Capability::permissions` is now a `HashSet` instead of a `Vec`. diff --git a/core/tauri-utils/src/acl/capability.rs b/core/tauri-utils/src/acl/capability.rs index d1a170263..366e5068b 100644 --- a/core/tauri-utils/src/acl/capability.rs +++ b/core/tauri-utils/src/acl/capability.rs @@ -4,7 +4,7 @@ //! End-user abstraction for selecting permissions a window has access to. -use std::{path::Path, str::FromStr}; +use std::{collections::HashSet, hash::Hash, path::Path, str::FromStr}; use crate::{acl::Identifier, platform::Target}; use serde::{Deserialize, Serialize}; @@ -13,7 +13,7 @@ use super::Scopes; /// An entry for a permission value in a [`Capability`] can be either a raw permission [`Identifier`] /// or an object that references a permission and extends its scope. -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] pub enum PermissionEntry { @@ -29,6 +29,20 @@ pub enum PermissionEntry { }, } +impl PartialEq for PermissionEntry { + fn eq(&self, other: &Self) -> bool { + self.identifier() == other.identifier() + } +} + +impl Eq for PermissionEntry {} + +impl Hash for PermissionEntry { + fn hash(&self, state: &mut H) { + self.identifier().hash(state); + } +} + impl PermissionEntry { /// The identifier of the permission referenced in this entry. pub fn identifier(&self) -> &Identifier { @@ -157,8 +171,7 @@ pub struct Capability { /// "allow": [{ "path": "$HOME/test.txt" }] /// } /// ``` - #[cfg_attr(feature = "schema", schemars(schema_with = "unique_permission"))] - pub permissions: Vec, + pub permissions: HashSet, /// Limit which target platforms this capability applies to. /// /// By default all platforms are targeted. @@ -170,21 +183,6 @@ pub struct Capability { pub platforms: Option>, } -#[cfg(feature = "schema")] -fn unique_permission(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - use schemars::schema; - schema::SchemaObject { - instance_type: Some(schema::InstanceType::Array.into()), - array: Some(Box::new(schema::ArrayValidation { - unique_items: Some(true), - items: Some(gen.subschema_for::().into()), - ..Default::default() - })), - ..Default::default() - } - .into() -} - fn default_capability_local() -> bool { true } diff --git a/core/tauri-utils/src/acl/identifier.rs b/core/tauri-utils/src/acl/identifier.rs index 92d210aa8..7a8208b04 100644 --- a/core/tauri-utils/src/acl/identifier.rs +++ b/core/tauri-utils/src/acl/identifier.rs @@ -17,7 +17,7 @@ const MAX_LEN_BASE: usize = 64; const MAX_LEN_IDENTIFIER: usize = MAX_LEN_PREFIX + 1 + MAX_LEN_BASE; /// Plugin identifier. -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Identifier { inner: String, separator: Option, diff --git a/core/tauri/src/ipc/authority.rs b/core/tauri/src/ipc/authority.rs index 662fa48a1..a168a92ee 100644 --- a/core/tauri/src/ipc/authority.rs +++ b/core/tauri/src/ipc/authority.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -use std::collections::BTreeMap; +use std::collections::{BTreeMap, HashSet}; use std::fmt::{Debug, Display}; use std::sync::Arc; @@ -93,7 +93,7 @@ impl CapabilityBuilder { local: true, windows: Vec::new(), webviews: Vec::new(), - permissions: Vec::new(), + permissions: HashSet::new(), platforms: None, }) } @@ -145,7 +145,7 @@ impl CapabilityBuilder { /// Add a new permission to this capability. pub fn permission(mut self, permission: impl Into) -> Self { let permission = permission.into(); - self.0.permissions.push(PermissionEntry::PermissionRef( + self.0.permissions.insert(PermissionEntry::PermissionRef( permission .clone() .try_into() @@ -191,7 +191,7 @@ impl CapabilityBuilder { self .0 .permissions - .push(PermissionEntry::ExtendedPermission { identifier, scope }); + .insert(PermissionEntry::ExtendedPermission { identifier, scope }); self }