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)
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")
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})
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)
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)
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 }, )
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 }, )
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)