236 lines
7.4 KiB
Python
236 lines
7.4 KiB
Python
from django.contrib.auth import get_user_model
|
|
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
|
|
from django.http import HttpResponse, HttpResponseRedirect
|
|
from django.urls import reverse, reverse_lazy
|
|
from django.views.generic import DetailView, ListView, RedirectView, TemplateView
|
|
from django.views.generic.detail import SingleObjectMixin
|
|
from django.views.generic.edit import BaseFormView
|
|
|
|
from wiki_groups.forms import CreateGroupForm, SelectGroupForm, SelectUserForm
|
|
from wiki_groups.models import WikiGroup
|
|
|
|
User = get_user_model()
|
|
|
|
|
|
def dot_graph(request):
|
|
response = HttpResponse(content_type="text/vnd.graphviz")
|
|
response["Content-Disposition"] = 'attachment; filename="groups.dot"'
|
|
|
|
response.write("digraph {\n")
|
|
nodes = WikiGroup.objects.values_list("id", "django_group__name")
|
|
edges = WikiGroup.includes_groups.through.objects.values_list(
|
|
"to_wikigroup", "from_wikigroup"
|
|
)
|
|
for id, name in nodes:
|
|
response.write(' {} ["label"="{}"];\n'.format(id, name))
|
|
for u, v in edges:
|
|
response.write(" {} -> {};\n".format(u, v))
|
|
response.write("}\n")
|
|
|
|
return response
|
|
|
|
|
|
graph = TemplateView.as_view(template_name="wiki_groups/graph.html")
|
|
|
|
|
|
class WikiGroupMixin(SingleObjectMixin, UserPassesTestMixin):
|
|
"""
|
|
Restricts the view to a manager of the wikigroup, and selects automatically
|
|
the required WikiGroup with its Django group
|
|
"""
|
|
|
|
model = WikiGroup
|
|
|
|
def get_queryset(self):
|
|
return super().get_queryset().select_related("django_group")
|
|
|
|
def test_func(self):
|
|
self.object = self.get_object()
|
|
return self.request.user.is_staff or self.object.is_manager(self.request.user)
|
|
|
|
|
|
class StaffMixin(UserPassesTestMixin):
|
|
"""Restricts the view to a staff member"""
|
|
|
|
def test_func(self):
|
|
return self.request.user.is_staff
|
|
|
|
|
|
class ManagedGroupsView(LoginRequiredMixin, ListView):
|
|
model = WikiGroup
|
|
template_name = "wiki_groups/managed.html"
|
|
|
|
def get_queryset(self):
|
|
if self.request.user.is_staff:
|
|
return WikiGroup.objects.select_related("django_group")
|
|
return self.request.user.managed_groups.select_related("django_group")
|
|
|
|
def get_context_data(self, **kwargs):
|
|
ctx = super().get_context_data(**kwargs)
|
|
wikigroups = set()
|
|
|
|
for group in ctx["wikigroup_list"]:
|
|
wikigroups |= group.get_all_groups()
|
|
|
|
ctx["wikigroup_list"] = wikigroups
|
|
ctx["object_list"] = wikigroups
|
|
|
|
return ctx
|
|
|
|
|
|
class WikiGroupView(WikiGroupMixin, DetailView):
|
|
template_name = "wiki_groups/admin.html"
|
|
|
|
def get_context_data(self, **kwargs):
|
|
kwargs.update({"errors": self.request.session.pop("wiki_form_errors", None)})
|
|
return super().get_context_data(**kwargs)
|
|
|
|
|
|
class RemoveUserView(WikiGroupMixin, RedirectView):
|
|
def get_redirect_url(self, *args, **kwargs):
|
|
return reverse("wiki_groups:admin-group", args=[kwargs["pk"]])
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
user = User.objects.filter(pk=kwargs["user_pk"]).first()
|
|
|
|
if user is not None:
|
|
self.object.users.remove(user)
|
|
|
|
return super().get(request, *args, **kwargs)
|
|
|
|
|
|
class RemoveManagerView(WikiGroupMixin, RedirectView):
|
|
def get_redirect_url(self, *args, **kwargs):
|
|
return reverse("wiki_groups:admin-group", args=[kwargs["pk"]])
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
user = User.objects.filter(pk=kwargs["user_pk"]).first()
|
|
|
|
if user is not None:
|
|
self.object.users.remove(user)
|
|
|
|
self.object.managers.remove(user)
|
|
|
|
return super().get(request, *args, **kwargs)
|
|
|
|
|
|
class RemoveGroupView(WikiGroupMixin, RedirectView):
|
|
def get_redirect_url(self, *args, **kwargs):
|
|
return reverse("wiki_groups:admin-group", args=[kwargs["pk"]])
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
group = WikiGroup.objects.filter(pk=kwargs["group_pk"]).first()
|
|
|
|
if group is not None:
|
|
self.object.includes_groups.remove(group)
|
|
|
|
return super().get(request, *args, **kwargs)
|
|
|
|
|
|
class AddUserView(WikiGroupMixin, BaseFormView):
|
|
form_class = SelectUserForm
|
|
|
|
def get_success_url(self):
|
|
return reverse("wiki_groups:admin-group", args=[self.object.pk])
|
|
|
|
def form_valid(self, form):
|
|
self.object.users.add(form.cleaned_data["user"])
|
|
|
|
return super().form_valid(form)
|
|
|
|
def form_invalid(self, form):
|
|
self.request.session["wiki_form_errors"] = {
|
|
"user": {"value": form["user"].value(), "msg": form.errors["user"]}
|
|
}
|
|
return HttpResponseRedirect(self.get_success_url())
|
|
|
|
|
|
class AddManagerView(WikiGroupMixin, BaseFormView):
|
|
form_class = SelectUserForm
|
|
|
|
def get_success_url(self):
|
|
return reverse("wiki_groups:admin-group", args=[self.object.pk])
|
|
|
|
def form_valid(self, form):
|
|
self.object.managers.add(form.cleaned_data["user"])
|
|
|
|
return super().form_valid(form)
|
|
|
|
def form_invalid(self, form):
|
|
self.request.session["wiki_form_errors"] = {
|
|
"manager": {"value": form["user"].value(), "msg": form.errors["user"]}
|
|
}
|
|
return HttpResponseRedirect(self.get_success_url())
|
|
|
|
|
|
class AddGroupView(WikiGroupMixin, BaseFormView):
|
|
"""Adds an existing metagroup to this group"""
|
|
|
|
form_class = SelectGroupForm
|
|
|
|
def get_success_url(self):
|
|
return reverse("wiki_groups:admin-group", args=[self.object.pk])
|
|
|
|
def form_valid(self, form):
|
|
subgroup = form.cleaned_data["group"]
|
|
group = self.object
|
|
|
|
if group.group_in_cycle(list(group.includes_groups.all()) + [subgroup]):
|
|
form.add_error(
|
|
"group",
|
|
(
|
|
"Ajout impossible sous peine de créer un cycle "
|
|
f"({group} est inclus dans {subgroup})"
|
|
),
|
|
)
|
|
return self.form_invalid(form)
|
|
|
|
group.includes_groups.add(subgroup)
|
|
return super().form_valid(form)
|
|
|
|
def form_invalid(self, form):
|
|
self.request.session["wiki_form_errors"] = {
|
|
"group_add": {"value": form["group"].value(), "msg": form.errors["group"]}
|
|
}
|
|
return HttpResponseRedirect(self.get_success_url())
|
|
|
|
|
|
class CreateGroupView(WikiGroupMixin, BaseFormView):
|
|
"""Creates a metagroup included in this group"""
|
|
|
|
form_class = CreateGroupForm
|
|
|
|
def get_success_url(self):
|
|
return reverse("wiki_groups:admin-group", args=[self.object.pk])
|
|
|
|
def form_valid(self, form):
|
|
new_group = form.cleaned_data["group"]
|
|
|
|
self.object.includes_groups.add(new_group)
|
|
new_group.managers.add(self.request.user)
|
|
|
|
return super().form_valid(form)
|
|
|
|
def form_invalid(self, form):
|
|
self.request.session["wiki_form_errors"] = {
|
|
"group_create": {
|
|
"value": form["group"].value(),
|
|
"msg": form.errors["group"],
|
|
}
|
|
}
|
|
return HttpResponseRedirect(self.get_success_url())
|
|
|
|
|
|
class DeleteGroupView(SingleObjectMixin, StaffMixin, RedirectView):
|
|
model = WikiGroup
|
|
url = reverse_lazy("wiki_groups:managed-groups")
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
group = self.get_object()
|
|
# On enlève les membres pour répercuter les changements
|
|
group.users.clear()
|
|
|
|
# On utilise la propagation de la suppression django_group -> wiki_group
|
|
group.django_group.delete()
|
|
|
|
return super().get(request, *args, **kwargs)
|