django-oscar / django-oscar-api

RESTful JSON API for django-oscar
Other
363 stars 160 forks source link

Potential problem with basket for unauthenticated users #336

Closed dylanGerlach closed 4 months ago

dylanGerlach commented 4 months ago

To preface, I am not 100% familiar with the code, but I found a potential fix, but its in an area that cant be overriden by users. While setting up my project, I ran into a problem with guest users adding to products to the basket. It turns out that the code for fetching the basket in AddProductView is creating a new basket instead of using a prexisting one, or the one that matches up with the session basket. My simple fix is in this method:
def post(self, request, *args, **kwargs): # pylint: disable=redefined-builtin

    p_ser = self.add_product_serializer_class(
        data=request.data, context={"request": request}
    )
    if p_ser.is_valid():
        basket = operations.get_basket(request)
        product = p_ser.validated_data["url"]
        quantity = p_ser.validated_data["quantity"]
        options = p_ser.validated_data.get("options", [])

        basket_valid, message = self.validate(basket, product, quantity, options)
        if not basket_valid:
            return Response(
                {"reason": message}, status=status.HTTP_406_NOT_ACCEPTABLE
            )

        basket.add_product(product, quantity=quantity, options=options)
        signals.basket_addition.send(
            sender=self, product=product, user=request.user, request=request
        )

        operations.apply_offers(request, basket)
        ser = self.serializer_class(basket, context={"request": request})

        return Response(ser.data)

    return Response({"reason": p_ser.errors}, status=status.HTTP_406_NOT_ACCEPTABLE)

where one would change : basket = operations.get_basket(request) to basket = request.basket im worried that this will break other things, and you can also go into basket.operations and just return request.basket for unauthenticated users which seems to be safe but again I'm not 100% familiar with the code.