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.views.site import search_user
from counter.models import Counter, Customer, Product
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()
)
from counter.utils import sent_from_logged_counter
class RightManagedLookupChannel(LookupChannel):
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

View File

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

View File

@ -21,7 +21,7 @@ from django import forms
from django.conf import settings
from django.core.exceptions import PermissionDenied
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.urls import reverse
from django.utils.http import http_date
@ -37,27 +37,23 @@ from core.views import (
CanViewMixin,
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
memory at once. The FileWrapper will turn the file object into an
iterator for chunks of 8KB.
"""
f = get_object_or_404(file_class, id=file_id)
if not (
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()
)
):
if not can_view(f, request.user) and not sent_from_logged_counter(request):
raise PermissionDenied
name = f.__getattribute__(file_attr).name
name = getattr(f, file_attr).name
filepath = settings.MEDIA_ROOT / name
# 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,
StudentCard,
)
from counter.utils import sent_from_logged_counter
class CounterAdminMixin(View):
@ -901,15 +902,9 @@ class RefillingDeleteView(DeleteView):
def dispatch(self, request, *args, **kwargs):
"""We have here a very particular right handling, we can't inherit from CanEditPropMixin."""
self.object = self.get_object()
if (
timezone.now() - self.object.date
<= timedelta(minutes=settings.SITH_LAST_OPERATIONS_LIMIT)
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()
):
if timezone.now() - self.object.date <= timedelta(
minutes=settings.SITH_LAST_OPERATIONS_LIMIT
) and sent_from_logged_counter(request):
self.success_url = reverse(
"counter:details", kwargs={"counter_id": self.object.counter.id}
)
@ -932,15 +927,9 @@ class SellingDeleteView(DeleteView):
def dispatch(self, request, *args, **kwargs):
"""We have here a very particular right handling, we can't inherit from CanEditPropMixin."""
self.object = self.get_object()
if (
timezone.now() - self.object.date
<= timedelta(minutes=settings.SITH_LAST_OPERATIONS_LIMIT)
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()
):
if timezone.now() - self.object.date <= timedelta(
minutes=settings.SITH_LAST_OPERATIONS_LIMIT
) and sent_from_logged_counter(request):
self.success_url = reverse(
"counter:details", kwargs={"counter_id": self.object.counter.id}
)
@ -1175,14 +1164,7 @@ class CounterLastOperationsView(CounterTabsMixin, CanViewMixin, DetailView):
def dispatch(self, request, *args, **kwargs):
"""We have here again a very particular right handling."""
self.object = self.get_object()
if (
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()
):
if sent_from_logged_counter(request) and self.object.barmen_list:
return super().dispatch(request, *args, **kwargs)
return HttpResponseRedirect(
reverse("counter:details", kwargs={"counter_id": self.object.id})
@ -1215,14 +1197,7 @@ class CounterCashSummaryView(CounterTabsMixin, CanViewMixin, DetailView):
def dispatch(self, request, *args, **kwargs):
"""We have here again a very particular right handling."""
self.object = self.get_object()
if (
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()
):
if sent_from_logged_counter(request) and self.object.barmen_list:
return super().dispatch(request, *args, **kwargs)
return HttpResponseRedirect(
reverse("counter:details", kwargs={"counter_id": self.object.id})