PCv5/app/models/forum.py

67 lines
2.3 KiB
Python
Raw Normal View History

2019-08-20 17:34:00 +02:00
from app import db
class Forum(db.Model):
__tablename__ = 'forum'
id = db.Column(db.Integer, primary_key=True)
# Forum name, as displayed on the site (eg. "Problèmes de transfert")
2019-08-20 17:34:00 +02:00
name = db.Column(db.Unicode(64))
# Privilege prefix (sort of slug) for single-forum privileges (lowercase)
prefix = db.Column(db.Unicode(64))
# Forum description, as displayed on the site
descr = db.Column(db.UnicodeText)
# Forum URL, for dynamic routes
url = db.Column(db.String(64))
2019-08-20 17:34:00 +02:00
# Relationships
parent_id = db.Column(db.Integer, db.ForeignKey('forum.id'), nullable=True)
parent = db.relationship('Forum', backref='sub_forums', remote_side=id,
lazy=True, foreign_keys=parent_id)
2019-11-21 15:31:46 +01:00
# Other fields populated automatically through relations:
2021-02-20 19:30:18 +01:00
# <sub_forums> Children forums
# <topics> List of topics in this exact forum (of type Topic)
2019-08-20 17:34:00 +02:00
# Some configuration
TOPICS_PER_PAGE = 30
def __init__(self, url, name, prefix, descr="", parent=None):
self.url = url
2019-08-20 17:34:00 +02:00
self.name = name
self.descr = descr
self.prefix = prefix
if isinstance(parent, str):
self.parent = Forum.query.filter_by(url=str).first()
else:
self.parent = parent
2019-08-20 17:34:00 +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
def is_news(self):
"""Whether this forum is a news board."""
return (self.parent is not None) and (self.parent.prefix == "news")
def is_default_accessible(self):
"""Whether this forum can be read without privileges."""
return (self.prefix != "admin") and (self.prefix != "creativecalc")
def is_default_postable(self):
"""Whether this forum can be posted to without privileges."""
return self.is_default_accessible() and (not self.is_news()) and \
(self.sub_forums == [])
def post_count(self):
"""Number of posts in every topic of the forum, without subforums."""
2020-09-24 00:22:20 +02:00
# TODO: optimize this with real ORM
return sum(t.thread.comments.count() for t in self.topics)
2019-11-21 15:31:46 +01:00
def delete(self):
"""Recursively delete forum and all associated contents."""
for t in self.topics:
t.delete()
db.session.commit()
db.session.delete(self)
2019-11-21 15:31:46 +01:00
def __repr__(self):
return f'<Forum: {self.name}>'