Replace redirect() with redirect_to_url() if we don't need Django's resolution

This commit is contained in:
Raphael Michel
2023-12-08 15:38:25 +01:00
parent 2acf043872
commit 12a898476e
19 changed files with 134 additions and 111 deletions

View File

@@ -34,7 +34,7 @@ from django.core.exceptions import PermissionDenied, ValidationError
from django.core.files.uploadedfile import UploadedFile from django.core.files.uploadedfile import UploadedFile
from django.db import transaction from django.db import transaction
from django.http import HttpResponse, JsonResponse, QueryDict from django.http import HttpResponse, JsonResponse, QueryDict
from django.shortcuts import redirect, render from django.shortcuts import render
from django.test import RequestFactory from django.test import RequestFactory
from django.utils import timezone, translation from django.utils import timezone, translation
from django.utils.datastructures import MultiValueDict from django.utils.datastructures import MultiValueDict
@@ -47,6 +47,7 @@ from redis import ResponseError
from pretix.base.models import CachedFile, User from pretix.base.models import CachedFile, User
from pretix.base.services.tasks import ProfiledEventTask from pretix.base.services.tasks import ProfiledEventTask
from pretix.celery_app import app from pretix.celery_app import app
from pretix.helpers.http import redirect_to_url
logger = logging.getLogger('pretix.base.tasks') logger = logging.getLogger('pretix.base.tasks')
@@ -152,7 +153,7 @@ class AsyncMixin:
'redirect': self.get_success_url(value), 'redirect': self.get_success_url(value),
'message': str(self.get_success_message(value)) 'message': str(self.get_success_message(value))
}) })
return redirect(self.get_success_url(value)) return redirect_to_url(self.get_success_url(value))
def error(self, exception): def error(self, exception):
if isinstance(exception, PermissionDenied): if isinstance(exception, PermissionDenied):
@@ -165,7 +166,7 @@ class AsyncMixin:
'redirect': self.get_error_url(), 'redirect': self.get_error_url(),
'message': str(self.get_error_message(exception)) 'message': str(self.get_error_message(exception))
}) })
return redirect(self.get_error_url()) return redirect_to_url(self.get_error_url())
def get_error_message(self, exception): def get_error_message(self, exception):
if isinstance(exception, dict) and exception['exc_type'] in self.known_errortypes: if isinstance(exception, dict) and exception['exc_type'] in self.known_errortypes:
@@ -203,7 +204,7 @@ class AsyncAction(AsyncMixin):
return self.success(res.info) return self.success(res.info)
else: else:
return self.error(res.info) return self.error(res.info)
return redirect(self.get_check_url(res.id, False)) return redirect_to_url(self.get_check_url(res.id, False))
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
if 'async_id' in request.GET and settings.HAS_CELERY: if 'async_id' in request.GET and settings.HAS_CELERY:
@@ -375,7 +376,7 @@ class AsyncFormView(AsyncMixin, FormView):
return self.success(res.info) return self.success(res.info)
else: else:
return self.error(res.info) return self.error(res.info)
return redirect(self.get_check_url(res.id, False)) return redirect_to_url(self.get_check_url(res.id, False))
class AsyncPostView(AsyncMixin, View): class AsyncPostView(AsyncMixin, View):
@@ -478,4 +479,4 @@ class AsyncPostView(AsyncMixin, View):
return self.success(res.info) return self.success(res.info)
else: else:
return self.error(res.info) return self.error(res.info)
return redirect(self.get_check_url(res.id, False)) return redirect_to_url(self.get_check_url(res.id, False))

View File

@@ -37,7 +37,7 @@ from urllib.parse import quote, urljoin, urlparse
from django.conf import settings from django.conf import settings
from django.contrib.auth import REDIRECT_FIELD_NAME, logout from django.contrib.auth import REDIRECT_FIELD_NAME, logout
from django.http import Http404 from django.http import Http404
from django.shortcuts import get_object_or_404, redirect, resolve_url from django.shortcuts import get_object_or_404, resolve_url
from django.template.response import TemplateResponse from django.template.response import TemplateResponse
from django.urls import get_script_prefix, resolve, reverse from django.urls import get_script_prefix, resolve, reverse
from django.utils.encoding import force_str from django.utils.encoding import force_str
@@ -46,6 +46,7 @@ from django_scopes import scope
from pretix.base.models import Event, Organizer from pretix.base.models import Event, Organizer
from pretix.base.models.auth import SuperuserPermissionSet, User from pretix.base.models.auth import SuperuserPermissionSet, User
from pretix.helpers.http import redirect_to_url
from pretix.helpers.security import ( from pretix.helpers.security import (
SessionInvalid, SessionReauthRequired, assert_session_valid, SessionInvalid, SessionReauthRequired, assert_session_valid,
) )
@@ -118,7 +119,7 @@ class PermissionMiddleware:
if hasattr(request, 'organizer'): if hasattr(request, 'organizer'):
# If the user is on a organizer's subdomain, he should be redirected to pretix # If the user is on a organizer's subdomain, he should be redirected to pretix
return redirect(urljoin(settings.SITE_URL, request.get_full_path())) return redirect_to_url(urljoin(settings.SITE_URL, request.get_full_path()))
if url_name in self.EXCEPTIONS: if url_name in self.EXCEPTIONS:
return self.get_response(request) return self.get_response(request)
if not request.user.is_authenticated: if not request.user.is_authenticated:
@@ -132,14 +133,14 @@ class PermissionMiddleware:
return self._login_redirect(request) return self._login_redirect(request)
except SessionReauthRequired: except SessionReauthRequired:
if url_name not in ('user.reauth', 'auth.logout'): if url_name not in ('user.reauth', 'auth.logout'):
return redirect(reverse('control:user.reauth') + '?next=' + quote(request.get_full_path())) return redirect_to_url(reverse('control:user.reauth') + '?next=' + quote(request.get_full_path()))
if request.user.needs_password_change and url_name not in self.EXCEPTIONS_FORCED_PW_CHANGE: if request.user.needs_password_change and url_name not in self.EXCEPTIONS_FORCED_PW_CHANGE:
return redirect(reverse('control:user.settings') + '?next=' + quote(request.get_full_path())) return redirect_to_url(reverse('control:user.settings') + '?next=' + quote(request.get_full_path()))
if not request.user.require_2fa and settings.PRETIX_OBLIGATORY_2FA \ if not request.user.require_2fa and settings.PRETIX_OBLIGATORY_2FA \
and url_name not in self.EXCEPTIONS_2FA: and url_name not in self.EXCEPTIONS_2FA:
return redirect(reverse('control:user.settings.2fa')) return redirect_to_url(reverse('control:user.settings.2fa'))
if 'event' in url.kwargs and 'organizer' in url.kwargs: if 'event' in url.kwargs and 'organizer' in url.kwargs:
if url.kwargs['organizer'] == '-' and url.kwargs['event'] == '-': if url.kwargs['organizer'] == '-' and url.kwargs['event'] == '-':
@@ -152,7 +153,7 @@ class PermissionMiddleware:
k = dict(url.kwargs) k = dict(url.kwargs)
k['organizer'] = ev.organizer.slug k['organizer'] = ev.organizer.slug
k['event'] = ev.slug k['event'] = ev.slug
return redirect(reverse(url.view_name, kwargs=k, args=url.args)) return redirect_to_url(reverse(url.view_name, kwargs=k, args=url.args))
with scope(organizer=None): with scope(organizer=None):
request.event = Event.objects.filter( request.event = Event.objects.filter(
@@ -178,7 +179,7 @@ class PermissionMiddleware:
"have no permission to administrate it.")) "have no permission to administrate it."))
k = dict(url.kwargs) k = dict(url.kwargs)
k['organizer'] = org.slug k['organizer'] = org.slug
return redirect(reverse(url.view_name, kwargs=k, args=url.args)) return redirect_to_url(reverse(url.view_name, kwargs=k, args=url.args))
request.organizer = Organizer.objects.filter( request.organizer = Organizer.objects.filter(
slug=url.kwargs['organizer'], slug=url.kwargs['organizer'],

View File

@@ -35,10 +35,11 @@
from urllib.parse import quote from urllib.parse import quote
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django.shortcuts import redirect
from django.urls import reverse from django.urls import reverse
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from pretix.helpers.http import redirect_to_url
def current_url(request): def current_url(request):
if request.GET: if request.GET:
@@ -135,7 +136,7 @@ def administrator_permission_required():
raise PermissionDenied() raise PermissionDenied()
if not request.user.has_active_staff_session(request.session.session_key): if not request.user.has_active_staff_session(request.session.session_key):
if request.user.is_staff: if request.user.is_staff:
return redirect(reverse('control:user.sudo') + '?next=' + quote(current_url(request))) return redirect_to_url(reverse('control:user.sudo') + '?next=' + quote(current_url(request)))
raise PermissionDenied(_('You do not have permission to view this content.')) raise PermissionDenied(_('You do not have permission to view this content.'))
return function(request, *args, **kw) return function(request, *args, **kw)
return wrapper return wrapper

View File

@@ -87,8 +87,8 @@ def process_login(request, user, keep_logged_in):
auth_login(request, user) auth_login(request, user)
request.session['pretix_auth_login_time'] = int(time.time()) request.session['pretix_auth_login_time'] = int(time.time())
if next_url and url_has_allowed_host_and_scheme(next_url, allowed_hosts=None): if next_url and url_has_allowed_host_and_scheme(next_url, allowed_hosts=None):
return redirect(next_url) return redirect_to_url(next_url)
return redirect(reverse('control:index')) return redirect('control:index')
def login(request): def login(request):
@@ -149,7 +149,10 @@ def register(request):
raise PermissionDenied('Registration is disabled') raise PermissionDenied('Registration is disabled')
ctx = {} ctx = {}
if request.user.is_authenticated: if request.user.is_authenticated:
return redirect(request.GET.get("next", 'control:index')) next_url = request.GET.get("next") or reverse("control:index")
if next_url and url_has_allowed_host_and_scheme(next_url, allowed_hosts=None):
return redirect_to_url(next_url)
return redirect("control:index")
if request.method == 'POST': if request.method == 'POST':
form = RegistrationForm(data=request.POST) form = RegistrationForm(data=request.POST)
if form.is_valid(): if form.is_valid():
@@ -256,7 +259,10 @@ class Forgot(TemplateView):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
if request.user.is_authenticated: if request.user.is_authenticated:
return redirect(request.GET.get("next", 'control:index')) next_url = request.GET.get("next") or reverse("control:index")
if next_url and url_has_allowed_host_and_scheme(next_url, allowed_hosts=None):
return redirect_to_url(next_url)
return redirect("control:index")
return super().get(request, *args, **kwargs) return super().get(request, *args, **kwargs)
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
@@ -329,7 +335,10 @@ class Recover(TemplateView):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
if request.user.is_authenticated: if request.user.is_authenticated:
return redirect(request.GET.get("next", 'control:index')) next_url = request.GET.get("next") or reverse("control:index")
if next_url and url_has_allowed_host_and_scheme(next_url, allowed_hosts=None):
return redirect_to_url(next_url)
return redirect("control:index")
try: try:
user = User.objects.get(id=self.request.GET.get('id'), is_active=True, auth_backend='native') user = User.objects.get(id=self.request.GET.get('id'), is_active=True, auth_backend='native')
except User.DoesNotExist: except User.DoesNotExist:
@@ -453,7 +462,7 @@ class Login2FAView(TemplateView):
del request.session['pretix_auth_2fa_time'] del request.session['pretix_auth_2fa_time']
if "next" in request.GET and url_has_allowed_host_and_scheme(request.GET.get("next"), allowed_hosts=None): if "next" in request.GET and url_has_allowed_host_and_scheme(request.GET.get("next"), allowed_hosts=None):
return redirect_to_url(request.GET.get("next")) return redirect_to_url(request.GET.get("next"))
return redirect(reverse('control:index')) return redirect('control:index')
else: else:
messages.error(request, _('Invalid code, please try again.')) messages.error(request, _('Invalid code, please try again.'))
return redirect('control:auth.login.2fa') return redirect('control:auth.login.2fa')

View File

@@ -50,6 +50,7 @@ from pretix.base.services.orderimport import import_orders, parse_csv
from pretix.base.views.tasks import AsyncAction from pretix.base.views.tasks import AsyncAction
from pretix.control.forms.orderimport import ProcessForm from pretix.control.forms.orderimport import ProcessForm
from pretix.control.permissions import EventPermissionRequiredMixin from pretix.control.permissions import EventPermissionRequiredMixin
from pretix.helpers.http import redirect_to_url
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
ENCODINGS = ( ENCODINGS = (
@@ -69,19 +70,19 @@ class ImportView(EventPermissionRequiredMixin, TemplateView):
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
if 'file' not in request.FILES: if 'file' not in request.FILES:
return redirect(reverse('control:event.orders.import', kwargs={ return redirect_to_url(reverse('control:event.orders.import', kwargs={
'event': request.event.slug, 'event': request.event.slug,
'organizer': request.organizer.slug, 'organizer': request.organizer.slug,
})) }))
if not request.FILES['file'].name.lower().endswith('.csv'): if not request.FILES['file'].name.lower().endswith('.csv'):
messages.error(request, _('Please only upload CSV files.')) messages.error(request, _('Please only upload CSV files.'))
return redirect(reverse('control:event.orders.import', kwargs={ return redirect_to_url(reverse('control:event.orders.import', kwargs={
'event': request.event.slug, 'event': request.event.slug,
'organizer': request.organizer.slug, 'organizer': request.organizer.slug,
})) }))
if request.FILES['file'].size > settings.FILE_UPLOAD_MAX_SIZE_OTHER: if request.FILES['file'].size > settings.FILE_UPLOAD_MAX_SIZE_OTHER:
messages.error(request, _('Please do not upload files larger than 10 MB.')) messages.error(request, _('Please do not upload files larger than 10 MB.'))
return redirect(reverse('control:event.orders.import', kwargs={ return redirect_to_url(reverse('control:event.orders.import', kwargs={
'event': request.event.slug, 'event': request.event.slug,
'organizer': request.organizer.slug, 'organizer': request.organizer.slug,
})) }))

View File

@@ -42,7 +42,7 @@ from django.contrib import messages
from django.core import signing from django.core import signing
from django.db.models import Sum from django.db.models import Sum
from django.http import HttpResponse, HttpResponseBadRequest from django.http import HttpResponse, HttpResponseBadRequest
from django.shortcuts import redirect, render from django.shortcuts import render
from django.urls import reverse from django.urls import reverse
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.views.decorators.clickjacking import xframe_options_exempt from django.views.decorators.clickjacking import xframe_options_exempt
@@ -53,6 +53,7 @@ from django_scopes import scopes_disabled
from pretix.base.models import Order, OrderPayment, OrderRefund, Quota from pretix.base.models import Order, OrderPayment, OrderRefund, Quota
from pretix.base.payment import PaymentException from pretix.base.payment import PaymentException
from pretix.control.permissions import event_permission_required from pretix.control.permissions import event_permission_required
from pretix.helpers.http import redirect_to_url
from pretix.multidomain.urlreverse import eventreverse from pretix.multidomain.urlreverse import eventreverse
from pretix.plugins.paypal.models import ReferencedPayPalObject from pretix.plugins.paypal.models import ReferencedPayPalObject
from pretix.plugins.paypal.payment import Paypal from pretix.plugins.paypal.payment import Paypal
@@ -99,23 +100,23 @@ def success(request, *args, **kwargs):
except PaymentException as e: except PaymentException as e:
messages.error(request, str(e)) messages.error(request, str(e))
urlkwargs['step'] = 'payment' urlkwargs['step'] = 'payment'
return redirect(eventreverse(request.event, 'presale:event.checkout', kwargs=urlkwargs)) return redirect_to_url(eventreverse(request.event, 'presale:event.checkout', kwargs=urlkwargs))
if resp: if resp:
return resp return resp
else: else:
messages.error(request, _('Invalid response from PayPal received.')) messages.error(request, _('Invalid response from PayPal received.'))
logger.error('Session did not contain payment_paypal_id') logger.error('Session did not contain payment_paypal_id')
urlkwargs['step'] = 'payment' urlkwargs['step'] = 'payment'
return redirect(eventreverse(request.event, 'presale:event.checkout', kwargs=urlkwargs)) return redirect_to_url(eventreverse(request.event, 'presale:event.checkout', kwargs=urlkwargs))
if payment: if payment:
return redirect(eventreverse(request.event, 'presale:event.order', kwargs={ return redirect_to_url(eventreverse(request.event, 'presale:event.order', kwargs={
'order': payment.order.code, 'order': payment.order.code,
'secret': payment.order.secret 'secret': payment.order.secret
}) + ('?paid=yes' if payment.order.status == Order.STATUS_PAID else '')) }) + ('?paid=yes' if payment.order.status == Order.STATUS_PAID else ''))
else: else:
urlkwargs['step'] = 'confirm' urlkwargs['step'] = 'confirm'
return redirect(eventreverse(request.event, 'presale:event.checkout', kwargs=urlkwargs)) return redirect_to_url(eventreverse(request.event, 'presale:event.checkout', kwargs=urlkwargs))
def abort(request, *args, **kwargs): def abort(request, *args, **kwargs):
@@ -127,12 +128,12 @@ def abort(request, *args, **kwargs):
payment = None payment = None
if payment: if payment:
return redirect(eventreverse(request.event, 'presale:event.order', kwargs={ return redirect_to_url(eventreverse(request.event, 'presale:event.order', kwargs={
'order': payment.order.code, 'order': payment.order.code,
'secret': payment.order.secret 'secret': payment.order.secret
}) + ('?paid=yes' if payment.order.status == Order.STATUS_PAID else '')) }) + ('?paid=yes' if payment.order.status == Order.STATUS_PAID else ''))
else: else:
return redirect(eventreverse(request.event, 'presale:event.checkout', kwargs={'step': 'payment'})) return redirect_to_url(eventreverse(request.event, 'presale:event.checkout', kwargs={'step': 'payment'}))
@csrf_exempt @csrf_exempt
@@ -259,7 +260,7 @@ def oauth_disconnect(request, **kwargs):
event.enable_plugin("pretix.plugins.paypal2") event.enable_plugin("pretix.plugins.paypal2")
event.save() event.save()
return redirect(reverse('control:event.settings.payment.provider', kwargs={ return redirect_to_url(reverse('control:event.settings.payment.provider', kwargs={
'organizer': request.event.organizer.slug, 'organizer': request.event.organizer.slug,
'event': request.event.slug, 'event': request.event.slug,
'provider': 'paypal_settings' 'provider': 'paypal_settings'

View File

@@ -63,6 +63,7 @@ from pretix.base.payment import PaymentException
from pretix.base.services.cart import add_payment_to_cart, get_fees from pretix.base.services.cart import add_payment_to_cart, get_fees
from pretix.base.settings import GlobalSettingsObject from pretix.base.settings import GlobalSettingsObject
from pretix.control.permissions import event_permission_required from pretix.control.permissions import event_permission_required
from pretix.helpers.http import redirect_to_url
from pretix.multidomain.urlreverse import eventreverse from pretix.multidomain.urlreverse import eventreverse
from pretix.plugins.paypal2.client.customer.partners_merchantintegrations_get_request import ( from pretix.plugins.paypal2.client.customer.partners_merchantintegrations_get_request import (
PartnersMerchantIntegrationsGetRequest, PartnersMerchantIntegrationsGetRequest,
@@ -222,7 +223,7 @@ def isu_return(request, *args, **kwargs):
missing_getparams = set(getparams) - set(request.GET) missing_getparams = set(getparams) - set(request.GET)
missing_sessionparams = {p for p in sessionparams if p not in request.session} missing_sessionparams = {p for p in sessionparams if p not in request.session}
logger.exception('PayPal2 - Missing params in GET {} and/or Session {}'.format(missing_getparams, missing_sessionparams)) logger.exception('PayPal2 - Missing params in GET {} and/or Session {}'.format(missing_getparams, missing_sessionparams))
return redirect(reverse('control:index')) return redirect('control:index')
event = get_object_or_404(Event, pk=request.session['payment_paypal_isu_event']) event = get_object_or_404(Event, pk=request.session['payment_paypal_isu_event'])
@@ -282,7 +283,7 @@ def isu_return(request, *args, **kwargs):
if third_party.partner_client_id == prov.client.environment.client_id: if third_party.partner_client_id == prov.client.environment.client_id:
event.settings.payment_paypal_isu_scopes = third_party.scopes event.settings.payment_paypal_isu_scopes = third_party.scopes
return redirect(reverse('control:event.settings.payment.provider', kwargs={ return redirect_to_url(reverse('control:event.settings.payment.provider', kwargs={
'organizer': event.organizer.slug, 'organizer': event.organizer.slug,
'event': event.slug, 'event': event.slug,
'provider': 'paypal_settings' 'provider': 'paypal_settings'
@@ -345,12 +346,12 @@ def abort(request, *args, **kwargs):
payment = None payment = None
if payment: if payment:
return redirect(eventreverse(request.event, 'presale:event.order', kwargs={ return redirect_to_url(eventreverse(request.event, 'presale:event.order', kwargs={
'order': payment.order.code, 'order': payment.order.code,
'secret': payment.order.secret 'secret': payment.order.secret
}) + ('?paid=yes' if payment.order.status == Order.STATUS_PAID else '')) }) + ('?paid=yes' if payment.order.status == Order.STATUS_PAID else ''))
else: else:
return redirect(eventreverse(request.event, 'presale:event.checkout', kwargs={'step': 'payment'})) return redirect_to_url(eventreverse(request.event, 'presale:event.checkout', kwargs={'step': 'payment'}))
@csrf_exempt @csrf_exempt
@@ -518,7 +519,7 @@ def isu_disconnect(request, **kwargs):
request.event.settings.payment_paypal__enabled = False request.event.settings.payment_paypal__enabled = False
messages.success(request, _('Your PayPal account has been disconnected.')) messages.success(request, _('Your PayPal account has been disconnected.'))
return redirect(reverse('control:event.settings.payment.provider', kwargs={ return redirect_to_url(reverse('control:event.settings.payment.provider', kwargs={
'organizer': request.event.organizer.slug, 'organizer': request.event.organizer.slug,
'event': request.event.slug, 'event': request.event.slug,
'provider': 'paypal_settings' 'provider': 'paypal_settings'

View File

@@ -24,11 +24,11 @@ from urllib.parse import urlencode
from django.contrib.messages import constants as messages, get_messages from django.contrib.messages import constants as messages, get_messages
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django.dispatch import receiver from django.dispatch import receiver
from django.shortcuts import redirect
from django.urls import resolve, reverse from django.urls import resolve, reverse
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from pretix.control.signals import nav_event_settings from pretix.control.signals import nav_event_settings
from pretix.helpers.http import redirect_to_url
from pretix.presale.signals import process_request from pretix.presale.signals import process_request
@@ -64,7 +64,7 @@ def returnurl_process_request(sender, request, **kwargs):
url += '&' + urlencode(query) url += '&' + urlencode(query)
else: else:
url += '?' + urlencode(query) url += '?' + urlencode(query)
r = redirect(url) r = redirect_to_url(url)
del request.session[key] del request.session[key]
return r return r
elif urlname != 'event.order' and 'return_url' in request.GET: elif urlname != 'event.order' and 'return_url' in request.GET:

View File

@@ -65,6 +65,7 @@ from pretix.control.permissions import (
from pretix.control.views.event import DecoupleMixin from pretix.control.views.event import DecoupleMixin
from pretix.control.views.organizer import OrganizerDetailViewMixin from pretix.control.views.organizer import OrganizerDetailViewMixin
from pretix.helpers import OF_SELF from pretix.helpers import OF_SELF
from pretix.helpers.http import redirect_to_url
from pretix.multidomain.urlreverse import build_absolute_uri, eventreverse from pretix.multidomain.urlreverse import build_absolute_uri, eventreverse
from pretix.plugins.stripe.forms import OrganizerStripeSettingsForm from pretix.plugins.stripe.forms import OrganizerStripeSettingsForm
from pretix.plugins.stripe.models import ReferencedStripeObject from pretix.plugins.stripe.models import ReferencedStripeObject
@@ -102,13 +103,13 @@ def redirect_view(request, *args, **kwargs):
def oauth_return(request, *args, **kwargs): def oauth_return(request, *args, **kwargs):
if 'payment_stripe_oauth_event' not in request.session: if 'payment_stripe_oauth_event' not in request.session:
messages.error(request, _('An error occurred during connecting with Stripe, please try again.')) messages.error(request, _('An error occurred during connecting with Stripe, please try again.'))
return redirect(reverse('control:index')) return redirect('control:index')
event = get_object_or_404(Event, pk=request.session['payment_stripe_oauth_event']) event = get_object_or_404(Event, pk=request.session['payment_stripe_oauth_event'])
if request.GET.get('state') != request.session['payment_stripe_oauth_token']: if request.GET.get('state') != request.session['payment_stripe_oauth_token']:
messages.error(request, _('An error occurred during connecting with Stripe, please try again.')) messages.error(request, _('An error occurred during connecting with Stripe, please try again.'))
return redirect(reverse('control:event.settings.payment.provider', kwargs={ return redirect_to_url(reverse('control:event.settings.payment.provider', kwargs={
'organizer': event.organizer.slug, 'organizer': event.organizer.slug,
'event': event.slug, 'event': event.slug,
'provider': 'stripe_settings' 'provider': 'stripe_settings'
@@ -147,7 +148,7 @@ def oauth_return(request, *args, **kwargs):
except: except:
logger.exception('Failed to obtain OAuth token') logger.exception('Failed to obtain OAuth token')
messages.error(request, _('An error occurred during connecting with Stripe, please try again.')) messages.error(request, _('An error occurred during connecting with Stripe, please try again.'))
return redirect(reverse('control:event.settings.payment.provider', kwargs={ return redirect_to_url(reverse('control:event.settings.payment.provider', kwargs={
'organizer': event.organizer.slug, 'organizer': event.organizer.slug,
'event': event.slug, 'event': event.slug,
'provider': 'stripe_settings' 'provider': 'stripe_settings'
@@ -188,7 +189,7 @@ def oauth_return(request, *args, **kwargs):
stripe_verify_domain.apply_async(args=(event.pk, get_domain_for_event(event))) stripe_verify_domain.apply_async(args=(event.pk, get_domain_for_event(event)))
return redirect(reverse('control:event.settings.payment.provider', kwargs={ return redirect_to_url(reverse('control:event.settings.payment.provider', kwargs={
'organizer': event.organizer.slug, 'organizer': event.organizer.slug,
'event': event.slug, 'event': event.slug,
'provider': 'stripe_settings' 'provider': 'stripe_settings'
@@ -469,7 +470,7 @@ def oauth_disconnect(request, **kwargs):
request.event.settings.payment_stripe__enabled = False request.event.settings.payment_stripe__enabled = False
messages.success(request, _('Your Stripe account has been disconnected.')) messages.success(request, _('Your Stripe account has been disconnected.'))
return redirect(reverse('control:event.settings.payment.provider', kwargs={ return redirect_to_url(reverse('control:event.settings.payment.provider', kwargs={
'organizer': request.event.organizer.slug, 'organizer': request.event.organizer.slug,
'event': request.event.slug, 'event': request.event.slug,
'provider': 'stripe_settings' 'provider': 'stripe_settings'
@@ -503,9 +504,9 @@ class StripeOrderView:
if self.request.session.get('payment_stripe_order_secret') != self.order.secret and not self.payment.provider.startswith('stripe'): if self.request.session.get('payment_stripe_order_secret') != self.order.secret and not self.payment.provider.startswith('stripe'):
messages.error(self.request, _('Sorry, there was an error in the payment process. Please check the link ' messages.error(self.request, _('Sorry, there was an error in the payment process. Please check the link '
'in your emails to continue.')) 'in your emails to continue.'))
return redirect(eventreverse(self.request.event, 'presale:event.index')) return redirect_to_url(eventreverse(self.request.event, 'presale:event.index'))
return redirect(eventreverse(self.request.event, 'presale:event.order', kwargs={ return redirect_to_url(eventreverse(self.request.event, 'presale:event.order', kwargs={
'order': self.order.code, 'order': self.order.code,
'secret': self.order.secret 'secret': self.order.secret
}) + ('?paid=yes' if self.order.status == Order.STATUS_PAID else '')) }) + ('?paid=yes' if self.order.status == Order.STATUS_PAID else ''))
@@ -522,12 +523,12 @@ class ReturnView(StripeOrderView, View):
logger.exception('Could not retrieve source') logger.exception('Could not retrieve source')
messages.error(self.request, _('Sorry, there was an error in the payment process. Please check the link ' messages.error(self.request, _('Sorry, there was an error in the payment process. Please check the link '
'in your emails to continue.')) 'in your emails to continue.'))
return redirect(eventreverse(self.request.event, 'presale:event.index')) return redirect_to_url(eventreverse(self.request.event, 'presale:event.index'))
if src.client_secret != request.GET.get('client_secret'): if src.client_secret != request.GET.get('client_secret'):
messages.error(self.request, _('Sorry, there was an error in the payment process. Please check the link ' messages.error(self.request, _('Sorry, there was an error in the payment process. Please check the link '
'in your emails to continue.')) 'in your emails to continue.'))
return redirect(eventreverse(self.request.event, 'presale:event.index')) return redirect_to_url(eventreverse(self.request.event, 'presale:event.index'))
with transaction.atomic(): with transaction.atomic():
self.order.refresh_from_db() self.order.refresh_from_db()
@@ -664,7 +665,7 @@ class OrganizerSettingsFormView(DecoupleMixin, OrganizerDetailViewMixin, Adminis
} }
) )
messages.success(self.request, _('Your changes have been saved.')) messages.success(self.request, _('Your changes have been saved.'))
return redirect(self.get_success_url()) return redirect_to_url(self.get_success_url())
else: else:
messages.error(self.request, _('We could not save your changes. See below for details.')) messages.error(self.request, _('We could not save your changes. See below for details.'))
return self.get(request) return self.get(request)

View File

@@ -47,7 +47,6 @@ from django.db import models
from django.db.models import Count, F, Q, Sum from django.db.models import Count, F, Q, Sum
from django.db.models.functions import Cast from django.db.models.functions import Cast
from django.http import HttpResponseNotAllowed, JsonResponse from django.http import HttpResponseNotAllowed, JsonResponse
from django.shortcuts import redirect
from django.utils import translation from django.utils import translation
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.utils.translation import ( from django.utils.translation import (
@@ -73,6 +72,7 @@ from pretix.base.templatetags.phone_format import phone_format
from pretix.base.templatetags.rich_text import rich_text_snippet from pretix.base.templatetags.rich_text import rich_text_snippet
from pretix.base.views.tasks import AsyncAction from pretix.base.views.tasks import AsyncAction
from pretix.celery_app import app from pretix.celery_app import app
from pretix.helpers.http import redirect_to_url
from pretix.multidomain.urlreverse import eventreverse from pretix.multidomain.urlreverse import eventreverse
from pretix.presale.forms.checkout import ( from pretix.presale.forms.checkout import (
ContactForm, InvoiceAddressForm, InvoiceNameForm, MembershipForm, ContactForm, InvoiceAddressForm, InvoiceNameForm, MembershipForm,
@@ -320,23 +320,23 @@ class CustomerStep(CartMixin, TemplateFlowStep):
if request.POST.get("customer_mode") == 'login': if request.POST.get("customer_mode") == 'login':
if self.cart_session.get('customer'): if self.cart_session.get('customer'):
return redirect(self.get_next_url(request)) return redirect_to_url(self.get_next_url(request))
elif request.customer: elif request.customer:
self.cart_session['customer_mode'] = 'login' self.cart_session['customer_mode'] = 'login'
self.cart_session['customer'] = request.customer.pk self.cart_session['customer'] = request.customer.pk
self.cart_session['customer_cart_tied_to_login'] = True self.cart_session['customer_cart_tied_to_login'] = True
return redirect(self.get_next_url(request)) return redirect_to_url(self.get_next_url(request))
elif self.request.POST.get("login-sso-data"): elif self.request.POST.get("login-sso-data"):
if not self._handle_sso_login(): if not self._handle_sso_login():
messages.error(request, _('We failed to process your authentication request, please try again.')) messages.error(request, _('We failed to process your authentication request, please try again.'))
return self.render() return self.render()
return redirect(self.get_next_url(request)) return redirect_to_url(self.get_next_url(request))
elif self.event.settings.customer_accounts_native and self.login_form.is_valid(): elif self.event.settings.customer_accounts_native and self.login_form.is_valid():
customer_login(self.request, self.login_form.get_customer()) customer_login(self.request, self.login_form.get_customer())
self.cart_session['customer_mode'] = 'login' self.cart_session['customer_mode'] = 'login'
self.cart_session['customer'] = self.login_form.get_customer().pk self.cart_session['customer'] = self.login_form.get_customer().pk
self.cart_session['customer_cart_tied_to_login'] = True self.cart_session['customer_cart_tied_to_login'] = True
return redirect(self.get_next_url(request)) return redirect_to_url(self.get_next_url(request))
else: else:
return self.render() return self.render()
elif request.POST.get("customer_mode") == 'register' and self.signup_allowed: elif request.POST.get("customer_mode") == 'register' and self.signup_allowed:
@@ -345,13 +345,13 @@ class CustomerStep(CartMixin, TemplateFlowStep):
self.cart_session['customer_mode'] = 'login' self.cart_session['customer_mode'] = 'login'
self.cart_session['customer'] = customer.pk self.cart_session['customer'] = customer.pk
self.cart_session['customer_cart_tied_to_login'] = False self.cart_session['customer_cart_tied_to_login'] = False
return redirect(self.get_next_url(request)) return redirect_to_url(self.get_next_url(request))
else: else:
return self.render() return self.render()
elif request.POST.get("customer_mode") == 'guest' and self.guest_allowed: elif request.POST.get("customer_mode") == 'guest' and self.guest_allowed:
self.cart_session['customer'] = None self.cart_session['customer'] = None
self.cart_session['customer_mode'] = 'guest' self.cart_session['customer_mode'] = 'guest'
return redirect(self.get_next_url(request)) return redirect_to_url(self.get_next_url(request))
else: else:
return self.render() return self.render()
@@ -453,7 +453,7 @@ class MembershipStep(CartMixin, TemplateFlowStep):
for f in self.forms: for f in self.forms:
f.position.save(update_fields=['used_membership']) f.position.save(update_fields=['used_membership'])
return redirect(self.get_next_url(request)) return redirect_to_url(self.get_next_url(request))
def is_completed(self, request, warn=False): def is_completed(self, request, warn=False):
self.request = request self.request = request
@@ -932,9 +932,9 @@ class QuestionsStep(QuestionsViewMixin, CartMixin, TemplateFlowStep):
messages.info(request, _('Due to the invoice address you entered, we need to apply a different tax ' messages.info(request, _('Due to the invoice address you entered, we need to apply a different tax '
'rate to your purchase and the price of the products in your cart has ' 'rate to your purchase and the price of the products in your cart has '
'changed accordingly.')) 'changed accordingly.'))
return redirect(self.get_next_url(request) + '?open_cart=true') return redirect_to_url(self.get_next_url(request) + '?open_cart=true')
return redirect(self.get_next_url(request)) return redirect_to_url(self.get_next_url(request))
def is_completed(self, request, warn=False): def is_completed(self, request, warn=False):
self.request = request self.request = request
@@ -1237,7 +1237,7 @@ class PaymentStep(CartMixin, TemplateFlowStep):
if "remove_payment" in request.POST: if "remove_payment" in request.POST:
self._remove_payment(request.POST["remove_payment"]) self._remove_payment(request.POST["remove_payment"])
return redirect(self.get_step_url(request)) return redirect_to_url(self.get_step_url(request))
for p in self.provider_forms: for p in self.provider_forms:
pprov = p['provider'] pprov = p['provider']
@@ -1277,7 +1277,7 @@ class PaymentStep(CartMixin, TemplateFlowStep):
cart = self.get_cart() cart = self.get_cart()
valid, remainder = self.current_payments_valid(cart['total']) valid, remainder = self.current_payments_valid(cart['total'])
if valid: if valid:
return redirect(self.get_next_url(request)) return redirect_to_url(self.get_next_url(request))
else: else:
# Show payment step again to select another method # Show payment step again to select another method
messages.success( messages.success(
@@ -1287,9 +1287,9 @@ class PaymentStep(CartMixin, TemplateFlowStep):
money_filter(remainder, self.event.currency) money_filter(remainder, self.event.currency)
) )
) )
return redirect(self.get_step_url(request)) return redirect_to_url(self.get_step_url(request))
elif isinstance(resp, str): elif isinstance(resp, str):
return redirect(resp) return redirect_to_url(resp)
else: else:
if resp is True or isinstance(resp, str): if resp is True or isinstance(resp, str):
# There can only be one payment method that does not have multi_use_supported, remove all # There can only be one payment method that does not have multi_use_supported, remove all
@@ -1298,14 +1298,14 @@ class PaymentStep(CartMixin, TemplateFlowStep):
add_payment_to_cart(request, pprov, None, None, None) add_payment_to_cart(request, pprov, None, None, None)
if isinstance(resp, str): if isinstance(resp, str):
return redirect(resp) return redirect_to_url(resp)
else: else:
return redirect(self.get_next_url(request)) return redirect_to_url(self.get_next_url(request))
return self.render() return self.render()
if self.is_completed(request, warn=False): if self.is_completed(request, warn=False):
# All payments already accounted for, no need to select one # All payments already accounted for, no need to select one
return redirect(self.get_next_url(request)) return redirect_to_url(self.get_next_url(request))
messages.error(self.request, _("Please select a payment method.")) messages.error(self.request, _("Please select a payment method."))
return self.render() return self.render()
@@ -1507,7 +1507,7 @@ class ConfirmStep(CartMixin, AsyncAction, TemplateFlowStep):
'redirect': self.get_error_url(), 'redirect': self.get_error_url(),
'message': msg 'message': msg
}) })
return redirect(self.get_error_url()) return redirect_to_url(self.get_error_url())
meta_info = { meta_info = {
'contact_form_data': self.cart_session.get('contact_form_data', {}), 'contact_form_data': self.cart_session.get('contact_form_data', {}),

View File

@@ -42,7 +42,6 @@ from django.core.exceptions import PermissionDenied
from django.db.models import Q from django.db.models import Q
from django.http import Http404 from django.http import Http404
from django.middleware.csrf import rotate_token from django.middleware.csrf import rotate_token
from django.shortcuts import redirect
from django.template.response import TemplateResponse from django.template.response import TemplateResponse
from django.urls import resolve from django.urls import resolve
from django.utils.crypto import constant_time_compare from django.utils.crypto import constant_time_compare
@@ -54,6 +53,7 @@ from django_scopes import scope
from pretix.base.middleware import LocaleMiddleware from pretix.base.middleware import LocaleMiddleware
from pretix.base.models import Customer, Event, Organizer from pretix.base.models import Customer, Event, Organizer
from pretix.helpers.http import redirect_to_url
from pretix.multidomain.urlreverse import ( from pretix.multidomain.urlreverse import (
get_event_domain, get_organizer_domain, get_event_domain, get_organizer_domain,
) )
@@ -241,7 +241,7 @@ def _detect_event(request, require_live=True, require_plugin=None):
if url.kwargs['organizer'] != request.organizer.slug: if url.kwargs['organizer'] != request.organizer.slug:
raise Http404(_('The selected event was not found.')) raise Http404(_('The selected event was not found.'))
path = "/" + request.get_full_path().split("/", 2)[-1] path = "/" + request.get_full_path().split("/", 2)[-1]
return redirect(path) return redirect_to_url(path)
request.organizer = request.organizer request.organizer = request.organizer
if 'event' in url.kwargs: if 'event' in url.kwargs:
@@ -256,7 +256,7 @@ def _detect_event(request, require_live=True, require_plugin=None):
if request.port and request.port not in (80, 443): if request.port and request.port not in (80, 443):
domain = '%s:%d' % (domain, request.port) domain = '%s:%d' % (domain, request.port)
path = request.get_full_path().split("/", 2)[-1] path = request.get_full_path().split("/", 2)[-1]
r = redirect(urljoin('%s://%s' % (request.scheme, domain), path)) r = redirect_to_url(urljoin('%s://%s' % (request.scheme, domain), path))
r['Access-Control-Allow-Origin'] = '*' r['Access-Control-Allow-Origin'] = '*'
return r return r
else: else:
@@ -277,7 +277,7 @@ def _detect_event(request, require_live=True, require_plugin=None):
if request.port and request.port not in (80, 443): if request.port and request.port not in (80, 443):
domain = '%s:%d' % (domain, request.port) domain = '%s:%d' % (domain, request.port)
path = request.get_full_path().split("/", 3)[-1] path = request.get_full_path().split("/", 3)[-1]
r = redirect(urljoin('%s://%s' % (request.scheme, domain), path)) r = redirect_to_url(urljoin('%s://%s' % (request.scheme, domain), path))
r['Access-Control-Allow-Origin'] = '*' r['Access-Control-Allow-Origin'] = '*'
return r return r
elif 'organizer' in url.kwargs: elif 'organizer' in url.kwargs:
@@ -293,7 +293,7 @@ def _detect_event(request, require_live=True, require_plugin=None):
if request.port and request.port not in (80, 443): if request.port and request.port not in (80, 443):
domain = '%s:%d' % (domain, request.port) domain = '%s:%d' % (domain, request.port)
path = request.get_full_path().split("/", 2)[-1] path = request.get_full_path().split("/", 2)[-1]
r = redirect(urljoin('%s://%s' % (request.scheme, domain), path)) r = redirect_to_url(urljoin('%s://%s' % (request.scheme, domain), path))
r['Access-Control-Allow-Origin'] = '*' r['Access-Control-Allow-Origin'] = '*'
return r return r
@@ -350,7 +350,7 @@ def _detect_event(request, require_live=True, require_plugin=None):
) )
pathparts = request.get_full_path().split('/') pathparts = request.get_full_path().split('/')
pathparts[1] = event.slug pathparts[1] = event.slug
r = redirect('/'.join(pathparts)) r = redirect_to_url('/'.join(pathparts))
r['Access-Control-Allow-Origin'] = '*' r['Access-Control-Allow-Origin'] = '*'
return r return r
else: else:
@@ -362,7 +362,7 @@ def _detect_event(request, require_live=True, require_plugin=None):
pathparts = request.get_full_path().split('/') pathparts = request.get_full_path().split('/')
pathparts[1] = event.organizer.slug pathparts[1] = event.organizer.slug
pathparts[2] = event.slug pathparts[2] = event.slug
r = redirect('/'.join(pathparts)) r = redirect_to_url('/'.join(pathparts))
r['Access-Control-Allow-Origin'] = '*' r['Access-Control-Allow-Origin'] = '*'
return r return r
except Event.DoesNotExist: except Event.DoesNotExist:
@@ -378,7 +378,7 @@ def _detect_event(request, require_live=True, require_plugin=None):
raise Http404(_('The selected organizer was not found.')) raise Http404(_('The selected organizer was not found.'))
pathparts = request.get_full_path().split('/') pathparts = request.get_full_path().split('/')
pathparts[1] = organizer.slug pathparts[1] = organizer.slug
r = redirect('/'.join(pathparts)) r = redirect_to_url('/'.join(pathparts))
r['Access-Control-Allow-Origin'] = '*' r['Access-Control-Allow-Origin'] = '*'
return r return r
raise Http404(_('The selected organizer was not found.')) raise Http404(_('The selected organizer was not found.'))

View File

@@ -44,7 +44,7 @@ from django.contrib import messages
from django.core.cache import caches from django.core.cache import caches
from django.db.models import Q from django.db.models import Q
from django.http import FileResponse, Http404, JsonResponse from django.http import FileResponse, Http404, JsonResponse
from django.shortcuts import get_object_or_404, redirect, render from django.shortcuts import get_object_or_404, render
from django.utils import translation from django.utils import translation
from django.utils.crypto import get_random_string from django.utils.crypto import get_random_string
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
@@ -430,7 +430,7 @@ class CartApplyVoucher(EventViewMixin, CartActionMixin, AsyncAction, View):
'redirect': self.get_error_url() 'redirect': self.get_error_url()
}) })
else: else:
return redirect(self.get_error_url()) return redirect_to_url(self.get_error_url())
@method_decorator(allow_frame_if_namespaced, 'dispatch') @method_decorator(allow_frame_if_namespaced, 'dispatch')
@@ -451,14 +451,14 @@ class CartRemove(EventViewMixin, CartActionMixin, AsyncAction, View):
return self.do(self.request.event.id, int(request.POST.get('id')), get_or_create_cart_id(self.request), return self.do(self.request.event.id, int(request.POST.get('id')), get_or_create_cart_id(self.request),
translation.get_language(), request.sales_channel.identifier) translation.get_language(), request.sales_channel.identifier)
except ValueError: except ValueError:
return redirect(self.get_error_url()) return redirect_to_url(self.get_error_url())
else: else:
if 'ajax' in self.request.GET or 'ajax' in self.request.POST: if 'ajax' in self.request.GET or 'ajax' in self.request.POST:
return JsonResponse({ return JsonResponse({
'redirect': self.get_error_url() 'redirect': self.get_error_url()
}) })
else: else:
return redirect(self.get_error_url()) return redirect_to_url(self.get_error_url())
@method_decorator(allow_frame_if_namespaced, 'dispatch') @method_decorator(allow_frame_if_namespaced, 'dispatch')
@@ -537,7 +537,7 @@ class CartAdd(EventViewMixin, CartActionMixin, AsyncAction, View):
'message': str(error_messages['empty']) 'message': str(error_messages['empty'])
}) })
else: else:
return redirect(self.get_error_url()) return redirect_to_url(self.get_error_url())
@method_decorator(allow_frame_if_namespaced, 'dispatch') @method_decorator(allow_frame_if_namespaced, 'dispatch')
@@ -660,8 +660,12 @@ class RedeemView(NoSearchIndexViewMixin, EventViewMixin, CartMixin, TemplateView
self.subevent = self.voucher.subevent self.subevent = self.voucher.subevent
if not err and not self.subevent: if not err and not self.subevent:
return redirect(eventreverse(self.request.event, 'presale:event.index', return redirect_to_url(
kwargs={'cart_namespace': kwargs.get('cart_namespace') or ''}) + '?voucher=' + quote(self.voucher.code)) eventreverse(
self.request.event, 'presale:event.index',
kwargs={'cart_namespace': kwargs.get('cart_namespace') or ''}
) + '?voucher=' + quote(self.voucher.code)
)
else: else:
pass pass
@@ -678,7 +682,7 @@ class RedeemView(NoSearchIndexViewMixin, EventViewMixin, CartMixin, TemplateView
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
if 'iframe' in request.GET and 'require_cookie' not in request.GET: if 'iframe' in request.GET and 'require_cookie' not in request.GET:
return redirect(request.get_full_path() + '&require_cookie=1') return redirect_to_url(request.get_full_path() + '&require_cookie=1')
if len(self.request.GET.get('widget_data', '{}')) > 3: if len(self.request.GET.get('widget_data', '{}')) > 3:
# We've been passed data from a widget, we need to create a cart session to store it. # We've been passed data from a widget, we need to create a cart session to store it.

View File

@@ -23,13 +23,13 @@ from urllib.parse import quote
from django.contrib import messages from django.contrib import messages
from django.http import Http404 from django.http import Http404
from django.shortcuts import redirect
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.views.generic import View from django.views.generic import View
from pretix.base.services.cart import CartError from pretix.base.services.cart import CartError
from pretix.base.signals import validate_cart from pretix.base.signals import validate_cart
from pretix.helpers.http import redirect_to_url
from pretix.multidomain.urlreverse import eventreverse from pretix.multidomain.urlreverse import eventreverse
from pretix.presale.checkoutflow import get_checkout_flow from pretix.presale.checkoutflow import get_checkout_flow
from pretix.presale.views import ( from pretix.presale.views import (
@@ -94,4 +94,4 @@ class CheckoutView(View):
def redirect(self, url): def redirect(self, url):
if 'cart_id' in self.request.GET: if 'cart_id' in self.request.GET:
url += ('&' if '?' in url else '?') + 'cart_id=' + quote(self.request.GET.get('cart_id')) url += ('&' if '?' in url else '?') + 'cart_id=' + quote(self.request.GET.get('cart_id'))
return redirect(url) return redirect_to_url(url)

View File

@@ -35,7 +35,7 @@ from django.db.models import (
Count, IntegerField, OuterRef, Prefetch, Q, Subquery, Count, IntegerField, OuterRef, Prefetch, Q, Subquery,
) )
from django.http import Http404, HttpResponseRedirect from django.http import Http404, HttpResponseRedirect
from django.shortcuts import get_object_or_404, redirect, render from django.shortcuts import get_object_or_404, render
from django.utils.crypto import get_random_string from django.utils.crypto import get_random_string
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.utils.functional import cached_property from django.utils.functional import cached_property
@@ -343,7 +343,7 @@ class CustomerRequiredMixin:
if not request.organizer.settings.customer_accounts: if not request.organizer.settings.customer_accounts:
raise Http404('Feature not enabled') raise Http404('Feature not enabled')
if not getattr(request, 'customer', None): if not getattr(request, 'customer', None):
return redirect( return redirect_to_url(
eventreverse(self.request.organizer, 'presale:organizer.customer.login', kwargs={}) + eventreverse(self.request.organizer, 'presale:organizer.customer.login', kwargs={}) +
'?next=' + quote(self.request.path_info + '?' + self.request.GET.urlencode()) '?next=' + quote(self.request.path_info + '?' + self.request.GET.urlencode())
) )
@@ -848,7 +848,7 @@ class SSOLoginReturnView(RedirectBackMixin, View):
self.request, self.request,
message, message,
) )
return redirect(eventreverse(self.request.organizer, 'presale:organizer.customer.login', kwargs={})) return redirect_to_url(eventreverse(self.request.organizer, 'presale:organizer.customer.login', kwargs={}))
else: else:
return render(self.request, 'pretixpresale/postmessage.html', { return render(self.request, 'pretixpresale/postmessage.html', {
'message': { 'message': {

View File

@@ -49,7 +49,7 @@ from django.db.models import (
Count, Exists, IntegerField, OuterRef, Prefetch, Q, Value, Count, Exists, IntegerField, OuterRef, Prefetch, Q, Value,
) )
from django.http import Http404, HttpResponse from django.http import Http404, HttpResponse
from django.shortcuts import get_object_or_404, redirect, render from django.shortcuts import get_object_or_404, render
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.utils.formats import get_format from django.utils.formats import get_format
from django.utils.functional import SimpleLazyObject from django.utils.functional import SimpleLazyObject
@@ -78,6 +78,7 @@ from pretix.presale.views.organizer import (
) )
from ...helpers.formats.en.formats import SHORT_MONTH_DAY_FORMAT, WEEK_FORMAT from ...helpers.formats.en.formats import SHORT_MONTH_DAY_FORMAT, WEEK_FORMAT
from ...helpers.http import redirect_to_url
from . import ( from . import (
CartMixin, EventViewMixin, allow_frame_if_namespaced, get_cart, CartMixin, EventViewMixin, allow_frame_if_namespaced, get_cart,
iframe_entry_view_wrapper, iframe_entry_view_wrapper,
@@ -456,14 +457,14 @@ class EventIndex(EventViewMixin, EventListMixin, CartMixin, TemplateView):
if all(k in request.GET for k in keys): if all(k in request.GET for k in keys):
get_params = {k: v for k, v in request.GET.items() if k not in keys} get_params = {k: v for k, v in request.GET.items() if k not in keys}
get_params["date"] = "%s-%s" % (request.GET.get("year"), request.GET.get("month")) get_params["date"] = "%s-%s" % (request.GET.get("year"), request.GET.get("month"))
return redirect(self.request.path + "?" + urlencode(get_params)) return redirect_to_url(self.request.path + "?" + urlencode(get_params))
# redirect old week-year-URLs to new date-URLs # redirect old week-year-URLs to new date-URLs
keys = ("week", "year") keys = ("week", "year")
if all(k in request.GET for k in keys): if all(k in request.GET for k in keys):
get_params = {k: v for k, v in request.GET.items() if k not in keys} get_params = {k: v for k, v in request.GET.items() if k not in keys}
get_params["date"] = "%s-W%s" % (request.GET.get("year"), request.GET.get("week")) get_params["date"] = "%s-W%s" % (request.GET.get("year"), request.GET.get("week"))
return redirect(self.request.path + "?" + urlencode(get_params)) return redirect_to_url(self.request.path + "?" + urlencode(get_params))
from pretix.presale.views.cart import get_or_create_cart_id from pretix.presale.views.cart import get_or_create_cart_id
@@ -471,11 +472,11 @@ class EventIndex(EventViewMixin, EventListMixin, CartMixin, TemplateView):
if request.GET.get('src', '') == 'widget' and 'take_cart_id' in request.GET: if request.GET.get('src', '') == 'widget' and 'take_cart_id' in request.GET:
# User has clicked "Open in a new tab" link in widget # User has clicked "Open in a new tab" link in widget
get_or_create_cart_id(request) get_or_create_cart_id(request)
return redirect(eventreverse(request.event, 'presale:event.index', kwargs=kwargs)) return redirect_to_url(eventreverse(request.event, 'presale:event.index', kwargs=kwargs))
elif request.GET.get('iframe', '') == '1' and 'take_cart_id' in request.GET: elif request.GET.get('iframe', '') == '1' and 'take_cart_id' in request.GET:
# Widget just opened, a cart already exists. Let's to a stupid redirect to check if cookies are disabled # Widget just opened, a cart already exists. Let's to a stupid redirect to check if cookies are disabled
get_or_create_cart_id(request) get_or_create_cart_id(request)
return redirect(eventreverse(request.event, 'presale:event.index', kwargs=kwargs) + '?' + urllib.parse.urlencode({ return redirect_to_url(eventreverse(request.event, 'presale:event.index', kwargs=kwargs) + '?' + urllib.parse.urlencode({
'require_cookie': 'true', 'require_cookie': 'true',
'cart_id': request.GET.get('take_cart_id'), 'cart_id': request.GET.get('take_cart_id'),
**({"locale": request.GET.get('locale')} if request.GET.get('locale') else {}), **({"locale": request.GET.get('locale')} if request.GET.get('locale') else {}),
@@ -510,7 +511,7 @@ class EventIndex(EventViewMixin, EventListMixin, CartMixin, TemplateView):
return super().get(request, *args, **kwargs) return super().get(request, *args, **kwargs)
else: else:
if 'subevent' in kwargs: if 'subevent' in kwargs:
return redirect(self.get_index_url()) return redirect_to_url(self.get_index_url())
else: else:
return super().get(request, *args, **kwargs) return super().get(request, *args, **kwargs)
@@ -787,11 +788,11 @@ class SeatingPlanView(EventViewMixin, TemplateView):
if request.GET.get('src', '') == 'widget' and 'take_cart_id' in request.GET: if request.GET.get('src', '') == 'widget' and 'take_cart_id' in request.GET:
# User has clicked "Open in a new tab" link in widget # User has clicked "Open in a new tab" link in widget
get_or_create_cart_id(request) get_or_create_cart_id(request)
return redirect(eventreverse(request.event, 'presale:event.seatingplan', kwargs=kwargs)) return redirect_to_url(eventreverse(request.event, 'presale:event.seatingplan', kwargs=kwargs))
elif request.GET.get('iframe', '') == '1' and 'take_cart_id' in request.GET: elif request.GET.get('iframe', '') == '1' and 'take_cart_id' in request.GET:
# Widget just opened, a cart already exists. Let's to a stupid redirect to check if cookies are disabled # Widget just opened, a cart already exists. Let's to a stupid redirect to check if cookies are disabled
get_or_create_cart_id(request) get_or_create_cart_id(request)
return redirect(eventreverse(request.event, 'presale:event.seatingplan', kwargs=kwargs) + '?require_cookie=true&cart_id={}'.format( return redirect_to_url(eventreverse(request.event, 'presale:event.seatingplan', kwargs=kwargs) + '?require_cookie=true&cart_id={}'.format(
request.GET.get('take_cart_id') request.GET.get('take_cart_id')
)) ))
elif request.GET.get('iframe', '') == '1' and len(self.request.GET.get('widget_data', '{}')) > 3: elif request.GET.get('iframe', '') == '1' and len(self.request.GET.get('widget_data', '{}')) > 3:
@@ -890,4 +891,4 @@ class EventAuth(View):
raise PermissionDenied(_('Please go back and try again.')) raise PermissionDenied(_('Please go back and try again.'))
request.session['pretix_event_access_{}'.format(request.event.pk)] = parent request.session['pretix_event_access_{}'.format(request.event.pk)] = parent
return redirect(eventreverse(request.event, 'presale:event.index')) return redirect_to_url(eventreverse(request.event, 'presale:event.index'))

View File

@@ -44,6 +44,7 @@ from pretix.base.customersso.oidc import (
from pretix.base.models.customers import ( from pretix.base.models.customers import (
CustomerSSOAccessToken, CustomerSSOClient, CustomerSSOGrant, CustomerSSOAccessToken, CustomerSSOClient, CustomerSSOGrant,
) )
from pretix.helpers.http import redirect_to_url
from pretix.multidomain.middlewares import CsrfViewMiddleware from pretix.multidomain.middlewares import CsrfViewMiddleware
from pretix.multidomain.urlreverse import build_absolute_uri from pretix.multidomain.urlreverse import build_absolute_uri
from pretix.presale.forms.customer import AuthenticationForm from pretix.presale.forms.customer import AuthenticationForm
@@ -106,7 +107,7 @@ class AuthorizeView(View):
CsrfViewMiddleware(lambda: None)._check_token(request) CsrfViewMiddleware(lambda: None)._check_token(request)
except: except:
# External request, we prefer GET and will redirect to prevent confusion with our login form # External request, we prefer GET and will redirect to prevent confusion with our login form
return redirect(request.path + '?' + request.POST.urlencode()) return redirect_to_url(request.path + '?' + request.POST.urlencode())
return self._process_auth_request(request, request.GET) return self._process_auth_request(request, request.GET)
def _final_error(self, error, error_description): def _final_error(self, error, error_description):

View File

@@ -86,6 +86,7 @@ from pretix.base.signals import (
from pretix.base.templatetags.money import money_filter from pretix.base.templatetags.money import money_filter
from pretix.base.views.mixins import OrderQuestionsViewMixin from pretix.base.views.mixins import OrderQuestionsViewMixin
from pretix.base.views.tasks import AsyncAction from pretix.base.views.tasks import AsyncAction
from pretix.helpers.http import redirect_to_url
from pretix.helpers.safedownload import check_token from pretix.helpers.safedownload import check_token
from pretix.multidomain.urlreverse import build_absolute_uri, eventreverse from pretix.multidomain.urlreverse import build_absolute_uri, eventreverse
from pretix.presale.forms.checkout import InvoiceAddressForm, QuestionsForm from pretix.presale.forms.checkout import InvoiceAddressForm, QuestionsForm
@@ -420,9 +421,9 @@ class OrderPaymentStart(EventViewMixin, OrderDetailMixin, TemplateView):
if 'payment_change_{}'.format(self.order.pk) in request.session: if 'payment_change_{}'.format(self.order.pk) in request.session:
del request.session['payment_change_{}'.format(self.order.pk)] del request.session['payment_change_{}'.format(self.order.pk)]
if isinstance(resp, str): if isinstance(resp, str):
return redirect(resp) return redirect_to_url(resp)
elif resp is True: elif resp is True:
return redirect(self.get_confirm_url()) return redirect_to_url(self.get_confirm_url())
else: else:
return self.get(request, *args, **kwargs) return self.get(request, *args, **kwargs)
@@ -574,9 +575,9 @@ class OrderPaymentComplete(EventViewMixin, OrderDetailMixin, View):
return redirect(self.get_order_url()) return redirect(self.get_order_url())
if self.order.status == Order.STATUS_PAID: if self.order.status == Order.STATUS_PAID:
return redirect(resp or self.get_order_url() + '?paid=yes') return redirect_to_url(resp or self.get_order_url() + '?paid=yes')
else: else:
return redirect(resp or self.get_order_url() + '?thanks=yes') return redirect_to_url(resp or self.get_order_url() + '?thanks=yes')
def get_payment_url(self): def get_payment_url(self):
return eventreverse(self.request.event, 'presale:event.order.pay', kwargs={ return eventreverse(self.request.event, 'presale:event.order.pay', kwargs={

View File

@@ -48,7 +48,6 @@ from django.core.cache import caches
from django.db.models import Exists, Max, Min, OuterRef, Prefetch, Q from django.db.models import Exists, Max, Min, OuterRef, Prefetch, Q
from django.db.models.functions import Coalesce, Greatest from django.db.models.functions import Coalesce, Greatest
from django.http import Http404, HttpResponse, QueryDict from django.http import Http404, HttpResponse, QueryDict
from django.shortcuts import redirect
from django.templatetags.static import static from django.templatetags.static import static
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.utils.formats import date_format, get_format from django.utils.formats import date_format, get_format
@@ -68,6 +67,7 @@ from pretix.helpers.daterange import daterange
from pretix.helpers.formats.en.formats import ( from pretix.helpers.formats.en.formats import (
SHORT_MONTH_DAY_FORMAT, WEEK_FORMAT, SHORT_MONTH_DAY_FORMAT, WEEK_FORMAT,
) )
from pretix.helpers.http import redirect_to_url
from pretix.helpers.thumb import get_thumbnail from pretix.helpers.thumb import get_thumbnail
from pretix.multidomain.urlreverse import eventreverse from pretix.multidomain.urlreverse import eventreverse
from pretix.presale.forms.organizer import EventListFilterForm from pretix.presale.forms.organizer import EventListFilterForm
@@ -655,7 +655,7 @@ class CalendarView(OrganizerViewMixin, EventListMixin, TemplateView):
if all(k in request.GET for k in keys): if all(k in request.GET for k in keys):
get_params = {k: v for k, v in request.GET.items() if k not in keys} get_params = {k: v for k, v in request.GET.items() if k not in keys}
get_params["date"] = "%s-%s" % (request.GET.get("year"), request.GET.get("month")) get_params["date"] = "%s-%s" % (request.GET.get("year"), request.GET.get("month"))
return redirect(self.request.path + "?" + urlencode(get_params)) return redirect_to_url(self.request.path + "?" + urlencode(get_params))
self._set_month_year() self._set_month_year()
return super().get(request, *args, **kwargs) return super().get(request, *args, **kwargs)
@@ -736,7 +736,7 @@ class WeekCalendarView(OrganizerViewMixin, EventListMixin, TemplateView):
if all(k in request.GET for k in keys): if all(k in request.GET for k in keys):
get_params = {k: v for k, v in request.GET.items() if k not in keys} get_params = {k: v for k, v in request.GET.items() if k not in keys}
get_params["date"] = "%s-W%s" % (request.GET.get("year"), request.GET.get("week")) get_params["date"] = "%s-W%s" % (request.GET.get("year"), request.GET.get("week"))
return redirect(self.request.path + "?" + urlencode(get_params)) return redirect_to_url(self.request.path + "?" + urlencode(get_params))
self._set_week_year() self._set_week_year()
return super().get(request, *args, **kwargs) return super().get(request, *args, **kwargs)
@@ -1230,6 +1230,6 @@ class OrganizerIcalDownload(OrganizerViewMixin, View):
class OrganizerFavicon(View): class OrganizerFavicon(View):
def get(self, *args, **kwargs): def get(self, *args, **kwargs):
if self.request.organizer.settings.favicon: if self.request.organizer.settings.favicon:
return redirect(get_thumbnail(self.request.organizer.settings.favicon, '32x32^').thumb.url) return redirect_to_url(get_thumbnail(self.request.organizer.settings.favicon, '32x32^').thumb.url)
else: else:
return redirect(static("pretixbase/img/favicon.ico")) return redirect_to_url(static("pretixbase/img/favicon.ico"))

View File

@@ -36,7 +36,6 @@ import logging
from django.conf import settings from django.conf import settings
from django.contrib import messages from django.contrib import messages
from django.shortcuts import redirect
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.views import View from django.views import View
@@ -44,6 +43,7 @@ from django.views.generic import TemplateView
from pretix.base.email import get_email_context from pretix.base.email import get_email_context
from pretix.base.services.mail import INVALID_ADDRESS, SendMailException, mail from pretix.base.services.mail import INVALID_ADDRESS, SendMailException, mail
from pretix.helpers.http import redirect_to_url
from pretix.multidomain.urlreverse import eventreverse from pretix.multidomain.urlreverse import eventreverse
from pretix.presale.forms.user import ResendLinkForm from pretix.presale.forms.user import ResendLinkForm
from pretix.presale.views import EventViewMixin from pretix.presale.views import EventViewMixin
@@ -71,7 +71,7 @@ class ResendLinkView(EventViewMixin, TemplateView):
'already sent you an email with a link to your ticket in the past {number} hours. ' 'already sent you an email with a link to your ticket in the past {number} hours. '
'If the email did not arrive, please check your spam folder and also double check ' 'If the email did not arrive, please check your spam folder and also double check '
'that you used the correct email address.').format(number=24)) 'that you used the correct email address.').format(number=24))
return redirect(eventreverse(self.request.event, 'presale:event.resend_link')) return redirect_to_url(eventreverse(self.request.event, 'presale:event.resend_link'))
else: else:
rc.setex('pretix_resend_{}_{}'.format(request.event.pk, user), 3600 * 24, '1') rc.setex('pretix_resend_{}_{}'.format(request.event.pk, user), 3600 * 24, '1')
@@ -92,7 +92,7 @@ class ResendLinkView(EventViewMixin, TemplateView):
return self.get(request, *args, **kwargs) return self.get(request, *args, **kwargs)
messages.success(self.request, _('If there were any orders by this user, they will receive an email with their order codes.')) messages.success(self.request, _('If there were any orders by this user, they will receive an email with their order codes.'))
return redirect(eventreverse(self.request.event, 'presale:event.index')) return redirect_to_url(eventreverse(self.request.event, 'presale:event.index'))
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
@@ -107,4 +107,4 @@ class UnlockHashView(EventViewMixin, View):
hashes = request.session.get('pretix_unlock_hashes', []) hashes = request.session.get('pretix_unlock_hashes', [])
hashes.append(kwargs.get('hash')) hashes.append(kwargs.get('hash'))
request.session['pretix_unlock_hashes'] = hashes request.session['pretix_unlock_hashes'] = hashes
return redirect(eventreverse(self.request.event, 'presale:event.index')) return redirect_to_url(eventreverse(self.request.event, 'presale:event.index'))