diff --git a/app/blueprints/packages/packages.py b/app/blueprints/packages/packages.py index 0df1e6b..0bffdf9 100644 --- a/app/blueprints/packages/packages.py +++ b/app/blueprints/packages/packages.py @@ -115,6 +115,9 @@ def getReleases(package): @bp.route("/packages///") @is_package_page def view(package): + if not package.checkPerm(current_user, Permission.SEE_PACKAGE): + abort(404) + show_similar = not package.approved and ( current_user in package.maintainers or package.checkPerm(current_user, Permission.APPROVE_NEW)) @@ -205,6 +208,9 @@ def shield(package, type): @bp.route("/packages///download/") @is_package_page def download(package): + if not package.checkPerm(current_user, Permission.SEE_PACKAGE): + abort(404) + release = package.getDownloadRelease() if release is None: @@ -585,6 +591,9 @@ def alias_create_edit(package: Package, alias_id: int = None): @login_required @is_package_page def share(package): + if not package.checkPerm(current_user, Permission.SEE_PACKAGE): + abort(404) + return render_template("packages/share.html", package=package, tabs=get_package_tabs(current_user, package), current_tab="share") @@ -592,6 +601,9 @@ def share(package): @bp.route("/packages///similar/") @is_package_page def similar(package): + if not package.checkPerm(current_user, Permission.SEE_PACKAGE): + abort(404) + packages_modnames = {} for metapackage in package.provides: packages_modnames[metapackage] = Package.query.filter(Package.id != package.id, diff --git a/app/blueprints/packages/releases.py b/app/blueprints/packages/releases.py index 0fd53d8..303a1b8 100644 --- a/app/blueprints/packages/releases.py +++ b/app/blueprints/packages/releases.py @@ -33,6 +33,9 @@ from . import bp, get_package_tabs @bp.route("/packages///releases/", methods=["GET", "POST"]) @is_package_page def list_releases(package): + if not package.checkPerm(current_user, Permission.SEE_PACKAGE): + abort(404) + return render_template("packages/releases_list.html", package=package, tabs=get_package_tabs(current_user, package), current_tab="releases") @@ -107,6 +110,9 @@ def create_release(package): @bp.route("/packages///releases//download/") @is_package_page def download_release(package, id): + if not package.checkPerm(current_user, Permission.SEE_PACKAGE): + abort(404) + release = PackageRelease.query.get(id) if release is None or release.package != package: abort(404) diff --git a/app/blueprints/packages/reviews.py b/app/blueprints/packages/reviews.py index 28a69cd..bbc54a1 100644 --- a/app/blueprints/packages/reviews.py +++ b/app/blueprints/packages/reviews.py @@ -24,7 +24,8 @@ from flask_login import current_user, login_required from flask_wtf import FlaskForm from wtforms import * from wtforms.validators import * -from app.models import db, PackageReview, Thread, ThreadReply, NotificationType, PackageReviewVote, Package, UserRank +from app.models import db, PackageReview, Thread, ThreadReply, NotificationType, PackageReviewVote, Package, UserRank, \ + Permission from app.utils import is_package_page, addNotification, get_int_or_abort, isYes, is_safe_url, rank_required from app.tasks.webhooktasks import post_discord_webhook @@ -53,6 +54,9 @@ def review(package): flash(gettext("You can't review your own package!"), "danger") return redirect(package.getURL("packages.view")) + if not package.checkPerm(current_user, Permission.SEE_PACKAGE): + abort(404) + review = PackageReview.query.filter_by(package=package, author=current_user).first() form = ReviewForm(formdata=request.form, obj=review) diff --git a/app/models/packages.py b/app/models/packages.py index 5a4a66e..790f3eb 100644 --- a/app/models/packages.py +++ b/app/models/packages.py @@ -607,7 +607,10 @@ class Package(db.Model): isMaintainer = isOwner or user.rank.atLeast(UserRank.EDITOR) or user in self.maintainers isApprover = user.rank.atLeast(UserRank.APPROVER) - if perm == Permission.CREATE_THREAD: + if perm == Permission.SEE_PACKAGE: + return self.state == PackageState.APPROVED or isMaintainer or isApprover + + elif perm == Permission.CREATE_THREAD: return user.rank.atLeast(UserRank.MEMBER) # Members can edit their own packages, and editors can edit any packages diff --git a/app/models/users.py b/app/models/users.py index d50ac85..0fa917d 100644 --- a/app/models/users.py +++ b/app/models/users.py @@ -59,6 +59,7 @@ class UserRank(enum.Enum): class Permission(enum.Enum): + SEE_PACKAGE = "SEE_PACKAGE" EDIT_PACKAGE = "EDIT_PACKAGE" DELETE_PACKAGE = "DELETE_PACKAGE" CHANGE_AUTHOR = "CHANGE_AUTHOR" diff --git a/app/utils/models.py b/app/utils/models.py index 30dc03d..51cba93 100644 --- a/app/utils/models.py +++ b/app/utils/models.py @@ -18,7 +18,8 @@ from functools import wraps from flask import abort, redirect, url_for, request from flask_login import current_user -from app.models import User, NotificationType, Package, UserRank, Notification, db, AuditSeverity, AuditLogEntry, ThreadReply, Thread, PackageState, PackageType, PackageAlias +from app.models import User, NotificationType, Package, UserRank, Notification, db, AuditSeverity, AuditLogEntry, \ + ThreadReply, Thread, PackageState, PackageType, PackageAlias def getPackageByInfo(author, name): @@ -39,14 +40,15 @@ def is_package_page(f): if not ("author" in kwargs and "name" in kwargs): abort(400) - author = kwargs["author"] - name = kwargs["name"] + author = kwargs.pop("author") + name = kwargs.pop("name") package = getPackageByInfo(author, name) if package is None: package = getPackageByInfo(author, name + "_game") if package and package.type == PackageType.GAME: args = dict(kwargs) + args["author"] = author args["name"] = name + "_game" return redirect(url_for(request.endpoint, **args)) @@ -59,8 +61,6 @@ def is_package_page(f): abort(404) - del kwargs["author"] - del kwargs["name"] return f(package=package, *args, **kwargs) return decorated_function