In [2]:
from functools import update_wrapper
class PermissionDenied(Exception):
pass
class PermissionedMethod(object):
def __init__(self, *permissions):
self._permissions = [p() for p in permissions]
self._method = None
def __call__(self, method):
if self._method is not None:
raise TypeError("Method already loaded")
def permissioner(inst, request, *args, **kwargs):
for permission in self._permissions:
if not permission.has_permission(request, inst):
raise PermissionDenied(message=getattr(permission, 'message', None))
else:
return method(inst, request, *args, **kwargs)
self._method = update_wrapper(permissioner, method)
update_wrapper(self, method)
return self
def __get__(self, inst, cls):
if inst is None:
return self
return lambda req, *args, **kwargs: self._method(inst, req, *args, **kwargs)
In [3]:
class Permission(object):
def has_permission(self, request, view):
print("Permssioned!")
return True
In [4]:
class SomeView(object):
@PermissionedMethod(Permission)
def something(self, request, *args, **kwargs):
return (self, request, args, kwargs)
In [5]:
SomeView.something
Out[5]:
In [6]:
sv = SomeView()
In [7]:
sv.something(1)
Out[7]:
In [ ]: