import logging from functools import wraps from cnr.exception import UnauthorizedAccess from flask import Blueprint from app import metric_queue from auth.permissions import (AdministerRepositoryPermission, ReadRepositoryPermission, ModifyRepositoryPermission) from data import model # TODO: stop using model directly from util.metrics.metricqueue import time_blueprint appr_bp = Blueprint('appr', __name__) time_blueprint(appr_bp, metric_queue) 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_name'], kwargs['repo_name']] 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) 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 def _raise_method(repository, scopes): raise UnauthorizedAccess("Unauthorized access for: %s" % repository, {"package": repository, "scopes": scopes}) def _get_reponame_kwargs(*args, **kwargs): return [kwargs['namespace'], kwargs['package_name']] require_app_repo_read = require_repo_permission(ReadRepositoryPermission, scopes=['pull'], allow_public=True, raise_method=_raise_method, get_reponame_method=_get_reponame_kwargs) require_app_repo_write = require_repo_permission(ModifyRepositoryPermission, scopes=['pull', 'push'], raise_method=_raise_method, get_reponame_method=_get_reponame_kwargs) require_app_repo_admin = require_repo_permission(AdministerRepositoryPermission, scopes=['pull', 'push'], raise_method=_raise_method, get_reponame_method=_get_reponame_kwargs)