diff --git a/forums/templates/forums/forum_confirm_delete.html b/forums/templates/forums/forum_confirm_delete.html new file mode 100644 index 0000000000000000000000000000000000000000..6727f68effa8c19f673a02381580b65c81bf2905 --- /dev/null +++ b/forums/templates/forums/forum_confirm_delete.html @@ -0,0 +1,24 @@ +{% extends 'forums/base.html' %} + +{% load bootstrap %} + +{% block pagetitle %}: Delete Forum{% endblock pagetitle %} + +{% block content %} +<div class="row"> + <div class="col-12"> + <h1 class="highlight">Delete Forum</h1> + {{ object }} + </div> +</div> +<div class="row"> + <div class="col-12"> + <form method="post"> + {% csrf_token %} + <h3 class="mb-2">Are you sure you want to delete this Forum (and all associated Posts)?</h3> + <input type="submit" class="btn btn-danger" value="Yes, delete it" /> + </form> + </div> +</div> + +{% endblock content %} diff --git a/forums/templates/forums/forum_detail.html b/forums/templates/forums/forum_detail.html index 83407ea4ec8bed21d0f33e9c48585d56274cfc1f..a3cd6c99f220e490631aeecfbdfcc0e26dcce853 100644 --- a/forums/templates/forums/forum_detail.html +++ b/forums/templates/forums/forum_detail.html @@ -19,9 +19,24 @@ <div class="col-12"> <h3 class="highlight">{{ forum.name }}</h3> + {% if forum.parent %} + <p>Parent: <a href="{{ forum.parent.get_absolute_url }}">{{ forum.parent }}</a></p> + {% endif %} + {% if forum.child_forums.all|length > 0 %} + <p>Descendants: {% for child in forum.child_forums.all %}<a href="{{ child.get_absolute_url }}">{{ child }}</a>{% if not forloop.last %}, {% endif %}{% endfor %}</p> + {% endif %} + {% if perms.forums.add_forum or "can_change_forum" in user_perms %} + <h4>Admin actions:</h4> <ul> <li><a href="{% url 'forums:forum_create' parent_model='forum' parent_id=forum.id %}">Create a (sub)Forum within this one</a></li> + <li> + {% if not forum.child_forums %} + <a href="{% url 'forums:forum_delete' slug=forum.slug %}" class="text-danger">Delete this Forum (and all Posts it contains)</a> + {% else %} + <span class="text-danger" style="text-decoration: line-through;">Delete this Forum</span> Please delete descendant Forums first. + {% endif %} + </li> </ul> <div class="card"> diff --git a/forums/urls.py b/forums/urls.py index a522c6a63aa07c505a43d63cfc7931b57df31911..62cbc9352dc12d11286ea72696aa7bc8469367ec 100644 --- a/forums/urls.py +++ b/forums/urls.py @@ -22,6 +22,11 @@ urlpatterns = [ views.ForumDetailView.as_view(), name='forum_detail' ), + url( + r'^(?P<slug>[\w-]+)/delete/$', + views.ForumDeleteView.as_view(), + name='forum_delete' + ), url( r'^(?P<slug>[\w-]+)/permissions/(?P<group_id>[0-9]+)/$', views.ForumPermissionsView.as_view(), diff --git a/forums/views.py b/forums/views.py index 7cadc261651c564abf92c488dea1dd1a6d51dae0..402656dd9f3e9ca6acf5d9c13fc2005005b9decf 100644 --- a/forums/views.py +++ b/forums/views.py @@ -2,16 +2,17 @@ __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.core.urlresolvers import reverse_lazy from django.http import Http404 -from django.shortcuts import get_object_or_404 +from django.shortcuts import get_object_or_404, redirect from django.utils import timezone from django.views.generic.detail import DetailView -from django.views.generic.edit import CreateView, UpdateView +from django.views.generic.edit import CreateView, UpdateView, DeleteView from django.views.generic.list import ListView from guardian.mixins import PermissionRequiredMixin @@ -46,6 +47,28 @@ class ForumCreateView(PermissionsMixin, CreateView): return initial +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 diff --git a/organizations/views.py b/organizations/views.py index df80d6f32dd7fee4722a2eae33c087c1283857c3..e93a4f1b7cf9efb5b44df8f0bf6451011dd297c1 100644 --- a/organizations/views.py +++ b/organizations/views.py @@ -8,7 +8,8 @@ from django.contrib.auth.mixins import UserPassesTestMixin from django.core.exceptions import PermissionDenied from django.core.urlresolvers import reverse_lazy from django.db import transaction -from django.shortcuts import get_object_or_404, render, reverse, redirect +from django.shortcuts import get_object_or_404, render, redirect +from django.urls import reverse from django.utils import timezone from django.views.generic.detail import DetailView from django.views.generic.edit import CreateView, UpdateView, DeleteView