From 3a11ea42290a9d6697b177a774349dc4089c1adf Mon Sep 17 00:00:00 2001 From: yackob03 Date: Mon, 4 Nov 2013 18:52:38 -0500 Subject: [PATCH] Made a stupid assumption about when users belonged to an organization, now paying for my terrible ways. --- data/model.py | 47 +++++++++++++++++++++++++++------ endpoints/api.py | 43 +++++++++++++++++------------- static/js/app.js | 2 +- static/js/controllers.js | 10 +++---- static/partials/repo-admin.html | 2 +- 5 files changed, 71 insertions(+), 33 deletions(-) diff --git a/data/model.py b/data/model.py index a28f03cf8..f536658ab 100644 --- a/data/model.py +++ b/data/model.py @@ -222,13 +222,35 @@ def get_user(username): def get_matching_teams(team_prefix, organization): - query = Team.select().where(Team.name ** (team_prefix + '%'), Team.organization == organization) + query = Team.select().where(Team.name ** (team_prefix + '%'), + Team.organization == organization) return list(query.limit(10)) -def get_matching_users(username_prefix): - query = User.select().where(User.username ** (username_prefix + '%'), User.organization == False) - return list(query.limit(10)) +def get_matching_users(username_prefix, 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) + + if organization: + with_team = query.join(TeamMember, JOIN_LEFT_OUTER).join(Team, + JOIN_LEFT_OUTER) + with_org = with_team.join(Org, JOIN_LEFT_OUTER, + on=(Org.id == Team.organization)) + query = with_org.where((Org.id == organization) | (Org.id >> None)) + + + class MatchingUserResult(object): + def __init__(self, *args): + self.username = args[0] + if organization: + self.is_org_member = (args[1] == organization.username) + else: + self.is_org_member = False + + + return (MatchingUserResult(*args) for args in query.tuples().limit(10)) def verify_user(username, password): @@ -264,10 +286,12 @@ def get_organization(name): def get_organization_team(orgname, teamname): joined = Team.select().join(User) - query = joined.where(Team.name == teamname, User.organization == True, User.username == orgname).limit(1) + query = joined.where(Team.name == teamname, User.organization == True, + User.username == orgname).limit(1) result = list(query) if not result: - raise InvalidTeamException('Team does not exist: %s/%s', orgname, teamname) + raise InvalidTeamException('Team does not exist: %s/%s', orgname, + teamname) return result[0] @@ -278,6 +302,12 @@ def get_organization_team_members(teamid): return query +def get_organization_member_set(orgname): + Org = User.alias() + user_teams = User.select(User.username).join(TeamMember).join(Team) + with_org = user_teams.join(Org, on=(Org.username == orgname)) + return {user.username for user in with_org} + def get_teams_within_org(organization): return Team.select().where(Team.organization == organization) @@ -390,14 +420,15 @@ def get_org_wide_permissions(user): def get_all_repo_teams(namespace_name, repository_name): - select = RepositoryPermission.select(Team.name.alias('team_name'), Role.name, - RepositoryPermission) + select = RepositoryPermission.select(Team.name.alias('team_name'), + Role.name, RepositoryPermission) with_team = select.join(Team) with_role = with_team.switch(RepositoryPermission).join(Role) with_repo = with_role.switch(RepositoryPermission).join(Repository) return with_repo.where(Repository.namespace == namespace_name, Repository.name == repository_name) + def get_all_repo_users(namespace_name, repository_name): select = RepositoryPermission.select(User.username, Role.name, RepositoryPermission) diff --git a/endpoints/api.py b/endpoints/api.py index 941f33496..f2bf7e769 100644 --- a/endpoints/api.py +++ b/endpoints/api.py @@ -197,7 +197,6 @@ def get_matching_users(prefix): @app.route('/api/entities/', methods=['GET']) @api_login_required def get_matching_entities(prefix): - users = model.get_matching_users(prefix) teams = [] organization_name = request.args.get('organization', None) @@ -208,10 +207,12 @@ def get_matching_entities(prefix): except: pass - if organization: + if organization: # TODO: ensure that the user has access to the organization teams = model.get_matching_teams(prefix, organization) + users = model.get_matching_users(prefix, organization) + def team_view(team): return { 'name': team.name, @@ -224,7 +225,7 @@ def get_matching_entities(prefix): return { 'name': user.username, 'kind': 'user', - 'outside_org': True + 'is_org_member': user.is_org_member, } team_data = [team_view(team) for team in teams] @@ -661,10 +662,15 @@ def request_repo_build(namespace, repository): abort(403) # Permissions denied -def role_view(repo_perm_obj, org_member): +def role_view_org(repo_perm_obj, org_member): + return { + 'role': repo_perm_obj.role.name, + 'is_org_member': org_member, + } + +def role_view(repo_perm_obj): return { 'role': repo_perm_obj.role.name, - 'outside_org': org_member } @@ -753,10 +759,9 @@ def list_repo_team_permissions(namespace, repository): permission = AdministerRepositoryPermission(namespace, repository) if permission.can(): repo_perms = model.get_all_repo_teams(namespace, repository) - org_member = OrganizationMemberPermission(namespace).can() return jsonify({ - 'permissions': {repo_perm.team.name: role_view(repo_perm, org_member) + 'permissions': {repo_perm.team.name: role_view(repo_perm) for repo_perm in repo_perms} }) @@ -771,11 +776,15 @@ def list_repo_user_permissions(namespace, repository): permission = AdministerRepositoryPermission(namespace, repository) if permission.can(): repo_perms = model.get_all_repo_users(namespace, repository) - member = OrganizationMemberPermission(namespace).can() + org_members = model.get_organization_member_set(namespace) + + def process_perm(repo_perm): + return (repo_perm.user.username, + role_view_org(repo_perm, + repo_perm.user.username in org_members)) return jsonify({ - 'permissions': {repo_perm.user.username: role_view(repo_perm, member) - for repo_perm in repo_perms} + 'permissions': dict(process_perm(perm) for perm in repo_perms) }) abort(403) # Permission denied @@ -791,8 +800,8 @@ def get_user_permissions(namespace, repository, username): permission = AdministerRepositoryPermission(namespace, repository) if permission.can(): perm = model.get_user_reponame_permission(username, namespace, repository) - org_member = OrganizationMemberPermission(namespace).can() - return jsonify(role_view(perm, org_member)) + org_members = model.get_organization_member_set(namespace) + return jsonify(role_view_org(perm, perm.user.username in org_members)) abort(403) # Permission denied @@ -807,8 +816,7 @@ def get_team_permissions(namespace, repository, teamname): permission = AdministerRepositoryPermission(namespace, repository) if permission.can(): perm = model.get_team_reponame_permission(username, namespace, repository) - org_member = OrganizationMemberPermission(namespace).can() - return jsonify(role_view(perm, org_member)) + return jsonify(role_view(perm)) abort(403) # Permission denied @@ -832,8 +840,8 @@ def change_user_permissions(namespace, repository, username): logger.warning('User tried to remove themselves as admin.') abort(409) - org_member = OrganizationMemberPermission(namespace).can() - resp = jsonify(role_view(perm, org_member)) + org_members = model.get_organization_member_set(namespace) + resp = jsonify(role_view_org(perm, perm.user.username in org_members)) if request.method == 'POST': resp.status_code = 201 return resp @@ -860,8 +868,7 @@ def change_team_permissions(namespace, repository, teamname): logger.warning('User tried to remove themselves as admin.') abort(409) - org_member = OrganizationMemberPermission(namespace).can() - resp = jsonify(role_view(perm, org_member)) + resp = jsonify(role_view(perm)) if request.method == 'POST': resp.status_code = 201 return resp diff --git a/static/js/app.js b/static/js/app.js index 7b607a8a5..6fb984a47 100644 --- a/static/js/app.js +++ b/static/js/app.js @@ -303,7 +303,7 @@ quayApp.directive('entitySearch', function () { } template += '' + datum.value + ''; - if (datum.entity.outside_org) { + if (!datum.entity.is_org_member) { template += '
This user is outside your organization
'; } diff --git a/static/js/controllers.js b/static/js/controllers.js index 6d3ebff7a..d1cc85eec 100644 --- a/static/js/controllers.js +++ b/static/js/controllers.js @@ -562,7 +562,7 @@ function RepoAdminCtrl($scope, Restangular, $routeParams, $rootScope) { $scope.grantRole = function() { $('#confirmaddoutsideModal').modal('hide'); var entity = $scope.currentAddEntity; - $scope.addRole(entity.name, 'read', entity.kind, entity.outside_org) + $scope.addRole(entity.name, 'read', entity.kind, entity.is_org_member) $scope.currentAddEntity = null; }; @@ -570,7 +570,7 @@ function RepoAdminCtrl($scope, Restangular, $routeParams, $rootScope) { // Don't allow duplicates. if ($scope.permissions[entity.kind][entity.name]) { return; } - if (entity.outside_org) { + if (!entity.is_org_member) { $scope.currentAddEntity = entity; $('#confirmaddoutsideModal').modal('show'); return; @@ -579,7 +579,7 @@ function RepoAdminCtrl($scope, Restangular, $routeParams, $rootScope) { // Need the $scope.apply for both the permission stuff to change and for // the XHR call to be made. $scope.$apply(function() { - $scope.addRole(entity.name, 'read', entity.kind, entity.outside_org) + $scope.addRole(entity.name, 'read', entity.kind, entity.is_org_member) }); }; @@ -596,10 +596,10 @@ function RepoAdminCtrl($scope, Restangular, $routeParams, $rootScope) { }); }; - $scope.addRole = function(entityName, role, kind, outside_org) { + $scope.addRole = function(entityName, role, kind, is_org_member) { var permission = { 'role': role, - 'outside_org': !!outside_org + 'is_org_member': !!is_org_member }; var permissionPost = Restangular.one(getRestUrl('repository', namespace, name, 'permissions', kind, entityName)); diff --git a/static/partials/repo-admin.html b/static/partials/repo-admin.html index 511554a87..9a7e7d227 100644 --- a/static/partials/repo-admin.html +++ b/static/partials/repo-admin.html @@ -58,7 +58,7 @@ - + {{name}}