Beispiel #1
0
 def static(path):
     sp = _static(path)
     if not settings.MEDIA_URL.startswith("/") and sp.startswith("/"):
         if isinstance(object, Event):
             domain = get_event_domain(object, fallback=True)
         else:
             domain = get_organizer_domain(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 #2
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, 'event_domain'):
            # We are on an event's custom domain
            pass
        elif 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

            # If this event has a custom domain, send the user there
            domain = get_event_domain(request.event)
            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
        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

                # If this event has a custom domain, send the user there
                domain = get_event_domain(request.event)
                if domain:
                    if request.port and request.port not in (80, 443):
                        domain = '%s:%d' % (domain, request.port)
                    path = request.get_full_path().split("/", 3)[-1]
                    r = redirect(
                        urljoin('%s://%s' % (request.scheme, domain), path))
                    r['Access-Control-Allow-Origin'] = '*'
                    return r
            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_organizer_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:
                    # Directly construct view instead of just calling `raise` since this case is so common that we
                    # don't want it to show in our log files.
                    return permission_denied(
                        request,
                        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.'))

            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 #3
0
def get_domain_for_event(event):
    domain = get_event_domain(event, fallback=True)
    if not domain:
        siteurlsplit = urlsplit(settings.SITE_URL)
        return siteurlsplit.hostname
    return domain
Beispiel #4
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\"'

        img_src = []
        gs = global_settings_object(request)
        if gs.settings.leaflet_tiles:
            img_src.append(
                gs.settings.leaflet_tiles[:gs.settings.leaflet_tiles.
                                          index("/", 10)].replace("{s}", "*"))

        h = {
            'default-src': ["{static}"],
            'script-src': [
                '{static}', 'https://checkout.stripe.com',
                'https://js.stripe.com'
            ],
            'object-src': ["'none'"],
            'frame-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"] + img_src,
            '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 []),
        }
        if settings.LOG_CSP:
            h['report-uri'] = ["/csp_report/"]
        if 'Content-Security-Policy' in resp:
            _merge_csp(h, _parse_csp(resp['Content-Security-Policy']))
        if settings.CSP_ADDITIONAL_HEADER:
            _merge_csp(h, _parse_csp(settings.CSP_ADDITIONAL_HEADER))

        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:
            if hasattr(request, 'event') and request.event:
                domain = get_event_domain(request.event, fallback=True)
            else:
                domain = get_organizer_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