diff --git a/swh/deposit/api/common.py b/swh/deposit/api/common.py --- a/swh/deposit/api/common.py +++ b/swh/deposit/api/common.py @@ -739,6 +739,14 @@ create_origin = metadata.get("swh:deposit", {}).get("swh:create_origin") if create_origin: origin_url = create_origin["swh:origin"]["@url"] + if origin_url is not None: + provider_url = deposit.client.provider_url.rstrip("/") + "/" + if not origin_url.startswith(provider_url): + raise DepositError( + FORBIDDEN, + f"Cannot create origin {origin_url}, it must start with " + f"{provider_url}", + ) deposit.origin_url = origin_url if "atom:external_identifier" in metadata: diff --git a/swh/deposit/tests/api/test_collection_post_atom.py b/swh/deposit/tests/api/test_collection_post_atom.py --- a/swh/deposit/tests/api/test_collection_post_atom.py +++ b/swh/deposit/tests/api/test_collection_post_atom.py @@ -96,6 +96,28 @@ assert b"Malformed xml metadata" in response.content +def test_post_deposit_atom_403_wrong_origin_url_prefix( + authenticated_client, deposit_collection, atom_dataset, deposit_user +): + """Creating an origin for a prefix not owned by the client is forbidden + + """ + origin_url = "http://example.org/foo" + + response = authenticated_client.post( + reverse(COL_IRI, args=[deposit_collection.name]), + content_type="application/atom+xml;type=entry", + data=atom_dataset["entry-data0"] % origin_url, + HTTP_IN_PROGRESS="true", + ) + assert response.status_code == status.HTTP_403_FORBIDDEN + expected_msg = ( + f"Cannot create origin {origin_url}, " + f"it must start with {deposit_user.provider_url}" + ) + assert expected_msg in response.content.decode() + + def test_post_deposit_atom_use_slug_header( authenticated_client, deposit_collection, deposit_user, atom_dataset, mocker ):