diff options
-rw-r--r-- | app/blueprints/threads/__init__.py | 44 | ||||
-rw-r--r-- | app/flatpages/help/ranks_permissions.md | 15 | ||||
-rw-r--r-- | app/models.py | 7 | ||||
-rw-r--r-- | app/templates/macros/threads.html | 14 | ||||
-rw-r--r-- | app/templates/threads/edit_reply.html | 17 |
5 files changed, 95 insertions, 2 deletions
diff --git a/app/blueprints/threads/__init__.py b/app/blueprints/threads/__init__.py index 113cdfa..21666af 100644 --- a/app/blueprints/threads/__init__.py +++ b/app/blueprints/threads/__init__.py @@ -141,6 +141,50 @@ def delete_reply(id): return redirect(thread.getViewURL()) + + +class CommentForm(FlaskForm): + comment = TextAreaField("Comment", [InputRequired(), Length(10, 500)]) + submit = SubmitField("Comment") + + + +@bp.route("/threads/<int:id>/edit/", methods=["GET", "POST"]) +@login_required +def edit_reply(id): + thread = Thread.query.get(id) + if thread is None: + abort(404) + + reply_id = request.args.get("reply") + if reply_id is None: + abort(404) + + reply = ThreadReply.query.get(reply_id) + if reply is None or reply.thread != thread: + abort(404) + + if not reply.checkPerm(current_user, Permission.EDIT_REPLY): + abort(403) + + form = CommentForm(formdata=request.form, obj=reply) + if request.method == "POST" and form.validate(): + comment = form.comment.data + + msg = "Edited reply by {}".format(reply.author.display_name) + severity = AuditSeverity.NORMAL if current_user == reply.author else AuditSeverity.MODERATION + addNotification(reply.author, current_user, msg, thread.getViewURL(), thread.package) + addAuditLog(severity, current_user, msg, thread.getViewURL(), thread.package, reply.comment) + + reply.comment = comment + + db.session.commit() + + return redirect(thread.getViewURL()) + + return render_template("threads/edit_reply.html", thread=thread, reply=reply, form=form) + + @bp.route("/threads/<int:id>/", methods=["GET", "POST"]) def view(id): thread = Thread.query.get(id) diff --git a/app/flatpages/help/ranks_permissions.md b/app/flatpages/help/ranks_permissions.md index 5a2d592..972c570 100644 --- a/app/flatpages/help/ranks_permissions.md +++ b/app/flatpages/help/ranks_permissions.md @@ -205,6 +205,21 @@ title: Ranks and Permissions <th>✓</th> </tr> <tr> + <td>Edit Comments</td> + <th>✓</th> <!-- new --> + <th></th> + <th>✓</th> <!-- member --> + <th></th> + <th>✓</th> <!-- trusted member --> + <th></th> + <th>✓</th> <!-- editor --> + <th></th> + <th>✓</th> <!-- moderator --> + <th></th> + <th>✓</th> <!-- admin --> + <th>✓</th> + </tr> + <tr> <td>Set Email</td> <th>✓</th> <!-- new --> <th></th> diff --git a/app/models.py b/app/models.py index 62ac1ee..4ab4412 100644 --- a/app/models.py +++ b/app/models.py @@ -93,6 +93,7 @@ class Permission(enum.Enum): COMMENT_THREAD = "COMMENT_THREAD" LOCK_THREAD = "LOCK_THREAD" DELETE_REPLY = "DELETE_REPLY" + EDIT_REPLY = "EDIT_REPLY" UNAPPROVE_PACKAGE = "UNAPPROVE_PACKAGE" TOPIC_DISCARD = "TOPIC_DISCARD" CREATE_TOKEN = "CREATE_TOKEN" @@ -1146,7 +1147,11 @@ class ThreadReply(db.Model): elif type(perm) != Permission: raise Exception("Unknown permission given to ThreadReply.checkPerm()") - if perm == Permission.DELETE_REPLY: + if perm == Permission.EDIT_REPLY: + return (user == self.author and user.rank.atLeast(UserRank.MEMBER) and not self.thread.locked) or \ + user.rank.atLeast(UserRank.ADMIN) + + elif perm == Permission.DELETE_REPLY: return user.rank.atLeast(UserRank.MODERATOR) and self.thread.replies[0] != self else: diff --git a/app/templates/macros/threads.html b/app/templates/macros/threads.html index e94cded..21283d7 100644 --- a/app/templates/macros/threads.html +++ b/app/templates/macros/threads.html @@ -22,8 +22,20 @@ </div> <div class="card-body"> + {% if current_user == thread.author and thread.review and thread.replies[0] == r %} + <a class="float-right btn btn-primary btn-sm ml-2" + href="{{ thread.review.package.getReviewURL() }}"> + <i class="fas fa-edit"></i> + </a> + {% elif r.checkPerm(current_user, "EDIT_REPLY") %} + <a class="float-right btn btn-primary btn-sm ml-2" + href="{{ url_for('threads.edit_reply', id=thread.id, reply=r.id) }}"> + <i class="fas fa-edit"></i> + </a> + {% endif %} + {% if r.checkPerm(current_user, "DELETE_REPLY") %} - <a class="float-right btn btn-secondary btn-sm" + <a class="float-right btn btn-secondary btn-sm ml-2" href="{{ url_for('threads.delete_reply', id=thread.id, reply=r.id) }}"> <i class="fas fa-trash"></i> </a> diff --git a/app/templates/threads/edit_reply.html b/app/templates/threads/edit_reply.html new file mode 100644 index 0000000..9e92375 --- /dev/null +++ b/app/templates/threads/edit_reply.html @@ -0,0 +1,17 @@ +{% extends "base.html" %} + +{% block title %} + {{ _("Edit reply") }} - {{ thread.title }} +{% endblock %} + +{% block content %} + <h1>{{ _("Edit reply") }}</h1> + + {% from "macros/forms.html" import render_field, render_submit_field %} + <form method="POST" action="" enctype="multipart/form-data"> + {{ form.hidden_tag() }} + + {{ render_field(form.comment, label="", class_="m-0", fieldclass="form-control markdown") }} <br /> + {{ render_submit_field(form.submit) }} + </form> +{% endblock %} |