From 294a968c9f6169708d3ea7fdf861ef3a27e235a5 Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Sat, 25 Jun 2022 15:27:37 +0100 Subject: [PATCH] Fix crash when null is used for an array in .cdb.json Fixes #298 --- app/flatpages/help/package_config.md | 2 +- app/logic/package_validator.py | 39 ++++++++++++++++++++++++++++ app/logic/packages.py | 4 +-- 3 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 app/logic/package_validator.py diff --git a/app/flatpages/help/package_config.md b/app/flatpages/help/package_config.md index 114a384..3168aed 100644 --- a/app/flatpages/help/package_config.md +++ b/app/flatpages/help/package_config.md @@ -65,7 +65,7 @@ It should be a JSON dictionary with one or more of the following optional keys: * `forums`: forum topic ID. * `video_url`: URL to a video. -Use `null` to unset fields where relevant. +Use `null` or `[]` to unset fields where relevant. Example: diff --git a/app/logic/package_validator.py b/app/logic/package_validator.py new file mode 100644 index 0000000..b0738c5 --- /dev/null +++ b/app/logic/package_validator.py @@ -0,0 +1,39 @@ +from collections import namedtuple +from typing import List + +from flask_babel import lazy_gettext +from sqlalchemy import and_, or_ + +from app.models import Package, PackageType, PackageState, PackageRelease + +ValidationError = namedtuple("ValidationError", "status message") + + +def validate_package_for_approval(package: Package) -> List[ValidationError]: + retval: List[ValidationError] = [] + + normalised_name = package.getNormalisedName() + if package.type != PackageType.MOD and Package.query.filter( + and_(Package.state == PackageState.APPROVED, + or_(Package.name == normalised_name, + Package.name == normalised_name + "_game"))).count() > 0: + retval.append(("danger", lazy_gettext("A package already exists with this name. Please see Policy and Guidance 3"))) + + if package.releases.filter(PackageRelease.task_id.is_(None)).count() == 0: + retval.append(("danger", lazy_gettext("A release is required before this package can be approved."))) + # Don't bother validating any more until we have a release + return retval + + missing_deps = package.getMissingHardDependenciesQuery().all() + if len(missing_deps) > 0: + retval.append(("danger", lazy_gettext( + "The following hard dependencies need to be added to ContentDB first: %(deps)s", deps=missing_deps))) + + if (package.type == package.type.GAME or package.type == package.type.TXP) and \ + package.screenshots.count() == 0: + retval.append(("danger", lazy_gettext("You need to add at least one screenshot."))) + + if "Other" in package.license.name or "Other" in package.media_license.name: + retval.append(("info", lazy_gettext("Please wait for the license to be added to CDB."))) + + return retval diff --git a/app/logic/packages.py b/app/logic/packages.py index b50ce6f..d5e7675 100644 --- a/app/logic/packages.py +++ b/app/logic/packages.py @@ -150,7 +150,7 @@ def do_edit_package(user: User, package: Package, was_new: bool, was_web: bool, if "tags" in data: old_tags = list(package.tags) package.tags.clear() - for tag_id in data["tags"]: + for tag_id in (data["tags"] or []): if is_int(tag_id): tag = Tag.query.get(tag_id) else: @@ -173,7 +173,7 @@ def do_edit_package(user: User, package: Package, was_new: bool, was_web: bool, if "content_warnings" in data: package.content_warnings.clear() - for warning_id in data["content_warnings"]: + for warning_id in (data["content_warnings"] or []): if is_int(warning_id): package.content_warnings.append(ContentWarning.query.get(warning_id)) else: