From 3f5653f650189e0eabac367343b004a857969dc5 Mon Sep 17 00:00:00 2001 From: Mark Qvist Date: Tue, 5 May 2026 18:12:42 +0200 Subject: [PATCH] Added admin permission type in rngit --- RNS/Utilities/rngit/server.py | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/RNS/Utilities/rngit/server.py b/RNS/Utilities/rngit/server.py index 5f2d967f..c98523cc 100644 --- a/RNS/Utilities/rngit/server.py +++ b/RNS/Utilities/rngit/server.py @@ -227,6 +227,8 @@ class ReticulumGitClient(): self.configpath = self.configdir+"/client_config" self.identitypath = identitypath or self.configdir+"/client_identity" + if not os.path.isdir(self.configdir): os.makedirs(self.configdir) + if not os.path.isfile(self.identitypath): identity = RNS.Identity() identity.to_file(self.identitypath) @@ -1059,6 +1061,7 @@ class ReticulumGitNode(): PERM_STATS = 0x05 PERM_RELEASE = 0x06 PERM_INTERACT = 0x07 + PERM_ADMIN = 0xFE PERM_R_SMPHR = ["r", "read"] PERM_W_SMPHR = ["w", "write"] PERM_RW_SMPHR = ["rw", "readwrite"] @@ -1066,6 +1069,7 @@ class ReticulumGitNode(): PERM_S_SMPHR = ["s", "stats"] PERM_REL_SMPHR = ["rel", "release"] PERM_I_SMPHR = ["i", "interact"] + PERM_ADM_SMPHR = ["adm", "admin"] TGT_NONE = 0x01 TGT_ALL = 0x02 @@ -1255,14 +1259,15 @@ class ReticulumGitNode(): perm, target = self.parse_permission(entry) if not perm or not target: continue else: - read = False; write = False; create = False; - stats = False; release = False; interact = False + read = False; write = False; create = False + stats = False; release = False; interact = False; admin = False if perm == self.PERM_READ or perm == self.PERM_READWRITE: read = True if perm == self.PERM_WRITE or perm == self.PERM_READWRITE: write = True if perm == self.PERM_CREATE: create = True if perm == self.PERM_STATS: stats = True if perm == self.PERM_RELEASE: release = True if perm == self.PERM_INTERACT: interact = True + if perm == self.PERM_ADMIN: admin = True if read and not target in self.groups[group_name]["read"]: self.groups[group_name]["read"].append(target) if write and not target in self.groups[group_name]["write"]: self.groups[group_name]["write"].append(target) @@ -1270,6 +1275,7 @@ class ReticulumGitNode(): if stats and not target in self.groups[group_name]["stats"]: self.groups[group_name]["stats"].append(target) if release and not target in self.groups[group_name]["release"]: self.groups[group_name]["release"].append(target) if interact and not target in self.groups[group_name]["interact"]: self.groups[group_name]["interact"].append(target) + if admin and not target in self.groups[group_name]["admin"]: self.groups[group_name]["admin"].append(target) def parse_permission(self, permission_string): comps = permission_string.split(":") @@ -1283,6 +1289,7 @@ class ReticulumGitNode(): elif perm in self.PERM_S_SMPHR: perm = self.PERM_STATS elif perm in self.PERM_REL_SMPHR: perm = self.PERM_RELEASE elif perm in self.PERM_I_SMPHR: perm = self.PERM_INTERACT + elif perm in self.PERM_ADM_SMPHR: perm = self.PERM_ADMIN else: perm = None if target in self.TGT_NONE_SMPHR: target = self.TGT_NONE @@ -1336,16 +1343,25 @@ class ReticulumGitNode(): repository_permissions = self.groups[group_name]["repositories"][repository_name]["interact"] group_permissions = self.groups[group_name]["interact"] + elif permission == self.PERM_ADMIN: + repository_permissions = self.groups[group_name]["repositories"][repository_name]["admin"] + group_permissions = self.groups[group_name]["admin"] + else: return False + repository_admins = self.groups[group_name]["repositories"][repository_name]["admin"] + group_admins = self.groups[group_name]["admin"] + if self.TGT_NONE in repository_permissions: return False elif self.TGT_ALL in repository_permissions: return True elif remote_hash in repository_permissions: return True + elif remote_hash in repository_admins: return True else: if len(repository_permissions) > 0: return False elif self.TGT_NONE in group_permissions: return False elif self.TGT_ALL in group_permissions: return True elif remote_hash in group_permissions: return True + elif remote_hash in group_admins: return True else: return False return False @@ -1355,7 +1371,7 @@ class ReticulumGitNode(): def load_repository_group(self, group_name, group_path): # TODO: Implement group.allowed file if not group_name in self.groups: self.groups[group_name] = { "path": group_path, "repositories": {}, "read": [], "write": [], "create": [], - "stats": [], "release": [], "interact": [] } + "stats": [], "release": [], "interact": [], "admin": [] } if group_name in self.groups and self.groups[group_name]["path"] != group_path: RNS.log(f"Repository group path did not match existing entry while loading {group_name}, aborting load", RNS.LOG_ERROR) @@ -1381,6 +1397,7 @@ class ReticulumGitNode(): stats_allowed = [] release_allowed = [] interact_allowed = [] + admin_allowed = [] if os.path.isfile(allowed_path): if os.access(allowed_path, os.X_OK): @@ -1399,13 +1416,14 @@ class ReticulumGitNode(): if not perm or not target: continue else: read = False; write = False; create = False - stats = False; release = False; interact = False + stats = False; release = False; interact = False; admin = False if perm == self.PERM_READ or perm == self.PERM_READWRITE: read = True if perm == self.PERM_WRITE or perm == self.PERM_READWRITE: write = True if perm == self.PERM_CREATE: create = True if perm == self.PERM_STATS: stats = True if perm == self.PERM_RELEASE: release = True if perm == self.PERM_INTERACT: interact = True + if perm == self.PERM_ADMIN: admin = True if read and not target in read_allowed: read_allowed.append(target) if write and not target in write_allowed: write_allowed.append(target) @@ -1413,10 +1431,11 @@ class ReticulumGitNode(): if stats and not target in stats_allowed: stats_allowed.append(target) if release and not target in release_allowed: release_allowed.append(target) if interact and not target in interact_allowed: interact_allowed.append(target) + if admin and not target in admin_allowed: admin_allowed.append(target) group["repositories"][repository_name] = {"name": repository_name, "group": group_name, "path": path, - "read": read_allowed, "write": write_allowed, "create": create_allowed, - "stats": stats_allowed , "release": release_allowed, "interact": interact_allowed } + "read": read_allowed, "write": write_allowed, "create": create_allowed, "stats": stats_allowed , + "release": release_allowed, "interact": interact_allowed, "admin": admin_allowed } loaded += 1 ms = "y" if loaded == 1 else "ies"