|
@@ -0,0 +1,587 @@
|
|
|
+from django import forms
|
|
|
+from django.db import models
|
|
|
+from django.db.models import Q
|
|
|
+from django.utils.translation import ugettext_lazy as _
|
|
|
+from misago.acl.builder import BaseACL
|
|
|
+from misago.acl.exceptions import ACLError403, ACLError404
|
|
|
+from misago.forms import YesNoSwitch
|
|
|
+
|
|
|
+def make_forum_form(request, role, form):
|
|
|
+ form.base_fields['can_read_threads'] = forms.TypedChoiceField(choices=(
|
|
|
+ (0, _("No")),
|
|
|
+ (1, _("Yes, owned")),
|
|
|
+ (2, _("Yes, all")),
|
|
|
+ ), coerce=int)
|
|
|
+ form.base_fields['can_start_threads'] = forms.TypedChoiceField(choices=(
|
|
|
+ (0, _("No")),
|
|
|
+ (1, _("Yes, with moderation")),
|
|
|
+ (2, _("Yes")),
|
|
|
+ ), coerce=int)
|
|
|
+ form.base_fields['can_edit_own_threads'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
|
|
|
+ form.base_fields['can_soft_delete_own_threads'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
|
|
|
+ form.base_fields['can_write_posts'] = forms.TypedChoiceField(choices=(
|
|
|
+ (0, _("No")),
|
|
|
+ (1, _("Yes, with moderation")),
|
|
|
+ (2, _("Yes")),
|
|
|
+ ), coerce=int)
|
|
|
+ form.base_fields['can_edit_own_posts'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
|
|
|
+ form.base_fields['can_soft_delete_own_posts'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
|
|
|
+ form.base_fields['can_upvote_posts'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
|
|
|
+ form.base_fields['can_downvote_posts'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
|
|
|
+ form.base_fields['can_see_posts_scores'] = forms.TypedChoiceField(choices=(
|
|
|
+ (0, _("No")),
|
|
|
+ (1, _("Yes, final score")),
|
|
|
+ (2, _("Yes, both up and down-votes")),
|
|
|
+ ), coerce=int)
|
|
|
+ form.base_fields['can_see_votes'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
|
|
|
+ form.base_fields['can_make_polls'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
|
|
|
+ form.base_fields['can_vote_in_polls'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
|
|
|
+ form.base_fields['can_see_poll_votes'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
|
|
|
+ form.base_fields['can_see_attachments'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
|
|
|
+ form.base_fields['can_upload_attachments'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
|
|
|
+ form.base_fields['can_download_attachments'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
|
|
|
+ form.base_fields['attachment_size'] = forms.IntegerField(min_value=0, initial=100)
|
|
|
+ form.base_fields['attachment_limit'] = forms.IntegerField(min_value=0, initial=3)
|
|
|
+ form.base_fields['can_approve'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
|
|
|
+ form.base_fields['can_edit_labels'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
|
|
|
+ form.base_fields['can_see_changelog'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
|
|
|
+ form.base_fields['can_pin_threads'] = forms.TypedChoiceField(choices=(
|
|
|
+ (0, _("No")),
|
|
|
+ (1, _("Yes, to stickies")),
|
|
|
+ (2, _("Yes, to annoucements")),
|
|
|
+ ), coerce=int)
|
|
|
+ form.base_fields['can_edit_threads_posts'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
|
|
|
+ form.base_fields['can_move_threads_posts'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
|
|
|
+ form.base_fields['can_close_threads'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
|
|
|
+ form.base_fields['can_protect_posts'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
|
|
|
+ form.base_fields['can_delete_threads'] = forms.TypedChoiceField(choices=(
|
|
|
+ (0, _("No")),
|
|
|
+ (1, _("Yes, soft-delete")),
|
|
|
+ (2, _("Yes, hard-delete")),
|
|
|
+ ), coerce=int)
|
|
|
+ form.base_fields['can_delete_posts'] = forms.TypedChoiceField(choices=(
|
|
|
+ (0, _("No")),
|
|
|
+ (1, _("Yes, soft-delete")),
|
|
|
+ (2, _("Yes, hard-delete")),
|
|
|
+ ), coerce=int)
|
|
|
+ form.base_fields['can_delete_polls'] = forms.TypedChoiceField(choices=(
|
|
|
+ (0, _("No")),
|
|
|
+ (1, _("Yes, soft-delete")),
|
|
|
+ (2, _("Yes, hard-delete")),
|
|
|
+ ), coerce=int)
|
|
|
+ form.base_fields['can_delete_attachments'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
|
|
|
+
|
|
|
+ form.layout.append((
|
|
|
+ _("Threads"),
|
|
|
+ (
|
|
|
+ ('can_read_threads', {'label': _("Can read threads")}),
|
|
|
+ ('can_start_threads', {'label': _("Can start new threads")}),
|
|
|
+ ('can_edit_own_threads', {'label': _("Can edit own threads")}),
|
|
|
+ ('can_soft_delete_own_threads', {'label': _("Can soft-delete own threads")}),
|
|
|
+ ),
|
|
|
+ ),)
|
|
|
+ form.layout.append((
|
|
|
+ _("Posts"),
|
|
|
+ (
|
|
|
+ ('can_write_posts', {'label': _("Can write posts")}),
|
|
|
+ ('can_edit_own_posts', {'label': _("Can edit own posts")}),
|
|
|
+ ('can_soft_delete_own_posts', {'label': _("Can soft-delete own posts")}),
|
|
|
+ ),
|
|
|
+ ),)
|
|
|
+ form.layout.append((
|
|
|
+ _("Karma"),
|
|
|
+ (
|
|
|
+ ('can_upvote_posts', {'label': _("Can upvote posts")}),
|
|
|
+ ('can_downvote_posts', {'label': _("Can downvote posts")}),
|
|
|
+ ('can_see_posts_scores', {'label': _("Can see post score")}),
|
|
|
+ ('can_see_votes', {'label': _("Can see who voted on post")}),
|
|
|
+ ),
|
|
|
+ ),)
|
|
|
+ form.layout.append((
|
|
|
+ _("Polls"),
|
|
|
+ (
|
|
|
+ ('can_make_polls', {'label': _("Can make polls")}),
|
|
|
+ ('can_vote_in_polls', {'label': _("Can vote in polls")}),
|
|
|
+ ('can_see_poll_votes', {'label': _("Can see who voted in poll")}),
|
|
|
+ ),
|
|
|
+ ),)
|
|
|
+ form.layout.append((
|
|
|
+ _("Attachments"),
|
|
|
+ (
|
|
|
+ ('can_see_attachments', {'label': _("Can see attachments")}),
|
|
|
+ ('can_upload_attachments', {'label': _("Can upload attachments")}),
|
|
|
+ ('can_download_attachments', {'label': _("Can download attachments")}),
|
|
|
+ ('attachment_size', {'label': _("Max size of single attachment (in Kb)"), 'help_text': _("Enter zero for no limit.")}),
|
|
|
+ ('attachment_limit', {'label': _("Max number of attachments per post"), 'help_text': _("Enter zero for no limit.")}),
|
|
|
+ ),
|
|
|
+ ),)
|
|
|
+ form.layout.append((
|
|
|
+ _("Moderation"),
|
|
|
+ (
|
|
|
+ ('can_approve', {'label': _("Can accept threads and posts")}),
|
|
|
+ ('can_edit_labels', {'label': _("Can edit thread labels")}),
|
|
|
+ ('can_see_changelog', {'label': _("Can see edits history")}),
|
|
|
+ ('can_make_annoucements', {'label': _("Can make annoucements")}),
|
|
|
+ ('can_pin_threads', {'label': _("Can change threads weight")}),
|
|
|
+ ('can_edit_threads_posts', {'label': _("Can edit threads and posts")}),
|
|
|
+ ('can_move_threads_posts', {'label': _("Can move, merge and split threads and posts")}),
|
|
|
+ ('can_close_threads', {'label': _("Can close threads")}),
|
|
|
+ ('can_protect_posts', {'label': _("Can protect posts"), 'help_text': _("Protected posts cannot be changed by their owners.")}),
|
|
|
+ ('can_delete_threads', {'label': _("Can delete threads")}),
|
|
|
+ ('can_delete_posts', {'label': _("Can delete posts")}),
|
|
|
+ ('can_delete_polls', {'label': _("Can delete polls")}),
|
|
|
+ ('can_delete_attachments', {'label': _("Can delete attachments")}),
|
|
|
+ ),
|
|
|
+ ),)
|
|
|
+
|
|
|
+
|
|
|
+class ThreadsACL(BaseACL):
|
|
|
+ def get_role(self, forum):
|
|
|
+ try:
|
|
|
+ try:
|
|
|
+ return self.acl[forum.pk]
|
|
|
+ except AttributeError:
|
|
|
+ return self.acl[forum]
|
|
|
+ except KeyError:
|
|
|
+ return {}
|
|
|
+
|
|
|
+ def allow_thread_view(self, user, thread):
|
|
|
+ try:
|
|
|
+ forum_role = self.acl[thread.forum_id]
|
|
|
+ if forum_role['can_read_threads'] == 0:
|
|
|
+ raise ACLError403(_("You don't have permission to read threads in this forum."))
|
|
|
+ if forum_role['can_read_threads'] == 1 and thread.weight < 2 and thread.start_poster_id != user.id:
|
|
|
+ raise ACLError404()
|
|
|
+ if thread.moderated and not (forum_role['can_approve'] or (user.is_authenticated() and user == thread.start_poster)):
|
|
|
+ raise ACLError404()
|
|
|
+ if thread.deleted and not forum_role['can_delete_threads']:
|
|
|
+ raise ACLError404()
|
|
|
+ except KeyError:
|
|
|
+ raise ACLError403(_("You don't have permission to read threads in this forum."))
|
|
|
+
|
|
|
+ def allow_post_view(self, user, thread, post):
|
|
|
+ forum_role = self.acl[thread.forum_id]
|
|
|
+ if post.moderated and not (forum_role['can_approve'] or (user.is_authenticated() and user == post.user)):
|
|
|
+ raise ACLError404()
|
|
|
+ if post.deleted and not (forum_role['can_delete_posts'] or (user.is_authenticated() and user == post.user)):
|
|
|
+ raise ACLError404()
|
|
|
+
|
|
|
+ def get_readable_forums(self, acl):
|
|
|
+ readable = []
|
|
|
+ for forum in self.acl:
|
|
|
+ if acl.forums.can_browse(forum) and self.acl[forum]['can_read_threads']:
|
|
|
+ readable.append(forum)
|
|
|
+ return readable
|
|
|
+
|
|
|
+ def filter_threads(self, request, forum, queryset):
|
|
|
+ try:
|
|
|
+ forum_role = self.acl[forum.pk]
|
|
|
+ if not forum_role['can_approve']:
|
|
|
+ if request.user.is_authenticated():
|
|
|
+ queryset = queryset.filter(Q(moderated=0) | Q(start_poster=request.user))
|
|
|
+ else:
|
|
|
+ queryset = queryset.filter(moderated=0)
|
|
|
+ if forum_role['can_read_threads'] == 1:
|
|
|
+ queryset = queryset.filter(Q(weight=2) | Q(start_poster_id=request.user.id))
|
|
|
+ if not forum_role['can_delete_threads']:
|
|
|
+ queryset = queryset.filter(deleted=False)
|
|
|
+ except KeyError:
|
|
|
+ return False
|
|
|
+ return queryset
|
|
|
+
|
|
|
+ def filter_posts(self, request, thread, queryset):
|
|
|
+ try:
|
|
|
+ forum_role = self.acl[thread.forum.pk]
|
|
|
+ if not forum_role['can_approve']:
|
|
|
+ if request.user.is_authenticated():
|
|
|
+ queryset = queryset.filter(Q(moderated=0) | Q(user=request.user))
|
|
|
+ else:
|
|
|
+ queryset = queryset.filter(moderated=0)
|
|
|
+ except KeyError:
|
|
|
+ return False
|
|
|
+ return queryset
|
|
|
+
|
|
|
+ def can_start_threads(self, forum):
|
|
|
+ try:
|
|
|
+ forum_role = self.acl[forum.pk]
|
|
|
+ if forum_role['can_read_threads'] == 0 or forum_role['can_start_threads'] == 0:
|
|
|
+ return False
|
|
|
+ if forum.closed and forum_role['can_close_threads'] == 0:
|
|
|
+ return False
|
|
|
+ return True
|
|
|
+ except KeyError:
|
|
|
+ return False
|
|
|
+
|
|
|
+ def allow_new_threads(self, forum):
|
|
|
+ try:
|
|
|
+ forum_role = self.acl[forum.pk]
|
|
|
+ if forum_role['can_read_threads'] == 0 or forum_role['can_start_threads'] == 0:
|
|
|
+ raise ACLError403(_("You don't have permission to start new threads in this forum."))
|
|
|
+ if forum.closed and forum_role['can_close_threads'] == 0:
|
|
|
+ raise ACLError403(_("This forum is closed, you can't start new threads in it."))
|
|
|
+ except KeyError:
|
|
|
+ raise ACLError403(_("You don't have permission to start new threads in this forum."))
|
|
|
+
|
|
|
+ def can_edit_thread(self, user, forum, thread, post):
|
|
|
+ try:
|
|
|
+ forum_role = self.acl[thread.forum_id]
|
|
|
+ if forum_role['can_close_threads'] == 0 and (forum.closed or thread.closed):
|
|
|
+ return False
|
|
|
+ if forum_role['can_edit_threads_posts']:
|
|
|
+ return True
|
|
|
+ if forum_role['can_edit_own_threads'] and not post.protected and post.user_id == user.pk:
|
|
|
+ return True
|
|
|
+ return False
|
|
|
+ except KeyError:
|
|
|
+ return False
|
|
|
+
|
|
|
+ def allow_thread_edit(self, user, forum, thread, post):
|
|
|
+ try:
|
|
|
+ forum_role = self.acl[thread.forum_id]
|
|
|
+ if thread.deleted or post.deleted:
|
|
|
+ self.allow_deleted_post_view(forum)
|
|
|
+ if not forum_role['can_close_threads']:
|
|
|
+ if forum.closed:
|
|
|
+ raise ACLError403(_("You can't edit threads in closed forums."))
|
|
|
+ if thread.closed:
|
|
|
+ raise ACLError403(_("You can't edit closed threads."))
|
|
|
+ if not forum_role['can_edit_threads_posts']:
|
|
|
+ if post.user_id != user.pk:
|
|
|
+ raise ACLError403(_("You can't edit other members threads."))
|
|
|
+ if not forum_role['can_edit_own_threads']:
|
|
|
+ raise ACLError403(_("You can't edit your threads."))
|
|
|
+ if post.protected:
|
|
|
+ raise ACLError403(_("This thread is protected, you cannot edit it."))
|
|
|
+ except KeyError:
|
|
|
+ raise ACLError403(_("You don't have permission to edit threads in this forum."))
|
|
|
+
|
|
|
+ def can_reply(self, forum, thread):
|
|
|
+ try:
|
|
|
+ forum_role = self.acl[forum.pk]
|
|
|
+ if forum_role['can_write_posts'] == 0:
|
|
|
+ return False
|
|
|
+ if (forum.closed or thread.closed) and forum_role['can_close_threads'] == 0:
|
|
|
+ return False
|
|
|
+ return True
|
|
|
+ except KeyError:
|
|
|
+ return False
|
|
|
+
|
|
|
+ def allow_reply(self, forum, thread):
|
|
|
+ try:
|
|
|
+ forum_role = self.acl[thread.forum.pk]
|
|
|
+ if forum_role['can_write_posts'] == 0:
|
|
|
+ raise ACLError403(_("You don't have permission to write replies in this forum."))
|
|
|
+ if forum_role['can_close_threads'] == 0:
|
|
|
+ if forum.closed:
|
|
|
+ raise ACLError403(_("You can't write replies in closed forums."))
|
|
|
+ if thread.closed:
|
|
|
+ raise ACLError403(_("You can't write replies in closed threads."))
|
|
|
+ except KeyError:
|
|
|
+ raise ACLError403(_("You don't have permission to write replies in this forum."))
|
|
|
+
|
|
|
+ def can_edit_reply(self, user, forum, thread, post):
|
|
|
+ try:
|
|
|
+ forum_role = self.acl[thread.forum_id]
|
|
|
+ if forum_role['can_close_threads'] == 0 and (forum.closed or thread.closed):
|
|
|
+ return False
|
|
|
+ if forum_role['can_edit_threads_posts']:
|
|
|
+ return True
|
|
|
+ if forum_role['can_edit_own_posts'] and not post.protected and post.user_id == user.pk:
|
|
|
+ return True
|
|
|
+ return False
|
|
|
+ except KeyError:
|
|
|
+ return False
|
|
|
+
|
|
|
+ def allow_reply_edit(self, user, forum, thread, post):
|
|
|
+ try:
|
|
|
+ forum_role = self.acl[thread.forum_id]
|
|
|
+ if thread.deleted or post.deleted:
|
|
|
+ self.allow_deleted_post_view(forum)
|
|
|
+ if not forum_role['can_close_threads']:
|
|
|
+ if forum.closed:
|
|
|
+ raise ACLError403(_("You can't edit replies in closed forums."))
|
|
|
+ if thread.closed:
|
|
|
+ raise ACLError403(_("You can't edit replies in closed threads."))
|
|
|
+ if not forum_role['can_edit_threads_posts']:
|
|
|
+ if post.user_id != user.pk:
|
|
|
+ raise ACLError403(_("You can't edit other members replies."))
|
|
|
+ if not forum_role['can_edit_own_posts']:
|
|
|
+ raise ACLError403(_("You can't edit your replies."))
|
|
|
+ if post.protected:
|
|
|
+ raise ACLError403(_("This reply is protected, you cannot edit it."))
|
|
|
+ except KeyError:
|
|
|
+ raise ACLError403(_("You don't have permission to edit replies in this forum."))
|
|
|
+
|
|
|
+ def can_see_changelog(self, user, forum, post):
|
|
|
+ try:
|
|
|
+ forum_role = self.acl[forum.pk]
|
|
|
+ return forum_role['can_see_changelog'] or user.pk == post.user_id
|
|
|
+ except KeyError:
|
|
|
+ return False
|
|
|
+
|
|
|
+ def allow_changelog_view(self, user, forum, post):
|
|
|
+ try:
|
|
|
+ forum_role = self.acl[forum.pk]
|
|
|
+ if post.thread.deleted or post.deleted:
|
|
|
+ self.allow_deleted_post_view(forum)
|
|
|
+ if not (forum_role['can_see_changelog'] or user.pk == post.user_id):
|
|
|
+ raise ACLError403(_("You don't have permission to see history of changes made to this post."))
|
|
|
+ except KeyError:
|
|
|
+ raise ACLError403(_("You don't have permission to see history of changes made to this post."))
|
|
|
+
|
|
|
+ def can_make_revert(self, forum, thread):
|
|
|
+ try:
|
|
|
+ forum_role = self.acl[forum.pk]
|
|
|
+ if not forum_role['can_close_threads'] and (forum.closed or thread.closed):
|
|
|
+ return False
|
|
|
+ return forum_role['can_edit_threads_posts']
|
|
|
+ except KeyError:
|
|
|
+ return False
|
|
|
+
|
|
|
+ def allow_revert(self, forum, thread):
|
|
|
+ try:
|
|
|
+ forum_role = self.acl[forum.pk]
|
|
|
+ if not forum_role['can_close_threads']:
|
|
|
+ if forum.closed:
|
|
|
+ raise ACLError403(_("You can't make reverts in closed forums."))
|
|
|
+ if thread.closed:
|
|
|
+ raise ACLError403(_("You can't make reverts in closed threads."))
|
|
|
+ if not forum_role['can_edit_threads_posts']:
|
|
|
+ raise ACLError403(_("You don't have permission to make reverts in this forum."))
|
|
|
+ except KeyError:
|
|
|
+ raise ACLError403(_("You don't have permission to make reverts in this forum."))
|
|
|
+
|
|
|
+ def can_mod_threads(self, forum):
|
|
|
+ try:
|
|
|
+ forum_role = self.acl[forum.pk]
|
|
|
+ return (
|
|
|
+ forum_role['can_approve']
|
|
|
+ or forum_role['can_pin_threads']
|
|
|
+ or forum_role['can_move_threads_posts']
|
|
|
+ or forum_role['can_close_threads']
|
|
|
+ or forum_role['can_delete_threads']
|
|
|
+ )
|
|
|
+ except KeyError:
|
|
|
+ return False
|
|
|
+
|
|
|
+ def can_mod_posts(self, thread):
|
|
|
+ try:
|
|
|
+ forum_role = self.acl[thread.forum.pk]
|
|
|
+ return (
|
|
|
+ forum_role['can_edit_threads_posts']
|
|
|
+ or forum_role['can_move_threads_posts']
|
|
|
+ or forum_role['can_close_threads']
|
|
|
+ or forum_role['can_delete_threads']
|
|
|
+ or forum_role['can_delete_posts']
|
|
|
+ )
|
|
|
+ except KeyError:
|
|
|
+ return False
|
|
|
+
|
|
|
+ def can_approve(self, forum):
|
|
|
+ try:
|
|
|
+ forum_role = self.acl[forum.pk]
|
|
|
+ return forum_role['can_approve']
|
|
|
+ except KeyError:
|
|
|
+ return False
|
|
|
+
|
|
|
+ def can_protect(self, forum):
|
|
|
+ try:
|
|
|
+ forum_role = self.acl[forum.pk]
|
|
|
+ return forum_role['can_protect_posts']
|
|
|
+ except KeyError:
|
|
|
+ return False
|
|
|
+
|
|
|
+ def can_delete_thread(self, user, forum, thread, post):
|
|
|
+ try:
|
|
|
+ forum_role = self.acl[forum.pk]
|
|
|
+ if not forum_role['can_close_threads'] and (forum.closed or thread.closed):
|
|
|
+ return False
|
|
|
+ if post.protected and not forum_role['can_protect_posts']:
|
|
|
+ return False
|
|
|
+ if forum_role['can_delete_threads']:
|
|
|
+ return forum_role['can_delete_threads']
|
|
|
+ if thread.start_poster_id == user.pk and forum_role['can_soft_delete_own_threads']:
|
|
|
+ return 1
|
|
|
+ return False
|
|
|
+ except KeyError:
|
|
|
+ return False
|
|
|
+
|
|
|
+ def allow_delete_thread(self, user, forum, thread, post, delete=False):
|
|
|
+ try:
|
|
|
+ forum_role = self.acl[forum.pk]
|
|
|
+ if not forum_role['can_close_threads']:
|
|
|
+ if forum.closed:
|
|
|
+ raise ACLError403(_("You don't have permission to delete threads in closed forum."))
|
|
|
+ if thread.closed:
|
|
|
+ raise ACLError403(_("This thread is closed, you cannot delete it."))
|
|
|
+ if post.protected and not forum_role['can_protect_posts']:
|
|
|
+ raise ACLError403(_("This post is protected, you cannot delete it."))
|
|
|
+ if delete and forum_role['can_delete_threads'] < 2:
|
|
|
+ raise ACLError403(_("You cannot hard delete this thread."))
|
|
|
+ if not (forum_role['can_delete_threads'] or (thread.start_poster_id == user.pk and forum_role['can_soft_delete_own_threads'])):
|
|
|
+ raise ACLError403(_("You don't have permission to delete this thread."))
|
|
|
+ if thread.deleted and not delete:
|
|
|
+ raise ACLError403(_("This thread is already deleted."))
|
|
|
+ except KeyError:
|
|
|
+ raise ACLError403(_("You don't have permission to delete this thread."))
|
|
|
+
|
|
|
+ def can_delete_post(self, user, forum, thread, post):
|
|
|
+ try:
|
|
|
+ forum_role = self.acl[forum.pk]
|
|
|
+ if not forum_role['can_close_threads'] and (forum.closed or thread.closed):
|
|
|
+ return False
|
|
|
+ if post.protected and not forum_role['can_protect_posts']:
|
|
|
+ return False
|
|
|
+ if forum_role['can_delete_posts']:
|
|
|
+ return forum_role['can_delete_posts']
|
|
|
+ if post.user_id == user.pk and not post.protected and forum_role['can_soft_delete_own_posts']:
|
|
|
+ return 1
|
|
|
+ return False
|
|
|
+ except KeyError:
|
|
|
+ return False
|
|
|
+
|
|
|
+ def allow_delete_post(self, user, forum, thread, post, delete=False):
|
|
|
+ try:
|
|
|
+ forum_role = self.acl[forum.pk]
|
|
|
+ if not forum_role['can_close_threads']:
|
|
|
+ if forum.closed:
|
|
|
+ raise ACLError403(_("You don't have permission to delete posts in closed forum."))
|
|
|
+ if thread.closed:
|
|
|
+ raise ACLError403(_("This thread is closed, you cannot delete its posts."))
|
|
|
+ if post.protected and not forum_role['can_protect_posts']:
|
|
|
+ raise ACLError403(_("This post is protected, you cannot delete it."))
|
|
|
+ if delete and forum_role['can_delete_posts'] < 2:
|
|
|
+ raise ACLError403(_("You cannot hard delete this post."))
|
|
|
+ if not (forum_role['can_delete_posts'] or (post.user_id == user.pk and forum_role['can_soft_delete_own_posts'])):
|
|
|
+ raise ACLError403(_("You don't have permission to delete this post."))
|
|
|
+ if post.deleted and not delete:
|
|
|
+ raise ACLError403(_("This post is already deleted."))
|
|
|
+ except KeyError:
|
|
|
+ raise ACLError403(_("You don't have permission to delete this post."))
|
|
|
+
|
|
|
+ def can_see_deleted_threads(self, forum):
|
|
|
+ try:
|
|
|
+ forum_role = self.acl[forum.pk]
|
|
|
+ return forum_role['can_delete_threads']
|
|
|
+ except KeyError:
|
|
|
+ return False
|
|
|
+
|
|
|
+ def can_see_deleted_posts(self, forum):
|
|
|
+ try:
|
|
|
+ forum_role = self.acl[forum.pk]
|
|
|
+ return forum_role['can_delete_posts']
|
|
|
+ except KeyError:
|
|
|
+ return False
|
|
|
+
|
|
|
+ def allow_deleted_post_view(self, forum):
|
|
|
+ try:
|
|
|
+ forum_role = self.acl[forum.pk]
|
|
|
+ if not forum_role['can_delete_posts']:
|
|
|
+ raise ACLError404()
|
|
|
+ except KeyError:
|
|
|
+ raise ACLError404()
|
|
|
+
|
|
|
+ def can_upvote_posts(self, forum):
|
|
|
+ try:
|
|
|
+ forum_role = self.acl[forum.pk]
|
|
|
+ return forum_role['can_upvote_posts']
|
|
|
+ except KeyError:
|
|
|
+ return False
|
|
|
+
|
|
|
+ def can_downvote_posts(self, forum):
|
|
|
+ try:
|
|
|
+ forum_role = self.acl[forum.pk]
|
|
|
+ return forum_role['can_downvote_posts']
|
|
|
+ except KeyError:
|
|
|
+ return False
|
|
|
+
|
|
|
+ def can_see_post_score(self, forum):
|
|
|
+ try:
|
|
|
+ forum_role = self.acl[forum.pk]
|
|
|
+ return forum_role['can_see_posts_scores']
|
|
|
+ except KeyError:
|
|
|
+ return False
|
|
|
+
|
|
|
+ def can_see_post_votes(self, forum):
|
|
|
+ try:
|
|
|
+ forum_role = self.acl[forum.pk]
|
|
|
+ return forum_role['can_see_votes']
|
|
|
+ except KeyError:
|
|
|
+ return False
|
|
|
+
|
|
|
+ def allow_post_upvote(self, forum):
|
|
|
+ try:
|
|
|
+ forum_role = self.acl[forum.pk]
|
|
|
+ if not forum_role['can_upvote_posts']:
|
|
|
+ raise ACLError403(_("You cannot upvote posts in this forum."))
|
|
|
+ except KeyError:
|
|
|
+ raise ACLError403(_("You cannot upvote posts in this forum."))
|
|
|
+
|
|
|
+ def allow_post_downvote(self, forum):
|
|
|
+ try:
|
|
|
+ forum_role = self.acl[forum.pk]
|
|
|
+ if not forum_role['can_downvote_posts']:
|
|
|
+ raise ACLError403(_("You cannot downvote posts in this forum."))
|
|
|
+ except KeyError:
|
|
|
+ raise ACLError403(_("You cannot downvote posts in this forum."))
|
|
|
+
|
|
|
+ def allow_post_votes_view(self, forum):
|
|
|
+ try:
|
|
|
+ forum_role = self.acl[forum.pk]
|
|
|
+ if not forum_role['can_see_votes']:
|
|
|
+ raise ACLError403(_("You don't have permission to see who voted on this post."))
|
|
|
+ except KeyError:
|
|
|
+ raise ACLError403(_("You don't have permission to see who voted on this post."))
|
|
|
+
|
|
|
+
|
|
|
+def build_forums(acl, perms, forums, forum_roles):
|
|
|
+ acl.threads = ThreadsACL()
|
|
|
+ for forum in forums:
|
|
|
+ forum_role = {
|
|
|
+ 'can_read_threads': 0,
|
|
|
+ 'can_start_threads': 0,
|
|
|
+ 'can_edit_own_threads': False,
|
|
|
+ 'can_soft_delete_own_threads': False,
|
|
|
+ 'can_write_posts': 0,
|
|
|
+ 'can_edit_own_posts': False,
|
|
|
+ 'can_soft_delete_own_posts': False,
|
|
|
+ 'can_upvote_posts': False,
|
|
|
+ 'can_downvote_posts': False,
|
|
|
+ 'can_see_posts_scores': 0,
|
|
|
+ 'can_see_votes': False,
|
|
|
+ 'can_make_polls': False,
|
|
|
+ 'can_vote_in_polls': False,
|
|
|
+ 'can_see_poll_votes': False,
|
|
|
+ 'can_see_attachments': False,
|
|
|
+ 'can_upload_attachments': False,
|
|
|
+ 'can_download_attachments': False,
|
|
|
+ 'attachment_size': 100,
|
|
|
+ 'attachment_limit': 3,
|
|
|
+ 'can_approve': False,
|
|
|
+ 'can_edit_labels': False,
|
|
|
+ 'can_see_changelog': False,
|
|
|
+ 'can_make_annoucements': False,
|
|
|
+ 'can_pin_threads': 0,
|
|
|
+ 'can_edit_threads_posts': False,
|
|
|
+ 'can_move_threads_posts': False,
|
|
|
+ 'can_close_threads': False,
|
|
|
+ 'can_protect_posts': False,
|
|
|
+ 'can_delete_threads': 0,
|
|
|
+ 'can_delete_posts': 0,
|
|
|
+ 'can_delete_polls': 0,
|
|
|
+ 'can_delete_attachments': False,
|
|
|
+ }
|
|
|
+ for perm in perms:
|
|
|
+ try:
|
|
|
+ role = forum_roles[perm['forums'][forum.pk]]
|
|
|
+ for p in forum_role:
|
|
|
+ try:
|
|
|
+ if p in ['attachment_size', 'attachment_limit'] and role[p] == 0:
|
|
|
+ forum_role[p] = 0
|
|
|
+ elif role[p] > forum_role[p]:
|
|
|
+ forum_role[p] = role[p]
|
|
|
+ except KeyError:
|
|
|
+ pass
|
|
|
+ except KeyError:
|
|
|
+ pass
|
|
|
+ acl.threads.acl[forum.pk] = forum_role
|