Made a stupid assumption about when users belonged to an organization, now paying for my terrible ways.
This commit is contained in:
parent
109f09f0d0
commit
3a11ea4229
5 changed files with 71 additions and 33 deletions
|
@ -222,13 +222,35 @@ def get_user(username):
|
||||||
|
|
||||||
|
|
||||||
def get_matching_teams(team_prefix, organization):
|
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))
|
return list(query.limit(10))
|
||||||
|
|
||||||
|
|
||||||
def get_matching_users(username_prefix):
|
def get_matching_users(username_prefix, organization=None):
|
||||||
query = User.select().where(User.username ** (username_prefix + '%'), User.organization == False)
|
Org = User.alias()
|
||||||
return list(query.limit(10))
|
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):
|
def verify_user(username, password):
|
||||||
|
@ -264,10 +286,12 @@ def get_organization(name):
|
||||||
|
|
||||||
def get_organization_team(orgname, teamname):
|
def get_organization_team(orgname, teamname):
|
||||||
joined = Team.select().join(User)
|
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)
|
result = list(query)
|
||||||
if not result:
|
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]
|
return result[0]
|
||||||
|
|
||||||
|
@ -278,6 +302,12 @@ def get_organization_team_members(teamid):
|
||||||
return query
|
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):
|
def get_teams_within_org(organization):
|
||||||
return Team.select().where(Team.organization == 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):
|
def get_all_repo_teams(namespace_name, repository_name):
|
||||||
select = RepositoryPermission.select(Team.name.alias('team_name'), Role.name,
|
select = RepositoryPermission.select(Team.name.alias('team_name'),
|
||||||
RepositoryPermission)
|
Role.name, RepositoryPermission)
|
||||||
with_team = select.join(Team)
|
with_team = select.join(Team)
|
||||||
with_role = with_team.switch(RepositoryPermission).join(Role)
|
with_role = with_team.switch(RepositoryPermission).join(Role)
|
||||||
with_repo = with_role.switch(RepositoryPermission).join(Repository)
|
with_repo = with_role.switch(RepositoryPermission).join(Repository)
|
||||||
return with_repo.where(Repository.namespace == namespace_name,
|
return with_repo.where(Repository.namespace == namespace_name,
|
||||||
Repository.name == repository_name)
|
Repository.name == repository_name)
|
||||||
|
|
||||||
|
|
||||||
def get_all_repo_users(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, Role.name,
|
||||||
RepositoryPermission)
|
RepositoryPermission)
|
||||||
|
|
|
@ -197,7 +197,6 @@ def get_matching_users(prefix):
|
||||||
@app.route('/api/entities/<prefix>', methods=['GET'])
|
@app.route('/api/entities/<prefix>', methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
def get_matching_entities(prefix):
|
def get_matching_entities(prefix):
|
||||||
users = model.get_matching_users(prefix)
|
|
||||||
teams = []
|
teams = []
|
||||||
|
|
||||||
organization_name = request.args.get('organization', None)
|
organization_name = request.args.get('organization', None)
|
||||||
|
@ -212,6 +211,8 @@ def get_matching_entities(prefix):
|
||||||
# TODO: ensure that the user has access to the organization
|
# TODO: ensure that the user has access to the organization
|
||||||
teams = model.get_matching_teams(prefix, organization)
|
teams = model.get_matching_teams(prefix, organization)
|
||||||
|
|
||||||
|
users = model.get_matching_users(prefix, organization)
|
||||||
|
|
||||||
def team_view(team):
|
def team_view(team):
|
||||||
return {
|
return {
|
||||||
'name': team.name,
|
'name': team.name,
|
||||||
|
@ -224,7 +225,7 @@ def get_matching_entities(prefix):
|
||||||
return {
|
return {
|
||||||
'name': user.username,
|
'name': user.username,
|
||||||
'kind': 'user',
|
'kind': 'user',
|
||||||
'outside_org': True
|
'is_org_member': user.is_org_member,
|
||||||
}
|
}
|
||||||
|
|
||||||
team_data = [team_view(team) for team in teams]
|
team_data = [team_view(team) for team in teams]
|
||||||
|
@ -661,10 +662,15 @@ def request_repo_build(namespace, repository):
|
||||||
abort(403) # Permissions denied
|
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 {
|
return {
|
||||||
'role': repo_perm_obj.role.name,
|
'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)
|
permission = AdministerRepositoryPermission(namespace, repository)
|
||||||
if permission.can():
|
if permission.can():
|
||||||
repo_perms = model.get_all_repo_teams(namespace, repository)
|
repo_perms = model.get_all_repo_teams(namespace, repository)
|
||||||
org_member = OrganizationMemberPermission(namespace).can()
|
|
||||||
|
|
||||||
return jsonify({
|
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}
|
for repo_perm in repo_perms}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -771,11 +776,15 @@ def list_repo_user_permissions(namespace, repository):
|
||||||
permission = AdministerRepositoryPermission(namespace, repository)
|
permission = AdministerRepositoryPermission(namespace, repository)
|
||||||
if permission.can():
|
if permission.can():
|
||||||
repo_perms = model.get_all_repo_users(namespace, repository)
|
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({
|
return jsonify({
|
||||||
'permissions': {repo_perm.user.username: role_view(repo_perm, member)
|
'permissions': dict(process_perm(perm) for perm in repo_perms)
|
||||||
for repo_perm in repo_perms}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
abort(403) # Permission denied
|
abort(403) # Permission denied
|
||||||
|
@ -791,8 +800,8 @@ def get_user_permissions(namespace, repository, username):
|
||||||
permission = AdministerRepositoryPermission(namespace, repository)
|
permission = AdministerRepositoryPermission(namespace, repository)
|
||||||
if permission.can():
|
if permission.can():
|
||||||
perm = model.get_user_reponame_permission(username, namespace, repository)
|
perm = model.get_user_reponame_permission(username, namespace, repository)
|
||||||
org_member = OrganizationMemberPermission(namespace).can()
|
org_members = model.get_organization_member_set(namespace)
|
||||||
return jsonify(role_view(perm, org_member))
|
return jsonify(role_view_org(perm, perm.user.username in org_members))
|
||||||
|
|
||||||
abort(403) # Permission denied
|
abort(403) # Permission denied
|
||||||
|
|
||||||
|
@ -807,8 +816,7 @@ def get_team_permissions(namespace, repository, teamname):
|
||||||
permission = AdministerRepositoryPermission(namespace, repository)
|
permission = AdministerRepositoryPermission(namespace, repository)
|
||||||
if permission.can():
|
if permission.can():
|
||||||
perm = model.get_team_reponame_permission(username, namespace, repository)
|
perm = model.get_team_reponame_permission(username, namespace, repository)
|
||||||
org_member = OrganizationMemberPermission(namespace).can()
|
return jsonify(role_view(perm))
|
||||||
return jsonify(role_view(perm, org_member))
|
|
||||||
|
|
||||||
abort(403) # Permission denied
|
abort(403) # Permission denied
|
||||||
|
|
||||||
|
@ -832,8 +840,8 @@ def change_user_permissions(namespace, repository, username):
|
||||||
logger.warning('User tried to remove themselves as admin.')
|
logger.warning('User tried to remove themselves as admin.')
|
||||||
abort(409)
|
abort(409)
|
||||||
|
|
||||||
org_member = OrganizationMemberPermission(namespace).can()
|
org_members = model.get_organization_member_set(namespace)
|
||||||
resp = jsonify(role_view(perm, org_member))
|
resp = jsonify(role_view_org(perm, perm.user.username in org_members))
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
resp.status_code = 201
|
resp.status_code = 201
|
||||||
return resp
|
return resp
|
||||||
|
@ -860,8 +868,7 @@ def change_team_permissions(namespace, repository, teamname):
|
||||||
logger.warning('User tried to remove themselves as admin.')
|
logger.warning('User tried to remove themselves as admin.')
|
||||||
abort(409)
|
abort(409)
|
||||||
|
|
||||||
org_member = OrganizationMemberPermission(namespace).can()
|
resp = jsonify(role_view(perm))
|
||||||
resp = jsonify(role_view(perm, org_member))
|
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
resp.status_code = 201
|
resp.status_code = 201
|
||||||
return resp
|
return resp
|
||||||
|
|
|
@ -303,7 +303,7 @@ quayApp.directive('entitySearch', function () {
|
||||||
}
|
}
|
||||||
template += '<span class="name">' + datum.value + '</span>';
|
template += '<span class="name">' + datum.value + '</span>';
|
||||||
|
|
||||||
if (datum.entity.outside_org) {
|
if (!datum.entity.is_org_member) {
|
||||||
template += '<div class="alert-warning warning">This user is outside your organization</div>';
|
template += '<div class="alert-warning warning">This user is outside your organization</div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -562,7 +562,7 @@ function RepoAdminCtrl($scope, Restangular, $routeParams, $rootScope) {
|
||||||
$scope.grantRole = function() {
|
$scope.grantRole = function() {
|
||||||
$('#confirmaddoutsideModal').modal('hide');
|
$('#confirmaddoutsideModal').modal('hide');
|
||||||
var entity = $scope.currentAddEntity;
|
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;
|
$scope.currentAddEntity = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -570,7 +570,7 @@ function RepoAdminCtrl($scope, Restangular, $routeParams, $rootScope) {
|
||||||
// Don't allow duplicates.
|
// Don't allow duplicates.
|
||||||
if ($scope.permissions[entity.kind][entity.name]) { return; }
|
if ($scope.permissions[entity.kind][entity.name]) { return; }
|
||||||
|
|
||||||
if (entity.outside_org) {
|
if (!entity.is_org_member) {
|
||||||
$scope.currentAddEntity = entity;
|
$scope.currentAddEntity = entity;
|
||||||
$('#confirmaddoutsideModal').modal('show');
|
$('#confirmaddoutsideModal').modal('show');
|
||||||
return;
|
return;
|
||||||
|
@ -579,7 +579,7 @@ function RepoAdminCtrl($scope, Restangular, $routeParams, $rootScope) {
|
||||||
// Need the $scope.apply for both the permission stuff to change and for
|
// Need the $scope.apply for both the permission stuff to change and for
|
||||||
// the XHR call to be made.
|
// the XHR call to be made.
|
||||||
$scope.$apply(function() {
|
$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 = {
|
var permission = {
|
||||||
'role': role,
|
'role': role,
|
||||||
'outside_org': !!outside_org
|
'is_org_member': !!is_org_member
|
||||||
};
|
};
|
||||||
|
|
||||||
var permissionPost = Restangular.one(getRestUrl('repository', namespace, name, 'permissions', kind, entityName));
|
var permissionPost = Restangular.one(getRestUrl('repository', namespace, name, 'permissions', kind, entityName));
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
|
|
||||||
<!-- User Permissions -->
|
<!-- User Permissions -->
|
||||||
<tr ng-repeat="(name, permission) in permissions['user']">
|
<tr ng-repeat="(name, permission) in permissions['user']">
|
||||||
<td class="{{ 'user entity ' + (permission.outside_org ? 'outside' : '') }}">
|
<td class="{{ 'user entity ' + (permission.is_org_member ? '' : 'outside') }}">
|
||||||
<i class="fa fa-user"></i>
|
<i class="fa fa-user"></i>
|
||||||
<span>{{name}}</span>
|
<span>{{name}}</span>
|
||||||
</td>
|
</td>
|
||||||
|
|
Reference in a new issue