Last active
April 7, 2016 12:10
-
-
Save absent1706/bc1299e8b3c060db2513e2cf3348e909 to your computer and use it in GitHub Desktop.
python ACL decorators
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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