Add an endpoint for getting Projects related to a Team
This adds a subcontroller under teams, to expose the mapping of Teams to Projects. It also provides methods to add and remove Projects from a Team. Change-Id: I064082001a2a2d3080c35a1e937d420fd473d96c
This commit is contained in:
parent
e7fe27fa22
commit
84518d0ccc
@ -29,6 +29,7 @@ from storyboard.api.v1 import wmodels
|
||||
from storyboard.common import decorators
|
||||
from storyboard.common import exception as exc
|
||||
from storyboard.db.api import base as api_base
|
||||
from storyboard.db.api import projects as projects_api
|
||||
from storyboard.db.api import teams as teams_api
|
||||
from storyboard.db.api import users as users_api
|
||||
|
||||
@ -96,6 +97,65 @@ class UsersSubcontroller(rest.RestController):
|
||||
teams_api.team_delete_user(team_id, user_id)
|
||||
|
||||
|
||||
class ProjectsSubcontroller(rest.RestController):
|
||||
"""This controller should be used to list, add or remove projects from a Team.
|
||||
"""
|
||||
@decorators.db_exceptions
|
||||
@secure(checks.guest)
|
||||
@wsme_pecan.wsexpose([wmodels.Project], int)
|
||||
def get(self, team_id):
|
||||
"""Get projects related to a team.
|
||||
|
||||
Example::
|
||||
|
||||
curl https://my.example.org/api/v1/teams/1/projects
|
||||
|
||||
:param team_id: An ID of the team.
|
||||
"""
|
||||
|
||||
team = teams_api.team_get(team_id)
|
||||
|
||||
if not team:
|
||||
raise exc.NotFound(_("Team %s not found") % team_id)
|
||||
|
||||
return [wmodels.Project.from_db_model(project)
|
||||
for project in team.projects]
|
||||
|
||||
@decorators.db_exceptions
|
||||
@secure(checks.superuser)
|
||||
@wsme_pecan.wsexpose(wmodels.Project, int, int)
|
||||
def put(self, team_id, project_id):
|
||||
"""Relate a project to a team.
|
||||
|
||||
Example::
|
||||
|
||||
TODO
|
||||
|
||||
:param team_id: An ID of the team.
|
||||
:param project_id: An ID of the project.
|
||||
"""
|
||||
|
||||
teams_api.team_add_project(team_id, project_id)
|
||||
project = projects_api.project_get(project_id)
|
||||
|
||||
return wmodels.Project.from_db_model(project)
|
||||
|
||||
@decorators.db_exceptions
|
||||
@secure(checks.superuser)
|
||||
@wsme_pecan.wsexpose(None, int, int, status_code=204)
|
||||
def delete(self, team_id, project_id):
|
||||
"""Delete a user from a team.
|
||||
|
||||
Example::
|
||||
|
||||
TODO
|
||||
|
||||
:param team_id: An ID of the team.
|
||||
:param user_id: An ID of the user.
|
||||
"""
|
||||
teams_api.team_delete_project(team_id, project_id)
|
||||
|
||||
|
||||
class TeamsController(rest.RestController):
|
||||
"""REST controller for Teams."""
|
||||
|
||||
@ -220,6 +280,7 @@ class TeamsController(rest.RestController):
|
||||
raise exc.NotFound(_("Team %s not found") % team_id)
|
||||
|
||||
users = UsersSubcontroller()
|
||||
projects = ProjectsSubcontroller()
|
||||
|
||||
def _is_int(self, s):
|
||||
try:
|
||||
@ -234,7 +295,7 @@ class TeamsController(rest.RestController):
|
||||
# It's a request by a name or id
|
||||
first_token = args[0]
|
||||
if self._is_int(first_token):
|
||||
if len(args) > 1 and args[1] == "users":
|
||||
if len(args) > 1 and args[1] in ("projects", "users"):
|
||||
# Route to users subcontroller
|
||||
return super(TeamsController, self)._route(args, request)
|
||||
|
||||
|
@ -19,6 +19,7 @@ from wsme.exc import ClientSideError
|
||||
from storyboard._i18n import _
|
||||
from storyboard.common import exception as exc
|
||||
from storyboard.db.api import base as api_base
|
||||
from storyboard.db.api import projects
|
||||
from storyboard.db.api import users
|
||||
from storyboard.db import models
|
||||
|
||||
@ -108,6 +109,55 @@ def team_delete_user(team_id, user_id):
|
||||
return team
|
||||
|
||||
|
||||
def team_add_project(team_id, project_id):
|
||||
session = api_base.get_session()
|
||||
|
||||
with session.begin(subtransactions=True):
|
||||
team = _entity_get(team_id, session)
|
||||
if team is None:
|
||||
raise exc.NotFound(_("Team %s not found") % team_id)
|
||||
|
||||
project = projects.project_get(project_id)
|
||||
if project is None:
|
||||
raise exc.NotFound(_("Project %s not found") % project_id)
|
||||
|
||||
if project_id in [p.id for p in team.projects]:
|
||||
raise ClientSideError(_("The Project %(user_id)d is already "
|
||||
"in Team %(team_id)d") %
|
||||
{'project_id': project_id,
|
||||
'team_id': team_id})
|
||||
|
||||
team.projects.append(project)
|
||||
session.add(team)
|
||||
|
||||
return team
|
||||
|
||||
|
||||
def team_delete_project(team_id, project_id):
|
||||
session = api_base.get_session()
|
||||
|
||||
with session.begin(subtransactions=True):
|
||||
team = _entity_get(team_id, session)
|
||||
if team is None:
|
||||
raise exc.NotFound(_("Team %s not found") % team_id)
|
||||
|
||||
project = projects.project_get(project_id)
|
||||
if project is None:
|
||||
raise exc.NotFound(_("Project %s not found") % project_id)
|
||||
|
||||
if project_id not in [p.id for p in team.projects]:
|
||||
raise ClientSideError(_("The Project %(user_id)d is not in "
|
||||
"Team %(team_id)d") %
|
||||
{'project_id': project_id,
|
||||
'team_id': team_id})
|
||||
|
||||
project_entry = [p for p in team.projects if p.id == project_id][0]
|
||||
team.projects.remove(project_entry)
|
||||
session.add(team)
|
||||
|
||||
return team
|
||||
|
||||
|
||||
def team_delete(team_id):
|
||||
team = team_get(team_id)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user