Forráskód Böngészése

refactor(core): merge scope and commands resolving permission sets (#8731)

Lucas Fernandes Nogueira 1 éve
szülő
commit
a35b416e38

+ 79 - 64
core/tauri-utils/src/acl/resolved.rs

@@ -17,7 +17,7 @@ use crate::platform::Target;
 use super::{
   capability::{Capability, CapabilityContext, PermissionEntry},
   plugin::Manifest,
-  Error, ExecutionContext, Permission, PermissionSet, Scopes, Value,
+  Commands, Error, ExecutionContext, Permission, PermissionSet, Scopes, Value,
 };
 
 /// A key for a scope, used to link a [`ResolvedCommand#structfield.scope`] to the store [`Resolved#structfield.scopes`].
@@ -127,70 +127,85 @@ impl Resolved {
         if let Some(plugin_name) = permission_id.get_prefix() {
           let permissions = get_permissions(plugin_name, permission_name, &acl)?;
 
+          let mut resolved_scope = Scopes::default();
+          let mut commands = Commands::default();
+
+          if let PermissionEntry::ExtendedPermission {
+            identifier: _,
+            scope,
+          } = permission_entry
+          {
+            if let Some(allow) = scope.allow.clone() {
+              resolved_scope
+                .allow
+                .get_or_insert_with(Default::default)
+                .extend(allow);
+            }
+            if let Some(deny) = scope.deny.clone() {
+              resolved_scope
+                .deny
+                .get_or_insert_with(Default::default)
+                .extend(deny);
+            }
+          }
+
           for permission in permissions {
-            let scope = match permission_entry {
-              PermissionEntry::PermissionRef(_) => permission.scope.clone(),
-              PermissionEntry::ExtendedPermission {
-                identifier: _,
-                scope,
-              } => {
-                let mut merged = permission.scope.clone();
-                if let Some(allow) = scope.allow.clone() {
-                  merged
-                    .allow
-                    .get_or_insert_with(Default::default)
-                    .extend(allow);
-                }
-                if let Some(deny) = scope.deny.clone() {
-                  merged
-                    .deny
-                    .get_or_insert_with(Default::default)
-                    .extend(deny);
-                }
-                merged
-              }
-            };
+            if let Some(allow) = permission.scope.allow.clone() {
+              resolved_scope
+                .allow
+                .get_or_insert_with(Default::default)
+                .extend(allow);
+            }
+            if let Some(deny) = permission.scope.deny.clone() {
+              resolved_scope
+                .deny
+                .get_or_insert_with(Default::default)
+                .extend(deny);
+            }
 
-            if permission.commands.allow.is_empty() && permission.commands.deny.is_empty() {
-              // global scope
-              global_scope
-                .entry(plugin_name.to_string())
-                .or_default()
-                .push(scope.clone());
+            commands.allow.extend(permission.commands.allow.clone());
+            commands.deny.extend(permission.commands.deny.clone());
+          }
+
+          if commands.allow.is_empty() && commands.deny.is_empty() {
+            // global scope
+            global_scope
+              .entry(plugin_name.to_string())
+              .or_default()
+              .push(resolved_scope);
+          } else {
+            let has_scope = resolved_scope.allow.is_some() || resolved_scope.deny.is_some();
+            if has_scope {
+              current_scope_id += 1;
+              command_scopes.insert(current_scope_id, resolved_scope);
+            }
+
+            let scope_id = if has_scope {
+              Some(current_scope_id)
             } else {
-              let has_scope = scope.allow.is_some() || scope.deny.is_some();
-              if has_scope {
-                current_scope_id += 1;
-                command_scopes.insert(current_scope_id, scope.clone());
-              }
-
-              let scope_id = if has_scope {
-                Some(current_scope_id)
-              } else {
-                None
-              };
-
-              for allowed_command in &permission.commands.allow {
-                resolve_command(
-                  &mut allowed_commands,
-                  format!("plugin:{plugin_name}|{allowed_command}"),
-                  capability,
-                  scope_id,
-                  #[cfg(debug_assertions)]
-                  permission,
-                );
-              }
-
-              for denied_command in &permission.commands.deny {
-                resolve_command(
-                  &mut denied_commands,
-                  format!("plugin:{plugin_name}|{denied_command}"),
-                  capability,
-                  scope_id,
-                  #[cfg(debug_assertions)]
-                  permission,
-                );
-              }
+              None
+            };
+
+            for allowed_command in &commands.allow {
+              resolve_command(
+                &mut allowed_commands,
+                format!("plugin:{plugin_name}|{allowed_command}"),
+                capability,
+                scope_id,
+                #[cfg(debug_assertions)]
+                permission_name.to_string(),
+              );
+            }
+
+            for denied_command in &commands.deny {
+              resolve_command(
+                &mut denied_commands,
+                format!("plugin:{plugin_name}|{denied_command}"),
+                capability,
+                scope_id,
+                #[cfg(debug_assertions)]
+                permission_name.to_string(),
+              );
             }
           }
         }
@@ -306,7 +321,7 @@ fn resolve_command(
   command: String,
   capability: &Capability,
   scope_id: Option<ScopeKey>,
-  #[cfg(debug_assertions)] permission: &Permission,
+  #[cfg(debug_assertions)] referenced_by_permission_identifier: String,
 ) {
   let contexts = match &capability.context {
     CapabilityContext::Local => {
@@ -332,7 +347,7 @@ fn resolve_command(
     #[cfg(debug_assertions)]
     resolved.referenced_by.push(ResolvedCommandReference {
       capability: capability.identifier.clone(),
-      permission: permission.identifier.clone(),
+      permission: referenced_by_permission_identifier.clone(),
     });
 
     resolved.windows.extend(capability.windows.clone());

+ 2 - 1
core/tests/acl/fixtures/capabilities/scope-extended/cap.json

@@ -35,6 +35,7 @@
           "path": "$APP/*.db"
         }
       ]
-    }
+    },
+    "fs:read-download-dir"
   ]
 }

+ 1 - 0
core/tests/acl/fixtures/capabilities/scope/cap.toml

@@ -7,4 +7,5 @@ permissions = [
   "fs:deny-home",
   "fs:allow-read-resources",
   "fs:allow-move-temp",
+  "fs:read-download-dir"
 ]

+ 4 - 0
core/tests/acl/fixtures/plugins/fs/read-download-dir.toml

@@ -0,0 +1,4 @@
+[[set]]
+identifier = "read-download-dir"
+description = "allows all read the $DOWNLOAD dir"
+permissions = ["allow-read-dir", "allow-download-dir"]

+ 9 - 1
core/tests/acl/fixtures/plugins/fs/scope.toml

@@ -1,6 +1,14 @@
-
 [[permission]]
 identifier = "allow-app"
 description = "Allows accessing the $APP path."
 [[permission.scope.allow]]
 path = "$APP"
+
+
+[[permission]]
+identifier = "allow-download-dir"
+description = "Allows accessing the $DOWNLOAD directory."
+[[permission.scope.allow]]
+path = "$DOWNLOAD"
+[[permission.scope.allow]]
+path = "$DOWNLOAD/**"

+ 30 - 17
core/tests/acl/fixtures/snapshots/acl_tests__tests__scope-extended.snap

@@ -1,6 +1,5 @@
 ---
 source: core/tests/acl/src/lib.rs
-assertion_line: 59
 expression: resolved
 ---
 Resolved {
@@ -30,7 +29,7 @@ Resolved {
                 },
             ],
             scope: Some(
-                792017965103506125,
+                9188997750422900590,
             ),
         },
         CommandKey {
@@ -58,7 +57,7 @@ Resolved {
                 },
             ],
             scope: Some(
-                5856262838373339618,
+                1349364295896631601,
             ),
         },
         CommandKey {
@@ -86,44 +85,46 @@ Resolved {
                 },
             ],
             scope: Some(
-                10252531491715478446,
+                8031926490300119127,
             ),
         },
     },
     denied_commands: {},
     command_scope: {
-        792017965103506125: ResolvedScope {
+        1349364295896631601: ResolvedScope {
             allow: [
                 Map(
                     {
                         "path": String(
-                            "$TEMP/*",
+                            "$HOME/.config/**",
                         ),
                     },
                 ),
-            ],
-            deny: [],
-        },
-        5856262838373339618: ResolvedScope {
-            allow: [
                 Map(
                     {
                         "path": String(
-                            "$HOME/.config/**",
+                            "$RESOURCE/**",
                         ),
                     },
                 ),
                 Map(
                     {
                         "path": String(
-                            "$RESOURCE/**",
+                            "$RESOURCE",
                         ),
                     },
                 ),
                 Map(
                     {
                         "path": String(
-                            "$RESOURCE",
+                            "$DOWNLOAD",
+                        ),
+                    },
+                ),
+                Map(
+                    {
+                        "path": String(
+                            "$DOWNLOAD/**",
                         ),
                     },
                 ),
@@ -138,7 +139,7 @@ Resolved {
                 ),
             ],
         },
-        10252531491715478446: ResolvedScope {
+        8031926490300119127: ResolvedScope {
             allow: [
                 Map(
                     {
@@ -172,6 +173,18 @@ Resolved {
                 ),
             ],
         },
+        9188997750422900590: ResolvedScope {
+            allow: [
+                Map(
+                    {
+                        "path": String(
+                            "$TEMP/*",
+                        ),
+                    },
+                ),
+            ],
+            deny: [],
+        },
     },
     global_scope: {
         "fs": ResolvedScope {
@@ -179,14 +192,14 @@ Resolved {
                 Map(
                     {
                         "path": String(
-                            "$APP",
+                            "$APP/**",
                         ),
                     },
                 ),
                 Map(
                     {
                         "path": String(
-                            "$APP/**",
+                            "$APP",
                         ),
                     },
                 ),

+ 34 - 2
core/tests/acl/fixtures/snapshots/acl_tests__tests__scope.snap

@@ -1,6 +1,5 @@
 ---
 source: core/tests/acl/src/lib.rs
-assertion_line: 59
 expression: resolved
 ---
 Resolved {
@@ -58,7 +57,7 @@ Resolved {
                 },
             ],
             scope: Some(
-                7912899488978770657,
+                5856262838373339618,
             ),
         },
         CommandKey {
@@ -92,6 +91,39 @@ Resolved {
     },
     denied_commands: {},
     command_scope: {
+        5856262838373339618: ResolvedScope {
+            allow: [
+                Map(
+                    {
+                        "path": String(
+                            "$RESOURCE/**",
+                        ),
+                    },
+                ),
+                Map(
+                    {
+                        "path": String(
+                            "$RESOURCE",
+                        ),
+                    },
+                ),
+                Map(
+                    {
+                        "path": String(
+                            "$DOWNLOAD",
+                        ),
+                    },
+                ),
+                Map(
+                    {
+                        "path": String(
+                            "$DOWNLOAD/**",
+                        ),
+                    },
+                ),
+            ],
+            deny: [],
+        },
         7912899488978770657: ResolvedScope {
             allow: [
                 Map(