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.'))
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['_'] = '_'
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
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)
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
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
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.'))
def get_domain_for_event(event): domain = get_domain(event.organizer) if not domain: siteurlsplit = urlsplit(settings.SITE_URL) return siteurlsplit.hostname return domain
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
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