Implémentation 3DSv2 + résolution bugs eboutic + amélioration pages admin (#558)

Eboutic :
- Implémentation de la norme 3DSecure v2 pour les paiement par carte bancaire
- Amélioration générale de l'interface utilisateur
- Résolution du problème avec les caractères spéciaux dans le panier sur Safari
- Réparation du cookie du panier de l'eboutic qui n'était pas fonctionnel

Autre :
- Mise à jour de la documentation
- Mise à jour des dépendances Javascript
- Suppression du code inutilisé dans `subscription/models.py`
- Amélioration des pages administrateur (back-office Django)

Co-authored-by: thomas girod <56346771+imperosol@users.noreply.github.com>
Co-authored-by: Théo DURR <git@theodurr.fr>
Co-authored-by: Julien Constant <julienconstant190@gmail.com>
This commit is contained in:
thomas girod
2023-01-09 20:53:12 +01:00
committed by GitHub
parent 310f1a2283
commit 73305c0b28
53 changed files with 3461 additions and 2248 deletions

View File

@ -26,6 +26,7 @@ import json
import re
import typing
from urllib.parse import unquote
from django.http import HttpRequest
from django.utils.translation import gettext as _
from sentry_sdk import capture_message
@ -98,12 +99,16 @@ class BasketForm:
- all the ids refer to products the user is allowed to buy
- all the quantities are positive integers
"""
basket = self.cookies.get("basket_items", None)
if basket is None or basket in ("[]", ""):
# replace escaped double quotes by single quotes, as the RegEx used to check the json
# does not support escaped double quotes
basket = unquote(self.cookies.get("basket_items", "")).replace('\\"', "'")
if basket in ("[]", ""):
self.error_messages.add(_("You have no basket."))
return
# check that the json is not nested before parsing it to make sure
# malicious user can't ddos the server with deeply nested json
# malicious user can't DDoS the server with deeply nested json
if not BasketForm.json_cookie_re.match(basket):
# As the validation of the cookie goes through a rather boring regex,
# we can regularly have to deal with subtle errors that we hadn't forecasted,
@ -114,14 +119,17 @@ class BasketForm:
)
self.error_messages.add(_("The request was badly formatted."))
return
try:
basket = json.loads(basket)
except json.JSONDecodeError:
self.error_messages.add(_("The basket cookie was badly formatted."))
return
if type(basket) is not list or len(basket) == 0:
self.error_messages.add(_("Your basket is empty."))
return
for item in basket:
expected_keys = {"id", "quantity", "name", "unit_price"}
if type(item) is not dict or set(item.keys()) != expected_keys:
@ -146,7 +154,7 @@ class BasketForm:
continue
if type(item["quantity"]) is not int or item["quantity"] < 0:
self.error_messages.add(
_("You cannot buy %(nbr)d %(name)%s.")
_("You cannot buy %(nbr)d %(name)s.")
% {"nbr": item["quantity"], "name": item["name"]}
)
continue
@ -174,7 +182,6 @@ class BasketForm:
return True
def get_error_messages(self) -> typing.List[str]:
# return [msg for msg in self.error_messages]
return list(self.error_messages)
def get_cleaned_cookie(self) -> str: