@@ -48,236 +48,238 @@ def check_password(password, hashed):
@cache_region('super_short_term', 'cached_user')
def get_user_cached(username):
sa = meta.Session
try:
user = sa.query(User).filter(User.username == username).one()
finally:
meta.Session.remove()
return user
def authfunc(environ, username, password):
user = get_user_cached(username)
except (NoResultFound, MultipleResultsFound, OperationalError) as e:
log.error(e)
user = None
if user:
if user.active:
if user.username == username and check_password(password, user.password):
log.info('user %s authenticated correctly', username)
return True
else:
log.error('user %s is disabled', username)
return False
class AuthUser(object):
"""
A simple object that handles a mercurial username for authentication
def __init__(self):
self.username = 'None'
self.name = ''
self.lastname = ''
self.email = ''
self.user_id = None
self.is_authenticated = False
self.is_admin = False
self.permissions = {}
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:
log.info('getting information about all available permissions')
all_perms = sa.query(Permission).all()
config['available_permissions'] = [x.permission_name for x in all_perms]
def set_base_path(config):
config['base_path'] = config['pylons.app_globals'].base_path
def fill_data(user):
Fills user data with those from database and log out user if not present
in database
@param user:
dbuser = sa.query(User).get(user.user_id)
if dbuser:
user.username = dbuser.username
user.is_admin = dbuser.admin
user.name = dbuser.name
user.lastname = dbuser.lastname
user.email = dbuser.email
user.is_authenticated = False
from pprint import pprint
pprint(user.permissions)
def fill_perms(user):
Fills user permission attribute with permissions taken from database
user.permissions['repositories'] = {}
user.permissions['global'] = set()
#===========================================================================
# fetch default permissions
default_perms = sa.query(RepoToPerm, UserToPerm, Repository, Permission)\
.outerjoin((UserToPerm, RepoToPerm.user_id == UserToPerm.user_id))\
default_perms = sa.query(RepoToPerm, Repository, Permission)\
.join((Repository, RepoToPerm.repository_id == Repository.repo_id))\
.join((Permission, RepoToPerm.permission_id == Permission.permission_id))\
.filter(RepoToPerm.user_id == sa.query(User).filter(User.username ==
'default').one().user_id).all()
.filter(RepoToPerm.user == sa.query(User).filter(User.username ==
'default').scalar()).all()
if user.is_admin:
#=======================================================================
# #admin have all rights set to admin
# #admin have all default rights set to admin
user.permissions['global'].add('hg.admin')
for perm in default_perms:
p = 'repository.admin'
user.permissions['repositories'][perm.RepoToPerm.repository.repo_name] = p
# set default permissions
#default global
user.permissions['global'].add(perm.UserToPerm.permission.permission_name)
default_global_perms = sa.query(UserToPerm)\
.filter(UserToPerm.user == sa.query(User).filter(User.username ==
'default').one())
for perm in default_global_perms:
user.permissions['global'].add(perm.permission.permission_name)
#default repositories
if perm.Repository.private and not perm.Repository.user_id == user.user_id:
#disable defaults for private repos,
p = 'repository.none'
elif perm.Repository.user_id == user.user_id:
#set admin if owner
p = perm.Permission.permission_name
# #overwrite default with user permissions if any
user_perms = sa.query(RepoToPerm, UserToPerm, Permission, Repository)\
user_perms = sa.query(RepoToPerm, Permission, Repository)\
.filter(RepoToPerm.user_id == user.user_id).all()
for perm in user_perms:
if perm.Repository.user_id == user.user_id:#set admin if owner
def get_user(session):
Gets user from session, and wraps permissions into user
@param session:
user = session.get('hg_app_user', AuthUser())
if user.is_authenticated:
user = fill_data(user)
user = fill_perms(user)
session['hg_app_user'] = user
session.save()
#===============================================================================
# CHECK DECORATORS
class LoginRequired(object):
"""Must be logged in to execute this function else redirect to login page"""
def __call__(self, func):
return decorator(self.__wrapper, func)
def __wrapper(self, func, *fargs, **fkwargs):
log.debug('Checking login required for user:%s', user.username)
log.debug('user %s is authenticated', user.username)
return func(*fargs, **fkwargs)
log.warn('user %s not authenticated', user.username)
log.debug('redirecting to login page')
return redirect(url('login_home'))
class PermsDecorator(object):
"""Base class for decorators"""
def __init__(self, *required_perms):
available_perms = config['available_permissions']
for perm in required_perms:
if perm not in available_perms:
raise Exception("'%s' permission is not defined" % perm)
self.required_perms = set(required_perms)
self.user_perms = None
# _wrapper.__name__ = func.__name__
# _wrapper.__dict__.update(func.__dict__)
# _wrapper.__doc__ = func.__doc__
self.user_perms = session.get('hg_app_user', AuthUser()).permissions
log.debug('checking %s permissions %s for %s',
self.__class__.__name__, self.required_perms, func.__name__)
if self.check_permissions():
log.debug('Permission granted for %s', func.__name__)
log.warning('Permission denied for %s', func.__name__)
#redirect with forbidden ret code
return abort(403)
def check_permissions(self):
"""Dummy function for overriding"""
raise Exception('You have to write this function in child class')
class HasPermissionAllDecorator(PermsDecorator):
"""Checks for access permission for all given predicates. All of them
have to be meet in order to fulfill the request
if self.required_perms.issubset(self.user_perms.get('global')):
Status change: