176 lines
5.8 KiB
Python
176 lines
5.8 KiB
Python
from flask import request
|
|
|
|
from endpoints.api import (resource, nickname, ApiResource, validate_json_request, request_error,
|
|
log_action, Unauthorized, NotFound)
|
|
from auth.permissions import AdministerOrganizationPermission, ViewTeamPermission
|
|
from auth.auth_context import get_authenticated_user
|
|
from data import model
|
|
|
|
|
|
def team_view(orgname, team):
|
|
view_permission = ViewTeamPermission(orgname, team.name)
|
|
role = model.get_team_org_role(team).name
|
|
return {
|
|
'id': team.id,
|
|
'name': team.name,
|
|
'description': team.description,
|
|
'can_view': view_permission.can(),
|
|
'role': role
|
|
}
|
|
|
|
def member_view(member):
|
|
return {
|
|
'name': member.username,
|
|
'kind': 'user',
|
|
'is_robot': member.robot,
|
|
}
|
|
|
|
|
|
@resource('/v1/organization/<orgname>/team/<teamname>')
|
|
class OrganizationTeam(ApiResource):
|
|
""" Resource for manging an organization's teams. """
|
|
schemas = {
|
|
'TeamDescription': {
|
|
'id': 'TeamDescription',
|
|
'type': 'object',
|
|
'description': 'Description of a team',
|
|
'required': [
|
|
'role',
|
|
],
|
|
'properties': {
|
|
'role': {
|
|
'type': 'string',
|
|
'description': 'Org wide permissions that should apply to the team',
|
|
'enum': [
|
|
'member',
|
|
'creator',
|
|
'admin',
|
|
],
|
|
},
|
|
'description': {
|
|
'type': 'string',
|
|
'description': 'Markdown description for the team',
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
@nickname('updateOrganizationTeam')
|
|
@validate_json_request('TeamDescription')
|
|
def put(self, orgname, teamname):
|
|
""" Update the org-wide permission for the specified team. """
|
|
edit_permission = AdministerOrganizationPermission(orgname)
|
|
if edit_permission.can():
|
|
team = None
|
|
|
|
details = request.get_json()
|
|
is_existing = False
|
|
try:
|
|
team = model.get_organization_team(orgname, teamname)
|
|
is_existing = True
|
|
except model.InvalidTeamException:
|
|
# Create the new team.
|
|
description = details['description'] if 'description' in details else ''
|
|
role = details['role'] if 'role' in details else 'member'
|
|
|
|
org = model.get_organization(orgname)
|
|
team = model.create_team(teamname, org, role, description)
|
|
log_action('org_create_team', orgname, {'team': teamname})
|
|
|
|
if is_existing:
|
|
if ('description' in details and
|
|
team.description != details['description']):
|
|
team.description = details['description']
|
|
team.save()
|
|
log_action('org_set_team_description', orgname,
|
|
{'team': teamname, 'description': team.description})
|
|
|
|
if 'role' in details:
|
|
role = model.get_team_org_role(team).name
|
|
if role != details['role']:
|
|
team = model.set_team_org_permission(team, details['role'],
|
|
get_authenticated_user().username)
|
|
log_action('org_set_team_role', orgname, {'team': teamname, 'role': details['role']})
|
|
|
|
return team_view(orgname, team), 200
|
|
|
|
raise Unauthorized()
|
|
|
|
@nickname('deleteOrganizationTeam')
|
|
def delete(self, orgname, teamname):
|
|
""" Delete the specified team. """
|
|
permission = AdministerOrganizationPermission(orgname)
|
|
if permission.can():
|
|
model.remove_team(orgname, teamname, get_authenticated_user().username)
|
|
log_action('org_delete_team', orgname, {'team': teamname})
|
|
return 'Deleted', 204
|
|
|
|
raise Unauthorized()
|
|
|
|
|
|
@resource('/v1/organization/<orgname>/team/<teamname>/members')
|
|
class TeamMemberList(ApiResource):
|
|
""" Resource for managing the list of members for a team. """
|
|
@nickname('getOrganizationTeamMembers')
|
|
def get(self, orgname, teamname):
|
|
""" Retrieve the list of members for the specified team. """
|
|
view_permission = ViewTeamPermission(orgname, teamname)
|
|
edit_permission = AdministerOrganizationPermission(orgname)
|
|
|
|
if view_permission.can():
|
|
team = None
|
|
try:
|
|
team = model.get_organization_team(orgname, teamname)
|
|
except model.InvalidTeamException:
|
|
raise NotFound()
|
|
|
|
members = model.get_organization_team_members(team.id)
|
|
return {
|
|
'members': {m.username : member_view(m) for m in members},
|
|
'can_edit': edit_permission.can()
|
|
}
|
|
|
|
raise Unauthorized()
|
|
|
|
|
|
@resource('/v1/organization/<orgname>/team/<teamname>/members/<membername>')
|
|
class TeamMember(ApiResource):
|
|
""" Resource for managing individual members of a team. """
|
|
@nickname('updateOrganizationTeamMember')
|
|
def put(self, orgname, teamname, membername):
|
|
""" Add a member to an existing team. """
|
|
permission = AdministerOrganizationPermission(orgname)
|
|
if permission.can():
|
|
team = None
|
|
user = None
|
|
|
|
# Find the team.
|
|
try:
|
|
team = model.get_organization_team(orgname, teamname)
|
|
except model.InvalidTeamException:
|
|
raise NotFound()
|
|
|
|
# Find the user.
|
|
user = model.get_user(membername)
|
|
if not user:
|
|
raise request_error(message='Unknown user')
|
|
|
|
# Add the user to the team.
|
|
model.add_user_to_team(user, team)
|
|
log_action('org_add_team_member', orgname, {'member': membername, 'team': teamname})
|
|
return member_view(user)
|
|
|
|
raise Unauthorized()
|
|
|
|
@nickname('deleteOrganizationTeamMember')
|
|
def delete(self, orgname, teamname, membername):
|
|
""" Delete an existing member of a team. """
|
|
permission = AdministerOrganizationPermission(orgname)
|
|
if permission.can():
|
|
# Remote the user from the team.
|
|
invoking_user = get_authenticated_user().username
|
|
model.remove_user_from_team(orgname, teamname, membername, invoking_user)
|
|
log_action('org_remove_team_member', orgname, {'member': membername, 'team': teamname})
|
|
return 'Deleted', 204
|
|
|
|
raise Unauthorized()
|