Compare commits

...

1 Commits

Author SHA1 Message Date
Raphael Michel
489e898e1d Generate email confirmation secret from tagged_secret 2024-09-23 13:57:50 +02:00
5 changed files with 25 additions and 11 deletions

View File

@@ -381,8 +381,23 @@ class Order(LockModel, LoggedModel):
self.event.cache.delete('complain_testmode_orders')
self.delete()
def email_confirm_hash(self):
return hashlib.sha256(settings.SECRET_KEY.encode() + self.secret.encode()).hexdigest()[:9]
def email_confirm_secret(self):
return self.tagged_secret("email_confirm", 9)
def check_email_confirm_secret(self, received_secret):
return (
hmac.compare_digest(
self.tagged_secret("email_confirm", 9),
received_secret[:9].lower()
) or any(
# TODO: remove this clause after a while (compatibility with old secrets currently in flight)
hmac.compare_digest(
hashlib.sha256(sk.encode() + self.secret.encode()).hexdigest()[:9],
received_secret
)
for sk in [settings.SECRET_KEY, *settings.SECRET_KEY_FALLBACKS]
)
)
def get_extended_status_display(self):
# Changes in this method should to be replicated in pretixcontrol/orders/fragment_order_status.html

View File

@@ -301,7 +301,7 @@ def mail(email: Union[str, Sequence[str]], subject: str, template: Union[str, La
order.event, 'presale:event.order.open', kwargs={
'order': order.code,
'secret': order.secret,
'hash': order.email_confirm_hash()
'hash': order.email_confirm_secret()
}
)
)

View File

@@ -262,7 +262,7 @@ def base_placeholders(sender, **kwargs):
'presale:event.order.open', kwargs={
'order': order.code,
'secret': order.secret,
'hash': order.email_confirm_hash()
'hash': order.email_confirm_secret()
}
), lambda event: build_absolute_uri(
event,
@@ -443,7 +443,7 @@ def base_placeholders(sender, **kwargs):
'organizer': event.organizer.slug,
'order': order.code,
'secret': order.secret,
'hash': order.email_confirm_hash(),
'hash': order.email_confirm_secret(),
}),
)
for order in orders

View File

@@ -156,11 +156,10 @@ class OrderOpen(EventViewMixin, OrderDetailMixin, View):
def get(self, request, *args, **kwargs):
if not self.order:
raise Http404(_('Unknown order code or not authorized to access this order.'))
if kwargs.get('hash') == self.order.email_confirm_hash():
if not self.order.email_known_to_work:
self.order.log_action('pretix.event.order.contact.confirmed')
self.order.email_known_to_work = True
self.order.save(update_fields=['email_known_to_work'])
if self.order.check_email_confirm_secret(kwargs.get('hash')) and not self.order.email_known_to_work:
self.order.log_action('pretix.event.order.contact.confirmed')
self.order.email_known_to_work = True
self.order.save(update_fields=['email_known_to_work'])
return redirect(self.get_order_url())

View File

@@ -221,7 +221,7 @@ class OrdersTest(BaseOrdersTest):
assert not self.order.email_known_to_work
response = self.client.get(
'/%s/%s/order/%s/%s/open/%s/' % (self.orga.slug, self.event.slug, self.order.code, self.order.secret, self.order.email_confirm_hash())
'/%s/%s/order/%s/%s/open/%s/' % (self.orga.slug, self.event.slug, self.order.code, self.order.secret, self.order.email_confirm_secret())
)
assert response.status_code == 302
self.order.refresh_from_db()