Changeset View
Changeset View
Standalone View
Standalone View
swh/deposit/api/common.py
Show First 20 Lines • Show All 107 Lines • ▼ Show 20 Lines | def _read_headers(self, request: Request) -> Dict[str, Any]: | ||||
content_md5sum = meta.get("HTTP_CONTENT_MD5") | content_md5sum = meta.get("HTTP_CONTENT_MD5") | ||||
if content_md5sum: | if content_md5sum: | ||||
content_md5sum = bytes.fromhex(content_md5sum) | content_md5sum = bytes.fromhex(content_md5sum) | ||||
packaging = meta.get("HTTP_PACKAGING") | packaging = meta.get("HTTP_PACKAGING") | ||||
slug = meta.get("HTTP_SLUG") | slug = meta.get("HTTP_SLUG") | ||||
on_behalf_of = meta.get("HTTP_ON_BEHALF_OF") | on_behalf_of = meta.get("HTTP_ON_BEHALF_OF") | ||||
metadata_relevant = meta.get("HTTP_METADATA_RELEVANT") | metadata_relevant = meta.get("HTTP_METADATA_RELEVANT") | ||||
vlorentz: Why is it not `HTTP_X_CHECK_SWHID`? | |||||
Done Inline Actionssure, i just aligned with the document attached in the description ¯\_(ツ)_/¯ I even iterated over it already as i had initially issues with tests for some ardumont: sure, i just aligned with the document attached in the description ¯\_(ツ)_/¯
I even iterated… | |||||
Done Inline Actionsthe document is about the HTTP interface, that doesn't mean it's the same exposed by Django vlorentz: the document is about the HTTP interface, that doesn't mean it's the same exposed by Django | |||||
swhid = meta.get("HTTP_X_CHECK_SWHID") | |||||
return { | return { | ||||
"content-type": content_type, | "content-type": content_type, | ||||
"content-length": content_length, | "content-length": content_length, | ||||
"in-progress": in_progress, | "in-progress": in_progress, | ||||
"content-disposition": content_disposition, | "content-disposition": content_disposition, | ||||
"content-md5sum": content_md5sum, | "content-md5sum": content_md5sum, | ||||
"packaging": packaging, | "packaging": packaging, | ||||
"slug": slug, | "slug": slug, | ||||
"on-behalf-of": on_behalf_of, | "on-behalf-of": on_behalf_of, | ||||
"metadata-relevant": metadata_relevant, | "metadata-relevant": metadata_relevant, | ||||
"swhid": swhid, | |||||
} | } | ||||
def _compute_md5(self, filehandler) -> bytes: | def _compute_md5(self, filehandler) -> bytes: | ||||
"""Compute uploaded file's md5 sum. | """Compute uploaded file's md5 sum. | ||||
Args: | Args: | ||||
filehandler (InMemoryUploadedFile): the file to compute the md5 | filehandler (InMemoryUploadedFile): the file to compute the md5 | ||||
hash | hash | ||||
▲ Show 20 Lines • Show All 82 Lines • ▼ Show 20 Lines | ) -> Deposit: | ||||
return deposit | return deposit | ||||
def _deposit_request_put( | def _deposit_request_put( | ||||
self, | self, | ||||
deposit: Deposit, | deposit: Deposit, | ||||
deposit_request_data: Dict[str, Any], | deposit_request_data: Dict[str, Any], | ||||
replace_metadata: bool = False, | replace_metadata: bool = False, | ||||
replace_archives: bool = False, | replace_archives: bool = False, | ||||
) -> None: | ) -> DepositRequest: | ||||
"""Save a deposit request with metadata attached to a deposit. | """Save a deposit request with metadata attached to a deposit. | ||||
Args: | Args: | ||||
deposit: The deposit concerned by the request | deposit: The deposit concerned by the request | ||||
deposit_request_data: The dictionary with at most 2 deposit | deposit_request_data: The dictionary with at most 2 deposit | ||||
request types (archive, metadata) to associate to the deposit | request types (archive, metadata) to associate to the deposit | ||||
replace_metadata: Flag defining if we add or update | replace_metadata: Flag defining if we add or update | ||||
existing metadata to the deposit | existing metadata to the deposit | ||||
replace_archives: Flag defining if we add or update | replace_archives: Flag defining if we add or update | ||||
archives to existing deposit | archives to existing deposit | ||||
Returns: | Returns: | ||||
None | the DepositRequest object stored in the backend | ||||
""" | """ | ||||
if replace_metadata: | if replace_metadata: | ||||
DepositRequest.objects.filter(deposit=deposit, type=METADATA_TYPE).delete() | DepositRequest.objects.filter(deposit=deposit, type=METADATA_TYPE).delete() | ||||
if replace_archives: | if replace_archives: | ||||
DepositRequest.objects.filter(deposit=deposit, type=ARCHIVE_TYPE).delete() | DepositRequest.objects.filter(deposit=deposit, type=ARCHIVE_TYPE).delete() | ||||
Show All 13 Lines | ) -> DepositRequest: | ||||
type=METADATA_TYPE, | type=METADATA_TYPE, | ||||
deposit=deposit, | deposit=deposit, | ||||
metadata=metadata, | metadata=metadata, | ||||
raw_metadata=raw_metadata.decode("utf-8"), | raw_metadata=raw_metadata.decode("utf-8"), | ||||
) | ) | ||||
deposit_request.save() | deposit_request.save() | ||||
assert deposit_request is not None | assert deposit_request is not None | ||||
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: | try: | ||||
deposit = Deposit.objects.get(pk=deposit_id) | deposit = Deposit.objects.get(pk=deposit_id) | ||||
except Deposit.DoesNotExist: | except Deposit.DoesNotExist: | ||||
▲ Show 20 Lines • Show All 329 Lines • ▼ Show 20 Lines | def _atom_entry( | ||||
collection_name: str, | collection_name: str, | ||||
deposit_id: Optional[int] = None, | deposit_id: Optional[int] = None, | ||||
replace_metadata: bool = False, | replace_metadata: bool = False, | ||||
replace_archives: bool = False, | replace_archives: bool = False, | ||||
) -> Dict[str, Any]: | ) -> Dict[str, Any]: | ||||
"""Atom entry deposit. | """Atom entry deposit. | ||||
Args: | Args: | ||||
request (Request): the request holding information to parse | request: the request holding information to parse | ||||
and inject in db | and inject in db | ||||
headers: request headers formatted | headers: request headers formatted | ||||
collection_name: the associated client | collection_name: the associated client | ||||
deposit_id: deposit identifier if provided | deposit_id: deposit identifier if provided | ||||
replace_metadata: 'Update or add' request to existing | replace_metadata: 'Update or add' request to existing | ||||
deposit. If False (default), this adds new metadata request to | deposit. If False (default), this adds new metadata request to | ||||
existing ones. Otherwise, this will replace existing metadata. | existing ones. Otherwise, this will replace existing metadata. | ||||
replace_archives: 'Update or add' request to existing | replace_archives: 'Update or add' request to existing | ||||
▲ Show 20 Lines • Show All 150 Lines • ▼ Show 20 Lines | ) -> Dict[str, Any]: | ||||
collections = self._client.collections | collections = self._client.collections | ||||
assert collections is not None | assert collections is not None | ||||
if collection_id not in collections: | if collection_id not in collections: | ||||
return make_error_dict( | return make_error_dict( | ||||
FORBIDDEN, | FORBIDDEN, | ||||
f"Client {username} cannot access collection {collection_name}", | f"Client {username} cannot access collection {collection_name}", | ||||
) | ) | ||||
headers = self._read_headers(request) | |||||
if deposit_id: | if deposit_id: | ||||
try: | try: | ||||
deposit = Deposit.objects.get(pk=deposit_id) | deposit = Deposit.objects.get(pk=deposit_id) | ||||
except Deposit.DoesNotExist: | except Deposit.DoesNotExist: | ||||
return make_error_dict( | return make_error_dict( | ||||
NOT_FOUND, f"Deposit with id {deposit_id} does not exist" | NOT_FOUND, f"Deposit with id {deposit_id} does not exist" | ||||
) | ) | ||||
checks = self.restrict_access(request, deposit) | assert deposit is not None | ||||
checks = self.restrict_access(request, headers, deposit) | |||||
if checks: | if checks: | ||||
return checks | return checks | ||||
headers = self._read_headers(request) | |||||
if headers["on-behalf-of"]: | if headers["on-behalf-of"]: | ||||
return make_error_dict(MEDIATION_NOT_ALLOWED, "Mediation is not supported.") | return make_error_dict(MEDIATION_NOT_ALLOWED, "Mediation is not supported.") | ||||
checks = self.additional_checks(request, headers, collection_name, deposit_id) | checks = self.additional_checks(request, headers, collection_name, deposit_id) | ||||
if "error" in checks: | if "error" in checks: | ||||
return checks | return checks | ||||
return {"headers": headers} | return {"headers": headers} | ||||
def restrict_access( | def restrict_access( | ||||
self, request: Request, deposit: Optional[Deposit] = None | self, request: Request, headers: Dict, deposit: Deposit | ||||
) -> Dict[str, Any]: | ) -> Dict[str, Any]: | ||||
if deposit: | """Allow modifications on deposit with status 'partial' only, reject the rest. | ||||
""" | |||||
if request.method != "GET" and deposit.status != DEPOSIT_STATUS_PARTIAL: | if request.method != "GET" and deposit.status != DEPOSIT_STATUS_PARTIAL: | ||||
summary = "You can only act on deposit with status '%s'" % ( | summary = "You can only act on deposit with status '%s'" % ( | ||||
DEPOSIT_STATUS_PARTIAL, | DEPOSIT_STATUS_PARTIAL, | ||||
) | ) | ||||
description = f"This deposit has status '{deposit.status}'" | description = f"This deposit has status '{deposit.status}'" | ||||
return make_error_dict( | return make_error_dict( | ||||
BAD_REQUEST, summary=summary, verbose_description=description | BAD_REQUEST, summary=summary, verbose_description=description | ||||
) | ) | ||||
Done Inline Actionss/Add // vlorentz: s/Add // | |||||
Done Inline ActionsI did not grasp what you meant... ardumont: I did not grasp what you meant... | |||||
Done Inline ActionsThe function doesn't add anything to anything, it does the checks vlorentz: The function doesn't add anything to anything, it **does** the checks | |||||
Done Inline Actionsah yeah ok. ardumont: ah yeah ok.
I thought this sentence was not good anyway, so i already rework that sentence to… | |||||
return {} | return {} | ||||
def _basic_not_allowed_method(self, request: Request, method: str): | def _basic_not_allowed_method(self, request: Request, method: str): | ||||
return make_error_response( | return make_error_response( | ||||
request, | request, | ||||
METHOD_NOT_ALLOWED, | METHOD_NOT_ALLOWED, | ||||
f"{method} method is not supported on this endpoint", | f"{method} method is not supported on this endpoint", | ||||
) | ) | ||||
▲ Show 20 Lines • Show All 212 Lines • Show Last 20 Lines |
Why is it not HTTP_X_CHECK_SWHID?