Example #1
0
    def delete(self, type, identifier, attribute_id):
        """
        ---
        summary: Delete object attribute
        description: |
            Deletes attribute from specified object.

            User must have `removing_attributes` capability.
        security:
            - bearerAuth: []
        tags:
            - attribute
        parameters:
            - in: path
              name: type
              schema:
                type: string
                enum: [file, config, blob, object]
              description: Type of object
            - in: path
              name: identifier
              schema:
                type: string
              description: Object identifier
            - in: path
              name: attribute_id
              schema:
                type: string
              description: Identifier of attribute to be deleted
              required: true
        responses:
            200:
                description: When attribute was deleted successfully
            404:
                description: |
                    When object doesn't exist or user doesn't have access
                    to this object.
                    When attribute key is not defined or user doesn't have privileges
                    to set that one.
                    When attribute is already deleted
            503:
                description: |
                    Request canceled due to database statement timeout.
        """
        db_object = access_object(type, identifier)
        if db_object is None:
            raise NotFound("Object not found")

        attribute_to_delete = Attribute.get_by_id(db_object.id, attribute_id).first()
        is_deleted = db_object.remove_attribute_by_id(attribute_id)
        if is_deleted is False:
            raise NotFound(
                "Attribute is not defined or you have "
                "insufficient permissions to delete it"
            )
        db.session.commit()
        hooks.on_removed_attribute(db_object, attribute_to_delete)
        hooks.on_changed_object(db_object)
Example #2
0
    def delete(self, type, identifier, comment_id):
        """
        ---
        summary: Delete comment
        description: |
            Deletes a comment.

            Requires `removing_comments` capability.
        security:
            - bearerAuth: []
        tags:
            - comment
        parameters:
            - in: path
              name: type
              schema:
                type: string
                enum: [file, config, blob, object]
              description: Type of target object
            - in: path
              name: identifier
              schema:
                type: string
              description: Commented object identifier
            - in: path
              name: comment_id
              schema:
                type: string
              description: Comment identifier
        responses:
            200:
                description: When comment was successfully deleted
            403:
                description: When user doesn't have the `removing_comments` capability.
            404:
                description: |
                    When object or comment doesn't exist, user doesn't have access
                    to this object or comment doesn't belong to this object.
            503:
                description: |
                    Request canceled due to database statement timeout.
        """
        db_object = access_object(type, identifier)
        if db_object is None:
            raise NotFound("Object not found")

        db_comment = (db.session.query(Comment).filter(
            Comment.id == comment_id,
            Comment.object_id == db_object.id).first())

        if db_comment is not None:
            db.session.delete(db_comment)
            logger.info("comment deleted", extra={"comment": comment_id})
            db.session.commit()
            hooks.on_removed_comment(db_object, db_comment)
            hooks.on_changed_object(db_object)
        else:
            raise NotFound("Comment not found")
Example #3
0
    def post(self, type, identifier):
        """
        ---
        summary: Add object attribute
        description: |
            Adds attribute to specified object.

            User must have `set` access to the attribute key
            or `adding_all_attributes` capability.
        security:
            - bearerAuth: []
        tags:
            - attribute
        parameters:
            - in: path
              name: type
              schema:
                type: string
                enum: [file, config, blob, object]
              description: Type of object
            - in: path
              name: identifier
              schema:
                type: string
              description: Object identifier
        requestBody:
            description: Attribute key and value
            content:
              application/json:
                schema: AttributeItemRequestSchema
        responses:
            200:
                description: When attribute was added successfully
                content:
                  application/json:
                    schema: AttributeListResponseSchema
            404:
                description: |
                    When object doesn't exist or user doesn't have
                    access to this object.

                    When attribute key is not defined or user doesn't have
                    privileges to set that one.
            503:
                description: |
                    Request canceled due to database statement timeout.
        """
        schema = AttributeItemRequestSchema()
        obj = loads_schema(request.get_data(as_text=True), schema)

        db_object = access_object(type, identifier)
        if db_object is None:
            raise NotFound("Object not found")

        key = obj["key"]
        value = obj["value"]
        is_new = db_object.add_attribute(key, value, include_karton=False)
        if is_new is None:
            raise NotFound(
                f"Attribute '{key}' is not defined or you have "
                f"insufficient permissions to set it"
            )

        db.session.commit()
        db.session.refresh(db_object)
        attributes = db_object.get_attributes(show_karton=False)
        attribute = next((attr for attr in attributes if attr.key == key), None)
        if is_new:
            hooks.on_created_attribute(db_object, attribute)
            hooks.on_changed_object(db_object)
        schema = AttributeListResponseSchema()
        return schema.dump({"attributes": attributes})
Example #4
0
    def delete(self, type, identifier):
        """
        ---
        summary: Delete object tag
        description: |
            Removes tag from object.

            Requires `removing_tags` capability.
        security:
            - bearerAuth: []
        tags:
            - tag
        parameters:
            - in: path
              name: type
              schema:
                type: string
                enum: [file, config, blob, object]
              description: Type of object
            - in: path
              name: identifier
              schema:
                type: string
              description: Object identifier
            - in: query
              name: tag
              schema:
                type: string
              description: Tag to be deleted
              required: true
        responses:
            200:
                description: When tag is successfully removed
                content:
                  application/json:
                    schema:
                      type: array
                      items:
                        $ref: '#/components/schemas/TagItemResponse'
            400:
                description: When tag is invalid
            403:
                description: When user doesn't have `removing_tags` capability.
            404:
                description: |
                    When object doesn't exist or user doesn't have
                    access to this object.
            503:
                description: |
                    Request canceled due to database statement timeout.
        """

        schema = TagRequestSchema()
        obj = load_schema(request.args, schema)

        db_object = access_object(type, identifier)
        if db_object is None:
            raise NotFound("Object not found")

        tag_to_delete = next((t for t in db_object.tags if t.tag == obj["tag"]), None)
        tag_name = obj["tag"]
        is_removed = db_object.remove_tag(tag_name)

        logger.info("Tag removed", extra={"tag": tag_name, "dhash": db_object.dhash})
        db.session.refresh(db_object)
        if is_removed and tag_to_delete:
            hooks.on_removed_tag(db_object, tag_to_delete)
            hooks.on_changed_object(db_object)
        schema = TagItemResponseSchema(many=True)
        return schema.dump(db_object.tags)
Example #5
0
    def put(self, type, identifier):
        """
        ---
        summary: Add object tag
        description: |
            Add new tag to an object.

            Requires `adding_tags` capability.
        security:
            - bearerAuth: []
        tags:
            - tag
        parameters:
            - in: path
              name: type
              schema:
                type: string
                enum: [file, config, blob, object]
              description: Type of target object
            - in: path
              name: identifier
              schema:
                type: string
              description: Object identifier
        requestBody:
            description: Tag value
            content:
              application/json:
                schema: TagRequestSchema
        responses:
            200:
                description: When tag is successfully added
                content:
                  application/json:
                    schema:
                      type: array
                      items:
                        $ref: '#/components/schemas/TagItemResponse'
            400:
                description: When tag is invalid
            403:
                description: When user doesn't have `adding_tags` capability.
            404:
                description: |
                    When object doesn't exist or user doesn't have
                    access to this object.
            503:
                description: |
                    Request canceled due to database statement timeout.
        """
        schema = TagRequestSchema()
        obj = loads_schema(request.get_data(as_text=True), schema)

        db_object = access_object(type, identifier)
        if db_object is None:
            raise NotFound("Object not found")

        tag_name = obj["tag"]
        is_new = db_object.add_tag(tag_name)

        logger.info("Tag added", extra={"tag": tag_name, "dhash": db_object.dhash})
        db.session.refresh(db_object)

        tag = next((t for t in db_object.tags if t.tag == tag_name), None)
        if is_new and tag:
            hooks.on_created_tag(db_object, tag)
            hooks.on_changed_object(db_object)
        elif tag:
            hooks.on_reuploaded_tag(db_object, tag)

        schema = TagItemResponseSchema(many=True)
        return schema.dump(db_object.tags)
Example #6
0
    def put(self, type, parent, child):
        """
        ---
        summary: Link existing objects
        description: |
            Add new relation between existing objects.

            Requires `adding_parents` capability.
        security:
            - bearerAuth: []
        tags:
            - relations
        parameters:
            - in: path
              name: type
              schema:
                type: string
                enum: [file, config, blob, object]
              description: Type of parent object
            - in: path
              name: parent
              description: Identifier of the parent object
              required: true
              schema:
                type: string
            - in: path
              name: child
              description: Identifier of the child object
              required: true
              schema:
                type: string
        responses:
            200:
                description: When relation was successfully added
            403:
                description: When user doesn't have `adding_parents` capability.
            404:
                description: |
                    When one of objects doesn't exist or user
                    doesn't have access to object.
            503:
                description: |
                    Request canceled due to database statement timeout.
        """
        parent_object = access_object(type, parent)
        if parent_object is None:
            raise NotFound("Parent object not found")

        child_object = Object.access(child)
        if child_object is None:
            raise NotFound("Child object not found")

        is_added = child_object.add_parent(parent_object, commit=False)

        db.session.commit()
        if is_added:
            hooks.on_created_relation(parent_object, child_object)
            if parent_object.id != child_object.id:
                hooks.on_changed_object(parent_object)
                hooks.on_changed_object(child_object)
            else:
                hooks.on_changed_object(parent_object)
            logger.info(
                "Child added",
                extra={
                    "parent": parent_object.dhash,
                    "child": child_object.dhash
                },
            )
Example #7
0
    def delete(self, type, parent, child):
        """
        ---
        summary: Remove relation between existing objects
        description: |
            Remove relation between existing objects with permission inheritance.

            Requires `adding_parents` capability.
        security:
            - bearerAuth: []
        tags:
            - relations
        parameters:
            - in: path
              name: type
              schema:
                type: string
                enum: [file, config, blob, object]
              description: Type of parent object
            - in: path
              name: parent
              description: Identifier of the parent object
              required: true
              schema:
                type: string
            - in: path
              name: child
              description: Identifier of the child object
              required: true
              schema:
                type: string
        responses:
            200:
                description: When relation was successfully removed.
            403:
                description: When user doesn't have `removing_parents` capability.
            404:
                description: |
                    When one of objects doesn't exist or user
                    doesn't have access to object.
            503:
                description: |
                    Request canceled due to database statement timeout.
        """
        parent_object = access_object(type, parent)
        if parent_object is None:
            raise NotFound("Parent object not found")

        child_object = Object.access(child)
        if child_object is None:
            raise NotFound("Child object not found")

        result = child_object.remove_parent(parent_object)
        if not result:
            # Relation already removed
            return

        hooks.on_removed_relation(parent_object, child_object)
        if parent_object.id != child_object.id:
            hooks.on_changed_object(parent_object)
            hooks.on_changed_object(child_object)
        else:
            hooks.on_changed_object(parent_object)

        logger.info(
            "Child removed",
            extra={
                "parent": parent_object.dhash,
                "child": child_object.dhash
            },
        )
Example #8
0
    def post(self, type, identifier):
        """
        ---
        summary: Create a new comment
        description: |
            Posts a new comment.

            Requires `adding_comments` capability.
        security:
            - bearerAuth: []
        tags:
            - comment
        parameters:
            - in: path
              name: type
              schema:
                type: string
                enum: [file, config, blob, object]
              description: Type of commented object
            - in: path
              name: identifier
              schema:
                type: string
              description: Commented object's id
        requestBody:
            description: Comment content
            content:
              application/json:
                schema: CommentRequestSchema
        responses:
            200:
                description: Posted comment object
                content:
                  application/json:
                    schema: CommentItemResponseSchema
            400:
                description: When request body is invalid
            403:
                description: When user doesn't have `adding_comments` capability.
            404:
                description: |
                    When object doesn't exist or user doesn't have access
                    to this object.
            503:
                description: |
                    Request canceled due to database statement timeout.
        """
        schema = CommentRequestSchema()

        obj = loads_schema(request.get_data(as_text=True), schema)

        db_object = access_object(type, identifier)
        if db_object is None:
            raise NotFound("Object not found")

        comment = Comment(comment=obj["comment"],
                          user_id=g.auth_user.id,
                          object_id=db_object.id)
        db.session.add(comment)
        db.session.commit()

        logger.info("comment added", extra={"comment": comment.object_id})

        db.session.refresh(comment)
        hooks.on_created_comment(db_object, comment)
        hooks.on_changed_object(db_object)
        schema = CommentItemResponseSchema()
        return schema.dump(comment)