From 823c06d3eaa7fe484f7120dc8f3388177acdddf8 Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Sat, 24 Jul 2021 00:43:55 +0100 Subject: [PATCH] Prevent API from changing protected tags Fixes #322 --- app/blueprints/api/support.py | 2 +- app/blueprints/packages/packages.py | 2 +- app/logic/packages.py | 21 +++++++++++++++------ app/tasks/importtasks.py | 2 +- 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/app/blueprints/api/support.py b/app/blueprints/api/support.py index 2683637..d060c02 100644 --- a/app/blueprints/api/support.py +++ b/app/blueprints/api/support.py @@ -100,7 +100,7 @@ def api_edit_package(token: APIToken, package: Package, data: dict, reason: str reason += ", token=" + token.name - package = guard(do_edit_package)(token.owner, package, False, data, reason) + package = guard(do_edit_package)(token.owner, package, False, False, data, reason) return jsonify({ "success": True, diff --git a/app/blueprints/packages/packages.py b/app/blueprints/packages/packages.py index 426496a..54a1300 100644 --- a/app/blueprints/packages/packages.py +++ b/app/blueprints/packages/packages.py @@ -302,7 +302,7 @@ def create_edit(author=None, name=None): wasNew = True try: - do_edit_package(current_user, package, wasNew, { + do_edit_package(current_user, package, wasNew, True, { "type": form.type.data, "title": form.title.data, "name": form.name.data, diff --git a/app/logic/packages.py b/app/logic/packages.py index a3a62c5..29f6f5b 100644 --- a/app/logic/packages.py +++ b/app/logic/packages.py @@ -40,17 +40,17 @@ def get_license(name): name_re = re.compile("^[a-z0-9_]+$") -any = "?" +AnyType = "?" ALLOWED_FIELDS = { - "type": any, + "type": AnyType, "title": str, "name": str, "short_description": str, "short_desc": str, "tags": list, "content_warnings": list, - "license": any, - "media_license": any, + "license": AnyType, + "media_license": AnyType, "long_description": str, "desc": str, "repo": str, @@ -80,7 +80,7 @@ def validate(data: dict): if value is not None: typ = ALLOWED_FIELDS.get(key) check(typ is not None, key + " is not a known field") - if typ != any: + if typ != AnyType: check(isinstance(value, typ), key + " must be a " + typ.__name__) if "name" in data: @@ -98,7 +98,8 @@ def validate(data: dict): check(validators.url(value, public=True), key + " must be a valid URL") -def do_edit_package(user: User, package: Package, was_new: bool, data: dict, reason: str = None): +def do_edit_package(user: User, package: Package, was_new: bool, was_web: bool, data: dict, + reason: str = None): if not package.checkPerm(user, Permission.EDIT_PACKAGE): raise LogicError(403, "You do not have permission to edit this package") @@ -144,11 +145,19 @@ def do_edit_package(user: User, package: Package, was_new: bool, data: dict, rea if tag is None: raise LogicError(400, "Unknown tag: " + tag_id) + if not was_web and tag.is_protected: + break + if tag.is_protected and tag not in old_tags and not user.rank.atLeast(UserRank.EDITOR): raise LogicError(400, f"Unable to add protected tag {tag.title} to package") package.tags.append(tag) + if not was_web: + for tag in old_tags: + if tag.is_protected: + package.tags.append(tag) + if "content_warnings" in data: package.content_warnings.clear() for warning_id in data["content_warnings"]: diff --git a/app/tasks/importtasks.py b/app/tasks/importtasks.py index f20c08c..0a76560 100644 --- a/app/tasks/importtasks.py +++ b/app/tasks/importtasks.py @@ -119,7 +119,7 @@ def postReleaseCheckUpdate(self, release: PackageRelease, path): try: with open(os.path.join(tree.baseDir, ".cdb.json"), "r") as f: data = json.loads(f.read()) - do_edit_package(package.author, package, False, data, "Post release hook") + do_edit_package(package.author, package, False, False, data, "Post release hook") except LogicError as e: raise TaskError(e.message) except IOError: