This commit is contained in:
GitHub Merge Button 2012-02-07 02:14:46 -08:00
commit b132fc5b32
3 changed files with 66 additions and 19 deletions

View File

@ -527,6 +527,38 @@ class ModelMixin(object):
""" """
return self.get_queryset().get(**kwargs) return self.get_queryset().get(**kwargs)
def get_owner(self):
"""
Returns the model instance's owner, if any.
The owner is retrieved by calling the .get_owner() function on the model instance, if implemented.
"""
try:
return self.model_instance.get_owner()
except: pass
@property
def model_instance(self):
"""
Returns the model instance for read/update/delete, or None if does not exist.
"""
if hasattr(self, '_model_instance'): return self._model_instance
model = self.resource.model
request = self.request
args = self.args
kwargs = self.kwargs
query_kwargs = self.get_query_kwargs(request, *args, **kwargs)
try:
self._model_instance = self.get_instance(**query_kwargs)
except model.DoesNotExist:
pass
return self._model_instance
def get_queryset(self): def get_queryset(self):
""" """
Return the queryset for this view. Return the queryset for this view.
@ -546,12 +578,8 @@ class ReadModelMixin(ModelMixin):
Behavior to read a `model` instance on GET requests Behavior to read a `model` instance on GET requests
""" """
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
model = self.resource.model
query_kwargs = self.get_query_kwargs(request, *args, **kwargs)
try: if self.model_instance == None:
self.model_instance = self.get_instance(**query_kwargs)
except model.DoesNotExist:
raise ErrorResponse(status.HTTP_404_NOT_FOUND) raise ErrorResponse(status.HTTP_404_NOT_FOUND)
return self.model_instance return self.model_instance
@ -602,18 +630,17 @@ class UpdateModelMixin(ModelMixin):
Behavior to update a `model` instance on PUT requests Behavior to update a `model` instance on PUT requests
""" """
def put(self, request, *args, **kwargs): def put(self, request, *args, **kwargs):
model = self.resource.model model = self.resource.model
query_kwargs = self.get_query_kwargs(request, *args, **kwargs)
# TODO: update on the url of a non-existing resource url doesn't work # TODO: update on the url of a non-existing resource url doesn't work
# correctly at the moment - will end up with a new url # correctly at the moment - will end up with a new url
try: if self.model_instance == None:
self.model_instance = self.get_instance(**query_kwargs) self.model_instance = model(**self.get_instance_data(model, self.CONTENT, *args, **kwargs))
else:
for (key, val) in self.CONTENT.items(): for (key, val) in self.CONTENT.items():
setattr(self.model_instance, key, val) setattr(self.model_instance, key, val)
except model.DoesNotExist:
self.model_instance = model(**self.get_instance_data(model, self.CONTENT, *args, **kwargs))
self.model_instance.save() self.model_instance.save()
return self.model_instance return self.model_instance
@ -623,15 +650,9 @@ class DeleteModelMixin(ModelMixin):
Behavior to delete a `model` instance on DELETE requests Behavior to delete a `model` instance on DELETE requests
""" """
def delete(self, request, *args, **kwargs): def delete(self, request, *args, **kwargs):
model = self.resource.model
query_kwargs = self.get_query_kwargs(request, *args, **kwargs)
try: if self.model_instance == None: raise ErrorResponse(status.HTTP_404_NOT_FOUND, None, {})
instance = self.get_instance(**query_kwargs) self.model_instance.delete()
except model.DoesNotExist:
raise ErrorResponse(status.HTTP_404_NOT_FOUND, None, {})
instance.delete()
return return

View File

@ -13,6 +13,7 @@ __all__ = (
'BasePermission', 'BasePermission',
'FullAnonAccess', 'FullAnonAccess',
'IsAuthenticated', 'IsAuthenticated',
'IsResourceOwnerOrIsAnonReadOnly',
'IsAdminUser', 'IsAdminUser',
'IsUserOrIsAnonReadOnly', 'IsUserOrIsAnonReadOnly',
'PerUserThrottling', 'PerUserThrottling',
@ -77,6 +78,25 @@ class IsAdminUser(BasePermission):
raise _403_FORBIDDEN_RESPONSE raise _403_FORBIDDEN_RESPONSE
class IsResourceOwnerOrIsAnonReadOnly(BasePermission):
"""
The request is authenticated as the owner of the resource, or is a read-only request.
"""
def check_permission(self, user):
if self.view.method in('GET', 'HEAD',):
return
if not user.is_authenticated():
raise _403_FORBIDDEN_RESPONSE
if self.view.get_owner() == user:
return
raise _403_FORBIDDEN_RESPONSE
class IsUserOrIsAnonReadOnly(BasePermission): class IsUserOrIsAnonReadOnly(BasePermission):
""" """
The request is authenticated as a user, or is a read-only request. The request is authenticated as a user, or is a read-only request.

View File

@ -32,6 +32,12 @@ class BaseResource(Serializer):
""" """
return self.serialize(obj) return self.serialize(obj)
def get_owner(self):
"""
Returns a Django User instance as the owner of the resource, if any.
"""
return None
class Resource(BaseResource): class Resource(BaseResource):
""" """