Changeset View
Changeset View
Standalone View
Standalone View
swh/deposit/api/common.py
Show First 20 Lines • Show All 98 Lines • ▼ Show 20 Lines | |||||
def _compute_md5(filehandler: InMemoryUploadedFile) -> bytes: | def _compute_md5(filehandler: InMemoryUploadedFile) -> bytes: | ||||
h = hashlib.md5() | h = hashlib.md5() | ||||
for chunk in filehandler: | for chunk in filehandler: | ||||
h.update(chunk) # type: ignore | h.update(chunk) # type: ignore | ||||
return h.digest() | return h.digest() | ||||
def get_deposit_by_id( | |||||
deposit_id: int, collection_name: Optional[str] = None | |||||
) -> Deposit: | |||||
"""Gets an existing Deposit object if it exists, or raises `DepositError`. | |||||
If `collection` is not None, also checks the deposit belongs to the collection.""" | |||||
try: | |||||
deposit = Deposit.objects.get(pk=deposit_id) | |||||
except Deposit.DoesNotExist: | |||||
raise DepositError(NOT_FOUND, f"Deposit {deposit_id} does not exist") | |||||
if collection_name and deposit.collection.name != collection_name: | |||||
raise DepositError( | |||||
NOT_FOUND, | |||||
f"Deposit {deposit_id} does not belong to collection {collection_name}", | |||||
) | |||||
return deposit | |||||
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 97 Lines • ▼ Show 20 Lines | ) -> Deposit: | ||||
collection=self._collection, | collection=self._collection, | ||||
external_id=external_id or "", | external_id=external_id or "", | ||||
complete_date=complete_date, | complete_date=complete_date, | ||||
status=status_type, | status=status_type, | ||||
client=self._client, | client=self._client, | ||||
parent=deposit_parent, | parent=deposit_parent, | ||||
) | ) | ||||
else: | else: | ||||
deposit = Deposit.objects.get(pk=deposit_id) | deposit = get_deposit_by_id(deposit_id) | ||||
# update metadata | # update metadata | ||||
deposit.complete_date = complete_date | deposit.complete_date = complete_date | ||||
deposit.status = status_type | deposit.status = status_type | ||||
if self.config["checks"]: | if self.config["checks"]: | ||||
deposit.save() # needed to have a deposit id | deposit.save() # needed to have a deposit id | ||||
scheduler = self.scheduler | scheduler = self.scheduler | ||||
▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | ) -> DepositRequest: | ||||
assert deposit_request is not None | assert deposit_request is not None | ||||
return deposit_request | return deposit_request | ||||
def _delete_archives(self, collection_name: str, deposit_id: int) -> Dict: | def _delete_archives(self, collection_name: str, deposit_id: int) -> Dict: | ||||
"""Delete archive references from the deposit id. | """Delete archive references from the deposit id. | ||||
""" | """ | ||||
try: | deposit = get_deposit_by_id(deposit_id) | ||||
deposit = Deposit.objects.get(pk=deposit_id) | |||||
except Deposit.DoesNotExist: | |||||
raise DepositError(NOT_FOUND, f"The deposit {deposit_id} does not exist") | |||||
DepositRequest.objects.filter(deposit=deposit, type=ARCHIVE_TYPE).delete() | DepositRequest.objects.filter(deposit=deposit, type=ARCHIVE_TYPE).delete() | ||||
return {} | return {} | ||||
def _delete_deposit(self, collection_name: str, deposit_id: int) -> Dict: | def _delete_deposit(self, collection_name: str, deposit_id: int) -> Dict: | ||||
"""Delete deposit reference. | """Delete deposit reference. | ||||
Args: | Args: | ||||
collection_name: Client's collection | collection_name: Client's collection | ||||
deposit_id: The deposit to delete | deposit_id: The deposit to delete | ||||
Returns | Returns | ||||
Empty dict when ok. | Empty dict when ok. | ||||
Dict with error key to describe the failure. | Dict with error key to describe the failure. | ||||
""" | """ | ||||
try: | deposit = get_deposit_by_id(deposit_id) | ||||
deposit = Deposit.objects.get(pk=deposit_id) | |||||
except Deposit.DoesNotExist: | |||||
raise DepositError(NOT_FOUND, f"The deposit {deposit_id} does not exist") | |||||
if deposit.collection.name != collection_name: | if deposit.collection.name != collection_name: | ||||
summary = "Cannot delete a deposit from another collection" | summary = "Cannot delete a deposit from another collection" | ||||
description = "Deposit %s does not belong to the collection %s" % ( | description = "Deposit %s does not belong to the collection %s" % ( | ||||
deposit_id, | deposit_id, | ||||
collection_name, | collection_name, | ||||
) | ) | ||||
raise DepositError( | raise DepositError( | ||||
▲ Show 20 Lines • Show All 486 Lines • ▼ Show 20 Lines | ) -> Receipt: | ||||
Args: | Args: | ||||
request: the request holding information to parse | request: the request holding information to parse | ||||
and inject in db | and inject in db | ||||
headers: parsed request headers | headers: parsed request headers | ||||
collection_name: the associated client | collection_name: the associated client | ||||
deposit_id: deposit identifier | deposit_id: deposit identifier | ||||
""" | """ | ||||
deposit = Deposit.objects.get(pk=deposit_id) | deposit = get_deposit_by_id(deposit_id) | ||||
deposit.complete_date = timezone.now() | deposit.complete_date = timezone.now() | ||||
deposit.status = DEPOSIT_STATUS_DEPOSITED | deposit.status = DEPOSIT_STATUS_DEPOSITED | ||||
deposit.save() | deposit.save() | ||||
return Receipt( | return Receipt( | ||||
deposit_id=deposit_id, | deposit_id=deposit_id, | ||||
deposit_date=deposit.complete_date, | deposit_date=deposit.complete_date, | ||||
status=deposit.status, | status=deposit.status, | ||||
Show All 40 Lines | ) -> ParsedRequestHeaders: | ||||
raise DepositError( | raise DepositError( | ||||
FORBIDDEN, | FORBIDDEN, | ||||
f"Client {username} cannot access collection {collection_name}", | f"Client {username} cannot access collection {collection_name}", | ||||
) | ) | ||||
headers = self._read_headers(request) | headers = self._read_headers(request) | ||||
if deposit_id: | if deposit_id: | ||||
try: | deposit = get_deposit_by_id(deposit_id) | ||||
deposit = Deposit.objects.get(pk=deposit_id) | |||||
except Deposit.DoesNotExist: | |||||
raise DepositError( | |||||
NOT_FOUND, f"Deposit with id {deposit_id} does not exist" | |||||
) | |||||
assert deposit is not None | assert deposit is not None | ||||
self.restrict_access(request, headers, deposit) | self.restrict_access(request, headers, deposit) | ||||
if headers.on_behalf_of: | if headers.on_behalf_of: | ||||
raise DepositError(MEDIATION_NOT_ALLOWED, "Mediation is not supported.") | raise DepositError(MEDIATION_NOT_ALLOWED, "Mediation is not supported.") | ||||
self.additional_checks(request, headers, collection_name, deposit_id) | self.additional_checks(request, headers, collection_name, deposit_id) | ||||
▲ Show 20 Lines • Show All 239 Lines • Show Last 20 Lines |