From f33c15b5d1f04bc34868612ff17102d4ca3125e5 Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Fri, 12 Jun 2026 14:34:49 +0200 Subject: [PATCH] Rename confusingly named helpers for URL generation --- doc/development/implementation/urlconfig.rst | 2 +- src/pretix/api/serializers/event.py | 4 +- src/pretix/api/serializers/order.py | 6 +- src/pretix/api/serializers/organizer.py | 8 +-- src/pretix/base/customersso/oidc.py | 4 +- src/pretix/base/datasync/sourcefields.py | 6 +- src/pretix/base/exporters/orderlist.py | 6 +- src/pretix/base/models/auth.py | 6 +- src/pretix/base/models/customers.py | 8 +-- src/pretix/base/models/event.py | 4 +- src/pretix/base/notifications.py | 4 +- src/pretix/base/payment.py | 4 +- src/pretix/base/services/export.py | 6 +- src/pretix/base/services/mail.py | 6 +- src/pretix/base/services/notifications.py | 6 +- src/pretix/base/services/placeholders.py | 58 +++++++++---------- src/pretix/base/services/update_check.py | 4 +- src/pretix/control/forms/event.py | 4 +- src/pretix/control/forms/organizer.py | 4 +- src/pretix/control/views/event.py | 6 +- src/pretix/control/views/organizer.py | 18 +++--- src/pretix/control/views/vouchers.py | 4 +- src/pretix/helpers/security.py | 4 +- src/pretix/helpers/urls.py | 10 ++++ .../multidomain/templatetags/eventurl.py | 4 +- src/pretix/multidomain/urlreverse.py | 10 ++++ src/pretix/plugins/paypal/payment.py | 12 ++-- src/pretix/plugins/paypal2/payment.py | 12 ++-- src/pretix/plugins/stripe/payment.py | 18 +++--- src/pretix/plugins/stripe/views.py | 4 +- src/pretix/presale/forms/customer.py | 4 +- src/pretix/presale/ical.py | 12 ++-- src/pretix/presale/utils.py | 4 +- src/pretix/presale/views/customer.py | 14 +++-- src/pretix/presale/views/oidc_op.py | 12 ++-- src/pretix/presale/views/order.py | 4 +- src/pretix/presale/views/organizer.py | 4 +- src/pretix/presale/views/widget.py | 12 ++-- src/tests/helpers/test_urls.py | 6 +- src/tests/multidomain/test_urlreverse.py | 10 ++-- 40 files changed, 180 insertions(+), 154 deletions(-) diff --git a/doc/development/implementation/urlconfig.rst b/doc/development/implementation/urlconfig.rst index e1f5b86417..881d7c147d 100644 --- a/doc/development/implementation/urlconfig.rst +++ b/doc/development/implementation/urlconfig.rst @@ -81,7 +81,7 @@ is a python method that emulates a behavior similar to ``reverse``: If you need to communicate the URL externally, you can use a different method to ensure that it is always an absolute URL: -.. autofunction:: pretix.multidomain.urlreverse.build_absolute_uri +.. autofunction:: pretix.multidomain.urlreverse.eventreverse_absolute In addition, there is a template tag that works similar to ``url`` but takes an event or organizer object as its first argument and can be used like this:: diff --git a/src/pretix/api/serializers/event.py b/src/pretix/api/serializers/event.py index 52411e8fda..c6fef3d69c 100644 --- a/src/pretix/api/serializers/event.py +++ b/src/pretix/api/serializers/event.py @@ -73,7 +73,7 @@ from pretix.base.settings import ( LazyI18nStringList, validate_event_settings, ) from pretix.base.signals import api_event_settings_fields -from pretix.multidomain.urlreverse import build_absolute_uri +from pretix.multidomain.urlreverse import eventreverse_absolute logger = logging.getLogger(__name__) @@ -173,7 +173,7 @@ class EventSerializer(SalesChannelMigrationMixin, I18nAwareModelSerializer): ) def get_event_url(self, event): - return build_absolute_uri(event, 'presale:event.index') + return eventreverse_absolute(event, 'presale:event.index') class Meta: model = Event diff --git a/src/pretix/api/serializers/order.py b/src/pretix/api/serializers/order.py index 7ce4c567d4..83533a73c6 100644 --- a/src/pretix/api/serializers/order.py +++ b/src/pretix/api/serializers/order.py @@ -76,7 +76,7 @@ from pretix.base.settings import ( ) from pretix.base.signals import register_ticket_outputs from pretix.helpers.countries import CachedCountries -from pretix.multidomain.urlreverse import build_absolute_uri +from pretix.multidomain.urlreverse import eventreverse_absolute logger = logging.getLogger(__name__) @@ -757,7 +757,7 @@ class PaymentURLField(serializers.URLField): def to_representation(self, instance: OrderPayment): if instance.state != OrderPayment.PAYMENT_STATE_CREATED: return None - return build_absolute_uri(instance.order.event, 'presale:event.order.pay', kwargs={ + return eventreverse_absolute(instance.order.event, 'presale:event.order.pay', kwargs={ 'order': instance.order.code, 'secret': instance.order.secret, 'payment': instance.pk, @@ -806,7 +806,7 @@ class OrderRefundSerializer(I18nAwareModelSerializer): class OrderURLField(serializers.URLField): def to_representation(self, instance: Order): - return build_absolute_uri(instance.event, 'presale:event.order', kwargs={ + return eventreverse_absolute(instance.event, 'presale:event.order', kwargs={ 'order': instance.code, 'secret': instance.secret, }) diff --git a/src/pretix/api/serializers/organizer.py b/src/pretix/api/serializers/organizer.py index 9d595f7624..2dc03c7579 100644 --- a/src/pretix/api/serializers/organizer.py +++ b/src/pretix/api/serializers/organizer.py @@ -58,8 +58,8 @@ from pretix.helpers.permission_migration import ( OLD_TO_NEW_EVENT_COMPAT, OLD_TO_NEW_EVENT_MIGRATION, OLD_TO_NEW_ORGANIZER_COMPAT, OLD_TO_NEW_ORGANIZER_MIGRATION, ) -from pretix.helpers.urls import build_absolute_uri as build_global_uri -from pretix.multidomain.urlreverse import build_absolute_uri +from pretix.helpers.urls import build_absolute_uri +from pretix.multidomain.urlreverse import eventreverse_absolute logger = logging.getLogger(__name__) @@ -71,7 +71,7 @@ class OrganizerSerializer(I18nAwareModelSerializer): slug = serializers.CharField(read_only=True) def get_organizer_url(self, organizer): - return build_absolute_uri(organizer, 'presale:organizer.index') + return eventreverse_absolute(organizer, 'presale:organizer.index') class Meta: model = Organizer @@ -499,7 +499,7 @@ class TeamInviteSerializer(serializers.ModelSerializer): 'user': self, 'organizer': self.context['organizer'].name, 'team': instance.team.name, - 'url': build_global_uri('control:auth.invite', kwargs={ + 'url': build_absolute_uri('control:auth.invite', kwargs={ 'token': instance.token }) }, diff --git a/src/pretix/base/customersso/oidc.py b/src/pretix/base/customersso/oidc.py index 638f0be2a3..0e2d6e417e 100644 --- a/src/pretix/base/customersso/oidc.py +++ b/src/pretix/base/customersso/oidc.py @@ -36,7 +36,7 @@ from django.core.exceptions import ValidationError from django.utils.translation import gettext_lazy as _ from requests import RequestException -from pretix.multidomain.urlreverse import build_absolute_uri +from pretix.multidomain.urlreverse import eventreverse_absolute logger = logging.getLogger(__name__) @@ -313,7 +313,7 @@ def _get_or_create_server_keypair(organizer): def generate_id_token(customer, client, auth_time, nonce, scope, expires: datetime, scope_claims=False, with_code=None, with_access_token=None): payload = { - 'iss': build_absolute_uri(client.organizer, 'presale:organizer.index').rstrip('/'), + 'iss': eventreverse_absolute(client.organizer, 'presale:organizer.index').rstrip('/'), 'aud': client.client_id, 'exp': int(expires.timestamp()), 'iat': int(time.time()), diff --git a/src/pretix/base/datasync/sourcefields.py b/src/pretix/base/datasync/sourcefields.py index 156145cb8d..426604d66e 100644 --- a/src/pretix/base/datasync/sourcefields.py +++ b/src/pretix/base/datasync/sourcefields.py @@ -28,7 +28,7 @@ from django.utils.translation import gettext_lazy as _, pgettext_lazy from pretix.base.models import Checkin, InvoiceAddress, Order, Question from pretix.base.settings import PERSON_NAME_SCHEMES -from pretix.multidomain.urlreverse import build_absolute_uri +from pretix.multidomain.urlreverse import eventreverse_absolute def get_answer(op, question_identifier=None): @@ -545,7 +545,7 @@ def get_data_fields(event, for_model=None): _("Order link"), Question.TYPE_STRING, None, - lambda order: build_absolute_uri( + lambda order: eventreverse_absolute( event, 'presale:event.order', kwargs={ 'order': order.code, @@ -560,7 +560,7 @@ def get_data_fields(event, for_model=None): _("Ticket link"), Question.TYPE_STRING, None, - lambda op: build_absolute_uri( + lambda op: eventreverse_absolute( event, 'presale:event.order.position', kwargs={ 'order': op.order.code, diff --git a/src/pretix/base/exporters/orderlist.py b/src/pretix/base/exporters/orderlist.py index 7e401e17c8..bf96145ec4 100644 --- a/src/pretix/base/exporters/orderlist.py +++ b/src/pretix/base/exporters/orderlist.py @@ -68,7 +68,7 @@ from ...control.forms.filter import get_all_payment_providers from ...helpers import GroupConcat from ...helpers.iter import chunked_iterable from ...helpers.safe_openpyxl import remove_invalid_excel_chars -from ...multidomain.urlreverse import build_absolute_uri +from ...multidomain.urlreverse import eventreverse_absolute from ..exporter import ( ListExporter, MultiSheetListExporter, OrganizerLevelExportMixin, ) @@ -429,7 +429,7 @@ class OrderListExporter(MultiSheetListExporter): ])) row.append( - build_absolute_uri(order.event, 'presale:event.order', kwargs={ + eventreverse_absolute(order.event, 'presale:event.order', kwargs={ 'order': order.code, 'secret': order.secret, }) @@ -855,7 +855,7 @@ class OrderListExporter(MultiSheetListExporter): ])) row.append( - build_absolute_uri(order.event, 'presale:event.order.position', kwargs={ + eventreverse_absolute(order.event, 'presale:event.order.position', kwargs={ 'order': order.code, 'secret': op.web_secret, 'position': op.positionid diff --git a/src/pretix/base/models/auth.py b/src/pretix/base/models/auth.py index d783f7290c..18b43465b6 100644 --- a/src/pretix/base/models/auth.py +++ b/src/pretix/base/models/auth.py @@ -57,7 +57,7 @@ from django_otp.models import Device from django_scopes import scopes_disabled from pretix.base.i18n import language -from pretix.helpers.urls import build_absolute_uri +from pretix.helpers.urls import reverse_absolute_url_global_domain from ...helpers.countries import FastCountryField from ...helpers.u2f import pub_key_from_der, websafe_decode @@ -378,7 +378,7 @@ class User(AbstractBaseUser, PermissionsMixin, LoggingMixin): { 'user': self, 'messages': msg, - 'url': build_absolute_uri('control:user.settings'), + 'url': reverse_absolute_url_global_domain('control:user.settings'), 'instance': settings.PRETIX_INSTANCE_NAME, }, event=None, @@ -466,7 +466,7 @@ class User(AbstractBaseUser, PermissionsMixin, LoggingMixin): { 'instance': settings.PRETIX_INSTANCE_NAME, 'user': self, - 'url': (build_absolute_uri('control:auth.forgot.recover') + 'url': (reverse_absolute_url_global_domain('control:auth.forgot.recover') + '?id=%d&token=%s' % (self.id, default_token_generator.make_token(self))) }, None, locale=self.locale, user=self diff --git a/src/pretix/base/models/customers.py b/src/pretix/base/models/customers.py index ef9a3b26be..0b3ae5732b 100644 --- a/src/pretix/base/models/customers.py +++ b/src/pretix/base/models/customers.py @@ -167,7 +167,7 @@ class Customer(LoggedModel): def send_security_notice(self, message, email=None): from pretix.base.services.mail import SendMailException, mail - from pretix.multidomain.urlreverse import build_absolute_uri + from pretix.multidomain.urlreverse import eventreverse_absolute try: with language(self.locale): @@ -178,7 +178,7 @@ class Customer(LoggedModel): { **self.get_email_context(), 'message': str(message), - 'url': build_absolute_uri(self.organizer, 'presale:organizer.customer.index') + 'url': eventreverse_absolute(self.organizer, 'presale:organizer.customer.index') }, customer=self, organizer=self.organizer, @@ -299,12 +299,12 @@ class Customer(LoggedModel): def send_activation_mail(self): from pretix.base.services.mail import mail - from pretix.multidomain.urlreverse import build_absolute_uri + from pretix.multidomain.urlreverse import eventreverse_absolute from pretix.presale.forms.customer import TokenGenerator ctx = self.get_email_context() token = TokenGenerator().make_token(self) - ctx['url'] = build_absolute_uri( + ctx['url'] = eventreverse_absolute( self.organizer, 'presale:organizer.customer.activate' ) + '?id=' + self.identifier + '&token=' + token diff --git a/src/pretix/base/models/event.py b/src/pretix/base/models/event.py index 1feed0e367..63f70d03c4 100644 --- a/src/pretix/base/models/event.py +++ b/src/pretix/base/models/event.py @@ -724,7 +724,7 @@ class Event(EventMixin, LoggedModel): @property def social_image(self): - from pretix.multidomain.urlreverse import build_absolute_uri + from pretix.multidomain.urlreverse import eventreverse_absolute img = None logo_file = self.settings.get('logo_image', as_type=str, default='')[7:] @@ -742,7 +742,7 @@ class Event(EventMixin, LoggedModel): logger.exception(f'Failed to create thumbnail of {logo_file}') img = default_storage.url(logo_file) if img: - return urljoin(build_absolute_uri(self, 'presale:event.index'), img) + return urljoin(eventreverse_absolute(self, 'presale:event.index'), img) def _seats(self, ignore_voucher=None): from .seating import Seat diff --git a/src/pretix/base/notifications.py b/src/pretix/base/notifications.py index e29b947235..98f4f45287 100644 --- a/src/pretix/base/notifications.py +++ b/src/pretix/base/notifications.py @@ -43,7 +43,7 @@ from django.utils.translation import gettext_lazy as _, pgettext_lazy from pretix.base.models import Event, LogEntry from pretix.base.signals import register_notification_types from pretix.base.templatetags.money import money_filter -from pretix.helpers.urls import build_absolute_uri +from pretix.helpers.urls import reverse_absolute_url_global_domain logger = logging.getLogger(__name__) _ALL_TYPES = None @@ -170,7 +170,7 @@ class ParametrizedOrderNotificationType(NotificationType): def build_notification(self, logentry: LogEntry): order = logentry.content_object - order_url = build_absolute_uri( + order_url = reverse_absolute_url_global_domain( 'control:event.order', kwargs={ 'organizer': logentry.event.organizer.slug, diff --git a/src/pretix/base/payment.py b/src/pretix/base/payment.py index ddd42318f1..1c6822a4c5 100644 --- a/src/pretix/base/payment.py +++ b/src/pretix/base/payment.py @@ -71,7 +71,7 @@ from pretix.helpers import OF_SELF from pretix.helpers.countries import CachedCountries from pretix.helpers.format import format_map from pretix.helpers.money import DecimalTextInput -from pretix.multidomain.urlreverse import build_absolute_uri +from pretix.multidomain.urlreverse import eventreverse_absolute from pretix.presale.views import get_cart from pretix.presale.views.cart import cart_session, get_or_create_cart_id @@ -379,7 +379,7 @@ class BasePaymentProvider: if not self.settings.get('_hidden_seed'): self.settings.set('_hidden_seed', get_random_string(64)) - hidden_url = build_absolute_uri(self.event, 'presale:event.payment.unlock', kwargs={ + hidden_url = eventreverse_absolute(self.event, 'presale:event.payment.unlock', kwargs={ 'hash': hashlib.sha256((self.settings._hidden_seed + self.event.slug).encode()).hexdigest(), }) diff --git a/src/pretix/base/services/export.py b/src/pretix/base/services/export.py index c04119cf67..6bbe972daa 100644 --- a/src/pretix/base/services/export.py +++ b/src/pretix/base/services/export.py @@ -51,7 +51,7 @@ from pretix.base.signals import ( ) from pretix.celery_app import app from pretix.helpers import OF_SELF, repeatable_reads_transaction -from pretix.helpers.urls import build_absolute_uri +from pretix.helpers.urls import reverse_absolute_url_global_domain logger = logging.getLogger(__name__) @@ -455,7 +455,7 @@ def scheduled_organizer_export(self, organizer: Organizer, schedule: int) -> Non schedule, organizer, exporter, - build_absolute_uri( + reverse_absolute_url_global_domain( 'control:organizer.export', kwargs={ 'organizer': organizer.slug, @@ -481,7 +481,7 @@ def scheduled_event_export(self, event: Event, schedule: int) -> None: schedule, event, exporter, - build_absolute_uri( + reverse_absolute_url_global_domain( 'control:event.orders.export', kwargs={ 'event': event.slug, diff --git a/src/pretix/base/services/mail.py b/src/pretix/base/services/mail.py index b5fae6ba75..3b1b13f9d0 100644 --- a/src/pretix/base/services/mail.py +++ b/src/pretix/base/services/mail.py @@ -85,7 +85,7 @@ from pretix.helpers.format import ( FormattedString, PlainHtmlAlternativeString, SafeFormatter, format_map, ) from pretix.helpers.hierarkey import clean_filename -from pretix.multidomain.urlreverse import build_absolute_uri +from pretix.multidomain.urlreverse import eventreverse_absolute from pretix.presale.ical import get_private_icals logger = logging.getLogger('pretix.base.mail') @@ -997,7 +997,7 @@ def _wrap_plain_body(content_plain, signature, event, order, position, no_order_ body_plain += _( "You can view your order details at the following URL:\n{orderurl}." ).replace("\n", "\r\n").format( - orderurl=build_absolute_uri( + orderurl=eventreverse_absolute( order.event, 'presale:event.order.position', kwargs={ 'order': order.code, 'secret': position.web_secret, @@ -1013,7 +1013,7 @@ def _wrap_plain_body(content_plain, signature, event, order, position, no_order_ body_plain += _( "You can view your order details at the following URL:\n{orderurl}." ).replace("\n", "\r\n").format( - event=event.name, orderurl=build_absolute_uri( + event=event.name, orderurl=eventreverse_absolute( order.event, 'presale:event.order.open', kwargs={ 'order': order.code, 'secret': order.secret, diff --git a/src/pretix/base/services/notifications.py b/src/pretix/base/services/notifications.py index 0a70e7c32d..eaa94c1e24 100644 --- a/src/pretix/base/services/notifications.py +++ b/src/pretix/base/services/notifications.py @@ -37,7 +37,7 @@ from pretix.base.services.tasks import ProfiledTask, TransactionAwareTask from pretix.base.signals import notification from pretix.celery_app import app from pretix.helpers.celery import get_task_priority -from pretix.helpers.urls import build_absolute_uri +from pretix.helpers.urls import reverse_absolute_url_global_domain @app.task(base=TransactionAwareTask, acks_late=True, max_retries=9, default_retry_delay=900) @@ -136,10 +136,10 @@ def send_notification_mail(notification: Notification, user: User): 'site_url': settings.SITE_URL, 'color': settings.PRETIX_PRIMARY_COLOR, 'notification': notification, - 'settings_url': build_absolute_uri( + 'settings_url': reverse_absolute_url_global_domain( 'control:user.settings.notifications', ), - 'disable_url': build_absolute_uri( + 'disable_url': reverse_absolute_url_global_domain( 'control:user.settings.notifications.off', kwargs={ 'token': user.notifications_token, diff --git a/src/pretix/base/services/placeholders.py b/src/pretix/base/services/placeholders.py index f9b81554d3..1776b25e0e 100644 --- a/src/pretix/base/services/placeholders.py +++ b/src/pretix/base/services/placeholders.py @@ -327,7 +327,7 @@ def get_best_name(position_or_address, parts=False): @receiver(register_text_placeholders, dispatch_uid="pretixbase_register_text_placeholders") def base_placeholders(sender, **kwargs): - from pretix.multidomain.urlreverse import build_absolute_uri + from pretix.multidomain.urlreverse import eventreverse_absolute def _event_sample(event): if event.has_subevents: @@ -388,14 +388,14 @@ def base_placeholders(sender, **kwargs): lambda event: LazyDate(now() + timedelta(days=15)) ), SimpleFunctionalTextPlaceholder( - 'url', ['order', 'event'], lambda order, event: build_absolute_uri( + 'url', ['order', 'event'], lambda order, event: eventreverse_absolute( event, 'presale:event.order.open', kwargs={ 'order': order.code, 'secret': order.secret, 'hash': order.email_confirm_secret() } - ), lambda event: build_absolute_uri( + ), lambda event: eventreverse_absolute( event, 'presale:event.order.open', kwargs={ 'order': 'F8VVL', @@ -406,7 +406,7 @@ def base_placeholders(sender, **kwargs): ), SimpleButtonPlaceholder( 'url_button', ['order', 'event'], - url_func=lambda order, event: build_absolute_uri( + url_func=lambda order, event: eventreverse_absolute( event, 'presale:event.order.open', kwargs={ 'order': order.code, @@ -415,7 +415,7 @@ def base_placeholders(sender, **kwargs): } ), text_func=lambda order, event: _("View order details"), - sample_url_func=lambda event: build_absolute_uri( + sample_url_func=lambda event: eventreverse_absolute( event, 'presale:event.order.open', kwargs={ 'order': 'F8VVL', @@ -426,13 +426,13 @@ def base_placeholders(sender, **kwargs): sample_text_func=lambda event: _("View order details"), ), SimpleFunctionalTextPlaceholder( - 'url_info_change', ['order', 'event'], lambda order, event: build_absolute_uri( + 'url_info_change', ['order', 'event'], lambda order, event: eventreverse_absolute( event, 'presale:event.order.modify', kwargs={ 'order': order.code, 'secret': order.secret, } - ), lambda event: build_absolute_uri( + ), lambda event: eventreverse_absolute( event, 'presale:event.order.modify', kwargs={ 'order': 'F8VVL', @@ -441,13 +441,13 @@ def base_placeholders(sender, **kwargs): ), ), SimpleFunctionalTextPlaceholder( - 'url_products_change', ['order', 'event'], lambda order, event: build_absolute_uri( + 'url_products_change', ['order', 'event'], lambda order, event: eventreverse_absolute( event, 'presale:event.order.change', kwargs={ 'order': order.code, 'secret': order.secret, } - ), lambda event: build_absolute_uri( + ), lambda event: eventreverse_absolute( event, 'presale:event.order.change', kwargs={ 'order': 'F8VVL', @@ -456,13 +456,13 @@ def base_placeholders(sender, **kwargs): ), ), SimpleFunctionalTextPlaceholder( - 'url_cancel', ['order', 'event'], lambda order, event: build_absolute_uri( + 'url_cancel', ['order', 'event'], lambda order, event: eventreverse_absolute( event, 'presale:event.order.cancel', kwargs={ 'order': order.code, 'secret': order.secret, } - ), lambda event: build_absolute_uri( + ), lambda event: eventreverse_absolute( event, 'presale:event.order.cancel', kwargs={ 'order': 'F8VVL', @@ -471,7 +471,7 @@ def base_placeholders(sender, **kwargs): ), ), SimpleFunctionalTextPlaceholder( - 'url', ['event', 'position'], lambda event, position: build_absolute_uri( + 'url', ['event', 'position'], lambda event, position: eventreverse_absolute( event, 'presale:event.order.position', kwargs={ @@ -480,7 +480,7 @@ def base_placeholders(sender, **kwargs): 'position': position.positionid } ), - lambda event: build_absolute_uri( + lambda event: eventreverse_absolute( event, 'presale:event.order.position', kwargs={ 'order': 'F8VVL', @@ -491,7 +491,7 @@ def base_placeholders(sender, **kwargs): ), SimpleButtonPlaceholder( 'url_button', ['event', 'position'], - url_func=lambda event, position: build_absolute_uri( + url_func=lambda event, position: eventreverse_absolute( event, 'presale:event.order.position', kwargs={ 'order': position.order.code, @@ -500,7 +500,7 @@ def base_placeholders(sender, **kwargs): } ), text_func=lambda event, position: _("View registration details"), - sample_url_func=lambda event: build_absolute_uri( + sample_url_func=lambda event: eventreverse_absolute( event, 'presale:event.order.position', kwargs={ 'order': 'F8VVL', @@ -511,14 +511,14 @@ def base_placeholders(sender, **kwargs): sample_text_func=lambda event: _("View registration details"), ), SimpleFunctionalTextPlaceholder( - 'url_info_change', ['position', 'event'], lambda position, event: build_absolute_uri( + 'url_info_change', ['position', 'event'], lambda position, event: eventreverse_absolute( event, 'presale:event.order.position.modify', kwargs={ 'order': position.order.code, 'secret': position.web_secret, 'position': position.positionid } - ), lambda event: build_absolute_uri( + ), lambda event: eventreverse_absolute( event, 'presale:event.order.position.modify', kwargs={ 'order': 'F8VVL', @@ -528,14 +528,14 @@ def base_placeholders(sender, **kwargs): ), ), SimpleFunctionalTextPlaceholder( - 'url_products_change', ['position', 'event'], lambda position, event: build_absolute_uri( + 'url_products_change', ['position', 'event'], lambda position, event: eventreverse_absolute( event, 'presale:event.order.position.change', kwargs={ 'order': position.order.code, 'secret': position.web_secret, 'position': position.positionid } - ), lambda event: build_absolute_uri( + ), lambda event: eventreverse_absolute( event, 'presale:event.order.position.change', kwargs={ 'order': 'F8VVL', @@ -581,20 +581,20 @@ def base_placeholders(sender, **kwargs): ), SimpleFunctionalTextPlaceholder( 'url_remove', ['waiting_list_voucher', 'event'], - lambda waiting_list_voucher, event: build_absolute_uri( + lambda waiting_list_voucher, event: eventreverse_absolute( event, 'presale:event.waitinglist.remove' ) + '?voucher=' + waiting_list_voucher.code, - lambda event: build_absolute_uri( + lambda event: eventreverse_absolute( event, 'presale:event.waitinglist.remove', ) + '?voucher=68CYU2H6ZTP3WLK5', ), SimpleFunctionalTextPlaceholder( 'url', ['waiting_list_voucher', 'event'], - lambda waiting_list_voucher, event: build_absolute_uri( + lambda waiting_list_voucher, event: eventreverse_absolute( event, 'presale:event.redeem' ) + '?voucher=' + waiting_list_voucher.code, - lambda event: build_absolute_uri( + lambda event: eventreverse_absolute( event, 'presale:event.redeem', ) + '?voucher=68CYU2H6ZTP3WLK5', @@ -611,7 +611,7 @@ def base_placeholders(sender, **kwargs): 'orders', ['event', 'orders'], lambda event, orders: '\n' + '\n\n'.join( '* {} - {}'.format( order.full_code, - build_absolute_uri(event, 'presale:event.order.open', kwargs={ + eventreverse_absolute(event, 'presale:event.order.open', kwargs={ 'event': event.slug, 'organizer': event.organizer.slug, 'order': order.code, @@ -623,7 +623,7 @@ def base_placeholders(sender, **kwargs): ), lambda event: '\n' + '\n\n'.join( '* {} - {}'.format( '{}-{}'.format(event.slug.upper(), order['code']), - build_absolute_uri(event, 'presale:event.order.open', kwargs={ + eventreverse_absolute(event, 'presale:event.order.open', kwargs={ 'event': event.slug, 'organizer': event.organizer.slug, 'order': order['code'], @@ -662,13 +662,13 @@ def base_placeholders(sender, **kwargs): # join vouchers with two spaces at end of line so markdown-parser inserts a
'voucher_url_list', ['event', 'voucher_list'], lambda event, voucher_list: ' \n'.join([ - build_absolute_uri( + eventreverse_absolute( event, 'presale:event.redeem' ) + '?voucher=' + c for c in voucher_list ]), lambda event: ' \n'.join([ - build_absolute_uri( + eventreverse_absolute( event, 'presale:event.redeem' ) + '?voucher=' + c for c in ['68CYU2H6ZTP3WLK5', '7MB94KKPVEPSMVF2'] @@ -676,10 +676,10 @@ def base_placeholders(sender, **kwargs): inline=False, ), SimpleFunctionalTextPlaceholder( - 'url', ['event', 'voucher_list'], lambda event, voucher_list: build_absolute_uri(event, 'presale:event.index', kwargs={ + 'url', ['event', 'voucher_list'], lambda event, voucher_list: eventreverse_absolute(event, 'presale:event.index', kwargs={ 'event': event.slug, 'organizer': event.organizer.slug, - }), lambda event: build_absolute_uri(event, 'presale:event.index', kwargs={ + }), lambda event: eventreverse_absolute(event, 'presale:event.index', kwargs={ 'event': event.slug, 'organizer': event.organizer.slug, }) diff --git a/src/pretix/base/services/update_check.py b/src/pretix/base/services/update_check.py index 5a23b33884..801cb55b2a 100644 --- a/src/pretix/base/services/update_check.py +++ b/src/pretix/base/services/update_check.py @@ -37,7 +37,7 @@ from pretix.base.services.mail import mail from pretix.base.settings import GlobalSettingsObject from pretix.base.signals import periodic_task from pretix.celery_app import app -from pretix.helpers.urls import build_absolute_uri +from pretix.helpers.urls import reverse_absolute_url_global_domain @receiver(signal=periodic_task) @@ -121,7 +121,7 @@ def send_update_notification_email(): ) ), { - 'url': build_absolute_uri('control:global.update') + 'url': reverse_absolute_url_global_domain('control:global.update') }, ) diff --git a/src/pretix/control/forms/event.py b/src/pretix/control/forms/event.py index 6d672f204e..ca5a34d4c8 100644 --- a/src/pretix/control/forms/event.py +++ b/src/pretix/control/forms/event.py @@ -80,7 +80,7 @@ from pretix.control.forms.widgets import Select2 from pretix.helpers.countries import CachedCountries from pretix.multidomain.models import AlternativeDomainAssignment, KnownDomain from pretix.multidomain.urlreverse import ( - build_absolute_uri, get_organizer_domain, + eventreverse_absolute, get_organizer_domain, ) from pretix.plugins.banktransfer.payment import BankTransfer from pretix.presale.style import get_fonts @@ -219,7 +219,7 @@ class EventWizardBasicsForm(I18nModelForm): self.fields['location'].widget.attrs['placeholder'] = _( 'Sample Conference Center\nHeidelberg, Germany' ) - self.fields['slug'].widget.prefix = build_absolute_uri(self.organizer, 'presale:organizer.index') + self.fields['slug'].widget.prefix = eventreverse_absolute(self.organizer, 'presale:organizer.index') self.fields['tax_rate']._required = True # Do not render as optional because it is conditionally required if self.has_subevents: del self.fields['presale_start'] diff --git a/src/pretix/control/forms/organizer.py b/src/pretix/control/forms/organizer.py index f4175ddcda..0078562506 100644 --- a/src/pretix/control/forms/organizer.py +++ b/src/pretix/control/forms/organizer.py @@ -88,7 +88,7 @@ from pretix.control.forms.event import ( ) from pretix.control.forms.widgets import Select2, Select2Multiple from pretix.multidomain.models import KnownDomain -from pretix.multidomain.urlreverse import build_absolute_uri +from pretix.multidomain.urlreverse import eventreverse_absolute class OrganizerForm(I18nModelForm): @@ -791,7 +791,7 @@ class MailSettingsForm(SettingsForm): } if 'url' in base_parameters: - placeholders['url'] = build_absolute_uri( + placeholders['url'] = eventreverse_absolute( self.organizer, 'presale:organizer.customer.activate' ) + '?token=' + get_random_string(30) diff --git a/src/pretix/control/views/event.py b/src/pretix/control/views/event.py index d566050fca..6949f76759 100644 --- a/src/pretix/control/views/event.py +++ b/src/pretix/control/views/event.py @@ -97,7 +97,9 @@ from pretix.control.permissions import EventPermissionRequiredMixin from pretix.control.views.mailsetup import MailSettingsSetupView from pretix.control.views.user import RecentAuthenticationRequiredMixin from pretix.helpers.database import rolledback_transaction -from pretix.multidomain.urlreverse import build_absolute_uri, get_event_domain +from pretix.multidomain.urlreverse import ( + eventreverse_absolute, get_event_domain, +) from pretix.presale.views.widget import ( version_default as widget_version_default, ) @@ -1734,7 +1736,7 @@ class EventQRCode(EventPermissionRequiredMixin, View): permission = None def get(self, request, *args, filetype, **kwargs): - url = build_absolute_uri(request.event, 'presale:event.index') + url = eventreverse_absolute(request.event, 'presale:event.index') if "url" in request.GET: if url_has_allowed_host_and_scheme(request.GET["url"], allowed_hosts=[urlparse(url).netloc]): diff --git a/src/pretix/control/views/organizer.py b/src/pretix/control/views/organizer.py index c7c64fc90e..ef490b437a 100644 --- a/src/pretix/control/views/organizer.py +++ b/src/pretix/control/views/organizer.py @@ -139,8 +139,8 @@ from pretix.helpers import OF_SELF, GroupConcat from pretix.helpers.compat import CompatDeleteView from pretix.helpers.dicts import merge_dicts from pretix.helpers.format import SafeFormatter, format_map -from pretix.helpers.urls import build_absolute_uri as build_global_uri -from pretix.multidomain.urlreverse import build_absolute_uri +from pretix.helpers.urls import reverse_absolute_url_global_domain +from pretix.multidomain.urlreverse import eventreverse_absolute from pretix.presale.forms.customer import TokenGenerator logger = logging.getLogger(__name__) @@ -1039,7 +1039,7 @@ class TeamMemberView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMixin, 'user': self, 'organizer': self.request.organizer.name, 'team': instance.team.name, - 'url': build_global_uri('control:auth.invite', kwargs={ + 'url': reverse_absolute_url_global_domain('control:auth.invite', kwargs={ 'token': instance.token }) }, @@ -2851,10 +2851,12 @@ class SSOProviderUpdateView(OrganizerDetailViewMixin, OrganizerPermissionRequire def get_context_data(self, **kwargs): ctx = super().get_context_data(**kwargs) - ctx['redirect_uri'] = build_absolute_uri(self.request.organizer, 'presale:organizer.customer.login.return', - kwargs={ - 'provider': self.object.pk - }) + ctx['redirect_uri'] = eventreverse_absolute( + self.request.organizer, 'presale:organizer.customer.login.return', + kwargs={ + 'provider': self.object.pk + } + ) return ctx def get_form_kwargs(self): @@ -3085,7 +3087,7 @@ class CustomerDetailView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMi self.customer.log_action('pretix.customer.password.resetrequested', {}, user=self.request.user) ctx = self.customer.get_email_context() token = TokenGenerator().make_token(self.customer) - ctx['url'] = build_absolute_uri( + ctx['url'] = eventreverse_absolute( self.request.organizer, 'presale:organizer.customer.recoverpw' ) + '?id=' + self.customer.identifier + '&token=' + token diff --git a/src/pretix/control/views/vouchers.py b/src/pretix/control/views/vouchers.py index 4745f887cc..c5ae68eb2c 100644 --- a/src/pretix/control/views/vouchers.py +++ b/src/pretix/control/views/vouchers.py @@ -77,7 +77,7 @@ from pretix.control.views import PaginationMixin from pretix.helpers.compat import CompatDeleteView from pretix.helpers.format import SafeFormatter, format_map from pretix.helpers.models import modelcopy -from pretix.multidomain.urlreverse import build_absolute_uri +from pretix.multidomain.urlreverse import eventreverse_absolute class VoucherList(PaginationMixin, EventPermissionRequiredMixin, ListView): @@ -338,7 +338,7 @@ class VoucherUpdate(EventPermissionRequiredMixin, UpdateView): } if self.object.subevent_id: url_params['subevent'] = self.object.subevent_id - ctx['url'] = build_absolute_uri(self.request.event, "presale:event.redeem") + "?" + urlencode(url_params) + ctx['url'] = eventreverse_absolute(self.request.event, "presale:event.redeem") + "?" + urlencode(url_params) return ctx diff --git a/src/pretix/helpers/security.py b/src/pretix/helpers/security.py index d09fbe0f3d..5542c62138 100644 --- a/src/pretix/helpers/security.py +++ b/src/pretix/helpers/security.py @@ -35,7 +35,7 @@ from geoip2.errors import AddressNotFoundError from pretix.base.i18n import language from pretix.base.services.mail import mail from pretix.helpers.http import get_client_ip -from pretix.helpers.urls import build_absolute_uri +from pretix.helpers.urls import reverse_absolute_url_global_domain logger = logging.getLogger(__name__) @@ -175,7 +175,7 @@ def handle_login_source(user, request): 'source': src, 'country': Country(str(country)).name if country else _('Unknown country'), 'instance': settings.PRETIX_INSTANCE_NAME, - 'url': build_absolute_uri('control:user.settings') + 'url': reverse_absolute_url_global_domain('control:user.settings') }, event=None, user=user, diff --git a/src/pretix/helpers/urls.py b/src/pretix/helpers/urls.py index 7a91d498a9..5fa6fe684c 100644 --- a/src/pretix/helpers/urls.py +++ b/src/pretix/helpers/urls.py @@ -19,6 +19,7 @@ # You should have received a copy of the GNU Affero General Public License along with this program. If not, see # . # +import warnings from urllib.parse import urljoin from django.conf import settings @@ -26,6 +27,15 @@ from django.urls import reverse def build_absolute_uri(urlname, args=None, kwargs=None): + warnings.warn( + 'Usage of build_absolute_uri is confusing since there are many functions with that name. ' + 'Replace this usage with ', + DeprecationWarning + ) + return reverse_absolute_url_global_domain(urlname, args, kwargs) + + +def reverse_absolute_url_global_domain(urlname, args=None, kwargs=None): from pretix.multidomain import maindomain_urlconf return urljoin(settings.SITE_URL, reverse(urlname, args=args, kwargs=kwargs, urlconf=maindomain_urlconf)) diff --git a/src/pretix/multidomain/templatetags/eventurl.py b/src/pretix/multidomain/templatetags/eventurl.py index 002aa357da..84284ca59a 100644 --- a/src/pretix/multidomain/templatetags/eventurl.py +++ b/src/pretix/multidomain/templatetags/eventurl.py @@ -27,7 +27,7 @@ from django.urls import NoReverseMatch from django.utils.encoding import smart_str from django.utils.html import conditional_escape -from pretix.multidomain.urlreverse import build_absolute_uri, mainreverse +from pretix.multidomain.urlreverse import eventreverse_absolute, mainreverse register = template.Library() @@ -49,7 +49,7 @@ class EventURLNode(URLNode): url = '' try: if self.absolute: - url = build_absolute_uri(event, view_name, kwargs=kwargs) + url = eventreverse_absolute(event, view_name, kwargs=kwargs) elif self.event is False: url = mainreverse(view_name, kwargs) else: diff --git a/src/pretix/multidomain/urlreverse.py b/src/pretix/multidomain/urlreverse.py index f1577b0967..31419e0fb3 100644 --- a/src/pretix/multidomain/urlreverse.py +++ b/src/pretix/multidomain/urlreverse.py @@ -32,6 +32,7 @@ # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations under the License. +import warnings from urllib.parse import urljoin, urlsplit from django.conf import settings @@ -190,6 +191,15 @@ def eventreverse(obj, name, kwargs=None): def build_absolute_uri(obj, urlname, kwargs=None): + warnings.warn( + 'Usage of build_absolute_uri is confusing since there are many functions with that name. ' + 'Replace this usage with eventreverse_absolute', + DeprecationWarning + ) + return eventreverse_absolute(obj, urlname, kwargs) + + +def eventreverse_absolute(obj, urlname, kwargs=None): """ Works similar to ``eventreverse`` but always returns an absolute URL. diff --git a/src/pretix/plugins/paypal/payment.py b/src/pretix/plugins/paypal/payment.py index 9acc5ae4b2..a29b375467 100644 --- a/src/pretix/plugins/paypal/payment.py +++ b/src/pretix/plugins/paypal/payment.py @@ -58,7 +58,7 @@ from pretix.base.forms import SecretKeySettingsField from pretix.base.models import Event, Order, OrderPayment, OrderRefund, Quota from pretix.base.payment import BasePaymentProvider, PaymentException from pretix.base.settings import SettingsSandbox -from pretix.multidomain.urlreverse import build_absolute_uri +from pretix.multidomain.urlreverse import eventreverse_absolute from pretix.plugins.paypal.api import Api from pretix.plugins.paypal.models import ReferencedPayPalObject @@ -268,8 +268,8 @@ class Paypal(BasePaymentProvider): "payment_method": "paypal", }, "redirect_urls": { - "return_url": build_absolute_uri(request.event, 'plugins:paypal:return', kwargs=kwargs), - "cancel_url": build_absolute_uri(request.event, 'plugins:paypal:abort', kwargs=kwargs), + "return_url": eventreverse_absolute(request.event, 'plugins:paypal:return', kwargs=kwargs), + "cancel_url": eventreverse_absolute(request.event, 'plugins:paypal:abort', kwargs=kwargs), }, "transactions": [ { @@ -351,7 +351,7 @@ class Paypal(BasePaymentProvider): if request.session.get('iframe_session', False): signer = signing.Signer(salt='safe-redirect') return ( - build_absolute_uri(request.event, 'plugins:paypal:redirect') + '?url=' + + eventreverse_absolute(request.event, 'plugins:paypal:redirect') + '?url=' + urllib.parse.quote(signer.sign(link.href)) ) else: @@ -613,8 +613,8 @@ class Paypal(BasePaymentProvider): "payment_method": "paypal", }, "redirect_urls": { - "return_url": build_absolute_uri(request.event, 'plugins:paypal:return'), - "cancel_url": build_absolute_uri(request.event, 'plugins:paypal:abort'), + "return_url": eventreverse_absolute(request.event, 'plugins:paypal:return'), + "cancel_url": eventreverse_absolute(request.event, 'plugins:paypal:abort'), }, "transactions": [ { diff --git a/src/pretix/plugins/paypal2/payment.py b/src/pretix/plugins/paypal2/payment.py index 1ee0338f6a..d4e2d43a11 100644 --- a/src/pretix/plugins/paypal2/payment.py +++ b/src/pretix/plugins/paypal2/payment.py @@ -56,8 +56,8 @@ from pretix.base.models import Event, Order, OrderPayment, OrderRefund, Quota from pretix.base.payment import BasePaymentProvider, PaymentException from pretix.base.settings import SettingsSandbox from pretix.helpers import OF_SELF -from pretix.helpers.urls import build_absolute_uri as build_global_uri -from pretix.multidomain.urlreverse import build_absolute_uri, eventreverse +from pretix.helpers.urls import reverse_absolute_url_global_domain +from pretix.multidomain.urlreverse import eventreverse, eventreverse_absolute from pretix.plugins.paypal2.client.core.environment import ( LiveEnvironment, SandboxEnvironment, ) @@ -264,7 +264,7 @@ class PaypalSettingsHolder(BasePaymentProvider): settings_content = "
%s
%s
" % ( _('Please configure a PayPal Webhook to the following endpoint in order to automatically cancel orders ' 'when payments are refunded externally.'), - build_global_uri('plugins:paypal2:webhook') + reverse_absolute_url_global_domain('plugins:paypal2:webhook') ) if self.event.currency not in SUPPORTED_CURRENCIES: @@ -321,7 +321,7 @@ class PaypalSettingsHolder(BasePaymentProvider): ], "partner_config_override": { "partner_logo_url": urllib.parse.urljoin(settings.SITE_URL, static('pretixbase/img/pretix-logo.svg')), - "return_url": build_global_uri('plugins:paypal2:isu.return', kwargs={ + "return_url": reverse_absolute_url_global_domain('plugins:paypal2:isu.return', kwargs={ 'organizer': self.event.organizer.slug, 'event': self.event.slug, }) @@ -585,8 +585,8 @@ class PaypalMethod(BasePaymentProvider): 'locale': request.LANGUAGE_CODE.split('-')[0], 'shipping_preference': 'NO_SHIPPING', # 'SET_PROVIDED_ADDRESS', # Do not set on non-ship order? 'user_action': 'CONTINUE', - 'return_url': build_absolute_uri(request.event, 'plugins:paypal2:return', kwargs=kwargs), - 'cancel_url': build_absolute_uri(request.event, 'plugins:paypal2:abort', kwargs=kwargs), + 'return_url': eventreverse_absolute(request.event, 'plugins:paypal2:return', kwargs=kwargs), + 'cancel_url': eventreverse_absolute(request.event, 'plugins:paypal2:abort', kwargs=kwargs), }, }) response = self.client.execute(paymentreq) diff --git a/src/pretix/plugins/stripe/payment.py b/src/pretix/plugins/stripe/payment.py index 9bf3073624..e8e7ffd83d 100644 --- a/src/pretix/plugins/stripe/payment.py +++ b/src/pretix/plugins/stripe/payment.py @@ -75,8 +75,8 @@ from pretix.base.settings import SettingsSandbox from pretix.helpers import OF_SELF from pretix.helpers.countries import CachedCountries from pretix.helpers.http import get_client_ip -from pretix.helpers.urls import build_absolute_uri as build_global_uri -from pretix.multidomain.urlreverse import build_absolute_uri +from pretix.helpers.urls import reverse_absolute_url_global_domain +from pretix.multidomain.urlreverse import eventreverse_absolute from pretix.plugins.stripe.forms import StripeKeyValidator from pretix.plugins.stripe.models import ( ReferencedStripeObject, RegisteredApplePayDomain, @@ -197,7 +197,7 @@ class StripeSettingsHolder(BasePaymentProvider): ).format( self.settings.connect_client_id, request.session['payment_stripe_oauth_token'], - urllib.parse.quote(build_global_uri('plugins:stripe:oauth.return')), + urllib.parse.quote(reverse_absolute_url_global_domain('plugins:stripe:oauth.return')), ) def settings_content_render(self, request): @@ -229,7 +229,7 @@ class StripeSettingsHolder(BasePaymentProvider): _('Please configure a Stripe Webhook to ' 'the following endpoint in order to automatically cancel orders when charges are refunded externally ' 'and to process asynchronous payment methods like SOFORT.'), - build_global_uri('plugins:stripe:webhook') + reverse_absolute_url_global_domain('plugins:stripe:webhook') ) @property @@ -746,7 +746,7 @@ class StripeMethod(BasePaymentProvider): def redirect(self, request, url): if request.session.get('iframe_session', False): return ( - build_absolute_uri(request.event, 'plugins:stripe:redirect') + + eventreverse_absolute(request.event, 'plugins:stripe:redirect') + '?data=' + signing.dumps({ 'url': url, 'session': { @@ -941,7 +941,7 @@ class StripeMethod(BasePaymentProvider): }, # TODO: Is this sufficient? idempotency_key=str(self.event.id) + payment.order.code + idempotency_key_seed, - return_url=build_absolute_uri(self.event, 'plugins:stripe:sca.return', kwargs={ + return_url=eventreverse_absolute(self.event, 'plugins:stripe:sca.return', kwargs={ 'order': payment.order.code, 'payment': payment.pk, 'hash': payment.order.tagged_secret('plugins:stripe'), @@ -1047,13 +1047,13 @@ class StripeMethod(BasePaymentProvider): raise PaymentException(_('Stripe reported an error: %s') % intent.last_payment_error.message) def _redirect_to_sca(self, request, payment): - url = build_absolute_uri(self.event, 'plugins:stripe:sca', kwargs={ + url = eventreverse_absolute(self.event, 'plugins:stripe:sca', kwargs={ 'order': payment.order.code, 'payment': payment.pk, 'hash': payment.order.tagged_secret('plugins:stripe'), }) if not self.redirect_in_widget_allowed and request.session.get('iframe_session', False): - return build_absolute_uri(self.event, 'plugins:stripe:redirect') + '?data=' + signing.dumps({ + return eventreverse_absolute(self.event, 'plugins:stripe:redirect') + '?data=' + signing.dumps({ 'url': url, 'session': {}, }, salt='safe-redirect') @@ -1068,7 +1068,7 @@ class StripeMethod(BasePaymentProvider): intent = stripe.PaymentIntent.confirm( payment_info['id'], - return_url=build_absolute_uri(self.event, 'plugins:stripe:sca.return', kwargs={ + return_url=eventreverse_absolute(self.event, 'plugins:stripe:sca.return', kwargs={ 'order': payment.order.code, 'payment': payment.pk, 'hash': payment.order.tagged_secret('plugins:stripe'), diff --git a/src/pretix/plugins/stripe/views.py b/src/pretix/plugins/stripe/views.py index a9590f49ab..ae13aaf39e 100644 --- a/src/pretix/plugins/stripe/views.py +++ b/src/pretix/plugins/stripe/views.py @@ -64,7 +64,7 @@ from pretix.control.views.event import DecoupleMixin from pretix.control.views.organizer import OrganizerDetailViewMixin 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 eventreverse, eventreverse_absolute from pretix.plugins.stripe.forms import OrganizerStripeSettingsForm from pretix.plugins.stripe.models import ReferencedStripeObject from pretix.plugins.stripe.tasks import ( @@ -90,7 +90,7 @@ def redirect_view(request, *args, **kwargs): params = request.GET.copy() params['go'] = '1' r = render(request, 'pretixplugins/stripe/redirect.html', { - 'url': build_absolute_uri(request.event, 'plugins:stripe:redirect') + '?' + urllib.parse.urlencode(params), + 'url': eventreverse_absolute(request.event, 'plugins:stripe:redirect') + '?' + urllib.parse.urlencode(params), }) r._csp_ignore = True return r diff --git a/src/pretix/presale/forms/customer.py b/src/pretix/presale/forms/customer.py index 79d24cb80b..562ab3568f 100644 --- a/src/pretix/presale/forms/customer.py +++ b/src/pretix/presale/forms/customer.py @@ -44,7 +44,7 @@ from pretix.base.forms.questions import ( from pretix.base.i18n import get_language_without_region from pretix.base.models import Customer from pretix.helpers.http import get_client_ip -from pretix.multidomain.urlreverse import build_absolute_uri +from pretix.multidomain.urlreverse import eventreverse_absolute class TokenGenerator(PasswordResetTokenGenerator): @@ -84,7 +84,7 @@ class AuthenticationForm(forms.Form): self.customer_cache = None super().__init__(*args, **kwargs) self.fields['password'].help_text = "{}".format( - build_absolute_uri(False, 'presale:organizer.customer.resetpw', kwargs={ + eventreverse_absolute(False, 'presale:organizer.customer.resetpw', kwargs={ 'organizer': request.organizer.slug, }), _('Forgot your password?') diff --git a/src/pretix/presale/ical.py b/src/pretix/presale/ical.py index ba0571f244..10d48b769b 100644 --- a/src/pretix/presale/ical.py +++ b/src/pretix/presale/ical.py @@ -32,7 +32,7 @@ from django.utils.translation import gettext as _ from pretix.base.email import get_email_context from pretix.base.models import Event from pretix.helpers.format import format_map -from pretix.multidomain.urlreverse import build_absolute_uri +from pretix.multidomain.urlreverse import eventreverse_absolute def get_public_ical(events): @@ -48,9 +48,9 @@ def get_public_ical(events): event = ev if isinstance(ev, Event) else ev.event tz = event.timezone if isinstance(ev, Event): - url = build_absolute_uri(event, 'presale:event.index') + url = eventreverse_absolute(event, 'presale:event.index') else: - url = build_absolute_uri(event, 'presale:event.index', { + url = eventreverse_absolute(event, 'presale:event.index', { 'subevent': ev.pk }) @@ -134,7 +134,7 @@ def get_private_icals(event, positions): program_times = p.item.program_times.all() if program_times: # if program times have been configured, they are preferred for the position's calendar entries - url = build_absolute_uri(event, 'presale:event.index') + url = eventreverse_absolute(event, 'presale:event.index') for index, pt in enumerate(program_times): summary = _('{event} - {item}').format(event=ev, item=p.item.name) if event.settings.mail_attach_ical_description: @@ -167,11 +167,11 @@ def get_private_icals(event, positions): else: # without program times, the subevent or event times are used for calendar entries, preferring subevents if p.subevent: - url = build_absolute_uri(event, 'presale:event.index', { + url = eventreverse_absolute(event, 'presale:event.index', { 'subevent': p.subevent.pk }) else: - url = build_absolute_uri(event, 'presale:event.index') + url = eventreverse_absolute(event, 'presale:event.index') if event.settings.mail_attach_ical_description: ctx = get_email_context(event=event, event_or_subevent=ev) diff --git a/src/pretix/presale/utils.py b/src/pretix/presale/utils.py index 4b4d64e587..d0703a439d 100644 --- a/src/pretix/presale/utils.py +++ b/src/pretix/presale/utils.py @@ -59,7 +59,7 @@ from pretix.base.timemachine import time_machine_now_assigned_from_request from pretix.helpers.http import redirect_to_url from pretix.multidomain.models import KnownDomain from pretix.multidomain.urlreverse import ( - build_absolute_uri, get_event_domain, get_organizer_domain, + eventreverse_absolute, get_event_domain, get_organizer_domain, ) from pretix.presale.signals import process_request, process_response @@ -283,7 +283,7 @@ def _detect_event(request, require_live=True, require_plugin=None): domain, domainmode = get_event_domain(request.event, fallback=False, return_mode=True) if not domain and request_domain_mode == KnownDomain.MODE_ORG_ALT_DOMAIN: path = request.get_full_path().split("/", 2)[-1] - r = redirect_to_url(build_absolute_uri(request.event, "presale:event.index") + path) + r = redirect_to_url(eventreverse_absolute(request.event, "presale:event.index") + path) r['Access-Control-Allow-Origin'] = '*' return r elif domain and domain != request.host: diff --git a/src/pretix/presale/views/customer.py b/src/pretix/presale/views/customer.py index 0919bea236..5e15cfe442 100644 --- a/src/pretix/presale/views/customer.py +++ b/src/pretix/presale/views/customer.py @@ -56,7 +56,7 @@ from pretix.base.signals import customer_created, customer_signed_in from pretix.helpers.compat import CompatDeleteView from pretix.helpers.http import redirect_to_url from pretix.multidomain.models import KnownDomain -from pretix.multidomain.urlreverse import build_absolute_uri, eventreverse +from pretix.multidomain.urlreverse import eventreverse, eventreverse_absolute from pretix.presale.forms.customer import ( AuthenticationForm, ChangeInfoForm, ChangePasswordForm, RegistrationForm, ResetPasswordForm, SetPasswordForm, TokenGenerator, @@ -316,8 +316,10 @@ class ResetPasswordView(FormView): customer.log_action('pretix.customer.password.resetrequested', {}) ctx = customer.get_email_context() token = TokenGenerator().make_token(customer) - ctx['url'] = build_absolute_uri(self.request.organizer, - 'presale:organizer.customer.recoverpw') + '?id=' + customer.identifier + '&token=' + token + ctx['url'] = eventreverse_absolute( + self.request.organizer, + 'presale:organizer.customer.recoverpw' + ) + '?id=' + customer.identifier + '&token=' + token mail( customer.email, self.request.organizer.settings.mail_subject_customer_reset, @@ -574,7 +576,7 @@ class ChangeInformationView(CustomerAccountBaseMixin, FormView): new_email = form.cleaned_data['email'] form.cleaned_data['email'] = form.instance.email = self.initial_email ctx = form.instance.get_email_context() - ctx['url'] = build_absolute_uri( + ctx['url'] = eventreverse_absolute( self.request.organizer, 'presale:organizer.customer.change.confirm' ) + '?token=' + dumps({ @@ -703,7 +705,7 @@ class SSOLoginView(RedirectBackMixin, View): request.session[f'pretix_customerauth_{self.provider.pk}_nonce'] = nonce request.session[f'pretix_customerauth_{self.provider.pk}_popup_origin'] = popup_origin request.session[f'pretix_customerauth_{self.provider.pk}_cross_domain_requested'] = self.request.GET.get("request_cross_domain_customer_auth") == "true" - redirect_uri = build_absolute_uri(self.request.organizer, 'presale:organizer.customer.login.return', kwargs={ + redirect_uri = eventreverse_absolute(self.request.organizer, 'presale:organizer.customer.login.return', kwargs={ 'provider': self.provider.pk }) @@ -777,7 +779,7 @@ class SSOLoginReturnView(RedirectBackMixin, View): ), popup_origin, ) - redirect_uri = build_absolute_uri( + redirect_uri = eventreverse_absolute( self.request.organizer, 'presale:organizer.customer.login.return', kwargs={ 'provider': self.provider.pk diff --git a/src/pretix/presale/views/oidc_op.py b/src/pretix/presale/views/oidc_op.py index e79dbb1946..c84cd283cb 100644 --- a/src/pretix/presale/views/oidc_op.py +++ b/src/pretix/presale/views/oidc_op.py @@ -46,7 +46,7 @@ from pretix.base.models.customers import ( ) from pretix.helpers.http import redirect_to_url from pretix.multidomain.middlewares import CsrfViewMiddleware -from pretix.multidomain.urlreverse import build_absolute_uri +from pretix.multidomain.urlreverse import eventreverse_absolute from pretix.presale.forms.customer import AuthenticationForm from pretix.presale.utils import customer_login, get_customer_auth_time @@ -519,17 +519,17 @@ class ConfigurationView(View): def get(self, request, *args, **kwargs): return JsonResponse({ - 'issuer': build_absolute_uri(request.organizer, 'presale:organizer.index').rstrip('/'), - 'authorization_endpoint': build_absolute_uri( + 'issuer': eventreverse_absolute(request.organizer, 'presale:organizer.index').rstrip('/'), + 'authorization_endpoint': eventreverse_absolute( request.organizer, 'presale:organizer.oauth2.v1.authorize' ), - 'token_endpoint': build_absolute_uri( + 'token_endpoint': eventreverse_absolute( request.organizer, 'presale:organizer.oauth2.v1.token' ), - 'userinfo_endpoint': build_absolute_uri( + 'userinfo_endpoint': eventreverse_absolute( request.organizer, 'presale:organizer.oauth2.v1.userinfo' ), - 'jwks_uri': build_absolute_uri( + 'jwks_uri': eventreverse_absolute( request.organizer, 'presale:organizer.oauth2.v1.jwks' ), 'scopes_supported': [k for k, v in CustomerSSOClient.SCOPE_CHOICES], diff --git a/src/pretix/presale/views/order.py b/src/pretix/presale/views/order.py index 206de6ba7f..4fdff85710 100644 --- a/src/pretix/presale/views/order.py +++ b/src/pretix/presale/views/order.py @@ -89,7 +89,7 @@ from pretix.base.views.mixins import OrderQuestionsViewMixin from pretix.base.views.tasks import AsyncAction from pretix.helpers.http import redirect_to_url from pretix.helpers.safedownload import check_token -from pretix.multidomain.urlreverse import build_absolute_uri, eventreverse +from pretix.multidomain.urlreverse import eventreverse, eventreverse_absolute from pretix.presale.forms.checkout import InvoiceAddressForm, QuestionsForm from pretix.presale.forms.order import OrderPositionChangeForm from pretix.presale.signals import question_form_fields_overrides @@ -312,7 +312,7 @@ class OrderDetails(EventViewMixin, OrderDetailMixin, CartMixin, TicketPageMixin, state__in=[OrderPayment.PAYMENT_STATE_CANCELED, OrderPayment.PAYMENT_STATE_FAILED] ).exists() and self.order.status == Order.STATUS_PENDING: ctx['generate_invoice_requires'] = 'payment' - ctx['url'] = build_absolute_uri( + ctx['url'] = eventreverse_absolute( self.request.event, 'presale:event.order', kwargs={ 'order': self.order.code, 'secret': self.order.secret diff --git a/src/pretix/presale/views/organizer.py b/src/pretix/presale/views/organizer.py index 41535c4680..d527bb6465 100644 --- a/src/pretix/presale/views/organizer.py +++ b/src/pretix/presale/views/organizer.py @@ -74,7 +74,7 @@ from pretix.helpers.formats.en.formats import ( from pretix.helpers.http import redirect_to_url from pretix.helpers.i18n import parse_date_localized from pretix.helpers.thumb import get_thumbnail -from pretix.multidomain.urlreverse import build_absolute_uri, eventreverse +from pretix.multidomain.urlreverse import eventreverse, eventreverse_absolute from pretix.presale.forms.organizer import EventListFilterForm from pretix.presale.ical import get_public_ical from pretix.presale.signals import filter_subevents @@ -1380,7 +1380,7 @@ class OrganizerFavicon(View): class RedirectToOrganizerIndex(View): def get(self, *args, **kwargs): - return redirect_to_url(build_absolute_uri(self.request.organizer, "presale:organizer.index")) + return redirect_to_url(eventreverse_absolute(self.request.organizer, "presale:organizer.index")) class AccessibilityView(OrganizerViewMixin, EventListMixin, TemplateView): diff --git a/src/pretix/presale/views/widget.py b/src/pretix/presale/views/widget.py index 3c805d4d7b..6a4d4cfd0f 100644 --- a/src/pretix/presale/views/widget.py +++ b/src/pretix/presale/views/widget.py @@ -65,7 +65,7 @@ from pretix.base.settings import GlobalSettingsObject from pretix.base.templatetags.rich_text import rich_text from pretix.helpers.daterange import daterange from pretix.helpers.thumb import get_thumbnail -from pretix.multidomain.urlreverse import build_absolute_uri +from pretix.multidomain.urlreverse import eventreverse_absolute from pretix.presale.forms.organizer import meta_filtersets from pretix.presale.style import get_theme_vars_css from pretix.presale.views.cart import get_or_create_cart_id @@ -303,7 +303,7 @@ def get_picture(event, picture, size=None): logger.exception(f'Failed to create thumbnail of {picture.name}') if not thumb: thumb = default_storage.url(picture.name) - return urljoin(build_absolute_uri(event, 'presale:event.index'), thumb) + return urljoin(eventreverse_absolute(event, 'presale:event.index'), thumb) class WidgetAPIProductList(EventListMixin, View): @@ -547,7 +547,7 @@ class WidgetAPIProductList(EventListMixin, View): 'location': str(ev.location), 'date_range': self._get_date_range(ev, event, tz=tz), 'availability': self._get_availability(ev, event, tz=tz), - 'event_url': build_absolute_uri(event, 'presale:event.index'), + 'event_url': eventreverse_absolute(event, 'presale:event.index'), 'subevent': ev.pk if isinstance(ev, SubEvent) else None, }) return events @@ -748,7 +748,7 @@ class WidgetAPIProductList(EventListMixin, View): 'location': str(ev.location), 'date_range': self._get_date_range(ev, ev.event, tz), 'availability': self._get_availability(ev, ev.event, tz=tz), - 'event_url': build_absolute_uri(ev.event, 'presale:event.index'), + 'event_url': eventreverse_absolute(ev.event, 'presale:event.index'), 'subevent': ev.pk, } for ev in evs ] @@ -771,7 +771,7 @@ class WidgetAPIProductList(EventListMixin, View): 'location': str(event.location), 'date_range': dr, 'availability': avail, - 'event_url': build_absolute_uri(event, 'presale:event.index'), + 'event_url': eventreverse_absolute(event, 'presale:event.index'), }) cache.set(cache_key, data, 30) @@ -796,7 +796,7 @@ class WidgetAPIProductList(EventListMixin, View): return self.response(cached_data) data = { - 'target_url': build_absolute_uri(request.event, 'presale:event.index'), + 'target_url': eventreverse_absolute(request.event, 'presale:event.index'), 'subevent': self.subevent.pk if self.subevent else None, 'currency': request.event.currency, 'display_net_prices': request.event.settings.display_net_prices, diff --git a/src/tests/helpers/test_urls.py b/src/tests/helpers/test_urls.py index eabbed0f32..cdf2d98b89 100644 --- a/src/tests/helpers/test_urls.py +++ b/src/tests/helpers/test_urls.py @@ -22,17 +22,17 @@ from django import urls from django.test import override_settings -from pretix.helpers.urls import build_absolute_uri +from pretix.helpers.urls import reverse_absolute_url_global_domain def test_site_url_domain(): with override_settings(SITE_URL='https://example.com'): - assert build_absolute_uri('control:auth.login') == 'https://example.com/control/login' + assert reverse_absolute_url_global_domain('control:auth.login') == 'https://example.com/control/login' def test_site_url_subpath(): with override_settings(SITE_URL='https://example.com/presale'): old_prefix = urls.get_script_prefix() urls.set_script_prefix('/presale/') - assert build_absolute_uri('control:auth.login') == 'https://example.com/presale/control/login' + assert reverse_absolute_url_global_domain('control:auth.login') == 'https://example.com/presale/control/login' urls.set_script_prefix(old_prefix) diff --git a/src/tests/multidomain/test_urlreverse.py b/src/tests/multidomain/test_urlreverse.py index 74739d181c..23f954253e 100644 --- a/src/tests/multidomain/test_urlreverse.py +++ b/src/tests/multidomain/test_urlreverse.py @@ -26,7 +26,7 @@ from django_scopes import scopes_disabled from pretix.base.models import Event, Organizer from pretix.multidomain.models import KnownDomain -from pretix.multidomain.urlreverse import build_absolute_uri, eventreverse +from pretix.multidomain.urlreverse import eventreverse, eventreverse_absolute from pretix.testutils.queries import assert_num_queries @@ -248,20 +248,20 @@ def test_event_custom_domain_cache_clear(env): @pytest.mark.django_db def test_event_main_domain_absolute(env): - assert build_absolute_uri(env[1], 'presale:event.index') == 'http://example.com/mrmcd/2015/' + assert eventreverse_absolute(env[1], 'presale:event.index') == 'http://example.com/mrmcd/2015/' @pytest.mark.django_db def test_event_custom_domain_absolute(env): KnownDomain.objects.create(domainname='foobar', organizer=env[0]) KnownDomain.objects.create(domainname='barfoo', organizer=env[0], event=env[1]) - assert build_absolute_uri(env[1], 'presale:event.index') == 'http://barfoo/' + assert eventreverse_absolute(env[1], 'presale:event.index') == 'http://barfoo/' @pytest.mark.django_db def test_event_org_domain_absolute(env): KnownDomain.objects.create(domainname='foobar', organizer=env[0]) - assert build_absolute_uri(env[1], 'presale:event.index') == 'http://foobar/2015/' + assert eventreverse_absolute(env[1], 'presale:event.index') == 'http://foobar/2015/' @pytest.mark.django_db @@ -269,4 +269,4 @@ def test_event_org_alt_domain_absolute(env): KnownDomain.objects.create(domainname='foobar', organizer=env[0]) d = KnownDomain.objects.create(domainname='altfoo', organizer=env[0], mode=KnownDomain.MODE_ORG_ALT_DOMAIN) d.event_assignments.create(event=env[1]) - assert build_absolute_uri(env[1], 'presale:event.index') == 'http://altfoo/2015/' + assert eventreverse_absolute(env[1], 'presale:event.index') == 'http://altfoo/2015/'