diff --git a/storyboard/api/v1/attachments.py b/storyboard/api/v1/attachments.py index a8656be3..e40af7bc 100644 --- a/storyboard/api/v1/attachments.py +++ b/storyboard/api/v1/attachments.py @@ -14,6 +14,7 @@ # limitations under the License. from oslo_config import cfg +from pecan import abort from pecan import request from pecan import response from pecan import rest @@ -28,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 attachments as attachments_api +from storyboard.db.api import stories as stories_api CONF = cfg.CONF @@ -107,3 +109,44 @@ class AttachmentsController(rest.RestController): response.headers['X-Total'] = str(attachment_count) return [wmodels.Attachment.from_db_model(a) for a in attachments] + + @decorators.db_exceptions + @secure(checks.authenticated) + @wsme_pecan.wsexpose(wmodels.Attachment, int, body=wmodels.Attachment) + def post(self, story_id, attachment): + """Create a record of a new attachment. + + Example:: + + curl https://my.example.org/api/v1/stories/1/attachments \\ + -H 'Authorization: Bearer MY_ACCESS_TOKEN' \\ + -H 'Content-Type: application/json;charset=UTF-8' \\ + --data-binary '{"name":"logs.tar.gz",\\ + "link":"https://example.org/logs.tar.gz"}' + + :param story_id: The ID of the story the attachment is for. + :param attachment: Attachment details within the request body. + + """ + attachment_dict = attachment.as_dict() + user_id = request.current_user_id + + story = stories_api.story_get_simple(story_id, current_user=user_id) + if not story: + raise exc.NotFound(_("Story %s not found.") % story_id) + if attachment.creator_id and attachment.creator_id != user_id: + abort(400, _("You cannot select the creator of an attachment.")) + if attachment.story_id and attachment.story_id != story_id: + abort(400, _("You cannot attach to a different story.")) + if not attachment.link: + abort(400, _("An attachment must have a 'link' field.")) + if not attachment.name: + abort(400, _("An attachment must have a 'name' field.")) + + attachment_dict.update({ + "creator_id": user_id, + "story_id": story_id + }) + + created_attachment = attachments_api.create(attachment_dict) + return wmodels.Attachment.from_db_model(created_attachment) diff --git a/storyboard/db/api/attachments.py b/storyboard/db/api/attachments.py index 4e317cb5..8167cfb9 100644 --- a/storyboard/db/api/attachments.py +++ b/storyboard/db/api/attachments.py @@ -51,3 +51,7 @@ def get_all(current_user=None, session=None, **kwargs): def get_count(current_user=None, session=None, **kwargs): query = _build_query(current_user=current_user, session=session, **kwargs) return query.count() + + +def create(attachment_dict): + return api_base.entity_create(models.Attachment, attachment_dict)