From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 1509190D57 for ; Mon, 19 Dec 2022 15:13:34 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id EFF56288B2 for ; Mon, 19 Dec 2022 15:13:33 +0100 (CET) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS for ; Mon, 19 Dec 2022 15:13:32 +0100 (CET) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 6310344CB4 for ; Mon, 19 Dec 2022 15:13:32 +0100 (CET) From: Hannes Laimer To: pbs-devel@lists.proxmox.com Date: Mon, 19 Dec 2022 15:13:24 +0100 Message-Id: <20221219141326.201199-3-h.laimer@proxmox.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20221219141326.201199-1-h.laimer@proxmox.com> References: <20221219141326.201199-1-h.laimer@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.035 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [pbs-devel] [PATCH proxmox-backup 2/4] pbs-config: add delete_node for ACL-tree X-BeenThere: pbs-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Backup Server development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 19 Dec 2022 14:13:34 -0000 ... needed for the deletion of datastore ACL-nodes when the datastore is removed. Signed-off-by: Hannes Laimer --- pbs-config/src/acl.rs | 61 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/pbs-config/src/acl.rs b/pbs-config/src/acl.rs index 928a4121..9defc3c6 100644 --- a/pbs-config/src/acl.rs +++ b/pbs-config/src/acl.rs @@ -396,6 +396,21 @@ impl AclTree { node.delete_user_role(auth_id, role); } + /// Deletes the [AclTreeNode] at the specified patth + /// + /// Never fails, deletes a node iff the specified path exists. + pub fn delete_node(&mut self, path: &str) { + let mut path = split_acl_path(path); + let last = path.pop(); + let parent = match self.get_node_mut(&path) { + Some(n) => n, + None => return, + }; + if let Some(name) = last { + parent.children.remove(name); + } + } + /// Inserts the specified `role` into the `group` ACL on `path`. /// /// The [AclTreeNode] representing `path` will be created and inserted into the tree if @@ -947,4 +962,50 @@ acl:1:/storage/store1:user1@pbs:DatastoreBackup Ok(()) } + + #[test] + fn test_delete_node() -> Result<(), Error> { + let mut tree = AclTree::new(); + + let user1: Authid = "user1@pbs".parse()?; + + tree.insert_user_role("/storage", &user1, "NoAccess", true); + tree.insert_user_role("/storage/a", &user1, "NoAccess", true); + tree.insert_user_role("/storage/b", &user1, "NoAccess", true); + tree.insert_user_role("/storage/b/a", &user1, "NoAccess", true); + tree.insert_user_role("/storage/b/b", &user1, "NoAccess", true); + tree.insert_user_role("/datastore/c", &user1, "NoAccess", true); + tree.insert_user_role("/datastore/d", &user1, "NoAccess", true); + + assert!(tree.find_node("/storage/b/a").is_some()); + tree.delete_node("/storage/b/a"); + assert!(tree.find_node("/storage/b/a").is_none()); + + assert!(tree.find_node("/storage/b/b").is_some()); + assert!(tree.find_node("/storage/b").is_some()); + tree.delete_node("/storage/b"); + assert!(tree.find_node("/storage/b/b").is_none()); + assert!(tree.find_node("/storage/b").is_none()); + + assert!(tree.find_node("/storage").is_some()); + assert!(tree.find_node("/storage/a").is_some()); + tree.delete_node("/storage"); + assert!(tree.find_node("/storage").is_none()); + assert!(tree.find_node("/storage/a").is_none()); + + assert!(tree.find_node("/datastore/c").is_some()); + tree.delete_node("/datastore/c"); + assert!(tree.find_node("/datastore/c").is_none()); + + assert!(tree.find_node("/datastore/d").is_some()); + tree.delete_node("/datastore/d"); + assert!(tree.find_node("/datastore/d").is_none()); + + // '/' should not be deletable + assert!(tree.find_node("/").is_some()); + tree.delete_node("/"); + assert!(tree.find_node("/").is_some()); + + Ok(()) + } } -- 2.30.2