mirror of
https://github.com/pretix/pretix.git
synced 2026-05-06 15:24:02 +00:00
Customer accounts & Memberships (#2024)
This commit is contained in:
@@ -39,15 +39,19 @@ from urllib.parse import urljoin
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.http import Http404
|
||||
from django.middleware.csrf import rotate_token
|
||||
from django.shortcuts import redirect
|
||||
from django.template.response import TemplateResponse
|
||||
from django.urls import resolve
|
||||
from django.utils.crypto import constant_time_compare
|
||||
from django.utils.functional import SimpleLazyObject
|
||||
from django.utils.timezone import now
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.views.defaults import permission_denied
|
||||
from django_scopes import scope
|
||||
|
||||
from pretix.base.middleware import LocaleMiddleware
|
||||
from pretix.base.models import Event, Organizer
|
||||
from pretix.base.models import Customer, Event, Organizer
|
||||
from pretix.multidomain.urlreverse import (
|
||||
get_event_domain, get_organizer_domain,
|
||||
)
|
||||
@@ -56,8 +60,96 @@ from pretix.presale.signals import process_request, process_response
|
||||
SessionStore = import_module(settings.SESSION_ENGINE).SessionStore
|
||||
|
||||
|
||||
def get_customer(request):
|
||||
if not hasattr(request, '_cached_customer'):
|
||||
session_key = f'customer_auth_id:{request.organizer.pk}'
|
||||
hash_session_key = f'customer_auth_hash:{request.organizer.pk}'
|
||||
|
||||
with scope(organizer=request.organizer):
|
||||
try:
|
||||
customer = request.organizer.customers.get(
|
||||
is_active=True, is_verified=True,
|
||||
pk=request.session[session_key]
|
||||
)
|
||||
except (Customer.DoesNotExist, KeyError):
|
||||
request._cached_customer = None
|
||||
else:
|
||||
session_hash = request.session.get(hash_session_key)
|
||||
session_hash_verified = session_hash and constant_time_compare(
|
||||
session_hash,
|
||||
customer.get_session_auth_hash()
|
||||
)
|
||||
if session_hash_verified:
|
||||
request._cached_customer = customer
|
||||
else:
|
||||
request.session.flush()
|
||||
request._cached_customer = None
|
||||
|
||||
return request._cached_customer
|
||||
|
||||
|
||||
def update_customer_session_auth_hash(request, customer):
|
||||
hash_session_key = f'customer_auth_hash:{request.organizer.pk}'
|
||||
session_auth_hash = customer.get_session_auth_hash()
|
||||
request.session.cycle_key()
|
||||
request.session[hash_session_key] = session_auth_hash
|
||||
|
||||
|
||||
def add_customer_to_request(request):
|
||||
request.customer = SimpleLazyObject(lambda: get_customer(request))
|
||||
|
||||
|
||||
def customer_login(request, customer):
|
||||
session_key = f'customer_auth_id:{request.organizer.pk}'
|
||||
hash_session_key = f'customer_auth_hash:{request.organizer.pk}'
|
||||
session_auth_hash = customer.get_session_auth_hash()
|
||||
|
||||
if session_key in request.session:
|
||||
if request.session[session_key] != customer.pk or (
|
||||
not constant_time_compare(request.session.get(hash_session_key, ''), session_auth_hash)):
|
||||
# To avoid reusing another user's session, create a new, empty
|
||||
# session if the existing session corresponds to a different
|
||||
# authenticated user.
|
||||
request.session.flush()
|
||||
else:
|
||||
request.session.cycle_key()
|
||||
|
||||
request.session[session_key] = customer.pk
|
||||
request.session[hash_session_key] = session_auth_hash
|
||||
request.customer = customer
|
||||
|
||||
customer.last_login = now()
|
||||
customer.save(update_fields=['last_login'])
|
||||
|
||||
rotate_token(request)
|
||||
|
||||
|
||||
def customer_logout(request):
|
||||
session_key = f'customer_auth_id:{request.organizer.pk}'
|
||||
hash_session_key = f'customer_auth_hash:{request.organizer.pk}'
|
||||
|
||||
# Remove user session
|
||||
customer_id = request.session.pop(session_key, None)
|
||||
request.session.pop(hash_session_key, None)
|
||||
|
||||
# Remove carts tied to this user
|
||||
carts = request.session.get('carts', {})
|
||||
for k, v in list(carts.items()):
|
||||
if v.get('customer') == customer_id:
|
||||
carts.pop(k)
|
||||
request.session['carts'] = carts
|
||||
|
||||
# Cycle session key and CSRF token
|
||||
request.session.cycle_key()
|
||||
rotate_token(request)
|
||||
|
||||
request.customer = None
|
||||
request._cached_customer = None
|
||||
|
||||
|
||||
@scope(organizer=None)
|
||||
def _detect_event(request, require_live=True, require_plugin=None):
|
||||
|
||||
if hasattr(request, '_event_detected'):
|
||||
return
|
||||
|
||||
@@ -132,6 +224,9 @@ def _detect_event(request, require_live=True, require_plugin=None):
|
||||
r['Access-Control-Allow-Origin'] = '*'
|
||||
return r
|
||||
|
||||
if not hasattr(request, 'customer'):
|
||||
add_customer_to_request(request)
|
||||
|
||||
if hasattr(request, 'event'):
|
||||
# Restrict locales to the ones available for this event
|
||||
LocaleMiddleware().process_request(request)
|
||||
|
||||
Reference in New Issue
Block a user