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.

application.py 3.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. import six
  2. from django.conf.urls import patterns
  3. from oscar.core.loading import feature_hidden
  4. from oscar.views.decorators import permissions_required
  5. class Application(object):
  6. """
  7. Base application class.
  8. This is subclassed by each app to provide a customisable container for an
  9. app's views and permissions.
  10. """
  11. #: Namespace name
  12. name = None
  13. #: A name that allows the functionality within this app to be disabled
  14. hidable_feature_name = None
  15. #: Maps view names to a tuple or list of permissions
  16. permissions_map = {}
  17. #: Default permission for any view not in permissions_map
  18. default_permissions = None
  19. def __init__(self, app_name=None, **kwargs):
  20. self.app_name = app_name
  21. # Set all kwargs as object attributes
  22. for key, value in six.iteritems(kwargs):
  23. setattr(self, key, value)
  24. def get_urls(self):
  25. """
  26. Return the url patterns for this app.
  27. """
  28. return patterns('')
  29. def post_process_urls(self, urlpatterns):
  30. """
  31. Customise URL patterns.
  32. This method allows decorators to be wrapped around an apps URL
  33. patterns.
  34. By default, this only allows custom decorators to be specified, but you
  35. could override this method to do anything you want.
  36. Args:
  37. urlpatterns (list): A list of URL patterns
  38. """
  39. # Test if this the URLs in the Application instance should be
  40. # available. If the feature is hidden then we don't include the URLs.
  41. if feature_hidden(self.hidable_feature_name):
  42. return patterns('')
  43. for pattern in urlpatterns:
  44. if hasattr(pattern, 'url_patterns'):
  45. self.post_process_urls(pattern.url_patterns)
  46. if not hasattr(pattern, '_callback'):
  47. continue
  48. # Look for a custom decorator
  49. decorator = self.get_url_decorator(pattern)
  50. if decorator:
  51. # Nasty way of modifying a RegexURLPattern
  52. pattern._callback = decorator(pattern._callback)
  53. return urlpatterns
  54. def get_permissions(self, url):
  55. """
  56. Return a list of permissions for a given URL name
  57. Args:
  58. url (str): A URL name (eg ``basket.basket``)
  59. Returns:
  60. list: A list of permission strings.
  61. """
  62. # url namespaced?
  63. if url is not None and ':' in url:
  64. view_name = url.split(':')[1]
  65. else:
  66. view_name = url
  67. return self.permissions_map.get(view_name, self.default_permissions)
  68. def get_url_decorator(self, pattern):
  69. """
  70. Return the appropriate decorator for the view function with the passed
  71. URL name. Mainly used for access-protecting views.
  72. It's possible to specify:
  73. - no permissions necessary: use None
  74. - a set of permissions: use a list
  75. - two set of permissions (`or`): use a two-tuple of lists
  76. See permissions_required decorator for details
  77. """
  78. permissions = self.get_permissions(pattern.name)
  79. return permissions_required(permissions)
  80. @property
  81. def urls(self):
  82. # We set the application and instance namespace here
  83. return self.get_urls(), self.app_name, self.name