diff --git a/app/blueprints/packages/reviews.py b/app/blueprints/packages/reviews.py index 28a69cd..706f4ec 100644 --- a/app/blueprints/packages/reviews.py +++ b/app/blueprints/packages/reviews.py @@ -24,8 +24,9 @@ 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.utils import is_package_page, addNotification, get_int_or_abort, isYes, is_safe_url, rank_required +from app.models import db, PackageReview, Thread, ThreadReply, NotificationType, PackageReviewVote, Package, UserRank, \ + Permission, AuditSeverity +from app.utils import is_package_page, addNotification, get_int_or_abort, isYes, is_safe_url, rank_required, addAuditLog from app.tasks.webhooktasks import post_discord_webhook @@ -125,14 +126,19 @@ def review(package): form=form, package=package, review=review) -@bp.route("/packages///review/delete/", methods=["POST"]) +@bp.route("/packages///reviews//delete/", methods=["POST"]) @login_required @is_package_page -def delete_review(package): - review = PackageReview.query.filter_by(package=package, author=current_user).first() +def delete_review(package, reviewer): + review = PackageReview.query \ + .filter(PackageReview.package == package, PackageReview.author.has(username=reviewer)) \ + .first() if review is None or review.package != package: abort(404) + if not review.checkPerm(current_user, Permission.DELETE_REVIEW): + abort(403) + thread = review.thread reply = ThreadReply() @@ -143,6 +149,10 @@ def delete_review(package): thread.review = None + msg = "Converted review by {} to thread".format(review.author.display_name) + addAuditLog(AuditSeverity.MODERATION if current_user.username != reviewer else AuditSeverity.NORMAL, + current_user, msg, thread.getViewURL(), thread.package) + notif_msg = "Deleted review '{}', comments were kept as a thread".format(thread.title) addNotification(package.maintainers, current_user, NotificationType.OTHER, notif_msg, url_for("threads.view", id=thread.id), package) @@ -224,4 +234,4 @@ def review_votes(package): user_biases_info.sort(key=lambda x: -abs(x.balance)) return render_template("packages/review_votes.html", form=form, package=package, reviews=package.reviews, - user_biases=user_biases_info) \ No newline at end of file + user_biases=user_biases_info) diff --git a/app/models/threads.py b/app/models/threads.py index 02bcf50..6fdfa81 100644 --- a/app/models/threads.py +++ b/app/models/threads.py @@ -200,7 +200,8 @@ class PackageReview(db.Model): def getDeleteURL(self): return url_for("packages.delete_review", author=self.package.author.username, - name=self.package.name) + name=self.package.name, + reviewer=self.author.username) def getVoteUrl(self, next_url=None): return url_for("packages.review_vote", @@ -213,6 +214,20 @@ class PackageReview(db.Model): (pos, neg, _) = self.get_totals() self.score = 3 * (pos - neg) + 1 + def checkPerm(self, user, perm): + if not user.is_authenticated: + return False + + if type(perm) == str: + perm = Permission[perm] + elif type(perm) != Permission: + raise Exception("Unknown permission given to PackageReview.checkPerm()") + + if perm == Permission.DELETE_REVIEW: + return user == self.author or user.rank.atLeast(UserRank.MODERATOR) + else: + raise Exception("Permission {} is not related to reviews".format(perm.name)) + class PackageReviewVote(db.Model): review_id = db.Column(db.Integer, db.ForeignKey("package_review.id"), primary_key=True) diff --git a/app/models/users.py b/app/models/users.py index 1882825..f9aef0d 100644 --- a/app/models/users.py +++ b/app/models/users.py @@ -86,6 +86,7 @@ class Permission(enum.Enum): TOPIC_DISCARD = "TOPIC_DISCARD" CREATE_TOKEN = "CREATE_TOKEN" EDIT_MAINTAINERS = "EDIT_MAINTAINERS" + DELETE_REVIEW = "DELETE_REVIEW" CHANGE_PROFILE_URLS = "CHANGE_PROFILE_URLS" CHANGE_DISPLAY_NAME = "CHANGE_DISPLAY_NAME" diff --git a/app/templates/threads/view.html b/app/templates/threads/view.html index aebce7b..11eb900 100644 --- a/app/templates/threads/view.html +++ b/app/templates/threads/view.html @@ -36,10 +36,16 @@ {% endif %} - {% if thread and thread.checkPerm(current_user, "DELETE_THREAD") %} + {% if thread.checkPerm(current_user, "DELETE_THREAD") %} {{ _('Delete') }} {% endif %} - {% if thread and thread.checkPerm(current_user, "LOCK_THREAD") %} + {% if thread.review and thread.review.checkPerm(current_user, "DELETE_REVIEW") and current_user.username != thread.review.author.username %} +
+ + +
+ {% endif %} + {% if thread.checkPerm(current_user, "LOCK_THREAD") %} {% if thread.locked %}