Add team permissions support

This commit is contained in:
Joseph Schorr 2013-11-04 22:58:21 -05:00
parent 97fa69a361
commit 1cd4fa8d9b
6 changed files with 120 additions and 39 deletions

View file

@ -112,6 +112,10 @@ def create_team(name, org, team_role_name, description=''):
description=description)
def remove_team(name, org):
# TODO: have code to remove the team, and all its repo permissions, etc.
pass
def add_user_to_team(user, team):
return TeamMember.create(user=user, team=team)
@ -124,29 +128,16 @@ def remove_user_from_team(user, team):
raise InvalidTeamException('User does not belong to team.')
def set_team_org_permission(team, org, team_role_name):
new_role = TeamRole.get(TeamRole.name == tean_role_name)
def get_team_org_role(team):
return TeamRole.get(TeamRole.id == team.role.id)
def set_team_org_permission(team, team_role_name):
new_role = TeamRole.get(TeamRole.name == team_role_name)
team.role = new_role
team.save()
return team
def set_team_org_permission(team, org, role_name):
new_role = Role.get(Role.name == role_name)
# Fetch any existing permission for this user on the repo
try:
perm = TeamPermission.get(TeamPermission.team == team,
TeamPermission.organization == org)
perm.role = new_role
perm.save()
return perm
except TeamPermission.DoesNotExist:
new_perm = TeamPermission.create(team=team, organization=org,
role=new_role)
return new_perm
def create_federated_user(username, email, service_name, service_id):
new_user = create_user(username, None, email)
new_user.verified = True

View file

@ -215,10 +215,10 @@ def get_matching_entities(prefix):
users = model.get_matching_users(prefix, organization)
def team_view(team):
return {
result = {
'name': team.name,
'kind': 'team',
'is_org_member': True,
'is_org_member': True
}
def user_view(user):
@ -242,11 +242,13 @@ user_files = UserRequestFiles(app.config['AWS_ACCESS_KEY'],
def team_view(orgname, t):
view_permission = ViewTeamPermission(orgname, t.name)
role = model.get_team_org_role(t).name
return {
'id': t.id,
'name': t.name,
'description': t.description,
'can_view': view_permission.can()
'can_view': view_permission.can(),
'role': role
}
@app.route('/api/organization/<orgname>', methods=['GET'])
@ -255,11 +257,12 @@ def get_organization(orgname):
def org_view(o, teams):
admin_org = AdministerOrganizationPermission(orgname)
is_admin = admin_org.can()
return {
'name': o.username,
'gravatar': compute_hash(o.email),
'teams': {t.name : team_view(orgname, t) for t in teams},
'is_admin': admin_org.can()
'is_admin': is_admin
}
if current_user.is_anonymous():
@ -313,13 +316,25 @@ def update_organization_team(orgname, teamname):
if edit_permission.can():
team = None
json = request.get_json()
is_existing = False
try:
team = model.get_organization_team(orgname, teamname)
is_existing = True
except:
abort(404)
# Create the new team.
description = json['description'] if 'description' in json else ''
role = json['role'] if 'role' in json else 'member'
team = model.create_team(teamname, orgname, role, description)
if is_existing:
if 'description' in json:
team.description = json['description']
team.save()
if 'role' in json:
team = model.set_team_org_permission(team, json['role'])
team.description = request.get_json()['description']
team.save()
return jsonify(team_view(orgname, team))
abort(403)

View file

@ -1391,8 +1391,25 @@ p.editable:hover i {
}
.org-view .team-listing {
margin: 10px;
padding: 10px;
padding: 4px;
}
.org-view .header-col {
color: #444;
padding-left: 30px;
}
.org-view .header-col dd {
margin-bottom: 20px;
}
.org-view .header-col .info-icon {
float: none;
margin-left: 10px;
}
.org-view .team-listing .btn-group {
margin-top: 20px;
}
.org-view .team-listing i {

View file

@ -1076,7 +1076,14 @@ function NewRepoCtrl($scope, $location, $http, $timeout, UserService, Restangula
});
}
function OrgViewCtrl($scope, Restangular, $routeParams) {
function OrgViewCtrl($rootScope, $scope, Restangular, $routeParams) {
$('.info-icon').popover({
'trigger': 'hover',
'html': true
});
$rootScope.title = 'Loading...';
var orgname = $routeParams.orgname;
var loadOrganization = function() {
@ -1084,11 +1091,24 @@ function OrgViewCtrl($scope, Restangular, $routeParams) {
getOrganization.get().then(function(resp) {
$scope.organization = resp;
$scope.loading = false;
$rootScope.title = orgname;
}, function() {
$scope.loading = false;
});
};
$scope.setRole = function(teamname, role) {
$scope.organization.teams[teamname].role = role;
var updateTeam = Restangular.one(getRestUrl('organization', orgname, 'team', teamname));
var data = $scope.organization.teams[teamname];
updateTeam.customPUT(data).then(function(resp) {
}, function() {
$('#cannotChangeTeamModal').modal({});
});
};
loadOrganization();
}

View file

@ -9,16 +9,54 @@
<div class="org-view container" ng-show="!loading && organization">
<div class="organization-header" organization="organization"></div>
<div class="team-listing" ng-repeat="(name, team) in organization.teams">
<div class="team-title">
<i class="fa fa-group"></i>
<span ng-show="team.can_view">
<a href="/organization/{{ organization.name }}/teams/{{ team.name }}">{{ team.name }}</a>
</span>
<span ng-show="!team.can_view">
{{ team.name }}
</span>
<div class="row visible-sm visible-md visible-lg">
<div class="col-sm-8"></div>
<div class="col-sm-4 header-col">
Team Permissions
<i class="info-icon fa fa-info-circle" data-placement="bottom" data-original-title="" title=""
data-content="Global permissions for the team and its members<br><br><dl><dt>Member</dt><dd>Permissions are assigned on a per repository basis</dd><dt>Creator</dt><dd>A team can create its own repositories</dd><dt>Admin</dt><dd>A team has full control of the organization</dd></dl>"></i>
</div>
</div>
<div class="team-listing" ng-repeat="(name, team) in organization.teams">
<div class="row">
<div class="col-sm-8">
<div class="team-title">
<i class="fa fa-group"></i>
<span ng-show="team.can_view">
<a href="/organization/{{ organization.name }}/teams/{{ team.name }}">{{ team.name }}</a>
</span>
<span ng-show="!team.can_view">
{{ team.name }}
</span>
</div>
<div class="team-description markdown-view" content="team.description" first-line-only="true"></div>
</div>
<div class="btn-group btn-group-sm col-sm-4" ng-show="organization.is_admin">
<button type="button" class="btn btn-default" ng-click="setRole(name, 'member')" ng-class="{admin: '', creator: '', member: 'active'}[team.role]">Member</button>
<button type="button" class="btn btn-default" ng-click="setRole(name, 'creator')" ng-class="{admin: '', creator: 'active', member: ''}[team.role]">Creator</button>
<button type="button" class="btn btn-primary" ng-click="setRole(name, 'admin')" ng-class="{admin: 'active', creator: '', member: ''}[team.role]">Admin</button>
</div>
</div>
<div class="team-description markdown-view" content="team.description" first-line-only="true"></div>
</div>
</div>
<!-- Modal message dialog -->
<div class="modal fade" id="cannotChangeTeamModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">Cannot change team</h4>
</div>
<div class="modal-body">
You do not have permission to change properties on teams.
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->

View file

@ -66,7 +66,7 @@
<div class="btn-group btn-group-sm">
<button type="button" class="btn btn-default" ng-click="setRole(name, 'read', 'user')" ng-class="{read: 'active', write: '', admin: ''}[permission.role]">Read only</button>
<button type="button" class="btn btn-default" ng-click="setRole(name, 'write', 'user')" ng-class="{read: '', write: 'active', admin: ''}[permission.role]">Write</button>
<button type="button" class="btn btn-default" ng-click="setRole(name, 'admin', 'user')" ng-class="{read: '', write: '', admin: 'active'}[permission.role]">Admin</button>
<button type="button" class="btn btn-primary" ng-click="setRole(name, 'admin', 'user')" ng-class="{read: '', write: '', admin: 'active'}[permission.role]">Admin</button>
</div>
</td>
<td>