1
0
mirror of https://gitlab.com/animath/si/plateforme.git synced 2025-06-23 22:28:51 +02:00

Allow anonymous users to perform a payment using a special auth token

Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
This commit is contained in:
Emmy D'Anello
2024-02-21 22:44:50 +01:00
parent 8d08b18d08
commit b16b6e422f
5 changed files with 189 additions and 59 deletions

View File

@ -7,7 +7,7 @@ from tempfile import mkdtemp
from django.conf import settings
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.mixins import AccessMixin, LoginRequiredMixin
from django.contrib.auth.models import User
from django.contrib.sites.models import Site
from django.core.exceptions import PermissionDenied, ValidationError
@ -535,21 +535,41 @@ class PaymentUpdateGroupView(LoginRequiredMixin, DetailView):
return redirect(reverse_lazy("registration:update_payment", args=(payment.pk,)))
class PaymenRedirectHelloAssoView(LoginRequiredMixin, DetailView):
class PaymenRedirectHelloAssoView(AccessMixin, DetailView):
model = Payment
def dispatch(self, request, *args, **kwargs):
if not self.request.user.is_authenticated or \
not self.request.user.registration.is_admin \
and (self.request.user.registration not in self.get_object().registrations.all()
or self.get_object().valid is not False):
payment = self.get_object()
# An external user has the link for the payment
token = request.GET.get('token', "")
if token and token == payment.token:
return super().dispatch(request, *args, **kwargs)
if not request.user.is_authenticated:
return self.handle_no_permission()
if not request.user.registration.is_admin:
if request.user.registration.is_volunteer \
and payment.tournament not in request.user.registration.organized_tournaments.all():
return self.handle_no_permission()
if request.user.registration.is_student \
and request.user.registration not in payment.registrations.all():
return self.handle_no_permission()
if request.user.registration.is_coach \
and request.user.registration.team != payment.team:
return self.handle_no_permission()
return super().dispatch(request, *args, **kwargs)
def get(self, request, *args, **kwargs):
payment = self.get_object()
checkout_intent = payment.create_checkout_intent()
if payment.valid is not False:
raise PermissionDenied(_("The payment is already valid or pending validation."))
checkout_intent = payment.create_checkout_intent()
return redirect(checkout_intent["redirectUrl"])
@ -558,9 +578,10 @@ class PaymentHelloAssoReturnView(DetailView):
def get(self, request, *args, **kwargs):
checkout_id = request.GET.get("checkoutIntentId")
payment = Payment.objects.get(checkout_intent_id=checkout_id).exclude(valid=True)
if payment != self.get_object():
messages.error(request, _("The payment is not found or is already validated."))
payment = self.get_object()
payment_qs = Payment.objects.exclude(valid=True).filter(checkout_intent_id=checkout_id).filter(pk=payment.pk)
if not payment_qs.exists():
messages.error(request, _("The payment is not found or is already validated."), "danger")
return redirect("index")
team = payment.team
@ -580,18 +601,18 @@ class PaymentHelloAssoReturnView(DetailView):
return_type = request.GET.get("type")
if return_type == "error":
messages.error(request, format_lazy(_("An error occurred during the payment: {error}"),
error=request.GET.get("error")))
error=request.GET.get("error")), "danger")
return error_response
elif return_type == "return":
code = request.GET.get("code")
if code == "refused":
messages.error(request, _("The payment has been refused."))
messages.error(request, _("The payment has been refused."), "danger")
return error_response
elif code != "success":
messages.error(request, format_lazy(_("The return code is unknown: {code}"), code=code))
elif code != "succeeded":
messages.error(request, format_lazy(_("The return code is unknown: {code}"), code=code), "danger")
return error_response
else:
messages.error(request, format_lazy(_("The return type is unknown: {type}"), type=return_type))
messages.error(request, format_lazy(_("The return type is unknown: {type}"), type=return_type), "danger")
return error_response
checkout_intent = payment.get_checkout_intent()
@ -608,7 +629,7 @@ class PaymentHelloAssoReturnView(DetailView):
"and will be automatically done. "
"If it is not the case, please contact us."))
if request.user.registration in payment.registrations.all():
if not request.user.is_anonymous and request.user.registration in payment.registrations.all():
success_response = redirect("registration:user_detail", args=(request.user.pk,))
elif right_to_see:
success_response = redirect("participation:team_detail", args=(team.pk,))