Merge pull request #1905 from coreos-inc/external-auth-search
Add support for entity search against external auth users not yet linked
This commit is contained in:
commit
934cdecbd6
16 changed files with 817 additions and 100 deletions
|
@ -1,14 +1,15 @@
|
|||
""" Conduct searches against all registry context. """
|
||||
|
||||
from endpoints.api import (ApiResource, parse_args, query_param, truthy_bool, nickname, resource,
|
||||
require_scope, path_param)
|
||||
require_scope, path_param, internal_only, Unauthorized, InvalidRequest,
|
||||
show_if)
|
||||
from data import model
|
||||
from auth.permissions import (OrganizationMemberPermission, ReadRepositoryPermission,
|
||||
UserAdminPermission, AdministerOrganizationPermission,
|
||||
ReadRepositoryPermission)
|
||||
from auth.auth_context import get_authenticated_user
|
||||
from auth import scopes
|
||||
from app import avatar
|
||||
from app import avatar, authentication
|
||||
from operator import itemgetter
|
||||
from stringscore import liquidmetal
|
||||
from util.names import parse_robot_username
|
||||
|
@ -16,6 +17,32 @@ from util.names import parse_robot_username
|
|||
import anunidecode # Don't listen to pylint's lies. This import is required.
|
||||
import math
|
||||
|
||||
@show_if(authentication.federated_service) # Only enabled for non-DB auth.
|
||||
@resource('/v1/entities/link/<username>')
|
||||
@internal_only
|
||||
class LinkExternalEntity(ApiResource):
|
||||
""" Resource for linking external entities to internal users. """
|
||||
@nickname('linkExternalUser')
|
||||
def post(self, username):
|
||||
# Only allowed if there is a logged in user.
|
||||
if not get_authenticated_user():
|
||||
raise Unauthorized()
|
||||
|
||||
# Try to link the user with the given *external* username, to an internal record.
|
||||
(user, err_msg) = authentication.link_user(username)
|
||||
if user is None:
|
||||
raise InvalidRequest(err_msg, payload={'username': username})
|
||||
|
||||
return {
|
||||
'entity': {
|
||||
'name': user.username,
|
||||
'kind': 'user',
|
||||
'is_robot': False,
|
||||
'avatar': avatar.get_data_for_user(user)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@resource('/v1/entities/<prefix>')
|
||||
class EntitySearch(ApiResource):
|
||||
""" Resource for searching entities. """
|
||||
|
@ -69,7 +96,22 @@ class EntitySearch(ApiResource):
|
|||
if admin_permission.can():
|
||||
robot_namespace = namespace_name
|
||||
|
||||
users = model.user.get_matching_users(prefix, robot_namespace, organization)
|
||||
# Lookup users in the database for the prefix query.
|
||||
users = model.user.get_matching_users(prefix, robot_namespace, organization, limit=10)
|
||||
|
||||
# Lookup users via the user system for the prefix query. We'll filter out any users that
|
||||
# already exist in the database.
|
||||
external_users, federated_id, _ = authentication.query_users(prefix, limit=10)
|
||||
filtered_external_users = []
|
||||
if external_users and federated_id is not None:
|
||||
users = list(users)
|
||||
user_ids = [user.id for user in users]
|
||||
|
||||
# Filter the users if any are already found via the database. We do so by looking up all
|
||||
# the found users in the federated user system.
|
||||
federated_query = model.user.get_federated_logins(user_ids, federated_id)
|
||||
found = {result.service_ident for result in federated_query}
|
||||
filtered_external_users = [user for user in external_users if not user.username in found]
|
||||
|
||||
def entity_team_view(team):
|
||||
result = {
|
||||
|
@ -93,11 +135,20 @@ class EntitySearch(ApiResource):
|
|||
|
||||
return user_json
|
||||
|
||||
def external_view(user):
|
||||
result = {
|
||||
'name': user.username,
|
||||
'kind': 'external',
|
||||
'avatar': avatar.get_data_for_external_user(user)
|
||||
}
|
||||
return result
|
||||
|
||||
team_data = [entity_team_view(team) for team in teams]
|
||||
user_data = [user_view(user) for user in users]
|
||||
external_data = [external_view(user) for user in filtered_external_users]
|
||||
|
||||
return {
|
||||
'results': team_data + user_data + org_data
|
||||
'results': team_data + user_data + org_data + external_data
|
||||
}
|
||||
|
||||
|
||||
|
|
Reference in a new issue