feat 159: allow staff users to see grouped order overview pages

This commit is contained in:
Laetitia 2024-03-04 20:35:07 +01:00
parent b03d37ee7c
commit 6b3b361e07
5 changed files with 64 additions and 29 deletions

View file

@ -13,6 +13,7 @@ from icalendar import Calendar, Event, vCalAddress, vText
from ..forms import GroupedOrderForm, Item, JoinGroupedOrderForm from ..forms import GroupedOrderForm, Item, JoinGroupedOrderForm
from ..models import GroupedOrder, OrderAuthor from ..models import GroupedOrder, OrderAuthor
from .helpers import UserCanAccessGroupedOrderOverviewMixin
class IndexView(LoginRequiredMixin, generic.ListView): class IndexView(LoginRequiredMixin, generic.ListView):
@ -127,7 +128,7 @@ class GroupedOrderDetailView(generic.DetailView):
return context return context
class GroupedOrderOverview(UserPassesTestMixin, generic.DetailView): class GroupedOrderOverview(UserCanAccessGroupedOrderOverviewMixin, generic.DetailView):
model = GroupedOrder model = GroupedOrder
template_name = "order/grouped_order_overview.html" template_name = "order/grouped_order_overview.html"
context_object_name = "grouped_order" context_object_name = "grouped_order"
@ -136,8 +137,8 @@ class GroupedOrderOverview(UserPassesTestMixin, generic.DetailView):
return get_object_or_404(GroupedOrder, code=self.kwargs.get("code")) return get_object_or_404(GroupedOrder, code=self.kwargs.get("code"))
def test_func(self): def test_func(self):
# Restrict access to the manager # Access for grouped order manager, superuser, and staff (staff can see but not edit grouped orders)
return self.get_object().orga == self.request.user return super().test_func() or self.request.user.is_staff
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
# Compute grouped order total price before display # Compute grouped order total price before display
@ -175,7 +176,9 @@ class GroupedOrderCreateView(LoginRequiredMixin, generic.CreateView):
return super().form_valid(form) return super().form_valid(form)
class GroupedOrderUpdateView(UserPassesTestMixin, generic.UpdateView): class GroupedOrderUpdateView(
UserCanAccessGroupedOrderOverviewMixin, generic.UpdateView
):
model = GroupedOrder model = GroupedOrder
template_name = "order/grouped_order_update.html" template_name = "order/grouped_order_update.html"
context_object_name = "grouped_order" context_object_name = "grouped_order"
@ -184,24 +187,18 @@ class GroupedOrderUpdateView(UserPassesTestMixin, generic.UpdateView):
def get_object(self, queryset=None): def get_object(self, queryset=None):
return get_object_or_404(GroupedOrder, code=self.kwargs.get("code")) return get_object_or_404(GroupedOrder, code=self.kwargs.get("code"))
def test_func(self):
# Restrict access to the manager
return self.get_object().orga == self.request.user
def get_form_kwargs(self): def get_form_kwargs(self):
kwargs = super().get_form_kwargs() kwargs = super().get_form_kwargs()
kwargs["user"] = self.request.user kwargs["user"] = self.request.user
return kwargs return kwargs
class GroupedOrderDuplicateView(UserPassesTestMixin, generic.RedirectView): class GroupedOrderDuplicateView(
UserCanAccessGroupedOrderOverviewMixin, generic.RedirectView
):
def get_object(self, queryset=None): def get_object(self, queryset=None):
return get_object_or_404(GroupedOrder, code=self.kwargs.get("code")) return get_object_or_404(GroupedOrder, code=self.kwargs.get("code"))
def test_func(self):
# Restrict access to the manager
return self.get_object().orga == self.request.user
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
# overwrite the ``get`` function to copy the initial grouped order before # overwrite the ``get`` function to copy the initial grouped order before
# redirecting to the update view of the new grouped order # redirecting to the update view of the new grouped order
@ -238,7 +235,9 @@ class GroupedOrderDuplicateView(UserPassesTestMixin, generic.RedirectView):
) )
class GroupedOrderDeleteView(UserPassesTestMixin, generic.DeleteView): class GroupedOrderDeleteView(
UserCanAccessGroupedOrderOverviewMixin, generic.DeleteView
):
model = GroupedOrder model = GroupedOrder
template_name = "order/grouped_order_confirm_delete.html" template_name = "order/grouped_order_confirm_delete.html"
context_object_name = "grouped_order" context_object_name = "grouped_order"
@ -249,10 +248,6 @@ class GroupedOrderDeleteView(UserPassesTestMixin, generic.DeleteView):
def get_success_url(self): def get_success_url(self):
return reverse_lazy("order:index") return reverse_lazy("order:index")
def test_func(self):
# Restrict access to the manager
return self.get_object().orga == self.request.user
def form_valid(self, form): def form_valid(self, form):
# Delete related OrderAuthors # Delete related OrderAuthors
grouped_order = self.get_object() grouped_order = self.get_object()
@ -284,18 +279,20 @@ class GroupedOrderAddItemsView(UserPassesTestMixin, generic.ListView):
return grouped_order.orga == self.request.user return grouped_order.orga == self.request.user
class GroupedOrderExportView(UserPassesTestMixin, generic.DetailView): class GroupedOrderExportView(
UserCanAccessGroupedOrderOverviewMixin, generic.DetailView
):
model = GroupedOrder model = GroupedOrder
template_name = "order/grouped_order_sheet.html" template_name = "order/grouped_order_sheet.html"
context_object_name = "grouped_order" context_object_name = "grouped_order"
def test_func(self):
# Grouped order orga, superuser and staff can get this view
return super().test_func() or self.request.user.is_staff
def get_object(self, queryset=None): def get_object(self, queryset=None):
return get_object_or_404(GroupedOrder, code=self.kwargs.get("code")) return get_object_or_404(GroupedOrder, code=self.kwargs.get("code"))
def test_func(self):
# Restrict access to the manager
return self.get_object().orga == self.request.user
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(GroupedOrderExportView, self).get_context_data(**kwargs) context = super(GroupedOrderExportView, self).get_context_data(**kwargs)
grouped_order = self.get_object() grouped_order = self.get_object()
@ -328,9 +325,9 @@ class DownloadGroupedOrderSheetView(WeasyTemplateResponseMixin, GroupedOrderExpo
class ExportGroupOrderEmailAdressesToDownloadView(UserPassesTestMixin, generic.View): class ExportGroupOrderEmailAdressesToDownloadView(UserPassesTestMixin, generic.View):
def test_func(self): def test_func(self):
# Restrict access to the manager # Restrict access to the manager, superuser and staff
origin = get_object_or_404(GroupedOrder, code=self.kwargs.get("code")) origin = get_object_or_404(GroupedOrder, code=self.kwargs.get("code"))
return origin.orga == self.request.user return origin.orga == self.request.user or self.request.user.is_staff
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
grouped_order = get_object_or_404(GroupedOrder, code=self.kwargs.get("code")) grouped_order = get_object_or_404(GroupedOrder, code=self.kwargs.get("code"))

View file

@ -0,0 +1,13 @@
from django.contrib.auth.mixins import UserPassesTestMixin
class UserCanAccessGroupedOrderOverviewMixin(UserPassesTestMixin):
"""
The view is accessible only if the request user is orga or superuser
"""
def test_func(self):
return (
self.get_object().orga == self.request.user
or self.request.user.is_superuser
)

View file

@ -29,5 +29,8 @@ class ItemDeleteView(UserPassesTestMixin, generic.DeleteView):
return reverse_lazy("order:manage_items", args=[self.object.grouped_order.code]) return reverse_lazy("order:manage_items", args=[self.object.grouped_order.code])
def test_func(self): def test_func(self):
# Restrict access to the manager # Restrict access to the manager or a superuser
return self.get_object().grouped_order.orga == self.request.user return (
self.get_object().grouped_order.orga == self.request.user
or self.request.user.is_superuser
)

View file

@ -136,5 +136,8 @@ class OrderDeleteView(UserPassesTestMixin, generic.DeleteView):
) )
def test_func(self): def test_func(self):
"""Accessible only if the requesting user is the grouped order organizer""" # Restrict access to the manager or a superuser
return self.get_object().grouped_order.orga == self.request.user return (
self.get_object().grouped_order.orga == self.request.user
or self.request.user.is_superuser
)

View file

@ -735,6 +735,25 @@ class TestGroupedOrderOverview:
response = client_log.get(orga_view_url) response = client_log.get(orga_view_url)
assert response.status_code == 403 assert response.status_code == 403
def test_user_superuser_ok(self, other_user, admin_client):
"""
A superuser that is not orga can get the GroupedOrderOverview
"""
grouped_order = create_grouped_order(
days_before_delivery_date=5,
days_before_deadline=2,
name="gr order test",
orga_user=other_user,
)
orga_view_url = reverse(
"order:grouped_order_overview",
kwargs={
"code": grouped_order.code,
},
)
response = admin_client.get(orga_view_url)
assert response.status_code == 200
def test_deadline_passed(self, client_log): def test_deadline_passed(self, client_log):
""" """
If the deadline is passed, the user sees a message but cannot share link If the deadline is passed, the user sees a message but cannot share link