@@ -767,193 +767,193 @@ class LoginRequired(object):
self.api_access = api_access
self.allow_default_user = allow_default_user
def __call__(self, func):
return decorator(self.__wrapper, func)
def __wrapper(self, func, *fargs, **fkwargs):
controller = fargs[0]
user = request.authuser
loc = "%s:%s" % (controller.__class__.__name__, func.__name__)
log.debug('Checking access for user %s @ %s', user, loc)
if not AuthUser.check_ip_allowed(user, request.ip_addr):
raise _redirect_to_login(_('IP %s not allowed') % request.ip_addr)
# Check if we used an API key to authenticate.
api_key = user.authenticating_api_key
if api_key is not None:
# Check that controller is enabled for API key usage.
if not self.api_access and not allowed_api_access(loc, api_key=api_key):
# controller does not allow API access
log.warning('API access to %s is not allowed', loc)
raise HTTPForbidden()
log.info('user %s authenticated with API key ****%s @ %s',
user, api_key[-4:], loc)
return func(*fargs, **fkwargs)
# CSRF protection: Whenever a request has ambient authority (whether
# through a session cookie or its origin IP address), it must include
# the correct token, unless the HTTP method is GET or HEAD (and thus
# guaranteed to be side effect free. In practice, the only situation
# where we allow side effects without ambient authority is when the
# authority comes from an API key; and that is handled above.
if request.method not in ['GET', 'HEAD']:
token = request.POST.get(secure_form.token_key)
if not token or token != secure_form.authentication_token():
log.error('CSRF check failed')
# regular user authentication
if user.is_authenticated:
log.info('user %s authenticated with regular auth @ %s', user, loc)
elif user.is_default_user:
if self.allow_default_user:
log.info('default user @ %s', loc)
log.info('default user is not accepted here @ %s', loc)
else:
log.warning('user %s NOT authenticated with regular auth @ %s', user, loc)
raise _redirect_to_login()
# Use as decorator
class NotAnonymous(object):
"""Ensures that client is not logged in as the "default" user, and
redirects to the login page otherwise. Must be used together with
LoginRequired."""
cls = fargs[0]
log.debug('Checking that user %s is not anonymous @%s', user.username, cls)
if user.is_default_user:
raise _redirect_to_login(_('You need to be a registered user to '
'perform this action'))
class _PermsDecorator(object):
"""Base class for controller decorators with multiple permissions"""
def __init__(self, *required_perms):
self.required_perms = required_perms # usually very short - a list is thus fine
log.debug('checking %s permissions %s for %s %s',
self.__class__.__name__, self.required_perms, cls, user)
if self.check_permissions(user):
log.debug('Permission granted for %s %s', cls, user)
log.debug('Permission denied for %s %s', cls, user)
log.info('Permission denied for %s %s', cls, user)
raise _redirect_to_login(_('You need to be signed in to view this page'))
def check_permissions(self, user):
raise NotImplementedError()
class HasPermissionAnyDecorator(_PermsDecorator):
"""
Checks the user has any of the given global permissions.
global_permissions = user.permissions['global'] # usually very short
return any(p in global_permissions for p in self.required_perms)
class _PermDecorator(_PermsDecorator):
"""Base class for controller decorators with a single permission"""
def __init__(self, required_perm):
_PermsDecorator.__init__(self, [required_perm])
self.required_perm = required_perm
class HasRepoPermissionLevelDecorator(_PermDecorator):
Checks the user has at least the specified permission level for the requested repository.
repo_name = get_repo_slug(request)
return user.has_repository_permission_level(repo_name, self.required_perm)
class HasRepoGroupPermissionLevelDecorator(_PermDecorator):
Checks the user has any of given permissions for the requested repository group.
repo_group_name = get_repo_group_slug(request)
return user.has_repository_group_permission_level(repo_group_name, self.required_perm)
class HasUserGroupPermissionLevelDecorator(_PermDecorator):
Checks for access permission for any of given predicates for specific
user group. In order to fulfill the request any of predicates must be meet
user_group_name = get_user_group_slug(request)
return user.has_user_group_permission_level(user_group_name, self.required_perm)
#==============================================================================
# CHECK FUNCTIONS
class _PermsFunction(object):
"""Base function for other check functions with multiple permissions"""
def __nonzero__(self):
""" Defend against accidentally forgetting to call the object
and instead evaluating it directly in a boolean context,
which could have security implications.
raise AssertionError(self.__class__.__name__ + ' is not a bool and must be called!')
def __call__(self, *a, **b):
class HasPermissionAny(_PermsFunction):
def __call__(self, purpose=None):
global_permissions = request.user.permissions['global'] # usually very short
ok = any(p in global_permissions for p in self.required_perms)
log.debug('Check %s for global %s (%s): %s' %
(request.user.username, self.required_perms, purpose, ok))
return ok
class _PermFunction(_PermsFunction):
"""Base function for other check functions with a single permission"""
_PermsFunction.__init__(self, [required_perm])
Status change: