PCv5/app/routes/posts/edit.py

135 lines
4.0 KiB
Python
Raw Normal View History

from app import app, db
from app.models.user import Member
from app.models.post import Post
from app.models.comment import Comment
from app.models.attachment import Attachment
from app.models.topic import Topic
from app.models.program import Program
from app.utils.render import render
2020-09-26 14:55:55 +02:00
from app.utils.check_csrf import check_csrf
from app.forms.forum import CommentEditForm, AnonymousCommentEditForm, TopicEditForm
from wtforms import BooleanField
from urllib.parse import urlparse
from flask import redirect, url_for, abort, request
from flask_login import login_required, current_user
@app.route('/post/<int:postid>', methods=['GET','POST'])
@login_required
def edit_post(postid):
# TODO: Maybe not safe
referrer = urlparse(request.args.get('r', default = '/', type = str)).path
print(referrer)
p = Post.query.filter_by(id=postid).first_or_404()
review of privileges and forum permissions * Sorted privileges into categories, similar to the v4.3 style Added privilege check utilities: * Forum: is_news(), is_default_accessible() and is_default_postable() * Member: can_access_forum(), can_post_in_forum(), can_edit_post(), and can_delete_post() Unfortunately current_user is not a Guest when logged out, so one cannot usually write current_user.can_*() without checking for authentication first, so the checks are still somewhat verbose. Reviewed forum permissions; the following permission issues have been fixed (I have tested most but not all of them prior to fixing): * app/routes/forum/index.py: Users that were not meant to access a forum could still obtain a listing of the topics * app/routes/forum/topic.py: Users that were not meant to see topics could still read them by browsing the URL * app/routes/forum/topic.py: Authenticated users could post in any topic, including ones that they should not have access to * app/routes/posts/edit.py: Users with edit.posts (eg. mods) could edit and delete messages in forums they can't access (eg. creativecalc) * app/templates/account/user.html: Users with admin panel access would see account editing links they can't use (affects developers) * app/templates/base/navbar/forum.html: The "Forum" tab would list all forums including ones the user doesn't have access to * app/templates/forum/index.html: Users would see every single forum, including ones they can't access * app/template/widgets/thread.html: Anyone would see Edit/Delete links on every message, even though most were unusable Miscellaneous changes: * app/routes/forum/topic.py: Ordered comments by date as intended, which I assume worked by chance until now * Removed the old assets/privs.txt files which is now superseded by the list implemented in app/data/groups.yaml This commit changes group and forum information, run master.py with: @> forums update @> groups update
2021-02-26 18:29:25 +01:00
# Check permissions. TODO: Allow guests to edit their posts
if current_user.is_anonymous or not current_user.can_edit_post(p):
abort(403)
if isinstance(p, Comment):
base = CommentEditForm
comment = p
elif isinstance(p, Topic):
base = TopicEditForm
comment = p.thread.top_comment
else:
abort(404)
class TheForm(base):
pass
for a in comment.attachments:
setattr(TheForm, f'a{a.id}', BooleanField(f'a{a.id}'))
setattr(TheForm, 'attachment_list',
{ f'a{a.id}': a for a in comment.attachments })
form = TheForm()
if form.validate_on_submit():
comment.text = form.message.data
# Remove attachments
for id, a in form.attachment_list.items():
if form[id].data:
a.delete()
# Add new attachments
attachments = []
for file in form.attachments.data:
if file.filename != "":
a = Attachment(file, comment)
attachments.append((a, file))
db.session.add(a)
db.session.add(comment)
if isinstance(p, Topic):
p.title = form.title.data
db.session.add(p)
db.session.commit()
for a, file in attachments:
a.set_file(file)
return redirect(referrer)
# Non-submitted form
if isinstance(p, Comment):
form.message.data = p.text
return render('forum/edit_comment.html', comment=p, form=form)
elif isinstance(p, Topic):
form.message.data = p.thread.top_comment.text
form.title.data = p.title
return render('forum/edit_topic.html', t=p, form=form)
2020-09-26 14:55:55 +02:00
@app.route('/post/supprimer/<int:postid>', methods=['GET','POST'])
@login_required
@check_csrf
def delete_post(postid):
next_page = request.referrer
2020-09-26 14:55:55 +02:00
p = Post.query.filter_by(id=postid).first_or_404()
xp = -1
2020-09-26 14:55:55 +02:00
review of privileges and forum permissions * Sorted privileges into categories, similar to the v4.3 style Added privilege check utilities: * Forum: is_news(), is_default_accessible() and is_default_postable() * Member: can_access_forum(), can_post_in_forum(), can_edit_post(), and can_delete_post() Unfortunately current_user is not a Guest when logged out, so one cannot usually write current_user.can_*() without checking for authentication first, so the checks are still somewhat verbose. Reviewed forum permissions; the following permission issues have been fixed (I have tested most but not all of them prior to fixing): * app/routes/forum/index.py: Users that were not meant to access a forum could still obtain a listing of the topics * app/routes/forum/topic.py: Users that were not meant to see topics could still read them by browsing the URL * app/routes/forum/topic.py: Authenticated users could post in any topic, including ones that they should not have access to * app/routes/posts/edit.py: Users with edit.posts (eg. mods) could edit and delete messages in forums they can't access (eg. creativecalc) * app/templates/account/user.html: Users with admin panel access would see account editing links they can't use (affects developers) * app/templates/base/navbar/forum.html: The "Forum" tab would list all forums including ones the user doesn't have access to * app/templates/forum/index.html: Users would see every single forum, including ones they can't access * app/template/widgets/thread.html: Anyone would see Edit/Delete links on every message, even though most were unusable Miscellaneous changes: * app/routes/forum/topic.py: Ordered comments by date as intended, which I assume worked by chance until now * Removed the old assets/privs.txt files which is now superseded by the list implemented in app/data/groups.yaml This commit changes group and forum information, run master.py with: @> forums update @> groups update
2021-02-26 18:29:25 +01:00
if current_user.is_anonymous or not current_user.can_delete_post(p):
2020-09-26 14:55:55 +02:00
abort(403)
# Users who need to have their trophies updated
authors = set()
# When deleting topics, return to forum page
if isinstance(p, Topic):
next_page = url_for('forum_page', f=p.forum)
xp = -2
for comment in p.thread.comments:
if isinstance(comment.author, Member):
comment.author.add_xp(-1)
db.session.merge(comment.author)
authors.add(comment.author)
if isinstance(p.author, Member):
factor = 3 if request.args.get('penalty') == 'True' else 1
p.author.add_xp(xp * factor)
db.session.merge(p.author)
authors.add(p.author)
p.delete()
2020-09-26 14:55:55 +02:00
db.session.commit()
for author in authors:
author.update_trophies("new-post")
return redirect(next_page)
@app.route('/post/entete/<int:postid>', methods=['GET'])
@login_required
@check_csrf
def set_post_topcomment(postid):
comment = Post.query.filter_by(id=postid).first_or_404()
if current_user.can_set_topcomment(comment):
comment.thread.top_comment = comment
db.session.add(comment.thread)
db.session.commit()
return redirect(request.referrer)