Splitted URL configuration for main and subdomains

This commit is contained in:
Raphael Michel
2015-10-21 18:16:17 +02:00
parent 5e5292f2c4
commit 0b4cae07c4
8 changed files with 73 additions and 29 deletions

View File

@@ -3,7 +3,6 @@ from collections import OrderedDict
import pytz import pytz
from django.conf import settings from django.conf import settings
from django.core.urlresolvers import get_script_prefix from django.core.urlresolvers import get_script_prefix
from django.middleware.locale import LocaleMiddleware as BaseLocaleMiddleware
from django.utils import timezone, translation from django.utils import timezone, translation
from django.utils.cache import patch_vary_headers from django.utils.cache import patch_vary_headers
from django.utils.translation import LANGUAGE_SESSION_KEY from django.utils.translation import LANGUAGE_SESSION_KEY
@@ -15,7 +14,7 @@ from django.utils.translation.trans_real import (
_supported = None _supported = None
class LocaleMiddleware(BaseLocaleMiddleware): class LocaleMiddleware:
""" """
This middleware sets the correct locale and timezone This middleware sets the correct locale and timezone

View File

@@ -0,0 +1,13 @@
from django.conf.urls import include, url
from pretix.presale.urls import event_patterns, locale_patterns
from pretix.urls import common_patterns
presale_patterns_main = [
url(r'', include(locale_patterns + [
url(r'^(?P<organizer>[^/]+)/(?P<event>[^/]+)/', include(event_patterns))
], namespace='presale'))
]
# The presale namespace comes last, because it contains a wildcard catch
urlpatterns = common_patterns + presale_patterns_main

View File

@@ -5,6 +5,7 @@ from django.conf import settings
from django.contrib.sessions.middleware import \ from django.contrib.sessions.middleware import \
SessionMiddleware as BaseSessionMiddleware SessionMiddleware as BaseSessionMiddleware
from django.core.exceptions import DisallowedHost from django.core.exceptions import DisallowedHost
from django.core.urlresolvers import set_urlconf
from django.http.request import split_domain_port from django.http.request import split_domain_port
from django.middleware.csrf import CsrfViewMiddleware as BaseCsrfMiddleware from django.middleware.csrf import CsrfViewMiddleware as BaseCsrfMiddleware
from django.utils.cache import patch_vary_headers from django.utils.cache import patch_vary_headers
@@ -37,13 +38,24 @@ class MultiDomainMiddleware:
request.domain = kd request.domain = kd
except: except:
if settings.DEBUG or domain in ('testserver', 'localhost') or domain == default_domain: if settings.DEBUG or domain in ('testserver', 'localhost') or domain == default_domain:
return # TODO: Select main page request.urlconf = "pretix.multidomain.maindomain_urlconf"
raise DisallowedHost("Unknown host: %r" % host) else:
raise DisallowedHost("Unknown host: %r" % host)
else: else:
request.organizer = kd.organizer request.organizer = kd.organizer
request.urlconf = "pretix.multidomain.subdomain_urlconf"
else: else:
raise DisallowedHost("Invalid HTTP_HOST header: %r." % host) raise DisallowedHost("Invalid HTTP_HOST header: %r." % host)
# We need to manually set the urlconf for the whole thread. Normally, Django's basic request
# would do this for us, but we already need it in place for the other middlewares.
set_urlconf(request.urlconf)
def process_response(self, request, response):
if getattr(request, "urlconf", None):
patch_vary_headers(response, ('Host',))
return response
class SessionMiddleware(BaseSessionMiddleware): class SessionMiddleware(BaseSessionMiddleware):
def process_response(self, request, response): def process_response(self, request, response):

View File

@@ -0,0 +1,14 @@
from django.conf.urls import include, url
from pretix.presale.urls import event_patterns, locale_patterns
from pretix.urls import common_patterns
print(event_patterns)
presale_patterns = [
url(r'', include(locale_patterns + [
url(r'^(?P<event>[^/]+)/', include(event_patterns))
], namespace='presale'))
]
# The presale namespace comes last, because it contains a wildcard catch
urlpatterns = common_patterns + presale_patterns

View File

@@ -21,20 +21,23 @@ def eventreverse(event, name, kwargs=None):
Works similar to django.core.urlresolvers.reverse but takes into account that some Works similar to django.core.urlresolvers.reverse but takes into account that some
organizers might have their own (sub)domain instead of a subpath. organizers might have their own (sub)domain instead of a subpath.
""" """
from pretix.multidomain import subdomain_urlconf, maindomain_urlconf
kwargs = kwargs or {} kwargs = kwargs or {}
kwargs['event'] = event.slug kwargs['event'] = event.slug
domain = get_domain(event) domain = get_domain(event)
if domain: if domain:
if 'organizer' in kwargs: if 'organizer' in kwargs:
del kwargs['organizer'] del kwargs['organizer']
path = reverse(name, kwargs=kwargs)
path = reverse(name, kwargs=kwargs, urlconf=subdomain_urlconf)
siteurlsplit = urlsplit(settings.SITE_URL) siteurlsplit = urlsplit(settings.SITE_URL)
if siteurlsplit.port and siteurlsplit.port not in (80, 443): if siteurlsplit.port and siteurlsplit.port not in (80, 443):
domain = '%s:%d' % (domain, siteurlsplit.port) domain = '%s:%d' % (domain, siteurlsplit.port)
return urljoin('%s://%s' % (siteurlsplit.scheme, domain), path) return urljoin('%s://%s' % (siteurlsplit.scheme, domain), path)
kwargs['organizer'] = event.organizer.slug kwargs['organizer'] = event.organizer.slug
return reverse(name, kwargs=kwargs) return reverse(name, kwargs=kwargs, urlconf=maindomain_urlconf)
def build_absolute_uri(event, urlname, kwargs=None): def build_absolute_uri(event, urlname, kwargs=None):

View File

@@ -6,7 +6,10 @@ import pretix.presale.views.event
import pretix.presale.views.locale import pretix.presale.views.locale
import pretix.presale.views.order import pretix.presale.views.order
eventurls = [ # This is not a valid Django URL configuration, as the final
# configuration is done by the pretix.multidomain package.
event_patterns = [
url(r'^cart/add$', pretix.presale.views.cart.CartAdd.as_view(), name='event.cart.add'), url(r'^cart/add$', pretix.presale.views.cart.CartAdd.as_view(), name='event.cart.add'),
url(r'^cart/remove$', pretix.presale.views.cart.CartRemove.as_view(), name='event.cart.remove'), url(r'^cart/remove$', pretix.presale.views.cart.CartRemove.as_view(), name='event.cart.remove'),
url(r'^checkout/start$', pretix.presale.views.checkout.CheckoutView.as_view(), name='event.checkout.start'), url(r'^checkout/start$', pretix.presale.views.checkout.CheckoutView.as_view(), name='event.checkout.start'),
@@ -34,8 +37,6 @@ eventurls = [
url(r'^$', pretix.presale.views.event.EventIndex.as_view(), name='event.index'), url(r'^$', pretix.presale.views.event.EventIndex.as_view(), name='event.index'),
] ]
urlpatterns = [ locale_patterns = [
url(r'^locale/set$', pretix.presale.views.locale.LocaleSet.as_view(), name='locale.set'), url(r'^locale/set$', pretix.presale.views.locale.LocaleSet.as_view(), name='locale.set'),
url(r'^(?P<event>[^/]+)/', include(eventurls)),
url(r'^(?P<organizer>[^/]+)/(?P<event>[^/]+)/', include(eventurls)),
] ]

View File

@@ -9,33 +9,35 @@ import pretix.base.views.cachedfiles
import pretix.control.urls import pretix.control.urls
import pretix.presale.urls import pretix.presale.urls
urlpatterns = [ # This is not a valid Django URL configuration, as the final
# configuration is done by the pretix.multidomain package.
base_patterns = [
url(r'^download/(?P<id>[^/]+)/$', pretix.base.views.cachedfiles.DownloadView.as_view(), url(r'^download/(?P<id>[^/]+)/$', pretix.base.views.cachedfiles.DownloadView.as_view(),
name='cachedfile.download'), name='cachedfile.download')
url(r'^control/', include(pretix.control.urls, namespace='control')),
# The pretixpresale namespace is configured at the bottom of this file, because it
# contains a wildcard-style URL which has to be configured _after_ debug settings.
] ]
control_patterns = [
url(r'^control/', include(pretix.control.urls, namespace='control')),
]
debug_patterns = []
if settings.DEBUG: if settings.DEBUG:
import debug_toolbar import debug_toolbar
urlpatterns.append(
url(r'^__debug__/', include(debug_toolbar.urls)),
)
pluginpatterns = [] debug_patterns.append(url(r'^__debug__/', include(debug_toolbar.urls)))
raw_plugin_patterns = []
for app in apps.get_app_configs(): for app in apps.get_app_configs():
if hasattr(app, 'PretixPluginMeta'): if hasattr(app, 'PretixPluginMeta'):
if importlib.util.find_spec(app.name + '.urls'): if importlib.util.find_spec(app.name + '.urls'):
urlmod = importlib.import_module(app.name + '.urls') urlmod = importlib.import_module(app.name + '.urls')
pluginpatterns.append( raw_plugin_patterns.append(
url(r'', include(urlmod, namespace=app.label)) url(r'', include(urlmod, namespace=app.label))
) )
urlpatterns.append( plugin_patterns = [
url(r'', include(pluginpatterns, namespace='plugins')) url(r'', include(raw_plugin_patterns, namespace='plugins'))
) ]
urlpatterns.append( common_patterns = base_patterns + control_patterns + debug_patterns + plugin_patterns
url(r'', include(pretix.presale.urls, namespace='presale'))
)

View File

@@ -1,6 +1,6 @@
import pytest import pytest
from django.conf import settings from django.conf import settings
from django.template import Context, Template from django.http import Http404
from django.utils.timezone import now from django.utils.timezone import now
from pretix.base.models import Event, Organizer from pretix.base.models import Event, Organizer
@@ -55,8 +55,8 @@ def test_event_on_custom_domain_only_with_wrong_organizer(env, client):
date_from=now() date_from=now()
) )
KnownDomain.objects.create(domainname='foobar', organizer=env[0]) KnownDomain.objects.create(domainname='foobar', organizer=env[0])
r = client.get('/dummy/1234/', HTTP_HOST='foobar') with pytest.raises(Http404):
assert r.status_code == 404 client.get('/dummy/1234/', HTTP_HOST='foobar')
@pytest.mark.django_db @pytest.mark.django_db