44 lines
2.1 KiB
Python
44 lines
2.1 KiB
Python
import re
|
|
|
|
from django.contrib.auth import logout
|
|
from django.db import transaction
|
|
from django.db.models import F
|
|
from django.shortcuts import redirect, render
|
|
from django.utils import timezone
|
|
from django.views.decorators.cache import never_cache
|
|
from django.views.decorators.http import require_http_methods
|
|
|
|
from . import access, services
|
|
from .models import PaymentAccessLink
|
|
|
|
|
|
@never_cache
|
|
@require_http_methods(['GET', 'POST'])
|
|
def open_link(request, token):
|
|
# Keep previously issued long links valid until their original expiry/revocation.
|
|
link = access.active_links().filter(token_hash=access.token_digest(token)).first() if re.fullmatch(r'(?:[a-z0-9]{10}|[A-Za-z0-9_-]{43})', token) else None
|
|
if link is None:
|
|
return access.unavailable_link(request)
|
|
if request.user.is_authenticated and request.user.pk != link.customer_id:
|
|
confirmed = request.method == 'POST' and request.POST.get('action') == 'logout_and_open' and request.POST.get('account_id') == str(request.user.pk)
|
|
if not confirmed:
|
|
response = render(request, 'payments/link_confirmation.html')
|
|
response['Referrer-Policy'] = 'same-origin'
|
|
response['X-Robots-Tag'] = 'noindex, nofollow'
|
|
return response
|
|
logout(request)
|
|
if not request.user.is_authenticated:
|
|
access.grant_payment_access(request, link)
|
|
# Retain the token across redirects in the session; the link model still stores only its hash.
|
|
request.session[access.SHARE_SESSION_KEY] = {'link_id': link.pk, 'token': token}
|
|
with transaction.atomic():
|
|
PaymentAccessLink.objects.filter(pk=link.pk).update(view_count=F('view_count') + 1, last_used_at=timezone.now())
|
|
services.audit(None, 'PAYMENT_LINK_OPENED', link, {
|
|
'ip_address': request.META.get('REMOTE_ADDR', ''),
|
|
'user_agent': request.META.get('HTTP_USER_AGENT', '')[:500]})
|
|
target = link.receipt or link.notice
|
|
response = redirect('payments:receipt_detail' if link.receipt_id else 'payments:notice_detail', public_id=target.public_id)
|
|
response['Referrer-Policy'] = 'no-referrer'
|
|
response['X-Robots-Tag'] = 'noindex, nofollow'
|
|
return response
|