diff --git a/auth/permissions.py b/auth/permissions.py index 71fab3cf5..15512faa5 100644 --- a/auth/permissions.py +++ b/auth/permissions.py @@ -14,6 +14,7 @@ logger = logging.getLogger(__name__) _ResourceNeed = namedtuple('resource', ['type', 'namespace', 'name', 'role']) _RepositoryNeed = partial(_ResourceNeed, 'repository') _OrganizationNeed = namedtuple('organization', ['orgname', 'role']) +_OrganizationRepoNeed = namedtuple('organization', ['orgname', 'role']) _TeamNeed = namedtuple('orgteam', ['orgname', 'teamname', 'role']) _UserNeed = namedtuple('user', ['username', 'role']) @@ -22,6 +23,12 @@ REPO_ROLES = [None, 'read', 'write', 'admin'] TEAM_ROLES = [None, 'member', 'creator', 'admin'] USER_ROLES = [None, 'read', 'admin'] +TEAM_REPO_ROLES = { + 'admin': 'admin', + 'creator': 'read', + 'member': 'read', +} + SCOPE_MAX_REPO_ROLES = defaultdict(lambda: None) SCOPE_MAX_REPO_ROLES.update({ 'repo:read': 'read', @@ -83,8 +90,14 @@ class QuayDeferredPermissionUser(Identity): # Every user is the admin of their own 'org' user_namespace = _OrganizationNeed(user_object.username, self._team_role_for_scopes('admin')) + logger.debug('User namespace permission: {0}'.format(user_namespace)) self.provides.add(user_namespace) + # Org repo roles can differ for scopes + user_repos = _OrganizationRepoNeed(user_object.username, self._repo_role_for_scopes('admin')) + logger.debug('User namespace permission: {0}'.format(user_repos)) + self.provides.add(user_repos) + # Add repository permissions for perm in model.get_all_user_permissions(user_object): grant = _RepositoryNeed(perm.repository.namespace, perm.repository.name, @@ -99,6 +112,13 @@ class QuayDeferredPermissionUser(Identity): logger.debug('Organization team added permission: {0}'.format(grant)) self.provides.add(grant) + + team_repo_role = TEAM_REPO_ROLES[team.role.name] + org_repo_grant = _OrganizationRepoNeed(team.organization.username, + self._repo_role_for_scopes(team_repo_role)) + logger.debug('Organization team added repo permission: {0}'.format(org_repo_grant)) + self.provides.add(org_repo_grant) + team_grant = _TeamNeed(team.organization.username, team.name, self._team_role_for_scopes(team.role.name)) logger.debug('Team added permission: {0}'.format(team_grant)) @@ -113,9 +133,10 @@ class ModifyRepositoryPermission(Permission): def __init__(self, namespace, name): admin_need = _RepositoryNeed(namespace, name, 'admin') write_need = _RepositoryNeed(namespace, name, 'write') - org_admin_need = _OrganizationNeed(namespace, 'admin') - super(ModifyRepositoryPermission, self).__init__(admin_need, write_need, - org_admin_need) + org_admin_need = _OrganizationRepoNeed(namespace, 'admin') + org_write_need = _OrganizationRepoNeed(namespace, 'write') + super(ModifyRepositoryPermission, self).__init__(admin_need, write_need, org_admin_need, + org_write_need) class ReadRepositoryPermission(Permission): @@ -123,15 +144,17 @@ class ReadRepositoryPermission(Permission): admin_need = _RepositoryNeed(namespace, name, 'admin') write_need = _RepositoryNeed(namespace, name, 'write') read_need = _RepositoryNeed(namespace, name, 'read') - org_admin_need = _OrganizationNeed(namespace, 'admin') - super(ReadRepositoryPermission, self).__init__(admin_need, write_need, - read_need, org_admin_need) + org_admin_need = _OrganizationRepoNeed(namespace, 'admin') + org_write_need = _OrganizationRepoNeed(namespace, 'write') + org_read_need = _OrganizationRepoNeed(namespace, 'read') + super(ReadRepositoryPermission, self).__init__(admin_need, write_need, read_need, + org_admin_need, org_read_need, org_write_need) class AdministerRepositoryPermission(Permission): def __init__(self, namespace, name): admin_need = _RepositoryNeed(namespace, name, 'admin') - org_admin_need = _OrganizationNeed(namespace, 'admin') + org_admin_need = _OrganizationRepoNeed(namespace, 'admin') super(AdministerRepositoryPermission, self).__init__(admin_need, org_admin_need) diff --git a/endpoints/api/search.py b/endpoints/api/search.py index 2f3b837d0..9e2799d1d 100644 --- a/endpoints/api/search.py +++ b/endpoints/api/search.py @@ -1,7 +1,9 @@ -from endpoints.api import ApiResource, parse_args, query_param, truthy_bool, nickname, resource +from endpoints.api import (ApiResource, parse_args, query_param, truthy_bool, nickname, resource, + require_scope) from data import model from auth.permissions import OrganizationMemberPermission, ViewTeamPermission from auth.auth_context import get_authenticated_user +from auth import scopes @resource('/v1/entities/') @@ -11,6 +13,7 @@ class EntitySearch(ApiResource): @query_param('namespace', 'Namespace to use when querying for org entities.', type=str, default='') @query_param('includeTeams', 'Whether to include team names.', type=truthy_bool, default=False) + @require_scope(scopes.READ_USER) @nickname('getMatchingEntities') def get(self, args, prefix): """ Get a list of entities that match the specified prefix. """ @@ -84,6 +87,7 @@ class FindRepositories(ApiResource): """ Resource for finding repositories. """ @parse_args @query_param('query', 'The prefix to use when querying for repositories.', type=str, default='') + @require_scope(scopes.READ_USER) @nickname('findRepos') def get(self, args): """ Get a list of repositories that match the specified prefix query. """