extract sent_from_logged_counter(request)

This commit is contained in:
thomas girod 2024-08-04 22:30:54 +02:00
parent e5dfe1e638
commit a9f66e2cd9
5 changed files with 60 additions and 62 deletions

View File

@ -21,19 +21,12 @@ from club.models import Club
from core.models import Group, SithFile, User from core.models import Group, SithFile, User
from core.views.site import search_user from core.views.site import search_user
from counter.models import Counter, Customer, Product from counter.models import Counter, Customer, Product
from counter.utils import sent_from_logged_counter
def check_token(request):
return (
"counter_token" in request.session.keys()
and request.session["counter_token"]
and Counter.objects.filter(token=request.session["counter_token"]).exists()
)
class RightManagedLookupChannel(LookupChannel): class RightManagedLookupChannel(LookupChannel):
def check_auth(self, request): def check_auth(self, request):
if not request.user.was_subscribed and not check_token(request): if not request.user.was_subscribed and not sent_from_logged_counter(request):
raise PermissionDenied raise PermissionDenied

View File

@ -1137,11 +1137,9 @@ class SithFile(models.Model):
else: else:
self._check_path_consistence() self._check_path_consistence()
def __getattribute__(self, attr): @property
if attr == "is_file": def is_file(self):
return not self.is_folder return not self.is_folder
else:
return super().__getattribute__(attr)
@cached_property @cached_property
def as_picture(self): def as_picture(self):

View File

@ -21,7 +21,7 @@ from django import forms
from django.conf import settings from django.conf import settings
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django.forms.models import modelform_factory from django.forms.models import modelform_factory
from django.http import Http404, HttpResponse from django.http import Http404, HttpRequest, HttpResponse
from django.shortcuts import get_object_or_404, redirect from django.shortcuts import get_object_or_404, redirect
from django.urls import reverse from django.urls import reverse
from django.utils.http import http_date from django.utils.http import http_date
@ -37,27 +37,23 @@ from core.views import (
CanViewMixin, CanViewMixin,
can_view, can_view,
) )
from counter.models import Counter from counter.utils import sent_from_logged_counter
def send_file(request, file_id, file_class=SithFile, file_attr="file"): def send_file(
request: HttpRequest,
file_id: int,
file_class: type[SithFile] = SithFile,
file_attr: str = "file",
):
"""Send a file through Django without loading the whole file into """Send a file through Django without loading the whole file into
memory at once. The FileWrapper will turn the file object into an memory at once. The FileWrapper will turn the file object into an
iterator for chunks of 8KB. iterator for chunks of 8KB.
""" """
f = get_object_or_404(file_class, id=file_id) f = get_object_or_404(file_class, id=file_id)
if not ( if not can_view(f, request.user) and not sent_from_logged_counter(request):
can_view(f, request.user)
or (
"counter_token" in request.session.keys()
and request.session["counter_token"]
and Counter.objects.filter( # check if not null for counters that have no token set
token=request.session["counter_token"]
).exists()
)
):
raise PermissionDenied raise PermissionDenied
name = f.__getattribute__(file_attr).name name = getattr(f, file_attr).name
filepath = settings.MEDIA_ROOT / name filepath = settings.MEDIA_ROOT / name
# check if file exists on disk # check if file exists on disk

36
counter/utils.py Normal file
View File

@ -0,0 +1,36 @@
from urllib.parse import urlparse
from django.http import HttpRequest
from django.urls import resolve
from counter.models import Counter
def sent_from_logged_counter(request: HttpRequest) -> bool:
"""Check if the request is sent from a device logged to a counter.
The request must also be sent within the frame of a counter's activity.
Trying to use this function to manage access to non-sas
related resources probably won't work.
A request is considered as coming from a logged counter if :
- Its referer comes from the counter app
(eg. fetching user pictures from the click UI)
or the request path belongs to the counter app
(eg. the barman went back to the main by missclick and go back
to the counter)
- The current session has a counter token associated with it.
- A counter with this token exists.
"""
referer = urlparse(request.META["HTTP_REFERER"]).path
path_ok = (
request.resolver_match.app_name == "counter"
or resolve(referer).app_name == "counter"
)
return (
path_ok
and "counter_token" in request.session
and request.session["counter_token"]
and Counter.objects.filter(token=request.session["counter_token"]).exists()
)

View File

@ -80,6 +80,7 @@ from counter.models import (
Selling, Selling,
StudentCard, StudentCard,
) )
from counter.utils import sent_from_logged_counter
class CounterAdminMixin(View): class CounterAdminMixin(View):
@ -901,15 +902,9 @@ class RefillingDeleteView(DeleteView):
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
"""We have here a very particular right handling, we can't inherit from CanEditPropMixin.""" """We have here a very particular right handling, we can't inherit from CanEditPropMixin."""
self.object = self.get_object() self.object = self.get_object()
if ( if timezone.now() - self.object.date <= timedelta(
timezone.now() - self.object.date minutes=settings.SITH_LAST_OPERATIONS_LIMIT
<= timedelta(minutes=settings.SITH_LAST_OPERATIONS_LIMIT) ) and sent_from_logged_counter(request):
and "counter_token" in request.session.keys()
and request.session["counter_token"]
and Counter.objects.filter( # check if not null for counters that have no token set
token=request.session["counter_token"]
).exists()
):
self.success_url = reverse( self.success_url = reverse(
"counter:details", kwargs={"counter_id": self.object.counter.id} "counter:details", kwargs={"counter_id": self.object.counter.id}
) )
@ -932,15 +927,9 @@ class SellingDeleteView(DeleteView):
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
"""We have here a very particular right handling, we can't inherit from CanEditPropMixin.""" """We have here a very particular right handling, we can't inherit from CanEditPropMixin."""
self.object = self.get_object() self.object = self.get_object()
if ( if timezone.now() - self.object.date <= timedelta(
timezone.now() - self.object.date minutes=settings.SITH_LAST_OPERATIONS_LIMIT
<= timedelta(minutes=settings.SITH_LAST_OPERATIONS_LIMIT) ) and sent_from_logged_counter(request):
and "counter_token" in request.session.keys()
and request.session["counter_token"]
and Counter.objects.filter( # check if not null for counters that have no token set
token=request.session["counter_token"]
).exists()
):
self.success_url = reverse( self.success_url = reverse(
"counter:details", kwargs={"counter_id": self.object.counter.id} "counter:details", kwargs={"counter_id": self.object.counter.id}
) )
@ -1175,14 +1164,7 @@ class CounterLastOperationsView(CounterTabsMixin, CanViewMixin, DetailView):
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
"""We have here again a very particular right handling.""" """We have here again a very particular right handling."""
self.object = self.get_object() self.object = self.get_object()
if ( if sent_from_logged_counter(request) and self.object.barmen_list:
self.object.barmen_list
and "counter_token" in request.session.keys()
and request.session["counter_token"]
and Counter.objects.filter( # check if not null for counters that have no token set
token=request.session["counter_token"]
).exists()
):
return super().dispatch(request, *args, **kwargs) return super().dispatch(request, *args, **kwargs)
return HttpResponseRedirect( return HttpResponseRedirect(
reverse("counter:details", kwargs={"counter_id": self.object.id}) reverse("counter:details", kwargs={"counter_id": self.object.id})
@ -1215,14 +1197,7 @@ class CounterCashSummaryView(CounterTabsMixin, CanViewMixin, DetailView):
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
"""We have here again a very particular right handling.""" """We have here again a very particular right handling."""
self.object = self.get_object() self.object = self.get_object()
if ( if sent_from_logged_counter(request) and self.object.barmen_list:
self.object.barmen_list
and "counter_token" in request.session.keys()
and request.session["counter_token"]
and Counter.objects.filter( # check if not null for counters that have no token set
token=request.session["counter_token"]
).exists()
):
return super().dispatch(request, *args, **kwargs) return super().dispatch(request, *args, **kwargs)
return HttpResponseRedirect( return HttpResponseRedirect(
reverse("counter:details", kwargs={"counter_id": self.object.id}) reverse("counter:details", kwargs={"counter_id": self.object.id})