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 @@ -104,6 +104,25 @@ 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): """Mixin intended as a based API view to enforce the basic authentication check @@ -217,7 +236,7 @@ parent=deposit_parent, ) else: - deposit = Deposit.objects.get(pk=deposit_id) + deposit = get_deposit_by_id(deposit_id) # update metadata deposit.complete_date = complete_date @@ -295,10 +314,7 @@ """Delete archive references from the deposit id. """ - try: - deposit = Deposit.objects.get(pk=deposit_id) - except Deposit.DoesNotExist: - raise DepositError(NOT_FOUND, f"The deposit {deposit_id} does not exist") + deposit = get_deposit_by_id(deposit_id) DepositRequest.objects.filter(deposit=deposit, type=ARCHIVE_TYPE).delete() return {} @@ -315,10 +331,7 @@ Dict with error key to describe the failure. """ - try: - deposit = Deposit.objects.get(pk=deposit_id) - except Deposit.DoesNotExist: - raise DepositError(NOT_FOUND, f"The deposit {deposit_id} does not exist") + deposit = get_deposit_by_id(deposit_id) if deposit.collection.name != collection_name: summary = "Cannot delete a deposit from another collection" @@ -821,7 +834,7 @@ collection_name: the associated client deposit_id: deposit identifier """ - deposit = Deposit.objects.get(pk=deposit_id) + deposit = get_deposit_by_id(deposit_id) deposit.complete_date = timezone.now() deposit.status = DEPOSIT_STATUS_DEPOSITED deposit.save() @@ -878,12 +891,7 @@ headers = self._read_headers(request) if deposit_id: - try: - deposit = Deposit.objects.get(pk=deposit_id) - except Deposit.DoesNotExist: - raise DepositError( - NOT_FOUND, f"Deposit with id {deposit_id} does not exist" - ) + deposit = get_deposit_by_id(deposit_id) assert deposit is not None self.restrict_access(request, headers, deposit) diff --git a/swh/deposit/api/content.py b/swh/deposit/api/content.py --- a/swh/deposit/api/content.py +++ b/swh/deposit/api/content.py @@ -7,9 +7,8 @@ from django.shortcuts import render from rest_framework import status -from ..errors import NOT_FOUND, make_error_response -from ..models import DEPOSIT_STATUS_DETAIL, Deposit, DepositRequest -from .common import APIBase +from ..models import DEPOSIT_STATUS_DETAIL, DepositRequest +from .common import APIBase, get_deposit_by_id class ContentAPI(APIBase): @@ -24,17 +23,7 @@ def get(self, req, collection_name: str, deposit_id: int) -> HttpResponse: self.checks(req, collection_name, deposit_id) - try: - deposit = Deposit.objects.get(pk=deposit_id) - if deposit.collection.name != collection_name: - raise Deposit.DoesNotExist - except Deposit.DoesNotExist: - return make_error_response( - req, - NOT_FOUND, - "deposit %s does not belong to collection %s" - % (deposit_id, collection_name), - ) + deposit = get_deposit_by_id(deposit_id, collection_name) requests = DepositRequest.objects.filter(deposit=deposit) context = { diff --git a/swh/deposit/api/edit.py b/swh/deposit/api/edit.py --- a/swh/deposit/api/edit.py +++ b/swh/deposit/api/edit.py @@ -11,7 +11,7 @@ from ..config import DEPOSIT_STATUS_LOAD_SUCCESS from ..errors import BAD_REQUEST, DepositError, ParserError from ..parsers import SWHAtomEntryParser, SWHMultiPartParser -from .common import APIDelete, APIPut, ParsedRequestHeaders +from .common import APIDelete, APIPut, ParsedRequestHeaders, get_deposit_by_id class EditAPI(APIPut, APIDelete): @@ -97,7 +97,7 @@ # Write to the metadata storage (and the deposit backend) # no ingestion triggered - deposit = Deposit.objects.get(pk=deposit_id) + deposit = get_deposit_by_id(deposit_id, collection_name) assert deposit.status == DEPOSIT_STATUS_LOAD_SUCCESS if swhid != deposit.swhid: diff --git a/swh/deposit/api/private/__init__.py b/swh/deposit/api/private/__init__.py --- a/swh/deposit/api/private/__init__.py +++ b/swh/deposit/api/private/__init__.py @@ -9,10 +9,10 @@ from swh.deposit import utils from swh.deposit.api.common import AuthenticatedAPIView -from swh.deposit.errors import NOT_FOUND, DepositError from ...config import METADATA_TYPE, APIConfig from ...models import Deposit, DepositRequest +from ..common import get_deposit_by_id class DepositReadMixin: @@ -32,7 +32,7 @@ """ if isinstance(deposit, int): - deposit = Deposit.objects.get(pk=deposit) + deposit = get_deposit_by_id(deposit) deposit_requests = DepositRequest.objects.filter( type=request_type, deposit=deposit @@ -78,12 +78,7 @@ """ if deposit_id: - try: - Deposit.objects.get(pk=deposit_id) - except Deposit.DoesNotExist: - raise DepositError( - NOT_FOUND, "Deposit with id %s does not exist" % deposit_id - ) + get_deposit_by_id(deposit_id) headers = self._read_headers(req) self.additional_checks(req, headers, collection_name, deposit_id) diff --git a/swh/deposit/api/private/deposit_check.py b/swh/deposit/api/private/deposit_check.py --- a/swh/deposit/api/private/deposit_check.py +++ b/swh/deposit/api/private/deposit_check.py @@ -19,7 +19,7 @@ from ...config import ARCHIVE_TYPE, DEPOSIT_STATUS_REJECTED, DEPOSIT_STATUS_VERIFIED from ...models import Deposit, DepositRequest from ..checks import check_metadata -from ..common import APIGet +from ..common import APIGet, get_deposit_by_id MANDATORY_ARCHIVE_UNREADABLE = ( "At least one of its associated archives is not readable" # noqa @@ -145,7 +145,7 @@ Tuple status, stream of content, content-type """ - deposit = Deposit.objects.get(pk=deposit_id) + deposit = get_deposit_by_id(deposit_id) metadata, _ = self._metadata_get(deposit) problems: Dict = {} # will check each deposit's associated request (both of type diff --git a/swh/deposit/api/private/deposit_read.py b/swh/deposit/api/private/deposit_read.py --- a/swh/deposit/api/private/deposit_read.py +++ b/swh/deposit/api/private/deposit_read.py @@ -19,7 +19,7 @@ from . import APIPrivateView, DepositReadMixin from ...config import ARCHIVE_TYPE, SWH_PERSON from ...models import Deposit -from ..common import APIGet +from ..common import APIGet, get_deposit_by_id @contextmanager @@ -195,6 +195,6 @@ def process_get( self, request, collection_name: str, deposit_id: int ) -> Tuple[int, Dict, str]: - deposit = Deposit.objects.get(pk=deposit_id) + deposit = get_deposit_by_id(deposit_id) data = self.metadata_read(deposit) return status.HTTP_200_OK, data if data else {}, "application/json" diff --git a/swh/deposit/api/private/deposit_update_status.py b/swh/deposit/api/private/deposit_update_status.py --- a/swh/deposit/api/private/deposit_update_status.py +++ b/swh/deposit/api/private/deposit_update_status.py @@ -9,8 +9,8 @@ from . import APIPrivateView from ...errors import BAD_REQUEST, DepositError -from ...models import DEPOSIT_STATUS_DETAIL, DEPOSIT_STATUS_LOAD_SUCCESS, Deposit -from ..common import APIPut, ParsedRequestHeaders +from ...models import DEPOSIT_STATUS_DETAIL, DEPOSIT_STATUS_LOAD_SUCCESS +from ..common import APIPut, ParsedRequestHeaders, get_deposit_by_id MANDATORY_KEYS = ["origin_url", "revision_id", "directory_id", "snapshot_id"] @@ -79,7 +79,7 @@ """ data = request.data - deposit = Deposit.objects.get(pk=deposit_id) + deposit = get_deposit_by_id(deposit_id) status = data["status"] deposit.status = status diff --git a/swh/deposit/api/state.py b/swh/deposit/api/state.py --- a/swh/deposit/api/state.py +++ b/swh/deposit/api/state.py @@ -7,9 +7,8 @@ from django.shortcuts import render from rest_framework import status -from ..errors import NOT_FOUND, make_error_response -from ..models import DEPOSIT_STATUS_DETAIL, Deposit -from .common import APIBase +from ..models import DEPOSIT_STATUS_DETAIL +from .common import APIBase, get_deposit_by_id from .converters import convert_status_detail @@ -25,17 +24,7 @@ def get(self, req, collection_name: str, deposit_id: int) -> HttpResponse: self.checks(req, collection_name, deposit_id) - try: - deposit = Deposit.objects.get(pk=deposit_id) - if deposit.collection.name != collection_name: - raise Deposit.DoesNotExist - except Deposit.DoesNotExist: - return make_error_response( - req, - NOT_FOUND, - "deposit %s does not belong to collection %s" - % (deposit_id, collection_name), - ) + deposit = get_deposit_by_id(deposit_id, collection_name) status_detail = convert_status_detail(deposit.status_detail) if not status_detail: diff --git a/swh/deposit/tests/api/test_deposit_private_read_metadata.py b/swh/deposit/tests/api/test_deposit_private_read_metadata.py --- a/swh/deposit/tests/api/test_deposit_private_read_metadata.py +++ b/swh/deposit/tests/api/test_deposit_private_read_metadata.py @@ -394,5 +394,5 @@ for url in private_get_raw_url_endpoints(deposit_collection, unknown_id): response = authenticated_client.get(url) assert response.status_code == status.HTTP_404_NOT_FOUND - msg = "Deposit with id %s does not exist" % unknown_id + msg = "Deposit %s does not exist" % unknown_id assert msg in response.content.decode("utf-8") diff --git a/swh/deposit/tests/api/test_deposit_update.py b/swh/deposit/tests/api/test_deposit_update.py --- a/swh/deposit/tests/api/test_deposit_update.py +++ b/swh/deposit/tests/api/test_deposit_update.py @@ -409,7 +409,7 @@ assert response.status_code == status.HTTP_404_NOT_FOUND response_content = parse_xml(response.content) assert ( - "Deposit with id %s does not exist" % unknown_deposit_id + "Deposit %s does not exist" % unknown_deposit_id == response_content["sword:error"]["summary"] ) @@ -433,7 +433,7 @@ assert response.status_code == status.HTTP_404_NOT_FOUND response_content = parse_xml(response.content) assert ( - "Deposit with id %s does not exist" % unknown_deposit_id + "Deposit %s does not exist" % unknown_deposit_id == response_content["sword:error"]["summary"] ) @@ -457,7 +457,7 @@ assert response.status_code == status.HTTP_404_NOT_FOUND response_content = parse_xml(response.content) assert ( - "Deposit with id %s does not exist" % unknown_deposit_id + "Deposit %s does not exist" % unknown_deposit_id == response_content["sword:error"]["summary"] )