1
0
mirror of https://gitlab.crans.org/bde/nk20 synced 2025-06-21 01:48:21 +02:00

Check permissions per request instead of per user

Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
This commit is contained in:
2021-06-15 14:40:32 +02:00
parent 5e9f36ef1a
commit ea092803d7
25 changed files with 207 additions and 203 deletions

View File

@ -8,7 +8,7 @@ from rest_framework.exceptions import ValidationError
from rest_polymorphic.serializers import PolymorphicSerializer
from member.api.serializers import MembershipSerializer
from member.models import Membership
from note_kfet.middlewares import get_current_authenticated_user
from note_kfet.middlewares import get_current_request
from permission.backends import PermissionBackend
from rest_framework.utils import model_meta
@ -126,7 +126,7 @@ class ConsumerSerializer(serializers.ModelSerializer):
"""
# If the user has no right to see the note, then we only display the note identifier
return NotePolymorphicSerializer().to_representation(obj.note)\
if PermissionBackend.check_perm(get_current_authenticated_user(), "note.view_note", obj.note)\
if PermissionBackend.check_perm(get_current_request(), "note.view_note", obj.note)\
else dict(
id=obj.note.id,
name=str(obj.note),
@ -142,7 +142,7 @@ class ConsumerSerializer(serializers.ModelSerializer):
def get_membership(self, obj):
if isinstance(obj.note, NoteUser):
memberships = Membership.objects.filter(
PermissionBackend.filter_queryset(get_current_authenticated_user(), Membership, "view")).filter(
PermissionBackend.filter_queryset(get_current_request(), Membership, "view")).filter(
user=obj.note.user,
club=2, # Kfet
).order_by("-date_start")

View File

@ -10,7 +10,6 @@ from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework import status
from api.viewsets import ReadProtectedModelViewSet, ReadOnlyProtectedModelViewSet
from note_kfet.middlewares import get_current_session
from permission.backends import PermissionBackend
from .serializers import NotePolymorphicSerializer, AliasSerializer, ConsumerSerializer,\
@ -40,12 +39,12 @@ class NotePolymorphicViewSet(ReadProtectedModelViewSet):
Parse query and apply filters.
:return: The filtered set of requested notes
"""
user = self.request.user
get_current_session().setdefault("permission_mask", 42)
queryset = self.queryset.filter(PermissionBackend.filter_queryset(user, Note, "view")
| PermissionBackend.filter_queryset(user, NoteUser, "view")
| PermissionBackend.filter_queryset(user, NoteClub, "view")
| PermissionBackend.filter_queryset(user, NoteSpecial, "view")).distinct()
self.request.session.setdefault("permission_mask", 42)
queryset = self.queryset.filter(PermissionBackend.filter_queryset(self.request, Note, "view")
| PermissionBackend.filter_queryset(self.request, NoteUser, "view")
| PermissionBackend.filter_queryset(self.request, NoteClub, "view")
| PermissionBackend.filter_queryset(self.request, NoteSpecial, "view"))\
.distinct()
alias = self.request.query_params.get("alias", ".*")
queryset = queryset.filter(
@ -205,7 +204,6 @@ class TransactionViewSet(ReadProtectedModelViewSet):
ordering_fields = ['created_at', 'amount', ]
def get_queryset(self):
user = self.request.user
get_current_session().setdefault("permission_mask", 42)
return self.model.objects.filter(PermissionBackend.filter_queryset(user, self.model, "view"))\
self.request.session.setdefault("permission_mask", 42)
return self.model.objects.filter(PermissionBackend.filter_queryset(self.request, self.model, "view"))\
.order_by("created_at", "id")

View File

@ -7,7 +7,7 @@ import django_tables2 as tables
from django.utils.html import format_html
from django_tables2.utils import A
from django.utils.translation import gettext_lazy as _
from note_kfet.middlewares import get_current_authenticated_user
from note_kfet.middlewares import get_current_request
from permission.backends import PermissionBackend
from .models.notes import Alias
@ -88,16 +88,16 @@ class HistoryTable(tables.Table):
"class": lambda record:
str(record.valid).lower()
+ (' validate' if record.source.is_active and record.destination.is_active and PermissionBackend
.check_perm(get_current_authenticated_user(), "note.change_transaction_invalidity_reason", record)
.check_perm(get_current_request(), "note.change_transaction_invalidity_reason", record)
else ''),
"data-toggle": "tooltip",
"title": lambda record: (_("Click to invalidate") if record.valid else _("Click to validate"))
if PermissionBackend.check_perm(get_current_authenticated_user(),
if PermissionBackend.check_perm(get_current_request(),
"note.change_transaction_invalidity_reason", record)
and record.source.is_active and record.destination.is_active else None,
"onclick": lambda record: 'de_validate(' + str(record.id) + ', ' + str(record.valid).lower()
+ ', "' + str(record.__class__.__name__) + '")'
if PermissionBackend.check_perm(get_current_authenticated_user(),
if PermissionBackend.check_perm(get_current_request(),
"note.change_transaction_invalidity_reason", record)
and record.source.is_active and record.destination.is_active else None,
"onmouseover": lambda record: '$("#invalidity_reason_'
@ -126,7 +126,7 @@ class HistoryTable(tables.Table):
When the validation status is hovered, an input field is displayed to let the user specify an invalidity reason
"""
has_perm = PermissionBackend \
.check_perm(get_current_authenticated_user(), "note.change_transaction_invalidity_reason", record)
.check_perm(get_current_request(), "note.change_transaction_invalidity_reason", record)
val = "" if value else ""
@ -165,7 +165,7 @@ class AliasTable(tables.Table):
extra_context={"delete_trans": _('delete')},
attrs={'td': {'class': lambda record: 'col-sm-1' + (
' d-none' if not PermissionBackend.check_perm(
get_current_authenticated_user(), "note.delete_alias",
get_current_request(), "note.delete_alias",
record) else '')}}, verbose_name=_("Delete"), )

View File

@ -38,7 +38,7 @@ class TransactionCreateView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTabl
def get_queryset(self, **kwargs):
# retrieves only Transaction that user has the right to see.
return Transaction.objects.filter(
PermissionBackend.filter_queryset(self.request.user, Transaction, "view")
PermissionBackend.filter_queryset(self.request, Transaction, "view")
).order_by("-created_at").all()[:20]
def get_context_data(self, **kwargs):
@ -47,16 +47,16 @@ class TransactionCreateView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTabl
context['polymorphic_ctype'] = ContentType.objects.get_for_model(Transaction).pk
context['special_polymorphic_ctype'] = ContentType.objects.get_for_model(SpecialTransaction).pk
context['special_types'] = NoteSpecial.objects\
.filter(PermissionBackend.filter_queryset(self.request.user, NoteSpecial, "view"))\
.filter(PermissionBackend.filter_queryset(self.request, NoteSpecial, "view"))\
.order_by("special_type").all()
# Add a shortcut for entry page for open activities
if "activity" in settings.INSTALLED_APPS:
from activity.models import Activity
activities_open = Activity.objects.filter(open=True).filter(
PermissionBackend.filter_queryset(self.request.user, Activity, "view")).distinct().all()
PermissionBackend.filter_queryset(self.request, Activity, "view")).distinct().all()
context["activities_open"] = [a for a in activities_open
if PermissionBackend.check_perm(self.request.user,
if PermissionBackend.check_perm(self.request,
"activity.add_entry",
Entry(activity=a,
note=self.request.user.note, ))]
@ -159,7 +159,7 @@ class ConsoView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView):
return self.handle_no_permission()
templates = TransactionTemplate.objects.filter(
PermissionBackend().filter_queryset(self.request.user, TransactionTemplate, "view")
PermissionBackend().filter_queryset(self.request, TransactionTemplate, "view")
)
if not templates.exists():
raise PermissionDenied(_("You can't see any button."))
@ -170,7 +170,7 @@ class ConsoView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView):
restrict to the transaction history the user can see.
"""
return Transaction.objects.filter(
PermissionBackend.filter_queryset(self.request.user, Transaction, "view")
PermissionBackend.filter_queryset(self.request, Transaction, "view")
).order_by("-created_at").all()[:20]
def get_context_data(self, **kwargs):
@ -180,13 +180,13 @@ class ConsoView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView):
# for each category, find which transaction templates the user can see.
for category in categories:
category.templates_filtered = category.templates.filter(
PermissionBackend().filter_queryset(self.request.user, TransactionTemplate, "view")
PermissionBackend().filter_queryset(self.request, TransactionTemplate, "view")
).filter(display=True).order_by('name').all()
context['categories'] = [cat for cat in categories if cat.templates_filtered]
# some transactiontemplate are put forward to find them easily
context['highlighted'] = TransactionTemplate.objects.filter(highlighted=True).filter(
PermissionBackend().filter_queryset(self.request.user, TransactionTemplate, "view")
PermissionBackend().filter_queryset(self.request, TransactionTemplate, "view")
).order_by('name').all()
context['polymorphic_ctype'] = ContentType.objects.get_for_model(RecurrentTransaction).pk
@ -209,7 +209,7 @@ class TransactionSearchView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView
data = form.cleaned_data if form.is_valid() else {}
transactions = Transaction.objects.annotate(total_amount=F("quantity") * F("amount")).filter(
PermissionBackend.filter_queryset(self.request.user, Transaction, "view"))\
PermissionBackend.filter_queryset(self.request, Transaction, "view"))\
.filter(Q(source=self.object) | Q(destination=self.object)).order_by('-created_at')
if "source" in data and data["source"]: