# -*- coding:utf-8 -* # # Copyright 2022 # - Maréchal None: """ Perform all the checks, but return nothing. To know if the form is valid, the `is_valid()` method must be used. The form shall be considered as valid if it meets all the following conditions : - it contains a "basket_items" key in the cookies of the request given in the constructor - this cookie is a list of objects formatted this way : `[{'id': , 'quantity': , 'name': , 'unit_price': }, ...]`. The order of the fields in each object does not matter - all the ids are positive integers - all the ids refer to products available in the EBOUTIC - 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 ("[]", ""): 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 if not BasketForm.json_cookie_re.match(basket): 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: self.error_messages.add("One or more items are badly formatted.") continue # check the id field is a positive integer if type(item["id"]) is not int or item["id"] < 0: self.error_messages.add( _("%(name)s : this product does not exist.") % {"name": item["name"]} ) continue # check a product with this id does exist ids = {product.id for product in get_eboutic_products(self.user)} if not item["id"] in ids: self.error_messages.add( _( "%(name)s : this product does not exist or may no longer be available." ) % {"name": item["name"]} ) continue if type(item["quantity"]) is not int or item["quantity"] < 0: self.error_messages.add( _("You cannot buy %(nbr)d %(name)%s.") % {"nbr": item["quantity"], "name": item["name"]} ) continue # if we arrive here, it means this item has passed all tests self.correct_cookie.append(item) # for loop for item checking ends here # this function does not return anything. # instead, it fills a set containing the collected error messages # an empty set means that no error was seen thus everything is ok # and the form is valid. # a non-empty set means there was at least one error thus # the form is invalid def is_valid(self) -> bool: """ return True if the form is correct else False. If the `clean()` method has not been called beforehand, call it """ if self.error_messages == set() and self.correct_cookie == []: self.clean() if self.error_messages: return False 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: if not self.correct_cookie: return "" return json.dumps(self.correct_cookie)