Mercurial > public > src > rhodecode
diff pylons_app/lib/auth.py @ 239:b18f89d6d17f
Adde draft for permissions systems, made all needed decorators, and checks. For future usage in the system.
author | Marcin Kuzminski <marcin@python-works.com> |
---|---|
date | Sun, 30 May 2010 19:49:40 +0200 |
parents | a0116e944da1 |
children | 3782a6d698af |
line wrap: on
line diff
--- a/pylons_app/lib/auth.py Sun May 30 17:55:56 2010 +0200 +++ b/pylons_app/lib/auth.py Sun May 30 19:49:40 2010 +0200 @@ -1,5 +1,5 @@ from functools import wraps -from pylons import session, url +from pylons import session, url, app_globals as g from pylons.controllers.util import abort, redirect from pylons_app.model import meta from pylons_app.model.db import User @@ -47,7 +47,26 @@ def __init__(self): pass - + + + +def set_available_permissions(config): + """ + This function will propagate pylons globals with all available defined + permission given in db. We don't wannt to check each time from db for new + permissions since adding a new permission also requires application restart + ie. to decorate new views with the newly created permission + @param config: + """ + from pylons_app.model.meta import Session + from pylons_app.model.db import Permission + logging.info('getting information about all available permissions') + sa = Session() + all_perms = sa.query(Permission).all() + config['pylons.app_globals'].available_permissions = [x.permission_name for x in all_perms] + + + #=============================================================================== # DECORATORS #=============================================================================== @@ -73,3 +92,62 @@ return redirect(url('login_home')) return _wrapper + +class PermsDecorator(object): + + def __init__(self, *perms): + available_perms = g.available_permissions + for perm in perms: + if perm not in available_perms: + raise Exception("'%s' permission in not defined" % perm) + self.required_perms = set(perms) + self.user_perms = set([])#propagate this list from somewhere. + + def __call__(self, func): + @wraps(func) + def _wrapper(*args, **kwargs): + logging.info('checking %s permissions %s for %s', + self.__class__.__name__[-3:], self.required_perms, func.__name__) + + if self.check_permissions(): + logging.info('Permission granted for %s', func.__name__) + return func(*args, **kwargs) + + else: + logging.warning('Permission denied for %s', func.__name__) + #redirect with forbidden ret code + return redirect(url('access_denied'), 403) + return _wrapper + + + def check_permissions(self): + """ + Dummy function for overiding + """ + raise Exception('You have to write this function in child class') + +class CheckPermissionAll(PermsDecorator): + """ + Checks for access permission for all given predicates. All of them have to + be meet in order to fulfill the request + """ + + def check_permissions(self): + if self.required_perms.issubset(self.user_perms): + return True + return False + + +class CheckPermissionAny(PermsDecorator): + """ + Checks for access permission for any of given predicates. In order to + fulfill the request any of predicates must be meet + """ + + def check_permissions(self): + if self.required_perms.intersection(self.user_perms): + return True + return False + + +