mirror of
https://github.com/markqvist/Reticulum.git
synced 2026-06-08 14:11:53 -07:00
Preparation for create, fork and mirror functionality. Refactored and expanded permissions system. Added group .allowed files. Prepared dynamic permissions resolution. Basic functional scaffolding for create/fork/mirror.
This commit is contained in:
+213
-67
@@ -78,7 +78,11 @@ def program_setup(configdir, rnsconfigdir=None, verbosity=0, quietness=0, servic
|
||||
|
||||
else:
|
||||
command = task["command"]; operation = task["operation"]
|
||||
if command == "release":
|
||||
if command == "create":
|
||||
git_client = ReticulumGitClient(configdir=configdir, verbosity=targetverbosity, identitypath=identity)
|
||||
if operation == "create": git_client.create_repository(remote=task["remote"])
|
||||
|
||||
elif command == "release":
|
||||
git_client = ReticulumGitClient(configdir=configdir, verbosity=targetverbosity, identitypath=identity)
|
||||
if operation == "list": git_client.list_releases(remote=task["remote"])
|
||||
elif operation == "view": git_client.view_release(remote=task["remote"], target=task["target"])
|
||||
@@ -110,7 +114,7 @@ def program_setup(configdir, rnsconfigdir=None, verbosity=0, quietness=0, servic
|
||||
exit(0)
|
||||
|
||||
def main():
|
||||
subcommands = ["node", "release", "work"]
|
||||
subcommands = ["node", "release", "work", "create", "fork", "mirror"]
|
||||
try:
|
||||
if len(sys.argv) < 2 or sys.argv[1] not in subcommands: subcommand = "node"
|
||||
else: subcommand = sys.argv[1]; sys.argv.pop(1)
|
||||
@@ -124,6 +128,13 @@ def main():
|
||||
parser.add_argument('-s', '--service', action='store_true', default=False, help="rngit is running as a service and should log to file")
|
||||
parser.add_argument('-i', '--interactive', action='store_true', default=False, help="drop into interactive shell after initialisation")
|
||||
|
||||
elif subcommand == "create":
|
||||
parser = argparse.ArgumentParser(description="Reticulum Git Repository Creation")
|
||||
parser.add_argument("--config", action="store", default=None, help="path to alternative config directory", type=str)
|
||||
parser.add_argument("--rnsconfig", action="store", default=None, help="path to alternative Reticulum config directory", type=str)
|
||||
parser.add_argument("-i", "--identity", action="store", metavar="PATH", default=None, help="path to identity", type=str)
|
||||
parser.add_argument("repository", default=None, help="URL of repository to create", type=str)
|
||||
|
||||
elif subcommand == "release":
|
||||
parser = argparse.ArgumentParser(description="Reticulum Git Release Manager")
|
||||
parser.add_argument("--config", action="store", default=None, help="path to alternative config directory", type=str)
|
||||
@@ -144,6 +155,23 @@ def main():
|
||||
parser.add_argument("repository", nargs="?", default=None, help="URL of remote repository", type=str)
|
||||
parser.add_argument("operation", nargs="?", default=None, help="list, view, create, propose, edit, delete, update, complete, activate or perms", type=str)
|
||||
|
||||
elif subcommand == "fork":
|
||||
parser = argparse.ArgumentParser(description="Reticulum Git Repository Forker")
|
||||
parser.add_argument("--config", action="store", default=None, help="path to alternative config directory", type=str)
|
||||
parser.add_argument("--rnsconfig", action="store", default=None, help="path to alternative Reticulum config directory", type=str)
|
||||
parser.add_argument("-i", "--identity", action="store", metavar="PATH", default=None, help="path to identity", type=str)
|
||||
parser.add_argument("source", default=None, help="URL of source repository", type=str)
|
||||
parser.add_argument("target", default=None, help="URL of target repository", type=str)
|
||||
|
||||
elif subcommand == "mirror":
|
||||
parser = argparse.ArgumentParser(description="Reticulum Git Mirror Management")
|
||||
parser.add_argument("--config", action="store", default=None, help="path to alternative config directory", type=str)
|
||||
parser.add_argument("--rnsconfig", action="store", default=None, help="path to alternative Reticulum config directory", type=str)
|
||||
parser.add_argument("-i", "--identity", action="store", metavar="PATH", default=None, help="path to identity", type=str)
|
||||
parser.add_argument("--scope", action="store", default="active", help="document scope: active, completed or all", type=str)
|
||||
parser.add_argument("source", default=None, help="URL of source repository", type=str)
|
||||
parser.add_argument("target", default=None, help="URL of target repository", type=str)
|
||||
|
||||
parser.add_argument('-v', '--verbose', action='count', default=0)
|
||||
parser.add_argument('-q', '--quiet', action='count', default=0)
|
||||
parser.add_argument("--version", action="version", version="rngit {version}".format(version=__version__))
|
||||
@@ -157,20 +185,25 @@ def main():
|
||||
else: rnsconfigarg = None
|
||||
|
||||
if subcommand == "node":
|
||||
program_setup(configdir = configarg, rnsconfigdir=rnsconfigarg, service=args.service, verbosity=args.verbose,
|
||||
program_setup(configdir=configarg, rnsconfigdir=rnsconfigarg, service=args.service, verbosity=args.verbose,
|
||||
quietness=args.quiet, interactive=args.interactive, print_identity=args.print_identity)
|
||||
|
||||
elif subcommand == "create":
|
||||
task = {"command": subcommand, "operation": "create", "remote": args.repository}
|
||||
program_setup(configdir=configarg, rnsconfigdir=rnsconfigarg, verbosity=args.verbose, quietness=args.quiet,
|
||||
task=task, identity=args.identity)
|
||||
|
||||
elif subcommand == "release":
|
||||
if not args.operation: parser.print_help()
|
||||
task = {"command": subcommand, "operation": args.operation, "remote": args.repository, "target": args.target}
|
||||
program_setup(configdir = configarg, rnsconfigdir=rnsconfigarg, service=False, verbosity=args.verbose,
|
||||
program_setup(configdir=configarg, rnsconfigdir=rnsconfigarg, service=False, verbosity=args.verbose,
|
||||
quietness=args.quiet, interactive=False, print_identity=False, task=task, identity=args.identity)
|
||||
|
||||
elif subcommand == "work":
|
||||
if not args.operation: parser.print_help()
|
||||
task = {"command": subcommand, "operation": args.operation, "remote": args.repository,
|
||||
"scope": args.scope, "doc_id": args.id, "title": args.title}
|
||||
program_setup(configdir = configarg, rnsconfigdir=rnsconfigarg, service=False, verbosity=args.verbose,
|
||||
program_setup(configdir=configarg, rnsconfigdir=rnsconfigarg, service=False, verbosity=args.verbose,
|
||||
quietness=args.quiet, interactive=False, print_identity=False, task=task, identity=args.identity)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
@@ -344,6 +377,14 @@ class ReticulumGitClient():
|
||||
|
||||
return self.request_response, self.response_metadata
|
||||
|
||||
#########################
|
||||
# Repository Management #
|
||||
#########################
|
||||
|
||||
def create_repository(self, remote=None):
|
||||
# TODO: Implement
|
||||
pass
|
||||
|
||||
######################
|
||||
# Release Management #
|
||||
######################
|
||||
@@ -1289,6 +1330,7 @@ class ReticulumGitNode():
|
||||
PERM_I_SMPHR = ["i", "interact"]
|
||||
PERM_P_SMPHR = ["p", "propose"]
|
||||
PERM_ADM_SMPHR = ["adm", "admin"]
|
||||
ALL_PERMS = ["read", "write", "create", "stats", "release", "interact", "propose", "admin"]
|
||||
|
||||
TGT_NONE = 0x01
|
||||
TGT_ALL = 0x02
|
||||
@@ -1299,6 +1341,7 @@ class ReticulumGitNode():
|
||||
PATH_FETCH = "/git/fetch"
|
||||
PATH_PUSH = "/git/push"
|
||||
PATH_DELETE = "/git/delete"
|
||||
PATH_CREATE = "/git/create"
|
||||
PATH_RELEASE = "/mgmt/release"
|
||||
PATH_WORK = "/mgmt/work"
|
||||
|
||||
@@ -1468,37 +1511,7 @@ class ReticulumGitNode():
|
||||
RNS.log(f"Loading repositery group \"{group_name}\"", RNS.LOG_VERBOSE)
|
||||
group_path = os.path.expanduser(section[group_name])
|
||||
if not os.path.isdir(group_path): RNS.log(f"The path \"{group_path}\" specified for repository group \"{group_name}\" does not exist, skipping.", RNS.LOG_ERROR)
|
||||
else:
|
||||
self.load_repository_group(group_name, group_path)
|
||||
|
||||
if "access" in self.config:
|
||||
section = self.config["access"]
|
||||
for group_name in section:
|
||||
if group_name in self.groups:
|
||||
group_permissions = section.as_list(group_name)
|
||||
for entry in group_permissions:
|
||||
perm, target = self.parse_permission(entry)
|
||||
if not perm or not target: continue
|
||||
else:
|
||||
read = False; write = False; create = False; propose = 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_PROPOSE: propose = 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)
|
||||
if create and not target in self.groups[group_name]["create"]: self.groups[group_name]["create"].append(target)
|
||||
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 propose and not target in self.groups[group_name]["propose"]: self.groups[group_name]["propose"].append(target)
|
||||
if admin and not target in self.groups[group_name]["admin"]: self.groups[group_name]["admin"].append(target)
|
||||
else: self.load_repository_group(group_name, group_path)
|
||||
|
||||
def parse_permission(self, permission_string):
|
||||
comps = permission_string.split(":")
|
||||
@@ -1539,7 +1552,7 @@ class ReticulumGitNode():
|
||||
|
||||
def resolve_permission(self, remote_identity, group_name, repository_name, permission):
|
||||
remote_hash = remote_identity.hash
|
||||
RNS.log(f"Resolving {group_name}/{repository_name} permission {permission} for {RNS.prettyhexrep(remote_hash)}", RNS.LOG_DEBUG) # TODO: Remove
|
||||
RNS.log(f"Resolving {group_name}/{repository_name} permission {permission} for {RNS.prettyhexrep(remote_hash)}", RNS.LOG_DEBUG)
|
||||
if not group_name in self.groups: return False
|
||||
if not repository_name in self.groups[group_name]["repositories"]: return False
|
||||
else:
|
||||
@@ -1596,6 +1609,33 @@ class ReticulumGitNode():
|
||||
|
||||
return False
|
||||
|
||||
def resolve_group_permission(self, remote_identity, group_name, permission):
|
||||
remote_hash = remote_identity.hash
|
||||
RNS.log(f"Resolving {group_name} group permission {permission} for {RNS.prettyhexrep(remote_hash)}", RNS.LOG_DEBUG)
|
||||
if not group_name in self.groups: return False
|
||||
else:
|
||||
if permission == self.PERM_READ: group_permissions = self.groups[group_name]["read"]
|
||||
elif permission == self.PERM_WRITE: group_permissions = self.groups[group_name]["write"]
|
||||
elif permission == self.PERM_CREATE: group_permissions = self.groups[group_name]["create"]
|
||||
elif permission == self.PERM_STATS: group_permissions = self.groups[group_name]["stats"]
|
||||
elif permission == self.PERM_RELEASE: group_permissions = self.groups[group_name]["release"]
|
||||
elif permission == self.PERM_INTERACT: group_permissions = self.groups[group_name]["interact"]
|
||||
elif permission == self.PERM_PROPOSE: group_permissions = self.groups[group_name]["propose"]
|
||||
elif permission == self.PERM_ADMIN: group_permissions = self.groups[group_name]["admin"]
|
||||
else: return False
|
||||
|
||||
group_admins = self.groups[group_name]["admin"]
|
||||
|
||||
if 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
|
||||
|
||||
return False
|
||||
|
||||
def resolve_doc_permission(self, remote_identity, group_name, repository_name, doc_id, permission):
|
||||
remote_hash = remote_identity.hash
|
||||
RNS.log(f"Resolving {group_name}/{repository_name}/{doc_id} document permission {permission} for {RNS.prettyhexrep(remote_hash)}", RNS.LOG_DEBUG) # TODO: Remove
|
||||
@@ -1711,49 +1751,124 @@ class ReticulumGitNode():
|
||||
return permissions
|
||||
|
||||
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": [], "propose": [], "admin": [] }
|
||||
if not group_name in self.groups: self.groups[group_name] = { "path": group_path, "name": group_name, "repositories": {}, "dynamic_perms": False,
|
||||
"read": [], "write": [], "create": [], "stats": [], "release": [],
|
||||
"interact": [], "propose": [], "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)
|
||||
return
|
||||
|
||||
self.update_group_permissions(group_name)
|
||||
|
||||
loaded = 0
|
||||
group = self.groups[group_name]
|
||||
for entry in os.listdir(group_path):
|
||||
path = f"{group_path}/{entry}"
|
||||
if os.path.isdir(path) and not path.endswith(".work") and not path.endswith(".releases"):
|
||||
if not self.__is_git_repository(path): RNS.log(f"The directory \"{path}\" is not a git repository, skipping", RNS.LOG_WARNING)
|
||||
else:
|
||||
if not self.__is_bare_repository(path):
|
||||
RNS.log(f"The directory \"{path}\" is not a bare git repository, skipping", RNS.LOG_WARNING)
|
||||
RNS.log(f"You can change it to a bare repository using \"git config --bool core.bare true\".", RNS.LOG_WARNING)
|
||||
|
||||
else:
|
||||
repository_name = os.path.basename(path)
|
||||
allowed_path = f"{path}.allowed"
|
||||
allowed_input = ""
|
||||
if os.path.isfile(allowed_path):
|
||||
if os.access(allowed_path, os.X_OK):
|
||||
allowed_result = subprocess.run([allowed_path], stdout=subprocess.PIPE)
|
||||
allowed_input = allowed_result.stdout.decode("utf-8")
|
||||
|
||||
else:
|
||||
fh = open(allowed_path, "rb")
|
||||
allowed_input = fh.read().decode("utf-8")
|
||||
fh.close()
|
||||
|
||||
p = self.permissions_from_allowed_input(allowed_input)
|
||||
group["repositories"][repository_name] = {"name": repository_name, "group": group_name, "path": path,
|
||||
"read": p["read"], "write": p["write"], "create": p["create"],
|
||||
"stats": p["stats"], "release": p["release"], "interact": p["interact"],
|
||||
"propose": p["propose"], "admin": p["admin"] }
|
||||
loaded += 1
|
||||
if self.load_repository(group, path): loaded += 1
|
||||
|
||||
ms = "y" if loaded == 1 else "ies"
|
||||
RNS.log(f"Loaded {loaded} repositor{ms} for group \"{group_name}\"", RNS.LOG_VERBOSE)
|
||||
|
||||
def update_group_permissions(self, group_name):
|
||||
if not group_name in self.groups:
|
||||
RNS.log(f"Attempt to set group permissions for non-existing group {group_name}, aborting", RNS.LOG_WARNING)
|
||||
return
|
||||
|
||||
# Clear permissions before update
|
||||
for perm in self.ALL_PERMS: self.groups[group_name][perm] = []
|
||||
|
||||
# Apply permissions from allowed file if present
|
||||
group_path = self.groups[group_name]["path"]
|
||||
allowed_path = group_path+".allowed"
|
||||
if os.path.isfile(allowed_path):
|
||||
RNS.log(f"Applying group permissions for {group_name} from {allowed_path}", RNS.LOG_DEBUG)
|
||||
try:
|
||||
allowed_input = ""
|
||||
if os.access(allowed_path, os.X_OK):
|
||||
allowed_result = subprocess.run([allowed_path], stdout=subprocess.PIPE)
|
||||
allowed_input = allowed_result.stdout.decode("utf-8")
|
||||
self.groups[group_name]["dynamic_perms"] = True
|
||||
|
||||
else:
|
||||
fh = open(allowed_path, "rb")
|
||||
allowed_input = fh.read().decode("utf-8")
|
||||
fh.close()
|
||||
|
||||
group_permissions = self.permissions_from_allowed_input(allowed_input)
|
||||
for perm in group_permissions: self.groups[group_name][perm] = group_permissions[perm]
|
||||
|
||||
except Exception as e: RNS.log(f"Could not load group permissions from {allowed_path}: {e}", RNS.LOG_ERROR)
|
||||
|
||||
# Apply permissions from config file if present
|
||||
if "access" in self.config:
|
||||
section = self.config["access"]
|
||||
for config_group_name in section:
|
||||
if group_name == config_group_name:
|
||||
RNS.log(f"Applying group permissions for {group_name} from config file", RNS.LOG_DEBUG)
|
||||
config_group_permissions = section.as_list(group_name)
|
||||
|
||||
for entry in config_group_permissions:
|
||||
perm, target = self.parse_permission(entry)
|
||||
if not perm or not target: continue
|
||||
else:
|
||||
read = False; write = False; create = False; propose = 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_PROPOSE: propose = 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)
|
||||
if create and not target in self.groups[group_name]["create"]: self.groups[group_name]["create"].append(target)
|
||||
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 propose and not target in self.groups[group_name]["propose"]: self.groups[group_name]["propose"].append(target)
|
||||
if admin and not target in self.groups[group_name]["admin"]: self.groups[group_name]["admin"].append(target)
|
||||
|
||||
RNS.log(f"Final group permissions for {group_name}:\n{self.groups[group_name]}") # TODO: Remove
|
||||
|
||||
def load_repository(self, group, path):
|
||||
if not group or not path: return False
|
||||
group_name = group["name"]
|
||||
if not (os.path.isdir(path) and not path.endswith(".work") and not path.endswith(".releases")): return False
|
||||
else:
|
||||
if not self.__is_git_repository(path): RNS.log(f"The directory \"{path}\" is not a git repository, skipping", RNS.LOG_WARNING)
|
||||
else:
|
||||
if not self.__is_bare_repository(path):
|
||||
RNS.log(f"The directory \"{path}\" is not a bare git repository, skipping", RNS.LOG_WARNING)
|
||||
RNS.log(f"You can change it to a bare repository using \"git config --bool core.bare true\".", RNS.LOG_WARNING)
|
||||
|
||||
else:
|
||||
repository_name = os.path.basename(path)
|
||||
allowed_path = f"{path}.allowed"
|
||||
allowed_input = ""
|
||||
dynamic_perms = False
|
||||
if os.path.isfile(allowed_path):
|
||||
if os.access(allowed_path, os.X_OK):
|
||||
allowed_result = subprocess.run([allowed_path], stdout=subprocess.PIPE)
|
||||
allowed_input = allowed_result.stdout.decode("utf-8")
|
||||
dynamic_perms = True
|
||||
|
||||
else:
|
||||
fh = open(allowed_path, "rb")
|
||||
allowed_input = fh.read().decode("utf-8")
|
||||
fh.close()
|
||||
|
||||
p = self.permissions_from_allowed_input(allowed_input)
|
||||
group["repositories"][repository_name] = { "name": repository_name, "group": group_name, "path": path }
|
||||
for perm in self.ALL_PERMS: group["repositories"][repository_name][perm] = p[perm] if perm in p else []
|
||||
RNS.log(f"Final perms for {group_name}/{repository_name}:\n\n{group["repositories"][repository_name]}\n") # TODO: Remove
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def start(self):
|
||||
self._should_run = True
|
||||
threading.Thread(target=self.jobs, daemon=True).start()
|
||||
@@ -1833,6 +1948,7 @@ class ReticulumGitNode():
|
||||
self.destination.register_request_handler(self.PATH_LIST, self.handle_list, allow=self.global_allow, allowed_list=ga_list)
|
||||
self.destination.register_request_handler(self.PATH_FETCH, self.handle_fetch, allow=self.global_allow, allowed_list=ga_list)
|
||||
self.destination.register_request_handler(self.PATH_PUSH, self.handle_push, allow=self.global_allow, allowed_list=ga_list)
|
||||
self.destination.register_request_handler(self.PATH_CREATE, self.handle_create, allow=self.global_allow, allowed_list=ga_list)
|
||||
self.destination.register_request_handler(self.PATH_DELETE, self.handle_delete, allow=self.global_allow, allowed_list=ga_list)
|
||||
self.destination.register_request_handler(self.PATH_RELEASE, self.handle_release, allow=self.global_allow, allowed_list=ga_list)
|
||||
self.destination.register_request_handler(self.PATH_WORK, self.handle_work, allow=self.global_allow, allowed_list=ga_list)
|
||||
@@ -2114,6 +2230,36 @@ class ReticulumGitNode():
|
||||
RNS.log(f"Error while handling delete request for {group_name}/{repository_name}: {e}", RNS.LOG_ERROR)
|
||||
return self.RES_REMOTE_FAIL.to_bytes(1, "big") + b"Remote error"
|
||||
|
||||
def handle_create(self, path, data, request_id, remote_identity, requested_at):
|
||||
RNS.log(f"Create request from remote {remote_identity}", RNS.LOG_DEBUG)
|
||||
if not remote_identity: return self.RES_DISALLOWED.to_bytes(1, "big") + b"Not identified"
|
||||
if not type(data) == dict: return self.RES_INVALID_REQ.to_bytes(1, "big") + b"Invalid request"
|
||||
if not self.IDX_REPOSITORY in data: return self.RES_INVALID_REQ.to_bytes(1, "big") + b"No repository specified"
|
||||
|
||||
group_name, repository_name = self.parse_request_repository_path(data[self.IDX_REPOSITORY])
|
||||
if not group_name or not repository_name: return self.RES_INVALID_REQ.to_bytes(1, "big") + b"Invalid request"
|
||||
if not group_name in self.groups: return self.RES_NOT_FOUND.to_bytes(1, "big") + b"Not found"
|
||||
|
||||
read_access = self.resolve_group_permission(remote_identity, group_name, repository_name, self.PERM_READ)
|
||||
create_access = self.resolve_group_permission(remote_identity, group_name, repository_name, self.PERM_CREATE)
|
||||
|
||||
group_path_exists = os.path.exists(self.groups[group_name]["path"])
|
||||
if not group_path_exists: return self.RES_NOT_FOUND.to_bytes(1, "big") + b"Not found"
|
||||
|
||||
if not create_access: return self.RES_NOT_FOUND.to_bytes(1, "big") + b"Not found" if not read_access else self.RES_DISALLOWED.to_bytes(1, "big") + b"Not allowed"
|
||||
else:
|
||||
repository_exists = group_name in self.groups and repository_name in self.groups[group_name]
|
||||
path_exists = group_name in self.groups and os.path.exists()
|
||||
if repository_exists or path_exists:
|
||||
existing_read_access = self.resolve_permission(remote_identity, group_name, repository_name, self.PERM_READ)
|
||||
if existing_read_access: return self.RES_DISALLOWED.to_bytes(1, "big") + b"Repository already exists"
|
||||
else: return self.RES_NOT_FOUND.to_bytes(1, "big") + b"Not found"
|
||||
|
||||
else:
|
||||
# Permissions validated, and repository does not already exist
|
||||
# TODO: Implement new bare repository creation and loading into groups
|
||||
pass
|
||||
|
||||
def handle_release(self, path, data, request_id, remote_identity, requested_at):
|
||||
RNS.log(f"Release request from remote {remote_identity}", RNS.LOG_DEBUG)
|
||||
if not remote_identity: return self.RES_DISALLOWED.to_bytes(1, "big") + b"Not identified"
|
||||
|
||||
Reference in New Issue
Block a user