Fix le panier de l'Eboutic pour Safari (#518)

Co-authored-by: Théo DURR <git@theodurr.fr>
Co-authored-by: thomas girod <56346771+imperosol@users.noreply.github.com>
This commit is contained in:
Julien Constant
2022-12-14 08:38:41 +01:00
committed by GitHub
parent 1d82e2a7d9
commit faccc1367f
10 changed files with 46 additions and 19 deletions

View File

@ -26,8 +26,10 @@ 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
from eboutic.models import get_eboutic_products
@ -97,23 +99,34 @@ 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)
basket = unquote(self.cookies.get("basket_items", None))
if basket is None or 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,
# so we explicitly lay a Sentry message capture here.
capture_message(
"Eboutic basket regex checking failed to validate basket json",
level="error",
)
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:

View File

@ -63,7 +63,7 @@ document.addEventListener('alpine:init', () => {
edit_cookies() {
// a cookie survives an hour
document.cookie = "basket_items=" + JSON.stringify(this.items) + ";Max-Age=3600";
document.cookie = "basket_items=" + encodeURIComponent(JSON.stringify(this.items)) + ";Max-Age=3600";
},
/**

View File

@ -24,9 +24,10 @@
import base64
import json
from datetime import datetime
import sentry_sdk
from datetime import datetime
from urllib.parse import unquote
from OpenSSL import crypto
from django.conf import settings
from django.contrib.auth.decorators import login_required
@ -104,7 +105,7 @@ class EbouticCommand(TemplateView):
request.session["basket_id"] = basket.id
request.session.modified = True
items = json.loads(request.COOKIES["basket_items"])
items = json.loads(unquote(request.COOKIES["basket_items"]))
items.sort(key=lambda item: item["id"])
ids = [item["id"] for item in items]
quantities = [item["quantity"] for item in items]