Repository: dotkom/onlineweb4

Issue:
Dashboard per object permissions too strict
## What kind of an issue is this?

- [x] Bug report


## What is the expected behaviour?

Having access to items you expect to have access to.

## What is the current behaviour?

Some items are guarded by django-guardian per object permissions even though there are no per-object permissions granted for the object, resulting in not being able to access them.


## How do you reproduce this problem? 

Try creating/editing chunks without being a superuser.

## Other information

Recent changes to dashboard/tools (5f3ce15) were too extensive and added side effects to other views using the same dashboard view mixin.
This made some people lose access to items they previously had access to.


Discussion:

Resolving patch:
diff --git a/apps/dashboard/tools.py b/apps/dashboard/tools.py
--- a/apps/dashboard/tools.py
+++ b/apps/dashboard/tools.py
@@ -116,18 +116,34 @@ def get_context_data(self, **kwargs):
         return context
 
 
-class DashboardPermissionMixin(DashboardMixin, PermissionRequiredMixin):
+class DashboardObjectPermissionMixin(DashboardMixin, PermissionRequiredMixin):
     """
-    DashboardPermissionMixin combines the DashboardMixin with Django
+    DashboardObjectPermissionMixin combines the DashboardMixin with Django
     Guardian's permission based mixin, rendering a 403 Unauthorized
     template if the currently logged in user is lacking appropriate
-    permissions to access a certain view.
+    permissions to access a certain object in a view.
     """
 
     return_403 = True
 
 
-class DashboardCreatePermissionMixin(DashboardPermissionMixin):
+class DashboardPermissionMixin(DashboardObjectPermissionMixin):
+    """
+    DashboardPermissionMixin renders a 403 Unauthorized
+    template if the currently logged in user is lacking appropriate
+    permissions to access a certain view.
+    """
+
+    def get_permission_object(self, *args, **kwargs):
+        """
+        By default PermissionRequiredMixin works with object permissions.
+        By returning None we force guardian to only check if the user
+        has the proper permission.
+        """
+        return None
+
+
+class DashboardCreatePermissionMixin(DashboardObjectPermissionMixin):
     def get_permission_object(self):
         # There is no existing object when creating an object. @ToDo: override this in a nicer way?
         return None
diff --git a/apps/events/dashboard/views.py b/apps/events/dashboard/views.py
--- a/apps/events/dashboard/views.py
+++ b/apps/events/dashboard/views.py
@@ -17,8 +17,8 @@
 from guardian.decorators import permission_required
 from guardian.shortcuts import get_objects_for_user
 
-from apps.dashboard.tools import (DashboardCreatePermissionMixin, DashboardPermissionMixin,
-                                  get_base_context, has_access)
+from apps.dashboard.tools import (DashboardCreatePermissionMixin, DashboardObjectPermissionMixin,
+                                  DashboardPermissionMixin, get_base_context, has_access)
 from apps.events.dashboard import forms as dashboard_forms
 from apps.events.dashboard.utils import event_ajax_handler
 from apps.events.models import AttendanceEvent, Attendee, CompanyEvent, Event, Reservation, Reservee
@@ -107,7 +107,7 @@ def get_success_url(self):
         return reverse('dashboard_event_details', kwargs={'event_id': self.object.id})
 
 
-class UpdateEventView(DashboardPermissionMixin, UpdateView):
+class UpdateEventView(DashboardObjectPermissionMixin, UpdateView):
     model = Event
     form_class = dashboard_forms.CreateEventForm
     template_name = "events/dashboard/event_form.html"
@@ -133,7 +133,7 @@ def get_success_url(self):
         return reverse('dashboard_event_details', kwargs={'event_id': self.kwargs.get('event_id')})
 
 
-class UpdateAttendanceView(DashboardPermissionMixin, UpdateView):
+class UpdateAttendanceView(DashboardObjectPermissionMixin, UpdateView):
     model = AttendanceEvent
     form_class = dashboard_forms.CreateAttendanceEventForm
     template_name = "events/dashboard/attendanceevent_form.html"
@@ -158,7 +158,7 @@ def form_valid(self, form):
         return super().form_valid(form)
 
 
-class RemoveCompanyEventView(DashboardPermissionMixin, DeleteView):
+class RemoveCompanyEventView(DashboardObjectPermissionMixin, DeleteView):
     model = CompanyEvent
     permission_required = 'events.add_attendanceevent'
     pk_url_kwarg = 'event_id'
@@ -183,7 +183,7 @@ def form_valid(self, form):
         return super().form_valid(form)
 
 
-class RemoveFeedbackRelationView(DashboardPermissionMixin, DeleteView):
+class RemoveFeedbackRelationView(DashboardObjectPermissionMixin, DeleteView):
     model = FeedbackRelation
     permission_required = 'events.add_attendanceevent'
     pk_url_kwarg = 'event_id'


Test patch: