Skip to content

Instantly share code, notes, and snippets.

@absent1706
Last active April 7, 2016 12:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save absent1706/bc1299e8b3c060db2513e2cf3348e909 to your computer and use it in GitHub Desktop.
Save absent1706/bc1299e8b3c060db2513e2cf3348e909 to your computer and use it in GitHub Desktop.
python ACL decorators
from copy import copy
class NotAllowedError(Exception):
code = 503
def __init__(self, *args, **kwargs):
super(NotAllowedError, self).__init__(*args, **kwargs)
def _base_decorator(check_rights_function, *decorator_args, **decorator_kwargs):
def real_decorator(function):
def wrapper(handler, *function_args, **function_kwargs):
""":type handler: UserSessionHandlerMixin"""
# try to take user_id from handler is not set
if 'user_id' not in decorator_kwargs.keys():
decorator_kwargs['user_id'] = handler.user_id
# combine keyword arguments passed to function and decorator
# decorator arguments will have higher priority
can_kwargs = copy(function_kwargs)
can_kwargs.update(decorator_kwargs)
if check_rights_function(*decorator_args, **can_kwargs):
function(handler, *function_args, **function_kwargs)
else:
raise NotAllowedError("Sorry, you don't have rights to do this action")
return wrapper
return real_decorator
def decorator_can_update_product(*decorator_args, **decorator_kwargs):
return _base_decorator(can_update_product, *decorator_args, **decorator_kwargs)
def can_update_product(product_id = None, user_id = None, **kwargs):
print 'checking if user',user_id,'can update product',product_id,'...'
return False
# real code should look like:
# product = get_product(product_id)
# return product.user_id == user_id
def decorator_can_create_product(*decorator_args, **decorator_kwargs):
return _base_decorator(can_create_product, *decorator_args, **decorator_kwargs)
def can_create_product(user_id = None, **kwargs):
print 'checking if user',user_id,'can create product','...'
return True
# real code should look like:
# product = get_product(product_id)
# return product.user_id == user_id
########################## TEST ##########################
class Handler:
user_id = 2 # in real app we get user_id from session
@decorator_can_create_product()
def create(self):
print 'Well done! Created new product!'
# You can override params like:
# @decorator_can_update_product(user_id = 33)
# or
# @decorator_can_update_product(product_id = 33, user_id = 7879)
@decorator_can_update_product()
def update(self, product_id):
print 'Well done! Updated product ' + str(product_id)
# in real app, router will do this call ...
try:
Handler().create()
Handler().update(product_id = 111)
except NotAllowedError as e:
print 'Error with code {}: {}'.format(e.code, e)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment