Prevent API from changing protected tags

Fixes #322
This commit is contained in:
rubenwardy 2021-07-24 00:43:55 +01:00
parent 3049d17f5e
commit 823c06d3ea
4 changed files with 18 additions and 9 deletions

@ -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,

@ -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,

@ -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"]:

@ -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: