mirror of
https://github.com/ae-utbm/sith.git
synced 2026-06-05 07:39:21 +00:00
feat: request.barmen
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
from typing import TYPE_CHECKING, Callable
|
||||
|
||||
from django.db.models import Exists, OuterRef
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from django.utils.functional import SimpleLazyObject, empty
|
||||
|
||||
from core.models import User
|
||||
from counter.models import Permanency
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from django.contrib.sessions.backends.base import SessionBase
|
||||
|
||||
|
||||
SESSION_BARMEN_KEY = "barmen_ids"
|
||||
|
||||
|
||||
def get_cached_barmen(request: HttpRequest) -> set[User]:
|
||||
if not hasattr(request, "_cached_barmen"):
|
||||
session: SessionBase = request.session
|
||||
barmen_ids = session.get(SESSION_BARMEN_KEY, [])
|
||||
if barmen_ids:
|
||||
request._cached_barmen = set(
|
||||
User.objects.filter(
|
||||
Exists(Permanency.objects.filter(user=OuterRef("pk"), end=None)),
|
||||
id__in=barmen_ids,
|
||||
)
|
||||
)
|
||||
else:
|
||||
request._cached_barmen = set()
|
||||
|
||||
return request._cached_barmen
|
||||
|
||||
|
||||
class BarmenMiddleware:
|
||||
"""Inject barmen logged in the current session.
|
||||
|
||||
In a similar fashion as `request.user`, `request.barmen` contains
|
||||
users that are barmen in the current session, and ONLY them ;
|
||||
if a user is logged as a barman on another session,
|
||||
it will not be in `request.barmen`.
|
||||
|
||||
Notes:
|
||||
In case of ended permanence, users will be automatically
|
||||
removed from `request.barmen`.
|
||||
However, in case of newly started permanence, this middleware
|
||||
cannot add new barmen in the session data, so that operation
|
||||
must be explicitly done in the barman login view.
|
||||
"""
|
||||
|
||||
def __init__(self, get_response: Callable[[HttpRequest], HttpResponse]):
|
||||
self.get_response = get_response
|
||||
|
||||
def __call__(self, request: HttpRequest):
|
||||
request.barmen = SimpleLazyObject(lambda: get_cached_barmen(request))
|
||||
|
||||
response = self.get_response(request)
|
||||
|
||||
if request.barmen._wrapped is not empty and {
|
||||
b.id for b in request.barmen
|
||||
} != set(request.session.get(SESSION_BARMEN_KEY, [])):
|
||||
# update the session data only if `session.barmen`
|
||||
# has been accessed and modified.
|
||||
request.session[SESSION_BARMEN_KEY] = [b.id for b in request.barmen]
|
||||
return response
|
||||
Reference in New Issue
Block a user