diff --git a/auth/auth.py b/auth/auth.py index 2d77d6094..a20e20129 100644 --- a/auth/auth.py +++ b/auth/auth.py @@ -48,6 +48,20 @@ def process_basic_auth(auth): except model.DataModelException: logger.debug('Invalid token: %s' % credentials[1]) + elif '+' in credentials[0]: + logger.debug('Trying robot auth with credentials %s' % str(credentials)) + # Use as robot auth + try: + robot = model.verify_robot(credentials[0], credentials[1]) + logger.debug('Successfully validated robot: %s' % credentials[0]) + ctx = _request_ctx_stack.top + ctx.authenticated_user = robot + + identity_changed.send(app, identity=Identity(robot.username, 'username')) + return + except model.InvalidRobotException: + logger.debug('Invalid robot or password for robot: %s' % credentials[0]) + else: authenticated = model.verify_user(credentials[0], credentials[1]) diff --git a/data/model.py b/data/model.py index 822605b92..9fe51db65 100644 --- a/data/model.py +++ b/data/model.py @@ -627,7 +627,7 @@ def get_all_repo_teams(namespace_name, repository_name): def get_all_repo_users(namespace_name, repository_name): - select = RepositoryPermission.select(User.username, Role.name, + select = RepositoryPermission.select(User.username, User.robot, Role.name, RepositoryPermission) with_user = select.join(User) with_role = with_user.switch(RepositoryPermission).join(Role) diff --git a/endpoints/api.py b/endpoints/api.py index 202e723dd..aee4947d9 100644 --- a/endpoints/api.py +++ b/endpoints/api.py @@ -292,7 +292,8 @@ def get_matching_entities(prefix): def user_view(user): user_json = { 'name': user.username, - 'kind': 'robot' if user.is_robot else 'user', + 'kind': 'user', + 'is_robot': user.is_robot, } if user.is_org_member is not None: @@ -455,7 +456,8 @@ def get_organization_private_allowed(orgname): def member_view(member): return { - 'username': member.username + 'username': member.username, + 'is_robot': member.robot, } @@ -917,6 +919,11 @@ def role_view(repo_perm_obj): } +def wrap_role_view_user(role_json, user): + role_json['is_robot'] = user.robot + return role_json + + def wrap_role_view_org(role_json, org_member): role_json['is_org_member'] = org_member return role_json @@ -1033,7 +1040,7 @@ def list_repo_user_permissions(namespace, repository): model.get_organization(namespace) # Will raise an error if not org org_members = model.get_organization_member_set(namespace) def wrapped_role_view(repo_perm): - unwrapped = role_view(repo_perm) + unwrapped = wrap_role_view_user(role_view(repo_perm), repo_perm.user) return wrap_role_view_org(unwrapped, repo_perm.user.username in org_members) @@ -1062,7 +1069,7 @@ def get_user_permissions(namespace, repository, username): permission = AdministerRepositoryPermission(namespace, repository) if permission.can(): perm = model.get_user_reponame_permission(username, namespace, repository) - perm_view = role_view(perm) + perm_view = wrap_role_view_user(role_view(perm), perm.user) try: model.get_organization(namespace) @@ -1107,7 +1114,7 @@ def change_user_permissions(namespace, repository, username): perm = model.set_user_repo_permission(username, namespace, repository, new_permission['role']) - perm_view = role_view(perm) + perm_view = wrap_role_view_user(role_view(perm), perm.user) try: model.get_organization(namespace) diff --git a/endpoints/index.py b/endpoints/index.py index 207ace697..13525d5e9 100644 --- a/endpoints/index.py +++ b/endpoints/index.py @@ -62,6 +62,13 @@ def create_user(): except model.InvalidTokenException: abort(401) + elif '+' in username: + try: + model.verify_robot(username, password) + return make_response('Verified', 201) + except model.InvalidRobotException: + abort(401) + existing_user = model.get_user(username) if existing_user: verified = model.verify_user(username, password) diff --git a/static/js/app.js b/static/js/app.js index 04a887b8c..376c0feb3 100644 --- a/static/js/app.js +++ b/static/js/app.js @@ -643,8 +643,10 @@ quayApp.directive('entitySearch', function () { }, template: function (datum) { template = '
- + + {{ member.username }} |