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, ReadRepositoryPermission, UserAdminPermission, AdministerOrganizationPermission) from auth.auth_context import get_authenticated_user from auth import scopes from util.gravatar import compute_hash @resource('/v1/entities/') class EntitySearch(ApiResource): """ Resource for searching entities. """ @parse_args @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) @query_param('includeOrgs', 'Whether to include orgs names.', type=truthy_bool, default=False) @nickname('getMatchingEntities') def get(self, args, prefix): """ Get a list of entities that match the specified prefix. """ teams = [] org_data = [] namespace_name = args['namespace'] robot_namespace = None organization = None try: organization = model.get_organization(namespace_name) # namespace name was an org permission = OrganizationMemberPermission(namespace_name) if permission.can(): robot_namespace = namespace_name if args['includeTeams']: teams = model.get_matching_teams(prefix, organization) if args['includeOrgs'] and AdministerOrganizationPermission(namespace_name) \ and namespace_name.startswith(prefix): org_data = [{ 'name': namespace_name, 'kind': 'org', 'is_org_member': True, 'gravatar': compute_hash(organization.email), }] except model.InvalidOrganizationException: # namespace name was a user user = get_authenticated_user() if user and user.username == namespace_name: # Check if there is admin user permissions (login only) admin_permission = UserAdminPermission(user.username) if admin_permission.can(): robot_namespace = namespace_name users = model.get_matching_users(prefix, robot_namespace, organization) def entity_team_view(team): result = { 'name': team.name, 'kind': 'team', 'is_org_member': True } return result def user_view(user): user_json = { 'name': user.username, 'kind': 'user', 'is_robot': user.is_robot, } if organization is not None: user_json['is_org_member'] = user.is_robot or user.is_org_member return user_json team_data = [entity_team_view(team) for team in teams] user_data = [user_view(user) for user in users] return { 'results': team_data + user_data + org_data } def team_view(orgname, team): view_permission = ViewTeamPermission(orgname, team.name) role = model.get_team_org_role(team).name return { 'id': team.id, 'name': team.name, 'description': team.description, 'can_view': view_permission.can(), 'role': role } @resource('/v1/find/repository') 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_REPO) @nickname('findRepos') def get(self, args): """ Get a list of repositories that match the specified prefix query. """ prefix = args['query'] def repo_view(repo): return { 'namespace': repo.namespace, 'name': repo.name, 'description': repo.description } username = None user = get_authenticated_user() if user is not None: username = user.username matching = model.get_matching_repositories(prefix, username) return { 'repositories': [repo_view(repo) for repo in matching if (repo.visibility.name == 'public' or ReadRepositoryPermission(repo.namespace, repo.name).can())] }