Newer
Older
__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
__license__ = "AGPL v3"
from django.contrib import messages
from django.contrib.auth.models import Group
from django.contrib.auth.mixins import UserPassesTestMixin
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import PermissionDenied
from django.http import Http404
from django.shortcuts import get_object_or_404, redirect
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from guardian.mixins import PermissionRequiredMixin
from guardian.shortcuts import (assign_perm, remove_perm,
get_objects_for_user, get_perms, get_users_with_perms, get_groups_with_perms)
from .forms import ForumForm, ForumGroupPermissionsForm, ForumOrganizationPermissionsForm, PostForm
from scipost.mixins import PermissionsMixin
class ForumCreateView(PermissionsMixin, CreateView):
permission_required = 'forums.add_forum'
model = Forum
form_class = ForumForm
template_name = 'forums/forum_form.html'
success_url = reverse_lazy('forums:forums')
def get_initial(self):
initial = super().get_initial()
parent_model = self.kwargs.get('parent_model')
parent_content_type = None
parent_object_id = self.kwargs.get('parent_id')
if parent_model == 'forum':
parent_content_type = ContentType.objects.get(app_label='forums', model='forum')
'moderators': self.request.user,
'parent_content_type': parent_content_type,
'parent_object_id': parent_object_id,
class ForumDeleteView(PermissionRequiredMixin, DeleteView):
permission_required = 'forums.delete_forum'
model = Forum
success_url = reverse_lazy('forums:forums')
def delete(self, request, *args, **kwargs):
"""
A Forum can only be deleted if it does not have any descendants.
Upon deletion, all object-level permissions associated to the
Forum are explicitly removed.
"""
forum = get_object_or_404(Forum, slug=self.kwargs.get('slug'))
groups_perms_dict = get_groups_with_perms(forum, attach_perms=True)
if forum.child_forums.all().count() > 0:
messages.warning(request, 'A Forum with descendants cannot be deleted.')
return redirect(forum.get_absolute_url())
for group, perms_list in groups_perms_dict.items():
for perm in perms_list:
remove_perm(perm, group, forum)
return super().delete(request, *args, **kwargs)
class ForumDetailView(PermissionRequiredMixin, DetailView):
permission_required = 'forums.can_view_forum'
model = Forum
template_name = 'forums/forum_detail.html'
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
context['groups_with_perms'] = get_groups_with_perms(self.object).order_by('name')
context['users_with_perms'] = get_users_with_perms(self.object)
context['group_permissions_form'] = ForumGroupPermissionsForm()
context['organization_permissions_form'] = ForumOrganizationPermissionsForm()
return context
class ForumPermissionsView(PermissionRequiredMixin, UpdateView):
permission_required = 'forums.can_change_forum'
model = Forum
form_class = ForumGroupPermissionsForm
template_name = 'forums/forum_permissions.html'
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
try:
context['group'] = Group.objects.get(pk=self.kwargs.get('group_id'))
except Group.DoesNotExist:
pass
return context
def get_initial(self, *args, **kwargs):
initial = super().get_initial(*args, **kwargs)
try:
group = Group.objects.get(pk=self.kwargs.get('group_id'))
perms = get_perms (group, self.object)
initial['group'] = group.id
initial['can_view'] = 'can_view_forum' in perms
initial['can_post'] = 'can_post_to_forum' in perms
except Group.DoesNotExist:
pass
return initial
def form_valid(self, form):
if form.cleaned_data['can_view']:
assign_perm('can_view_forum', form.cleaned_data['group'], self.object)
else:
remove_perm('can_view_forum', form.cleaned_data['group'], self.object)
if form.cleaned_data['can_post']:
assign_perm('can_post_to_forum', form.cleaned_data['group'], self.object)
else:
remove_perm('can_post_to_forum', form.cleaned_data['group'], self.object)
return super().form_valid(form)
class ForumListView(ListView):
model = Forum
template_name = 'forum_list.html'
queryset = get_objects_for_user(self.request.user, 'forums.can_view_forum').anchors()
class PostCreateView(UserPassesTestMixin, CreateView):
def test_func(self):
if self.request.user.has_perm('forums.add_forum'):
return True
forum = get_object_or_404(Forum, slug=self.kwargs.get('slug'))
if self.request.user.has_perm('can_post_to_forum', forum):
return True
else:
raise PermissionDenied
def get_initial(self, *args, **kwargs):
initial = super().get_initial(*args, **kwargs)
parent_model = self.kwargs.get('parent_model')
parent_object_id = self.kwargs.get('parent_id')
subject = ''
if parent_model == 'forum':
parent_content_type = ContentType.objects.get(app_label='forums', model='forum')
parent_content_type = ContentType.objects.get(app_label='forums', model='post')
parent = parent_content_type.get_object_for_this_type(pk=parent_object_id)
subject = 'Reply to %s' % parent.subject
else:
raise Http404
initial.update({
'posted_by': self.request.user,
'posted_on': timezone.now(),
'parent_content_type': parent_content_type,
'parent_object_id': parent_object_id,
return self.object.get_absolute_url()