import logging from functools import wraps from data import model from util.http import abort logger = logging.getLogger(__name__) def _raise_unauthorized(repository, scopes): raise StandardError("Unauthorized acces to %s", repository) def _get_reponame_kwargs(*args, **kwargs): return [kwargs['namespace'], kwargs['package_name']] def disallow_for_image_repository(get_reponame_method=_get_reponame_kwargs): def wrapper(func): @wraps(func) def wrapped(*args, **kwargs): namespace_name, repo_name = get_reponame_method(*args, **kwargs) image_repo = model.repository.get_repository(namespace_name, repo_name, kind_filter='image') if image_repo is not None: logger.debug('Tried to invoked a CNR method on an image repository') abort(405, message='Cannot push an application to an image repository with the same name') return func(*args, **kwargs) return wrapped return wrapper def require_repo_permission(permission_class, scopes=None, allow_public=False, raise_method=_raise_unauthorized, get_reponame_method=_get_reponame_kwargs): def wrapper(func): @wraps(func) @disallow_for_image_repository(get_reponame_method=get_reponame_method) def wrapped(*args, **kwargs): namespace_name, repo_name = get_reponame_method(*args, **kwargs) logger.debug('Checking permission %s for repo: %s/%s', permission_class, namespace_name, repo_name) permission = permission_class(namespace_name, repo_name) if (permission.can() or (allow_public and model.repository.repository_is_public(namespace_name, repo_name))): return func(*args, **kwargs) repository = namespace_name + '/' + repo_name raise_method(repository, scopes) return wrapped return wrapper