Skip to content

Commit

Permalink
Add specialised route for adding creators to items
Browse files Browse the repository at this point in the history
  • Loading branch information
ml-evs committed Aug 4, 2024
1 parent 93dd3c6 commit 259955f
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 0 deletions.
65 changes: 65 additions & 0 deletions pydatalab/pydatalab/routes/v0_1/items.py
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,71 @@ def create_samples():
) # 207: multi-status


@ITEMS.route("/items/<refcode>/permissions", methods=["PATCH"])
def update_item_permissions(refcode: str):
"""Update the permissions of an item with the given refcode."""

request_json = request.get_json()
creator_ids: list[ObjectId] = []

if not len(refcode.split(":")) == 2:
refcode = f"{CONFIG.IDENTIFIER_PREFIX}:{refcode}"

current_item = flask_mongo.db.items.find_one(
{"refcode": refcode, **get_default_permissions(user_only=True)},
{"_id": 1, "creator_ids": 1},
) # type: ignore

if not current_item:
return (
jsonify(
{
"status": "error",
"message": f"No valid item found with the given {refcode=}.",
}
),
401,
)

current_creator_ids = current_item["creator_ids"]

if "creators" in request_json:
creator_ids = [
ObjectId(creator.get("immutable_id", None))
for creator in request_json["creators"]
if creator.get("immutable_id", None) is not None
]

# Validate all creator IDs are present in the database
found_ids = [d for d in flask_mongo.db.users.find({"_id": {"$in": creator_ids}}, {"_id": 1})] # type: ignore
if not len(found_ids) == len(creator_ids):
return (
jsonify(
{
"status": "error",
"message": "One or more creator IDs not found in the database.",
}
),
400,
)

if current_creator_ids:
base_owner = current_creator_ids[0]
if base_owner not in creator_ids:
creator_ids.append(base_owner)

LOGGER.warning("Setting permissions for item %s to %s", refcode, creator_ids)
result = flask_mongo.db.items.update_one(
{"refcode": refcode, **get_default_permissions(user_only=True)},
{"$set": {"creator_ids": creator_ids}},
)

if not result.modified_count == 1:
return jsonify({"status": "error", "message": "Failed to update permissions"}), 400

return jsonify({"status": "success"}), 200


@ITEMS.route("/items/<refcode>", methods=["DELETE"])
@ITEMS.route("/delete-sample/", methods=["POST"])
def delete_sample(refcode: str | None = None, item_id: str | None = None):
Expand Down
26 changes: 26 additions & 0 deletions pydatalab/tests/server/test_permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,29 @@ def test_unauthenticated_user_permissions(unauthenticated_client):

response = client.get("/starting-materials/")
assert response.status_code == 401


def test_basic_permissions_update(admin_client, admin_user_id, client, user_id):
"""Test that an admin can share an item with a normal user."""

response = admin_client.get("/new-sample/", json={"item_id": "test-admin-sample"})
assert response.status_code == 200

response = admin_client.get("/get-item-data/test-admin-sample")
assert response.status_code == 200
refcode = response["item_data"]["refcode"]

response = client.get(f"/items/{refcode}")
assert response.status_code == 404

admin_client.patch(f"/items/{refcode}", json={"creators": [{"immutable_id": user_id}]})
assert response.status_code == 200

response = client.get(f"/items/{refcode}")
assert response.status_code == 200

client.patch(f"/items/{refcode}", json={"creators": []})
assert response.status_code == 200

response = client.get(f"/items/{refcode}")
assert response.status_code == 404

0 comments on commit 259955f

Please sign in to comment.