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 decorators
|
||||||
from storyboard.common import exception as exc
|
from storyboard.common import exception as exc
|
||||||
from storyboard.db.api import base as api_base
|
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 teams as teams_api
|
||||||
from storyboard.db.api import users as users_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)
|
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):
|
class TeamsController(rest.RestController):
|
||||||
"""REST controller for Teams."""
|
"""REST controller for Teams."""
|
||||||
|
|
||||||
@ -220,6 +280,7 @@ class TeamsController(rest.RestController):
|
|||||||
raise exc.NotFound(_("Team %s not found") % team_id)
|
raise exc.NotFound(_("Team %s not found") % team_id)
|
||||||
|
|
||||||
users = UsersSubcontroller()
|
users = UsersSubcontroller()
|
||||||
|
projects = ProjectsSubcontroller()
|
||||||
|
|
||||||
def _is_int(self, s):
|
def _is_int(self, s):
|
||||||
try:
|
try:
|
||||||
@ -234,7 +295,7 @@ class TeamsController(rest.RestController):
|
|||||||
# It's a request by a name or id
|
# It's a request by a name or id
|
||||||
first_token = args[0]
|
first_token = args[0]
|
||||||
if self._is_int(first_token):
|
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
|
# Route to users subcontroller
|
||||||
return super(TeamsController, self)._route(args, request)
|
return super(TeamsController, self)._route(args, request)
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ from wsme.exc import ClientSideError
|
|||||||
from storyboard._i18n import _
|
from storyboard._i18n import _
|
||||||
from storyboard.common import exception as exc
|
from storyboard.common import exception as exc
|
||||||
from storyboard.db.api import base as api_base
|
from storyboard.db.api import base as api_base
|
||||||
|
from storyboard.db.api import projects
|
||||||
from storyboard.db.api import users
|
from storyboard.db.api import users
|
||||||
from storyboard.db import models
|
from storyboard.db import models
|
||||||
|
|
||||||
@ -108,6 +109,55 @@ def team_delete_user(team_id, user_id):
|
|||||||
return team
|
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):
|
def team_delete(team_id):
|
||||||
team = team_get(team_id)
|
team = team_get(team_id)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user