diff --git a/data/model.py b/data/model.py index a18dc0af4..822605b92 100644 --- a/data/model.py +++ b/data/model.py @@ -379,11 +379,19 @@ def get_matching_teams(team_prefix, organization): return query.limit(10) -def get_matching_users(username_prefix, organization=None): +def get_matching_users(username_prefix, robot_namespace=None, + organization=None): Org = User.alias() - users_no_orgs = (User.username ** (username_prefix + '%') & - (User.organization == False)) - query = User.select(User.username, Org.username).where(users_no_orgs) + direct_user_query = (User.username ** (username_prefix + '%') & + (User.organization == False) & (User.robot == False)) + + if robot_namespace: + robot_prefix = format_robot_username(robot_namespace, username_prefix) + direct_user_query = (direct_user_query | + (User.username ** (robot_prefix + '%') & + (User.robot == True))) + + query = User.select(User.username, Org.username, User.robot).where(direct_user_query) if organization: with_team = query.join(TeamMember, JOIN_LEFT_OUTER).join(Team, @@ -396,6 +404,7 @@ def get_matching_users(username_prefix, organization=None): class MatchingUserResult(object): def __init__(self, *args): self.username = args[0] + self.is_robot = args[2] if organization: self.is_org_member = (args[1] == organization.username) else: diff --git a/endpoints/api.py b/endpoints/api.py index 185459094..202e723dd 100644 --- a/endpoints/api.py +++ b/endpoints/api.py @@ -260,20 +260,26 @@ def get_matching_users(prefix): def get_matching_entities(prefix): teams = [] - organization_name = request.args.get('organization', None) + namespace_name = request.args.get('namespace', None) + robot_namespace = None organization = None - if organization_name: - permission = OrganizationMemberPermission(organization_name) + try: + organization = model.get_organization(namespace_name) + + # namespace name was an org + permission = OrganizationMemberPermission(namespace_name) if permission.can(): - try: - organization = model.get_organization(organization_name) - except model.InvalidOrganizationException: - pass + robot_namespace = namespace_name - if organization: - teams = model.get_matching_teams(prefix, organization) + if request.args.get('includeTeams', False): + teams = model.get_matching_teams(prefix, organization) - users = model.get_matching_users(prefix, organization) + except model.InvalidOrganizationException: + # namespace name was a user + if current_user.db_user().username == namespace_name: + robot_namespace = namespace_name + + users = model.get_matching_users(prefix, robot_namespace, organization) def entity_team_view(team): result = { @@ -286,7 +292,7 @@ def get_matching_entities(prefix): def user_view(user): user_json = { 'name': user.username, - 'kind': 'user', + 'kind': 'robot' if user.is_robot else 'user', } if user.is_org_member is not None: diff --git a/initdb.py b/initdb.py index 5a2fbeb40..e810d8ab7 100644 --- a/initdb.py +++ b/initdb.py @@ -132,6 +132,8 @@ def populate_database(): new_user_1.verified = True new_user_1.save() + model.create_robot('dtrobot', new_user_1) + new_user_2 = model.create_user('public', 'password', 'jacob.moshenko@gmail.com') new_user_2.verified = True @@ -188,6 +190,8 @@ def populate_database(): org.stripe_id = TEST_STRIPE_ID org.save() + model.create_robot('neworgrobot', org) + owners = model.get_organization_team('buynlarge', 'owners') owners.description = 'Owners have unfetterd access across the entire org.' owners.save() diff --git a/static/js/app.js b/static/js/app.js index 26d7aa5da..04a887b8c 100644 --- a/static/js/app.js +++ b/static/js/app.js @@ -604,9 +604,10 @@ quayApp.directive('entitySearch', function () { transclude: false, restrict: 'C', scope: { - 'organization': '=organization', + 'namespace': '=namespace', 'inputTitle': '=inputTitle', - 'entitySelected': '=entitySelected' + 'entitySelected': '=entitySelected', + 'includeTeams': '=includeTeams' }, controller: function($scope, $element) { if (!$scope.entitySelected) { return; } @@ -614,15 +615,16 @@ quayApp.directive('entitySearch', function () { number++; var input = $element[0].firstChild; - $scope.organization = $scope.organization || ''; + $scope.namespace = $scope.namespace || ''; $(input).typeahead({ name: 'entities' + number, remote: { url: '/api/entities/%QUERY', replace: function (url, uriEncodedQuery) { url = url.replace('%QUERY', uriEncodedQuery); - if ($scope.organization) { - url += '?organization=' + encodeURIComponent($scope.organization); + url += '?namespace=' + encodeURIComponent($scope.namespace); + if ($scope.includeTeams) { + url += '&includeTeams=true' } return url; }, @@ -648,7 +650,7 @@ quayApp.directive('entitySearch', function () { } template += '' + datum.value + ''; - if (datum.entity.is_org_member !== undefined && !datum.entity.is_org_member) { + if (datum.entity.is_org_member !== undefined && !datum.entity.is_org_member && datum.kind == 'user') { template += '