diff options
| author | Tom Christie | 2012-10-10 10:02:37 +0100 | 
|---|---|---|
| committer | Tom Christie | 2012-10-10 10:02:37 +0100 | 
| commit | ccd2b0117d9c26199b1862a302b1eb06dd2f07b2 (patch) | |
| tree | 05e47209445303f2cda704d4ac50791551ddae5b | |
| parent | 900c4b625b62a6c1f4a16bfe8d6b5d77480427ff (diff) | |
| download | django-rest-framework-ccd2b0117d9c26199b1862a302b1eb06dd2f07b2.tar.bz2 | |
Permissions and throttles no longer have a view attribute on self.  Explicitly passed to .has_permissions(request, view, obj=None) / .allow_request(request, view)
| -rw-r--r-- | docs/api-guide/permissions.md | 2 | ||||
| -rw-r--r-- | docs/api-guide/throttling.md | 4 | ||||
| -rw-r--r-- | rest_framework/permissions.py | 17 | ||||
| -rw-r--r-- | rest_framework/tests/renderers.py | 2 | ||||
| -rw-r--r-- | rest_framework/throttling.py | 41 | ||||
| -rw-r--r-- | rest_framework/views.py | 8 | 
6 files changed, 28 insertions, 46 deletions
| diff --git a/docs/api-guide/permissions.md b/docs/api-guide/permissions.md index 9a3c39ab..b6912d88 100644 --- a/docs/api-guide/permissions.md +++ b/docs/api-guide/permissions.md @@ -88,7 +88,7 @@ The `DjangoModelPermissions` class also supports object-level permissions.  Thir  ## Custom permissions -To implement a custom permission, override `BasePermission` and implement the `.has_permission(self, request, obj=None)` method. +To implement a custom permission, override `BasePermission` and implement the `.has_permission(self, request, view, obj=None)` method.  The method should return `True` if the request should be granted access, and `False` otherwise. diff --git a/docs/api-guide/throttling.md b/docs/api-guide/throttling.md index 7861e9ba..0e228905 100644 --- a/docs/api-guide/throttling.md +++ b/docs/api-guide/throttling.md @@ -144,8 +144,8 @@ User requests to either `ContactListView` or `ContactDetailView` would be restri  ## Custom throttles -To create a custom throttle, override `BaseThrottle` and implement `.allow_request(request)`.  The method should return `True` if the request should be allowed, and `False` otherwise. +To create a custom throttle, override `BaseThrottle` and implement `.allow_request(request, view)`.  The method should return `True` if the request should be allowed, and `False` otherwise. -Optionally you may also override the `.wait()` method.  If implemented, `.wait()` should return a recomended number of seconds to wait before attempting the next request, or `None`.  The `.wait()` method will only be called if `.check_throttle()` has previously returned `False`. +Optionally you may also override the `.wait()` method.  If implemented, `.wait()` should return a recomended number of seconds to wait before attempting the next request, or `None`.  The `.wait()` method will only be called if `.allow_request()` has previously returned `False`.  [permissions]: permissions.md diff --git a/rest_framework/permissions.py b/rest_framework/permissions.py index 51837a01..13ea39ea 100644 --- a/rest_framework/permissions.py +++ b/rest_framework/permissions.py @@ -13,13 +13,8 @@ class BasePermission(object):      """      A base class from which all permission classes should inherit.      """ -    def __init__(self, view): -        """ -        Permission classes are always passed the current view on creation. -        """ -        self.view = view -    def has_permission(self, request, obj=None): +    def has_permission(self, request, view, obj=None):          """          Should simply return, or raise an :exc:`response.ImmediateResponse`.          """ @@ -31,7 +26,7 @@ class IsAuthenticated(BasePermission):      Allows access only to authenticated users.      """ -    def has_permission(self, request, obj=None): +    def has_permission(self, request, view, obj=None):          if request.user and request.user.is_authenticated():              return True          return False @@ -42,7 +37,7 @@ class IsAdminUser(BasePermission):      Allows access only to admin users.      """ -    def has_permission(self, request, obj=None): +    def has_permission(self, request, view, obj=None):          if request.user and request.user.is_staff:              return True          return False @@ -53,7 +48,7 @@ class IsAuthenticatedOrReadOnly(BasePermission):      The request is authenticated as a user, or is a read-only request.      """ -    def has_permission(self, request, obj=None): +    def has_permission(self, request, view, obj=None):          if (request.method in SAFE_METHODS or              request.user and              request.user.is_authenticated()): @@ -96,8 +91,8 @@ class DjangoModelPermissions(BasePermission):          }          return [perm % kwargs for perm in self.perms_map[method]] -    def has_permission(self, request, obj=None): -        model_cls = self.view.model +    def has_permission(self, request, view, obj=None): +        model_cls = view.model          perms = self.get_required_permissions(request.method, model_cls)          if (request.user and diff --git a/rest_framework/tests/renderers.py b/rest_framework/tests/renderers.py index 6de8f124..b8c30fcc 100644 --- a/rest_framework/tests/renderers.py +++ b/rest_framework/tests/renderers.py @@ -92,7 +92,7 @@ urlpatterns = patterns('',  class POSTDeniedPermission(permissions.BasePermission): -    def has_permission(self, request, obj=None): +    def has_permission(self, request, view, obj=None):          return request.method != 'POST' diff --git a/rest_framework/throttling.py b/rest_framework/throttling.py index 0d33f0e2..566c277d 100644 --- a/rest_framework/throttling.py +++ b/rest_framework/throttling.py @@ -8,14 +8,7 @@ class BaseThrottle(object):      """      Rate throttling of requests.      """ - -    def __init__(self, view=None): -        """ -        All throttles hold a reference to the instantiating view. -        """ -        self.view = view - -    def allow_request(self, request): +    def allow_request(self, request, view):          """          Return `True` if the request should be allowed, `False` otherwise.          """ @@ -48,13 +41,12 @@ class SimpleRateThottle(BaseThrottle):      cache_format = 'throtte_%(scope)s_%(ident)s'      scope = None -    def __init__(self, view): -        super(SimpleRateThottle, self).__init__(view) +    def __init__(self):          if not getattr(self, 'rate', None):              self.rate = self.get_rate()          self.num_requests, self.duration = self.parse_rate(self.rate) -    def get_cache_key(self, request): +    def get_cache_key(self, request, view):          """          Should return a unique cache-key which can be used for throttling.          Must be overridden. @@ -90,7 +82,7 @@ class SimpleRateThottle(BaseThrottle):          duration = {'s': 1, 'm': 60, 'h': 3600, 'd': 86400}[period[0]]          return (num_requests, duration) -    def allow_request(self, request): +    def allow_request(self, request, view):          """          Implement the check to see if the request should be throttled. @@ -100,7 +92,7 @@ class SimpleRateThottle(BaseThrottle):          if self.rate is None:              return True -        self.key = self.get_cache_key(request) +        self.key = self.get_cache_key(request, view)          self.history = cache.get(self.key, [])          self.now = self.timer() @@ -149,7 +141,7 @@ class AnonRateThrottle(SimpleRateThottle):      """      scope = 'anon' -    def get_cache_key(self, request): +    def get_cache_key(self, request, view):          if request.user.is_authenticated():              return None  # Only throttle unauthenticated requests. @@ -171,7 +163,7 @@ class UserRateThrottle(SimpleRateThottle):      """      scope = 'user' -    def get_cache_key(self, request): +    def get_cache_key(self, request, view):          if request.user.is_authenticated():              ident = request.user.id          else: @@ -190,25 +182,20 @@ class ScopedRateThrottle(SimpleRateThottle):      throttled.  The unique cache key will be generated by concatenating the      user id of the request, and the scope of the view being accessed.      """ -      scope_attr = 'throttle_scope' -    def __init__(self, view): -        """ -        Scope is determined from the view being accessed. -        """ -        self.scope = getattr(self.view, self.scope_attr, None) -        super(ScopedRateThrottle, self).__init__(view) - -    def get_cache_key(self, request): +    def get_cache_key(self, request, view):          """          If `view.throttle_scope` is not set, don't apply this throttle.          Otherwise generate the unique cache key by concatenating the user id          with the '.throttle_scope` property of the view.          """ -        if not self.scope: -            return None  # Only throttle views if `.throttle_scope` is set. +        scope = getattr(view, self.scope_attr, None) + +        if not scope: +            # Only throttle views if `.throttle_scope` is set on the view. +            return None          if request.user.is_authenticated():              ident = request.user.id @@ -216,6 +203,6 @@ class ScopedRateThrottle(SimpleRateThottle):              ident = request.META.get('REMOTE_ADDR', None)          return self.cache_format % { -            'scope': self.scope, +            'scope': scope,              'ident': ident          } diff --git a/rest_framework/views.py b/rest_framework/views.py index 2c940dac..058a6cd3 100644 --- a/rest_framework/views.py +++ b/rest_framework/views.py @@ -189,13 +189,13 @@ class APIView(View):          """          Instantiates and returns the list of permissions that this view requires.          """ -        return [permission(self) for permission in self.permission_classes] +        return [permission() for permission in self.permission_classes]      def get_throttles(self):          """          Instantiates and returns the list of thottles that this view uses.          """ -        return [throttle(self) for throttle in self.throttle_classes] +        return [throttle() for throttle in self.throttle_classes]      def get_content_negotiator(self):          """ @@ -220,7 +220,7 @@ class APIView(View):          Return `True` if the request should be permitted.          """          for permission in self.get_permissions(): -            if not permission.has_permission(request, obj): +            if not permission.has_permission(request, self, obj):                  return False          return True @@ -229,7 +229,7 @@ class APIView(View):          Check if request should be throttled.          """          for throttle in self.get_throttles(): -            if not throttle.allow_request(request): +            if not throttle.allow_request(request, self):                  self.throttled(request, throttle.wait())      # Dispatch methods | 
