diff --git a/apps/permission/backends.py b/apps/permission/backends.py index f9c90d56..4d7ffbf1 100644 --- a/apps/permission/backends.py +++ b/apps/permission/backends.py @@ -198,6 +198,41 @@ class PermissionBackend(ModelBackend): def has_module_perms(self, user_obj, app_label): return False + @staticmethod + @memoize + def has_model_perm(request, model, type): + """ + Check is the given user has the permission over a given model for a given action. + The result is then memoized. + :param request: The current request + :param model: The model that the permissions shoud apply + :param type: The type of the permissions: view, change, add or delete + For view action, it is consider possible if user can view or change the model + """ + # Requested by a shell + if request is None: + return False + + user_obj = request.user + sess = request.session + + if hasattr(request, 'auth') and request.auth is not None and hasattr(request.auth, 'scope'): + # OAuth2 Authentication + user_obj = request.auth.user + + if user_obj is None or user_obj.is_anonymous: + return False + + if user_obj.is_superuser and sess.get("permission_mask", -1) >= 42: + return True + + ct = ContentType.objects.get_for_model(model) + if any(PermissionBackend.permissions(request, ct, type)): + return True + if type == "view" and any(PermissionBackend.permissions(request, ct, "change")): + return True + return False + def get_all_permissions(self, user_obj, obj=None): ct = ContentType.objects.get_for_model(obj) return list(self.permissions(get_current_request(), ct, "view")) diff --git a/apps/treasury/tests/test_treasury.py b/apps/treasury/tests/test_treasury.py index 798a960f..bc0eddc3 100644 --- a/apps/treasury/tests/test_treasury.py +++ b/apps/treasury/tests/test_treasury.py @@ -385,8 +385,7 @@ class TestSogeCredits(TestCase): response = self.client.post(reverse("treasury:manage_soge_credit", args=(soge_credit.pk,)), data=dict(delete=True)) - # 403 because no SogeCredit exists anymore, then a PermissionDenied is raised - self.assertRedirects(response, reverse("treasury:soge_credits"), 302, 403) + self.assertRedirects(response, reverse("treasury:soge_credits"), 302, 200) self.assertFalse(SogeCredit.objects.filter(pk=soge_credit.pk)) self.user.note.refresh_from_db() self.assertEqual(self.user.note.balance, 0) diff --git a/apps/treasury/views.py b/apps/treasury/views.py index 8543d289..fef684cc 100644 --- a/apps/treasury/views.py +++ b/apps/treasury/views.py @@ -101,14 +101,7 @@ class InvoiceListView(LoginRequiredMixin, SingleTableView): if not request.user.is_authenticated: return self.handle_no_permission() - sample_invoice = Invoice( - id=0, - object="", - description="", - name="", - address="", - ) - if not PermissionBackend.check_perm(self.request, "treasury.view_invoice", sample_invoice): + if not PermissionBackend.has_model_perm(self.request, Invoice(), "view"): raise PermissionDenied(_("You are not able to see the treasury interface.")) return super().dispatch(request, *args, **kwargs) @@ -278,11 +271,7 @@ class RemittanceListView(LoginRequiredMixin, TemplateView): if not request.user.is_authenticated: return self.handle_no_permission() - sample_remittance = Remittance( - remittance_type_id=1, - comment="", - ) - if not PermissionBackend.check_perm(self.request, "treasury.add_remittance", sample_remittance): + if not PermissionBackend.has_model_perm(self.request, Remittance(), "view"): raise PermissionDenied(_("You are not able to see the treasury interface.")) return super().dispatch(request, *args, **kwargs) @@ -408,7 +397,7 @@ class SogeCreditListView(LoginRequiredMixin, ProtectQuerysetMixin, SingleTableVi if not request.user.is_authenticated: return self.handle_no_permission() - if not super().get_queryset().exists(): + if not PermissionBackend.has_model_perm(self.request, SogeCredit(), "view"): raise PermissionDenied(_("You are not able to see the treasury interface.")) return super().dispatch(request, *args, **kwargs)