|
@@ -27,8 +27,9 @@ class IsAuthed(Requirement):
|
|
|
|
|
|
|
|
|
class IsModeratorInForum(IsAuthed):
|
|
|
- def __init__(self, forum_id=None):
|
|
|
+ def __init__(self, forum=None, forum_id=None):
|
|
|
self.forum_id = forum_id
|
|
|
+ self.forum = forum
|
|
|
|
|
|
def fulfill(self, user, request):
|
|
|
moderators = self._get_forum_moderators(request)
|
|
@@ -42,7 +43,9 @@ class IsModeratorInForum(IsAuthed):
|
|
|
return self._get_forum(request).moderators
|
|
|
|
|
|
def _get_forum(self, request):
|
|
|
- if self.forum_id is not None:
|
|
|
+ if self.forum is not None:
|
|
|
+ return self.forum
|
|
|
+ elif self.forum_id is not None:
|
|
|
return self._get_forum_from_id()
|
|
|
return self._get_forum_from_request(request)
|
|
|
|
|
@@ -77,42 +80,91 @@ class IsSameUser(IsAuthed):
|
|
|
|
|
|
|
|
|
class TopicNotLocked(Requirement):
|
|
|
+ def __init__(self, topic=None, topic_id=None):
|
|
|
+ self._topic = topic
|
|
|
+ self._topic_id = topic_id
|
|
|
+
|
|
|
def fulfill(self, user, request):
|
|
|
return not self._is_topic_or_forum_locked(request)
|
|
|
|
|
|
+ def _is_topic_or_forum_locked(self, request):
|
|
|
+ topic = self._determine_topic(request)
|
|
|
+ return topic.locked or topic.forum.locked
|
|
|
+
|
|
|
+ def _determine_topic(self, request):
|
|
|
+ if self._topic is not None:
|
|
|
+ return self._topic
|
|
|
+ elif self._topic_id is not None:
|
|
|
+ return Topic.query.get(self._topic_id)
|
|
|
+ else:
|
|
|
+ return self._get_topic_from_request(request)
|
|
|
+
|
|
|
def _get_topic_from_request(self, request):
|
|
|
view_args = request.view_args
|
|
|
if 'post_id' in view_args:
|
|
|
- return Post.query.get(view_args['post_id']).topic
|
|
|
+ return (
|
|
|
+ Topic.query.join(Post, Post.topic_id == Topic.id)
|
|
|
+ .filter(Post.id == view_args['post_id'])
|
|
|
+ .with_entities(Topic.locked)
|
|
|
+ .first()
|
|
|
+ )
|
|
|
elif 'topic_id' in view_args:
|
|
|
return Topic.query.get(view_args['topic_id'])
|
|
|
else:
|
|
|
raise FlaskBBError
|
|
|
|
|
|
- def _is_topic_or_forum_locked(self, request):
|
|
|
- topic = self._get_topic_from_request(request)
|
|
|
- return topic.locked or topic.forum.locked
|
|
|
-
|
|
|
|
|
|
class ForumNotLocked(Requirement):
|
|
|
+ def __init__(self, forum=None, forum_id=None):
|
|
|
+ self._forum = forum
|
|
|
+ self._forum_id = forum_id
|
|
|
+
|
|
|
def fulfill(self, user, request):
|
|
|
return not self._is_forum_locked(request)
|
|
|
|
|
|
def _is_forum_locked(self, request):
|
|
|
- return self._get_forum_from_request(request).locked
|
|
|
+ forum = self._determine_forum(request)
|
|
|
+ return not forum.locked
|
|
|
+
|
|
|
+ def _determine_forum(self, request):
|
|
|
+ if self._forum is not None:
|
|
|
+ return self._forum
|
|
|
+ elif self._forum_id is not None:
|
|
|
+ return Forum.query.get(self._forum_id)
|
|
|
+ else:
|
|
|
+ return self._get_forum_from_request(request)
|
|
|
|
|
|
def _get_forum_from_request(self, request):
|
|
|
view_args = request.view_args
|
|
|
+
|
|
|
+ # These queries look big and nasty, but they really aren't that bad
|
|
|
+ # Basically, find the forum this post or topic belongs to
|
|
|
+ # with_entities returns a KeyedTuple with only the locked status
|
|
|
+
|
|
|
if 'post_id' in view_args:
|
|
|
- return Post.query.get(view_args['post_id']).topic.forum
|
|
|
+ return (
|
|
|
+ Forum.query.join(Topic, Topic.forum_id == Forum.id)
|
|
|
+ .join(Post, Post.topic_id == Topic.id)
|
|
|
+ .filter(Post.id == view_args['post_id'])
|
|
|
+ .with_entities(Forum.locked)
|
|
|
+ .first()
|
|
|
+ )
|
|
|
+
|
|
|
elif 'topic_id' in view_args:
|
|
|
- return Topic.query.get(view_args['topic_id']).forum
|
|
|
+ return (
|
|
|
+ Forum.query.join(Topic, Topic.forum_id == Forum.id)
|
|
|
+ .filter(Topic.id == view_args['topic_id'])
|
|
|
+ .with_entities(Forum.locked)
|
|
|
+ .first()
|
|
|
+ )
|
|
|
+
|
|
|
elif 'forum_id' in view_args:
|
|
|
return Forum.query.get(view_args['forum_id'])
|
|
|
|
|
|
|
|
|
-def IsAtleastModeratorInForum(forum_id=None):
|
|
|
- return Or(IsAtleastSuperModerator, IsModeratorInForum(forum_id))
|
|
|
+def IsAtleastModeratorInForum(forum_id=None, forum=None):
|
|
|
+ return Or(IsAtleastSuperModerator, IsModeratorInForum(forum_id=forum_id,
|
|
|
+ forum=forum))
|
|
|
|
|
|
IsMod = And(IsAuthed(), Has('mod'))
|
|
|
IsSuperMod = And(IsAuthed(), Has('super_mod'))
|
|
@@ -130,9 +182,7 @@ CanEditPost = Or(And(IsSameUser(), Has('editpost'), TopicNotLocked()),
|
|
|
IsAtleastSuperModerator,
|
|
|
And(IsModeratorInForum(), Has('editpost')))
|
|
|
|
|
|
-CanDeletePost = Or(And(IsSameUser(), Has('editpost'), TopicNotLocked()),
|
|
|
- IsAtleastSuperModerator,
|
|
|
- And(IsModeratorInForum(), Has('editpost')))
|
|
|
+CanDeletePost = CanEditPost
|
|
|
|
|
|
CanPostReply = Or(And(Has('postreply'), TopicNotLocked()),
|
|
|
IsModeratorInForum(),
|
|
@@ -145,3 +195,88 @@ CanPostTopic = Or(And(Has('posttopic'), ForumNotLocked()),
|
|
|
CanDeleteTopic = Or(And(IsSameUser(), Has('deletetopic'), TopicNotLocked()),
|
|
|
IsAtleastSuperModerator,
|
|
|
And(IsModeratorInForum(), Has('deletetopic')))
|
|
|
+
|
|
|
+
|
|
|
+# Template Allowances -- gross, I know
|
|
|
+
|
|
|
+def TplCanModerate(request):
|
|
|
+ def _(user, forum):
|
|
|
+ kwargs = {}
|
|
|
+
|
|
|
+ if isinstance(forum, int):
|
|
|
+ kwargs['forum_id'] = forum
|
|
|
+ elif isinstance(forum, Forum):
|
|
|
+ kwargs['forum'] = forum
|
|
|
+
|
|
|
+ return IsAtleastModeratorInForum(**kwargs)(user, request)
|
|
|
+ return _
|
|
|
+
|
|
|
+
|
|
|
+def TplCanPostReply(request):
|
|
|
+ def _(user, topic=None):
|
|
|
+ kwargs = {}
|
|
|
+
|
|
|
+ if isinstance(topic, int):
|
|
|
+ kwargs['topic_id'] = topic
|
|
|
+ elif isinstance(topic, Topic):
|
|
|
+ kwargs['topic'] = topic
|
|
|
+
|
|
|
+ return Or(
|
|
|
+ IsAtleastSuperModerator,
|
|
|
+ IsModeratorInForum(),
|
|
|
+ And(Has('postreply'), TopicNotLocked(**kwargs))
|
|
|
+ )(user, request)
|
|
|
+ return _
|
|
|
+
|
|
|
+
|
|
|
+def TplCanEditPost(request):
|
|
|
+ def _(user, topic=None):
|
|
|
+ kwargs = {}
|
|
|
+
|
|
|
+ if isinstance(topic, int):
|
|
|
+ kwargs['topic_id'] = topic
|
|
|
+ elif isinstance(topic, Topic):
|
|
|
+ kwargs['topic'] = topic
|
|
|
+
|
|
|
+ return Or(
|
|
|
+ IsAtleastSuperModerator,
|
|
|
+ And(IsModeratorInForum(), Has('editpost')),
|
|
|
+ And(IsSameUser(), Has('editpost'), TopicNotLocked(**kwargs)),
|
|
|
+ )(user, request)
|
|
|
+ return _
|
|
|
+
|
|
|
+TplCanDeletePost = TplCanEditPost
|
|
|
+
|
|
|
+
|
|
|
+def TplCanPostTopic(request):
|
|
|
+ def _(user, forum):
|
|
|
+ kwargs = {}
|
|
|
+
|
|
|
+ if isinstance(forum, int):
|
|
|
+ kwargs['forum_id'] = forum
|
|
|
+ elif isinstance(forum, Forum):
|
|
|
+ kwargs['forum'] = forum
|
|
|
+
|
|
|
+ return Or(
|
|
|
+ IsAtleastSuperModerator,
|
|
|
+ IsModeratorInForum(**kwargs),
|
|
|
+ And(Has('posttopic'), ForumNotLocked(**kwargs))
|
|
|
+ )(user, request)
|
|
|
+ return _
|
|
|
+
|
|
|
+
|
|
|
+def TplCanDeleteTopic(request):
|
|
|
+ def _(user, topic=None):
|
|
|
+ kwargs = {}
|
|
|
+
|
|
|
+ if isinstance(topic, int):
|
|
|
+ kwargs['topic_id'] = topic
|
|
|
+ elif isinstance(topic, Topic):
|
|
|
+ kwargs['topic'] = topic
|
|
|
+
|
|
|
+ return Or(
|
|
|
+ IsAtleastSuperModerator,
|
|
|
+ And(IsModeratorInForum(), Has('deletetopic')),
|
|
|
+ And(IsSameUser(), Has('deletetopic'), TopicNotLocked(**kwargs))
|
|
|
+ )(user, request)
|
|
|
+ return _
|