forked from CGM_Public/pretix_original
New handling of plugin URLs (#609)
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
from django.apps import AppConfig
|
||||
from django.urls import RegexURLPattern
|
||||
|
||||
|
||||
class PretixMultidomainConfig(AppConfig):
|
||||
@@ -7,3 +8,12 @@ class PretixMultidomainConfig(AppConfig):
|
||||
|
||||
|
||||
default_app_config = 'pretix.multidomain.PretixMultidomainConfig'
|
||||
|
||||
|
||||
def event_url(regex, view, kwargs=None, name=None, require_live=True):
|
||||
if callable(view):
|
||||
r = RegexURLPattern(regex, view, kwargs, name)
|
||||
r._require_live = require_live
|
||||
return r
|
||||
else:
|
||||
raise TypeError('view must be a callable.')
|
||||
|
||||
@@ -5,6 +5,7 @@ from django.apps import apps
|
||||
from django.conf.urls import include, url
|
||||
from django.views.generic import TemplateView
|
||||
|
||||
from pretix.multidomain.plugin_handler import plugin_event_urls
|
||||
from pretix.presale.urls import (
|
||||
event_patterns, locale_patterns, organizer_patterns,
|
||||
)
|
||||
@@ -27,8 +28,9 @@ for app in apps.get_app_configs():
|
||||
if hasattr(urlmod, 'urlpatterns'):
|
||||
single_plugin_patterns += urlmod.urlpatterns
|
||||
if hasattr(urlmod, 'event_patterns'):
|
||||
patterns = plugin_event_urls(urlmod.event_patterns, plugin=app.name)
|
||||
single_plugin_patterns.append(url(r'^(?P<organizer>[^/]+)/(?P<event>[^/]+)/',
|
||||
include(urlmod.event_patterns)))
|
||||
include(patterns)))
|
||||
raw_plugin_patterns.append(
|
||||
url(r'', include((single_plugin_patterns, app.label)))
|
||||
)
|
||||
|
||||
@@ -50,6 +50,7 @@ class MultiDomainMiddleware(MiddlewareMixin):
|
||||
cache.set('pretix_multidomain_organizer_{}'.format(domain), orga.pk if orga else False, 3600)
|
||||
|
||||
if orga:
|
||||
request.organizer_domain = True
|
||||
request.organizer = orga if isinstance(orga, Organizer) else Organizer.objects.get(pk=orga)
|
||||
request.urlconf = "pretix.multidomain.subdomain_urlconf"
|
||||
else:
|
||||
|
||||
11
src/pretix/multidomain/plugin_handler.py
Normal file
11
src/pretix/multidomain/plugin_handler.py
Normal file
@@ -0,0 +1,11 @@
|
||||
from pretix.presale.utils import _event_view
|
||||
|
||||
|
||||
def plugin_event_urls(urllist, plugin):
|
||||
for entry in urllist:
|
||||
if hasattr(entry, 'url_patterns'):
|
||||
plugin_event_urls(entry.url_patterns, plugin)
|
||||
elif hasattr(entry, 'callback'):
|
||||
entry.callback = _event_view(entry.callback, require_plugin=plugin,
|
||||
require_live=getattr(entry, '_require_live', True))
|
||||
return urllist
|
||||
@@ -4,6 +4,7 @@ import warnings
|
||||
from django.apps import apps
|
||||
from django.conf.urls import include, url
|
||||
|
||||
from pretix.multidomain.plugin_handler import plugin_event_urls
|
||||
from pretix.presale.urls import (
|
||||
event_patterns, locale_patterns, organizer_patterns,
|
||||
)
|
||||
@@ -22,9 +23,11 @@ for app in apps.get_app_configs():
|
||||
if importlib.util.find_spec(app.name + '.urls'):
|
||||
urlmod = importlib.import_module(app.name + '.urls')
|
||||
if hasattr(urlmod, 'event_patterns'):
|
||||
patterns = plugin_event_urls(urlmod.event_patterns, plugin=app.name)
|
||||
raw_plugin_patterns.append(
|
||||
url(r'^(?P<event>[^/]+)/', include((urlmod.event_patterns, app.label)))
|
||||
url(r'^(?P<event>[^/]+)/', include((patterns, app.label)))
|
||||
)
|
||||
|
||||
elif importlib.util.find_spec(app.name + '.subdomain_urls'): # noqa
|
||||
warnings.warn('Please put your config in an \'urls\' module using the event_patterns '
|
||||
'attribute. Support for subdomain_urls in plugins will be dropped in the future.',
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
from django.conf.urls import include, url
|
||||
|
||||
from .views import abort, event_webbook, refund, success, webhook
|
||||
from pretix.multidomain import event_url
|
||||
|
||||
from .views import abort, refund, success, webhook
|
||||
|
||||
event_patterns = [
|
||||
url(r'^paypal/', include([
|
||||
url(r'^abort/$', abort, name='abort'),
|
||||
url(r'^return/$', success, name='return'),
|
||||
url(r'^webhook/$', event_webbook, name='webhook'),
|
||||
event_url(r'^webhook/$', webhook, name='webhook', require_live=False),
|
||||
])),
|
||||
]
|
||||
|
||||
|
||||
@@ -55,7 +55,6 @@ def success(request, *args, **kwargs):
|
||||
return redirect(eventreverse(request.event, 'presale:event.checkout', kwargs={'step': 'confirm'}))
|
||||
|
||||
|
||||
@event_view(require_live=False)
|
||||
def abort(request, *args, **kwargs):
|
||||
messages.error(request, _('It looks like you canceled the PayPal payment'))
|
||||
|
||||
@@ -151,9 +150,6 @@ def webhook(request, *args, **kwargs):
|
||||
return HttpResponse(status=200)
|
||||
|
||||
|
||||
event_webbook = csrf_exempt(event_view(require_live=False)(webhook))
|
||||
|
||||
|
||||
@event_permission_required('can_view_orders')
|
||||
@require_POST
|
||||
def refund(request, **kwargs):
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
from django.conf.urls import include, url
|
||||
|
||||
from .views import ReturnView, event_webbook, refund, webhook
|
||||
from pretix.multidomain import event_url
|
||||
|
||||
from .views import ReturnView, refund, webhook
|
||||
|
||||
event_patterns = [
|
||||
url(r'^stripe/', include([
|
||||
url(r'^webhook/$', event_webbook, name='webhook'),
|
||||
event_url(r'^webhook/$', webhook, name='webhook', require_live=False),
|
||||
url(r'^return/(?P<order>[^/]+)/(?P<hash>[^/]+)/$', ReturnView.as_view(), name='return'),
|
||||
])),
|
||||
]
|
||||
|
||||
@@ -8,7 +8,6 @@ from django.db import transaction
|
||||
from django.http import Http404, HttpResponse
|
||||
from django.shortcuts import get_object_or_404, redirect
|
||||
from django.urls import reverse
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.views import View
|
||||
@@ -22,7 +21,6 @@ from pretix.control.permissions import event_permission_required
|
||||
from pretix.multidomain.urlreverse import eventreverse
|
||||
from pretix.plugins.stripe.models import ReferencedStripeObject
|
||||
from pretix.plugins.stripe.payment import StripeCC
|
||||
from pretix.presale.utils import event_view
|
||||
|
||||
logger = logging.getLogger('pretix.plugins.stripe')
|
||||
|
||||
@@ -59,9 +57,6 @@ def webhook(request, *args, **kwargs):
|
||||
return HttpResponse("Unable to detect event", status=200)
|
||||
|
||||
|
||||
event_webbook = csrf_exempt(event_view(require_live=False)(webhook))
|
||||
|
||||
|
||||
def charge_webhook(event, event_json, charge_id):
|
||||
prov = StripeCC(event)
|
||||
prov._init_api()
|
||||
@@ -198,7 +193,6 @@ class StripeOrderView:
|
||||
return self.request.event.get_payment_providers()[self.order.payment_provider]
|
||||
|
||||
|
||||
@method_decorator(event_view, name='dispatch')
|
||||
class ReturnView(StripeOrderView, View):
|
||||
def get(self, request, *args, **kwargs):
|
||||
prov = self.pprov
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import warnings
|
||||
from importlib import import_module
|
||||
from urllib.parse import urljoin
|
||||
|
||||
@@ -16,10 +17,13 @@ from pretix.presale.signals import process_request, process_response
|
||||
SessionStore = import_module(settings.SESSION_ENGINE).SessionStore
|
||||
|
||||
|
||||
def _detect_event(request, require_live=True):
|
||||
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'):
|
||||
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:
|
||||
@@ -83,6 +87,10 @@ def _detect_event(request, require_live=True):
|
||||
if not can_access:
|
||||
raise PermissionDenied(_('The selected ticket shop is currently not available.'))
|
||||
|
||||
if require_plugin:
|
||||
if require_plugin not in request.event.get_plugins():
|
||||
raise Http404(_('This feature is not enabled.'))
|
||||
|
||||
for receiver, response in process_request.send(request.event, request=request):
|
||||
if response:
|
||||
return response
|
||||
@@ -92,11 +100,13 @@ def _detect_event(request, require_live=True):
|
||||
except Organizer.DoesNotExist:
|
||||
raise Http404(_('The selected organizer was not found.'))
|
||||
|
||||
request._event_detected = True
|
||||
|
||||
def event_view(function=None, require_live=True):
|
||||
|
||||
def _event_view(function=None, require_live=True, require_plugin=None):
|
||||
def event_view_wrapper(func, require_live=require_live):
|
||||
def wrap(request, *args, **kwargs):
|
||||
ret = _detect_event(request, require_live=require_live)
|
||||
ret = _detect_event(request, require_live=require_live, require_plugin=require_plugin)
|
||||
if ret:
|
||||
return ret
|
||||
else:
|
||||
@@ -104,8 +114,24 @@ def event_view(function=None, require_live=True):
|
||||
for receiver, r in process_response.send(request.event, request=request, response=response):
|
||||
response = r
|
||||
return response
|
||||
|
||||
for attrname in dir(func):
|
||||
# Preserve flags like csrf_exempt
|
||||
if not attrname.startswith('__'):
|
||||
setattr(wrap, attrname, getattr(func, attrname))
|
||||
return wrap
|
||||
|
||||
if function:
|
||||
return event_view_wrapper(function, require_live=require_live)
|
||||
return event_view_wrapper
|
||||
|
||||
|
||||
def event_view(function=None, require_live=True):
|
||||
warnings.warn('The event_view decorator is deprecated since it will be automatically applied by the URL routing '
|
||||
'layer when you use event_urls.',
|
||||
DeprecationWarning)
|
||||
|
||||
def noop(fn):
|
||||
return fn
|
||||
|
||||
return function or noop
|
||||
|
||||
@@ -16,7 +16,7 @@ def env():
|
||||
user = User.objects.create_user('dummy@dummy.dummy', 'dummy')
|
||||
o = Organizer.objects.create(name='Dummy', slug='dummy')
|
||||
event = Event.objects.create(
|
||||
organizer=o, name='Dummy', slug='dummy',
|
||||
organizer=o, name='Dummy', slug='dummy', plugins='pretix.plugins.paypal',
|
||||
date_from=now(), live=True
|
||||
)
|
||||
t = Team.objects.create(organizer=event.organizer, can_view_orders=True, can_change_orders=True)
|
||||
|
||||
@@ -16,7 +16,7 @@ def env():
|
||||
user = User.objects.create_user('dummy@dummy.dummy', 'dummy')
|
||||
o = Organizer.objects.create(name='Dummy', slug='dummy')
|
||||
event = Event.objects.create(
|
||||
organizer=o, name='Dummy', slug='dummy',
|
||||
organizer=o, name='Dummy', slug='dummy', plugins='pretix.plugins.stripe',
|
||||
date_from=now(), live=True
|
||||
)
|
||||
t = Team.objects.create(organizer=event.organizer, can_view_orders=True, can_change_orders=True)
|
||||
|
||||
Reference in New Issue
Block a user