Beispiel #1
0
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.'))

            for receiver, response in process_request.send(request.event, request=request):
                if response:
                    return response

    except Event.DoesNotExist:
        raise Http404(_('The selected event was not found.'))
    except Organizer.DoesNotExist:
        raise Http404(_('The selected organizer was not found.'))
Beispiel #2
0
    def process_request(self, request):
        url = resolve(request.path_info)
        url_namespace = url.namespace
        if url_namespace != 'presale':
            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') and 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.'))

        if '_' not in request.session:
            # We need to create session even if we do not yet store something there, because we need the session
            # key for e.g. saving the user's cart
            request.session['_'] = '_'
Beispiel #3
0
 def get_context_data(self, **kwargs):
     ctx = super().get_context_data(**kwargs)
     ctx['urlprefix'] = settings.SITE_URL
     domain = get_domain(self.request.organizer)
     if domain:
         siteurlsplit = urlsplit(settings.SITE_URL)
         if siteurlsplit.port and siteurlsplit.port not in (80, 443):
             domain = '%s:%d' % (domain, siteurlsplit.port)
         ctx['urlprefix'] = '%s://%s' % (siteurlsplit.scheme, domain)
     return ctx
Beispiel #4
0
 def static(path):
     sp = _static(path)
     if not settings.MEDIA_URL.startswith("/") and sp.startswith("/"):
         domain = get_domain(object.organizer if isinstance(object, Event) else object)
         if domain:
             siteurlsplit = urlsplit(settings.SITE_URL)
             if siteurlsplit.port and siteurlsplit.port not in (80, 443):
                 domain = '%s:%d' % (domain, siteurlsplit.port)
             sp = urljoin('%s://%s' % (siteurlsplit.scheme, domain), sp)
         else:
             sp = urljoin(settings.SITE_URL, sp)
     return '"{}"'.format(sp)
Beispiel #5
0
 def static(path):
     sp = _static(path)
     if not settings.MEDIA_URL.startswith("/") and sp.startswith("/"):
         domain = get_domain(object.organizer if isinstance(object, Event) else object)
         if domain:
             siteurlsplit = urlsplit(settings.SITE_URL)
             if siteurlsplit.port and siteurlsplit.port not in (80, 443):
                 domain = '%s:%d' % (domain, siteurlsplit.port)
             sp = urljoin('%s://%s' % (siteurlsplit.scheme, domain), sp)
         else:
             sp = urljoin(settings.SITE_URL, sp)
     return '"{}"'.format(sp)
Beispiel #6
0
    def process_response(self, request, resp):
        if settings.DEBUG and resp.status_code >= 400:
            # Don't use CSP on debug error page as it breaks of Django's fancy error
            # pages
            return resp

        resp['X-XSS-Protection'] = '1'
        h = {
            'default-src': ["{static}"],
            'script-src': ['{static}', 'https://checkout.stripe.com', 'https://js.stripe.com'],
            'object-src': ["'none'"],
            # frame-src is deprecated but kept for compatibility with CSP 1.0 browsers, e.g. Safari 9
            'frame-src': ['{static}', 'https://checkout.stripe.com', 'https://js.stripe.com'],
            'child-src': ['{static}', 'https://checkout.stripe.com', 'https://js.stripe.com'],
            'style-src': ["{static}"],
            'connect-src': ["{dynamic}", "https://checkout.stripe.com"],
            'img-src': ["{static}", "data:", "https://*.stripe.com"],
            # form-action is not only used to match on form actions, but also on URLs
            # form-actions redirect to. In the context of e.g. payment providers or
            # single-sign-on this can be nearly anything so we cannot really restrict
            # this. However, we'll restrict it to HTTPS.
            'form-action': ["{dynamic}", "https:"],
        }
        if 'Content-Security-Policy' in resp:
            _merge_csp(h, _parse_csp(resp['Content-Security-Policy']))

        staticdomain = "'self'"
        dynamicdomain = "'self'"
        if settings.STATIC_URL.startswith('http'):
            staticdomain += " " + settings.STATIC_URL[:settings.STATIC_URL.find('/', 9)]
        if settings.SITE_URL.startswith('http'):
            if settings.SITE_URL.find('/', 9) > 0:
                staticdomain += " " + settings.SITE_URL[:settings.SITE_URL.find('/', 9)]
                dynamicdomain += " " + settings.SITE_URL[:settings.SITE_URL.find('/', 9)]
            else:
                staticdomain += " " + settings.SITE_URL
                dynamicdomain += " " + settings.SITE_URL
        if hasattr(request, 'organizer') and request.organizer:
            domain = get_domain(request.organizer)
            if domain:
                siteurlsplit = urlsplit(settings.SITE_URL)
                if siteurlsplit.port and siteurlsplit.port not in (80, 443):
                    domain = '%s:%d' % (domain, siteurlsplit.port)
                dynamicdomain += " " + domain

        resp['Content-Security-Policy'] = _render_csp(h).format(static=staticdomain, dynamic=dynamicdomain)
        return resp
Beispiel #7
0
    def process_response(self, request, resp):
        if settings.DEBUG and resp.status_code >= 400:
            # Don't use CSP on debug error page as it breaks of Django's fancy error
            # pages
            return resp

        resp['X-XSS-Protection'] = '1'

        # We just need to have a P3P, not matter whats in there
        # https://blogs.msdn.microsoft.com/ieinternals/2013/09/17/a-quick-look-at-p3p/
        # https://github.com/pretix/pretix/issues/765
        resp['P3P'] = 'CP=\"ALL DSP COR CUR ADM TAI OUR IND COM NAV INT\"'

        h = {
            'default-src': ["{static}"],
            'script-src': ['{static}', 'https://checkout.stripe.com', 'https://js.stripe.com'],
            'object-src': ["'none'"],
            # frame-src is deprecated but kept for compatibility with CSP 1.0 browsers, e.g. Safari 9
            'frame-src': ['{static}', 'https://checkout.stripe.com', 'https://js.stripe.com'],
            'child-src': ['{static}', 'https://checkout.stripe.com', 'https://js.stripe.com'],
            'style-src': ["{static}", "{media}"],
            'connect-src': ["{dynamic}", "{media}", "https://checkout.stripe.com"],
            'img-src': ["{static}", "{media}", "data:", "https://*.stripe.com"],
            'font-src': ["{static}"],
            'media-src': ["{static}", "data:"],
            # form-action is not only used to match on form actions, but also on URLs
            # form-actions redirect to. In the context of e.g. payment providers or
            # single-sign-on this can be nearly anything so we cannot really restrict
            # this. However, we'll restrict it to HTTPS.
            'form-action': ["{dynamic}", "https:"] + (['http:'] if settings.SITE_URL.startswith('http://') else []),
            'report-uri': ["/csp_report/"],
        }
        if 'Content-Security-Policy' in resp:
            _merge_csp(h, _parse_csp(resp['Content-Security-Policy']))

        staticdomain = "'self'"
        dynamicdomain = "'self'"
        mediadomain = "'self'"
        if settings.MEDIA_URL.startswith('http'):
            mediadomain += " " + settings.MEDIA_URL[:settings.MEDIA_URL.find('/', 9)]
        if settings.STATIC_URL.startswith('http'):
            staticdomain += " " + settings.STATIC_URL[:settings.STATIC_URL.find('/', 9)]
        if settings.SITE_URL.startswith('http'):
            if settings.SITE_URL.find('/', 9) > 0:
                staticdomain += " " + settings.SITE_URL[:settings.SITE_URL.find('/', 9)]
                dynamicdomain += " " + settings.SITE_URL[:settings.SITE_URL.find('/', 9)]
            else:
                staticdomain += " " + settings.SITE_URL
                dynamicdomain += " " + settings.SITE_URL

        if hasattr(request, 'organizer') and request.organizer:
            domain = get_domain(request.organizer)
            if domain:
                siteurlsplit = urlsplit(settings.SITE_URL)
                if siteurlsplit.port and siteurlsplit.port not in (80, 443):
                    domain = '%s:%d' % (domain, siteurlsplit.port)
                dynamicdomain += " " + domain

        if request.path not in self.CSP_EXEMPT and not getattr(resp, '_csp_ignore', False):
            resp['Content-Security-Policy'] = _render_csp(h).format(static=staticdomain, dynamic=dynamicdomain,
                                                                    media=mediadomain)
            for k, v in h.items():
                h[k] = ' '.join(v).format(static=staticdomain, dynamic=dynamicdomain, media=mediadomain).split(' ')
            resp['Content-Security-Policy'] = _render_csp(h)
        elif 'Content-Security-Policy' in resp:
            del resp['Content-Security-Policy']

        return resp
Beispiel #8
0
def _detect_event(request, require_live=True):
    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 = request.organizer.events\
                .get(
                    slug=url.kwargs['event'],
                    organizer=request.organizer,
                )
            request.organizer = request.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 require_live and not request.event.live:
                can_access = (
                    url.url_name == 'event.auth'
                    or (request.user.is_authenticated
                        and EventPermission.objects.filter(
                            event=request.event, user=request.user).exists()))
                if not can_access and 'pretix_event_access_{}'.format(
                        request.event.pk) in request.session:
                    sparent = SessionStore(
                        request.session.get('pretix_event_access_{}'.format(
                            request.event.pk)))
                    try:
                        parentdata = sparent.load()
                    except:
                        pass
                    else:
                        can_access = 'event_access' in parentdata

                if not can_access:
                    raise PermissionDenied(
                        _('The selected ticket shop is currently not available.'
                          ))

            for receiver, response in process_request.send(request.event,
                                                           request=request):
                if response:
                    return response

    except Event.DoesNotExist:
        raise Http404(_('The selected event was not found.'))
    except Organizer.DoesNotExist:
        raise Http404(_('The selected organizer was not found.'))
Beispiel #9
0
def get_domain_for_event(event):
    domain = get_domain(event.organizer)
    if not domain:
        siteurlsplit = urlsplit(settings.SITE_URL)
        return siteurlsplit.hostname
    return domain
Beispiel #10
0
def _detect_event(request, require_live=True, require_plugin=None):
    if hasattr(request, '_event_detected'):
        return

    url = resolve(request.path_info)
    try:
        if hasattr(request, 'organizer_domain'):
            # 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 = request.organizer.events\
                .get(
                    slug=url.kwargs['event'],
                    organizer=request.organizer,
                )
            request.organizer = request.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 require_live and not request.event.live:
                can_access = (
                    url.url_name == 'event.auth'
                    or (
                        request.user.is_authenticated
                        and request.user.has_event_permission(request.organizer, request.event, request=request)
                    )

                )
                if not can_access and 'pretix_event_access_{}'.format(request.event.pk) in request.session:
                    sparent = SessionStore(request.session.get('pretix_event_access_{}'.format(request.event.pk)))
                    try:
                        parentdata = sparent.load()
                    except:
                        pass
                    else:
                        can_access = 'event_access' in parentdata

                if not can_access:
                    raise PermissionDenied(_('The selected ticket shop is currently not available.'))

            if require_plugin:
                is_core = any(require_plugin.startswith(m) for m in settings.CORE_MODULES)
                if require_plugin not in request.event.get_plugins() and not is_core:
                    raise Http404(_('This feature is not enabled.'))

            if not hasattr(request, 'sales_channel'):
                # The environ lookup is only relevant during unit testing
                request.sales_channel = request.environ.get('PRETIX_SALES_CHANNEL', 'web')
            for receiver, response in process_request.send(request.event, request=request):
                if response:
                    return response

    except Event.DoesNotExist:
        try:
            if hasattr(request, 'organizer_domain'):
                event = request.organizer.events.get(
                    slug__iexact=url.kwargs['event'],
                    organizer=request.organizer,
                )
                pathparts = request.get_full_path().split('/')
                pathparts[1] = event.slug
                return redirect('/'.join(pathparts))
            else:
                if 'event' in url.kwargs and 'organizer' in url.kwargs:
                    event = Event.objects.select_related('organizer').get(
                        slug__iexact=url.kwargs['event'],
                        organizer__slug__iexact=url.kwargs['organizer']
                    )
                    pathparts = request.get_full_path().split('/')
                    pathparts[1] = event.organizer.slug
                    pathparts[2] = event.slug
                    return redirect('/'.join(pathparts))
        except Event.DoesNotExist:
            raise Http404(_('The selected event was not found.'))
        raise Http404(_('The selected event was not found.'))
    except Organizer.DoesNotExist:
        if 'organizer' in url.kwargs:
            try:
                organizer = Organizer.objects.get(
                    slug__iexact=url.kwargs['organizer']
                )
            except Organizer.DoesNotExist:
                raise Http404(_('The selected organizer was not found.'))
            pathparts = request.get_full_path().split('/')
            pathparts[1] = organizer.slug
            return redirect('/'.join(pathparts))
        raise Http404(_('The selected organizer was not found.'))

    request._event_detected = True
Beispiel #11
0
def get_domain_for_event(event):
    domain = get_domain(event.organizer)
    if not domain:
        siteurlsplit = urlsplit(settings.SITE_URL)
        return siteurlsplit.hostname
    return domain
Beispiel #12
0
def _detect_event(request, require_live=True, require_plugin=None):
    if hasattr(request, '_event_detected'):
        return

    db = 'default'
    if request.method == 'GET':
        db = settings.DATABASE_REPLICA

    url = resolve(request.path_info)
    try:
        if hasattr(request, 'organizer_domain'):
            # 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 = request.organizer.events.using(db).get(
                slug=url.kwargs['event'],
                organizer=request.organizer,
            )
            request.organizer = request.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')\
                    .using(db)\
                    .get(
                        slug=url.kwargs['event'],
                        organizer__slug=url.kwargs['organizer']
                    )
                request.organizer = request.event.organizer
            elif 'organizer' in url.kwargs:
                request.organizer = Organizer.objects.using(db).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]
                r = redirect(
                    urljoin('%s://%s' % (request.scheme, domain), path))
                r['Access-Control-Allow-Origin'] = '*'
                return r

        if hasattr(request, 'event'):
            # Restrict locales to the ones available for this event
            LocaleMiddleware().process_request(request)

            if require_live and not request.event.live:
                can_access = (
                    url.url_name == 'event.auth' or
                    (request.user.is_authenticated
                     and request.user.has_event_permission(
                         request.organizer, request.event, request=request)))
                if not can_access and 'pretix_event_access_{}'.format(
                        request.event.pk) in request.session:
                    sparent = SessionStore(
                        request.session.get('pretix_event_access_{}'.format(
                            request.event.pk)))
                    try:
                        parentdata = sparent.load()
                    except:
                        pass
                    else:
                        can_access = 'event_access' in parentdata

                if not can_access:
                    raise PermissionDenied(
                        _('The selected ticket shop is currently not available.'
                          ))

            if require_plugin:
                is_core = any(
                    require_plugin.startswith(m)
                    for m in settings.CORE_MODULES)
                if require_plugin not in request.event.get_plugins(
                ) and not is_core:
                    raise Http404(_('This feature is not enabled.'))

            if not hasattr(request, 'sales_channel'):
                # The environ lookup is only relevant during unit testing
                request.sales_channel = request.environ.get(
                    'PRETIX_SALES_CHANNEL', 'web')
            for receiver, response in process_request.send(request.event,
                                                           request=request):
                if response:
                    return response

    except Event.DoesNotExist:
        try:
            if hasattr(request, 'organizer_domain'):
                event = request.organizer.events.get(
                    slug__iexact=url.kwargs['event'],
                    organizer=request.organizer,
                )
                pathparts = request.get_full_path().split('/')
                pathparts[1] = event.slug
                return redirect('/'.join(pathparts))
            else:
                if 'event' in url.kwargs and 'organizer' in url.kwargs:
                    event = Event.objects.select_related('organizer').get(
                        slug__iexact=url.kwargs['event'],
                        organizer__slug__iexact=url.kwargs['organizer'])
                    pathparts = request.get_full_path().split('/')
                    pathparts[1] = event.organizer.slug
                    pathparts[2] = event.slug
                    return redirect('/'.join(pathparts))
        except Event.DoesNotExist:
            raise Http404(_('The selected event was not found.'))
        raise Http404(_('The selected event was not found.'))
    except Organizer.DoesNotExist:
        if 'organizer' in url.kwargs:
            try:
                organizer = Organizer.objects.get(
                    slug__iexact=url.kwargs['organizer'])
            except Organizer.DoesNotExist:
                raise Http404(_('The selected organizer was not found.'))
            pathparts = request.get_full_path().split('/')
            pathparts[1] = organizer.slug
            return redirect('/'.join(pathparts))
        raise Http404(_('The selected organizer was not found.'))

    request._event_detected = True