Changeset View
Changeset View
Standalone View
Standalone View
swh/deposit/api/common.py
Show First 20 Lines • Show All 141 Lines • ▼ Show 20 Lines | def guess_deposit_origin_url(deposit: Deposit): | ||||
external_id = deposit.external_id | external_id = deposit.external_id | ||||
if not external_id: | if not external_id: | ||||
# The client provided neither an origin_url nor a slug. That's inconvenient, | # The client provided neither an origin_url nor a slug. That's inconvenient, | ||||
# but SWORD requires we support it. So let's generate a random slug. | # but SWORD requires we support it. So let's generate a random slug. | ||||
external_id = str(uuid.uuid4()) | external_id = str(uuid.uuid4()) | ||||
return "%s/%s" % (deposit.client.provider_url.rstrip("/"), external_id) | return "%s/%s" % (deposit.client.provider_url.rstrip("/"), external_id) | ||||
def check_client_origin(client: DepositClient, origin_url: str): | |||||
provider_url = 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}", | |||||
) | |||||
class AuthenticatedAPIView(APIView): | class AuthenticatedAPIView(APIView): | ||||
"""Mixin intended as a based API view to enforce the basic | """Mixin intended as a based API view to enforce the basic | ||||
authentication check | authentication check | ||||
""" | """ | ||||
authentication_classes: Sequence[Type[BaseAuthentication]] = (BasicAuthentication,) | authentication_classes: Sequence[Type[BaseAuthentication]] = (BasicAuthentication,) | ||||
permission_classes: Sequence[Type[BasePermission]] = (IsAuthenticated,) | permission_classes: Sequence[Type[BasePermission]] = (IsAuthenticated,) | ||||
▲ Show 20 Lines • Show All 574 Lines • ▼ Show 20 Lines | ) -> Receipt: | ||||
raise DepositError( | raise DepositError( | ||||
BAD_REQUEST, | BAD_REQUEST, | ||||
"Empty body request is not supported", | "Empty body request is not supported", | ||||
"Atom entry deposit is supposed to send for metadata. " | "Atom entry deposit is supposed to send for metadata. " | ||||
"If the body is empty, there is no metadata.", | "If the body is empty, there is no metadata.", | ||||
) | ) | ||||
create_origin = metadata.get("swh:deposit", {}).get("swh:create_origin") | create_origin = metadata.get("swh:deposit", {}).get("swh:create_origin") | ||||
if create_origin: | add_to_origin = metadata.get("swh:deposit", {}).get("swh:add_to_origin") | ||||
origin_url = create_origin["swh:origin"]["@url"] | |||||
if origin_url is not None: | if create_origin and add_to_origin: | ||||
provider_url = deposit.client.provider_url.rstrip("/") + "/" | |||||
if not origin_url.startswith(provider_url): | |||||
raise DepositError( | raise DepositError( | ||||
FORBIDDEN, | BAD_REQUEST, | ||||
f"Cannot create origin {origin_url}, it must start with " | "<swh:create_origin> and <swh:add_to_origin> are mutually exclusive, " | ||||
f"{provider_url}", | "as they respectively create a new origin and add to an existing " | ||||
"origin.", | |||||
ardumont: missing test scenario | |||||
) | ) | ||||
if create_origin: | |||||
origin_url = create_origin["swh:origin"]["@url"] | |||||
check_client_origin(deposit.client, origin_url) | |||||
deposit.origin_url = origin_url | deposit.origin_url = origin_url | ||||
if add_to_origin: | |||||
origin_url = add_to_origin["swh:origin"]["@url"] | |||||
check_client_origin(deposit.client, origin_url) | |||||
deposit.parent = ( | |||||
Deposit.objects.filter( | |||||
client=deposit.client, | |||||
origin_url=origin_url, | |||||
status=DEPOSIT_STATUS_LOAD_SUCCESS, | |||||
) | |||||
.order_by("-id")[0:1] | |||||
.get() | |||||
) | |||||
if "atom:external_identifier" in metadata: | if "atom:external_identifier" in metadata: | ||||
# Deprecated tag. | # Deprecated tag. | ||||
# When clients stopped using it, this should raise an error | # When clients stopped using it, this should raise an error | ||||
# unconditionally | # unconditionally | ||||
if deposit.origin_url: | if deposit.origin_url: | ||||
raise DepositError( | raise DepositError( | ||||
BAD_REQUEST, | BAD_REQUEST, | ||||
"<external_identifier> is deprecated, you should only use " | "<external_identifier> is deprecated, you should only use " | ||||
"<swh:create_origin> from now on.", | "<swh:create_origin> from now on.", | ||||
) | ) | ||||
if deposit.parent: | |||||
raise DepositError( | |||||
BAD_REQUEST, "<external_identifier> is deprecated.", | |||||
Not Done Inline Actionssame, missing scnenario ardumont: same, missing scnenario | |||||
) | |||||
if headers.slug and metadata["atom:external_identifier"] != headers.slug: | if headers.slug and metadata["atom:external_identifier"] != headers.slug: | ||||
raise DepositError( | raise DepositError( | ||||
BAD_REQUEST, | BAD_REQUEST, | ||||
"The 'external_identifier' tag is deprecated, " | "The 'external_identifier' tag is deprecated, " | ||||
"the Slug header should be used instead.", | "the Slug header should be used instead.", | ||||
) | ) | ||||
# Determine if we are in the metadata-only deposit case | # Determine if we are in the metadata-only deposit case | ||||
try: | try: | ||||
swhid = parse_swh_reference(metadata) | swhid = parse_swh_reference(metadata) | ||||
except ValidationError as e: | except ValidationError as e: | ||||
raise DepositError( | raise DepositError( | ||||
PARSING_ERROR, "Invalid SWHID reference", str(e), | PARSING_ERROR, "Invalid SWHID reference", str(e), | ||||
) | ) | ||||
if swhid is not None and ( | if swhid is not None and ( | ||||
deposit.origin_url or deposit.parent or deposit.external_id | deposit.origin_url or deposit.parent or deposit.external_id | ||||
): | ): | ||||
raise DepositError( | raise DepositError( | ||||
BAD_REQUEST, | BAD_REQUEST, | ||||
"<swh:reference> is for metadata-only deposits and " | "<swh:reference> is for metadata-only deposits and " | ||||
"<swh:create_origin> / Slug are for code deposits, " | "<swh:create_origin> / <swh:add_to_origin> / Slug are for " | ||||
"only one may be used on a given deposit.", | "code deposits, only one may be used on a given deposit.", | ||||
) | ) | ||||
self._deposit_put( | self._deposit_put( | ||||
deposit=deposit, in_progress=headers.in_progress, | deposit=deposit, in_progress=headers.in_progress, | ||||
) | ) | ||||
if swhid is not None: | if swhid is not None: | ||||
swhid, swhid_ref, depo, depo_request = self._store_metadata_deposit( | swhid, swhid_ref, depo, depo_request = self._store_metadata_deposit( | ||||
▲ Show 20 Lines • Show All 369 Lines • Show Last 20 Lines |
missing test scenario