You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

factory.py 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import zlib
  2. from django.conf import settings
  3. from oscar.services import import_module
  4. basket_models = import_module('basket.models', ['Basket', 'Line'])
  5. # Cookie keys
  6. COOKIE_KEY_OPEN_BASKET = 'oscar_open_basket'
  7. COOKIE_KEY_SAVED_BASKET = 'oscar_saved_basket'
  8. try:
  9. # The lifetime for the basket cookie can be set in settings.py
  10. COOKIE_LIFETIME = settings.OSCAR_BASKET_COOKIE_LIFETIME
  11. except AttributeError:
  12. COOKIE_LIFETIME = 7*24*60*60
  13. class BasketFactory(object):
  14. u"""Factory object for loading baskets."""
  15. def get_or_create_open_basket(self, request, response):
  16. u"""Loads or creates a normal OPEN basket for the current user (anonymous
  17. or not).
  18. """
  19. return self._get_or_create_cookie_basket(request, response,
  20. COOKIE_KEY_OPEN_BASKET, basket_models.Basket.open)
  21. def get_or_create_saved_basket(self, request, response):
  22. u"""Loads or creates a "save-for-later" basket for the current user"""
  23. return self._get_or_create_cookie_basket(request, response,
  24. COOKIE_KEY_SAVED_BASKET, basket_models.Basket.saved)
  25. def get_open_basket(self, request):
  26. u"""Returns the basket for the current user"""
  27. return self._get_basket(request, COOKIE_KEY_OPEN_BASKET, basket_models.Basket.open)
  28. def get_saved_basket(self, request):
  29. u"""Returns the saved basket for the current user"""
  30. return self._get_basket(request, COOKIE_KEY_SAVED_BASKET, basket_models.Basket.saved)
  31. # Utility methods
  32. def _get_or_create_cookie_basket(self, request, response, cookie_key, manager):
  33. u"""Loads or creates a basket for the current user"""
  34. anon_basket = self._get_cookie_basket(request, cookie_key, manager)
  35. if request.user.is_authenticated():
  36. basket, created = manager.get_or_create(owner=request.user)
  37. if anon_basket:
  38. # If signed in user also has a cookie basket, we merge them and
  39. # delete the cookies
  40. basket.merge(anon_basket)
  41. response.delete_cookie(cookie_key)
  42. elif not anon_basket:
  43. # No valid basket found for an unauthenticated user so we create a
  44. # new one and store the id and hash in a cookie.
  45. basket = manager.create()
  46. cookie = "%s_%s" % (basket.id, self._get_basket_hash(basket.id))
  47. response.set_cookie(cookie_key, cookie, max_age=COOKIE_LIFETIME, httponly=True)
  48. else:
  49. # Only the cookie basket found - return it
  50. basket = anon_basket
  51. return basket
  52. def _get_basket(self, request, cookie_key, manager):
  53. u"""Returns a basket object given a cookie key and manager."""
  54. b = None
  55. if request.user.is_authenticated():
  56. try:
  57. b = manager.get(owner=request.user)
  58. except basket_models.Basket.DoesNotExist, e:
  59. pass
  60. else:
  61. b = self._get_cookie_basket(request, cookie_key, manager)
  62. return b
  63. def _get_cookie_basket(self, request, cookie_key, manager):
  64. u"""Returns a basket based on the cookie key given."""
  65. b = None
  66. # If user is anonymous, their basket ID (if they have one) will be
  67. # stored in a cookie together with a hash which verifies it and prevents
  68. # it from being spoofed.
  69. if cookie_key in request.COOKIES:
  70. basket_id, basket_hash = request.COOKIES[cookie_key].split("_")
  71. if basket_hash == self._get_basket_hash(basket_id):
  72. try:
  73. b = manager.get(pk=basket_id, owner=None)
  74. except basket_models.Basket.DoesNotExist, e:
  75. b = None
  76. else:
  77. response.delete_cookie(cookie_key)
  78. return b
  79. def _get_basket_hash(self, id):
  80. u"""
  81. Create a hash of the basket ID using the SECRET_KEY
  82. variable defined in settings.py as a salt.
  83. """
  84. return str(zlib.crc32(str(id)+settings.SECRET_KEY))