From 310a14a393e7cf978bb0217211e700fd7cd27fde Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Tue, 26 Jul 2016 10:27:59 +0200 Subject: [PATCH] Move middleware functionality to utils.py (#154) This simplifies providing an `event_view` method which works as decorator for presale/ views (e.g. for plugins), providing passing requests with event and organizer context if possible, and re-routing or failing appropriately otherwise. --- doc/development/setup.rst | 2 +- src/pretix/presale/middleware.py | 61 ++---------------------- src/pretix/presale/utils.py | 79 ++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 58 deletions(-) create mode 100644 src/pretix/presale/utils.py diff --git a/doc/development/setup.rst b/doc/development/setup.rst index bd6c8bc05..28495cf61 100644 --- a/doc/development/setup.rst +++ b/doc/development/setup.rst @@ -85,7 +85,7 @@ Before you check in your code into git, always run the static checkers and unit flake8 . isort -c -rc . - python manage.py validate + python manage.py check py.test The ``flake8`` command by default is a bit stricter than what we really enforce, but we do enforce that all commits diff --git a/src/pretix/presale/middleware.py b/src/pretix/presale/middleware.py index bc32bfc2e..1a71602c1 100644 --- a/src/pretix/presale/middleware.py +++ b/src/pretix/presale/middleware.py @@ -1,14 +1,6 @@ -from urllib.parse import urljoin - -from django.core.exceptions import PermissionDenied from django.core.urlresolvers import resolve -from django.http import Http404 -from django.shortcuts import redirect -from django.utils.translation import ugettext_lazy as _ -from pretix.base.middleware import LocaleMiddleware -from pretix.base.models import Event, EventPermission, Organizer -from pretix.multidomain.urlreverse import get_domain +from .utils import _detect_event class EventMiddleware: @@ -19,54 +11,9 @@ class EventMiddleware: return if 'organizer' in url.kwargs or 'event' in url.kwargs: - try: - if hasattr(request, 'organizer'): - # We are on an organizer's custom domain - if 'organizer' in url.kwargs and url.kwargs['organizer']: - if url.kwargs['organizer'] != request.organizer.slug: - raise Http404(_('The selected event was not found.')) - path = "/" + request.get_full_path().split("/", 2)[-1] - return redirect(path) - - request.event = Event.objects.filter( - slug=url.kwargs['event'], - organizer=request.organizer, - ).select_related('organizer')[0] - request.organizer = request.event.organizer - else: - # We are on our main domain - if 'event' in url.kwargs and 'organizer' in url.kwargs: - request.event = Event.objects.filter( - slug=url.kwargs['event'], - organizer__slug=url.kwargs['organizer'] - ).select_related('organizer')[0] - request.organizer = request.event.organizer - elif 'organizer' in url.kwargs: - request.organizer = Organizer.objects.filter( - slug=url.kwargs['organizer'] - )[0] - else: - raise Http404() - - # If this organizer has a custom domain, send the user there - domain = get_domain(request.organizer) - if domain: - if request.port and request.port not in (80, 443): - domain = '%s:%d' % (domain, request.port) - path = request.get_full_path().split("/", 2)[-1] - return redirect(urljoin('%s://%s' % (request.scheme, domain), path)) - - if hasattr(request, 'event'): - # Restrict locales to the ones available for this event - LocaleMiddleware().process_request(request) - - if not request.event.live: - if not request.user.is_authenticated() or not EventPermission.objects.filter( - event=request.event, user=request.user).exists(): - raise PermissionDenied(_('The selected ticket shop is currently not available.')) - - except IndexError: - raise Http404(_('The selected event or organizer was not found.')) + redirect = _detect_event(request) + if redirect: + return redirect if '_' not in request.session: # We need to create session even if we do not yet store something there, because we need the session diff --git a/src/pretix/presale/utils.py b/src/pretix/presale/utils.py new file mode 100644 index 000000000..99553d8d1 --- /dev/null +++ b/src/pretix/presale/utils.py @@ -0,0 +1,79 @@ +from urllib.parse import urljoin + +from django.core.exceptions import PermissionDenied +from django.core.urlresolvers import resolve +from django.http import Http404 +from django.shortcuts import redirect +from django.utils.translation import ugettext_lazy as _ + +from pretix.base.middleware import LocaleMiddleware +from pretix.base.models import Event, EventPermission, Organizer +from pretix.multidomain.urlreverse import get_domain + + +def _detect_event(request): + url = resolve(request.path_info) + try: + if hasattr(request, 'organizer'): + # We are on an organizer's custom domain + if 'organizer' in url.kwargs and url.kwargs['organizer']: + if url.kwargs['organizer'] != request.organizer.slug: + raise Http404(_('The selected event was not found.')) + path = "/" + request.get_full_path().split("/", 2)[-1] + return redirect(path) + + request.event = Event.objects\ + .select_related('organizer')\ + .get( + slug=url.kwargs['event'], + organizer=request.organizer, + ) + request.organizer = request.event.organizer + else: + # We are on our main domain + if 'event' in url.kwargs and 'organizer' in url.kwargs: + request.event = Event.objects\ + .select_related('organizer')\ + .get( + slug=url.kwargs['event'], + organizer__slug=url.kwargs['organizer'] + ) + request.organizer = request.event.organizer + elif 'organizer' in url.kwargs: + request.organizer = Organizer.objects.get( + slug=url.kwargs['organizer'] + ) + else: + raise Http404() + + # If this organizer has a custom domain, send the user there + domain = get_domain(request.organizer) + if domain: + if request.port and request.port not in (80, 443): + domain = '%s:%d' % (domain, request.port) + path = request.get_full_path().split("/", 2)[-1] + return redirect(urljoin('%s://%s' % (request.scheme, domain), path)) + + if hasattr(request, 'event'): + # Restrict locales to the ones available for this event + LocaleMiddleware().process_request(request) + + if not request.event.live: + if not request.user.is_authenticated() or not EventPermission.objects.filter( + event=request.event, user=request.user).exists(): + raise PermissionDenied(_('The selected ticket shop is currently not available.')) + + except Event.DoesNotExist: + raise Http404(_('The selected event was not found.')) + except Organizer.DoesNotExist: + raise Http404(_('The selected organizer was not found.')) + + +def event_view(func): + def wrap(request, *args, **kwargs): + ret = _detect_event(request) + if ret: + return ret + else: + return func(request=request, *args, **kwargs) + return wrap