Skip to content
This repository has been archived by the owner on Jan 7, 2024. It is now read-only.

expose ETag in submission/reply downloads #96

Merged
merged 1 commit into from
Jun 20, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 12 additions & 16 deletions sdclientapi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -553,13 +553,14 @@ def download_submission(
self, submission: Submission, path: str = "", timeout: Optional[int] = None
) -> Tuple[str, str]:
"""
Returns a tuple of sha256sum and file path for a given Submission object. This method
also requires a directory path in where it will save the submission file.
Returns a tuple of etag (format is algorithm:checksum) and file path for
a given Submission object. This method also requires a directory path
in where it will save the submission file.

:param submission: Submission object
:param path: Local directory path to save the submission

:returns: Tuple of sha256sum and path of the saved submission.
:returns: Tuple of etag and path of the saved submission.
"""
path_query = "api/v1/sources/{}/submissions/{}/download".format(
submission.source_uuid, submission.uuid
Expand Down Expand Up @@ -597,11 +598,8 @@ def download_submission(
filepath = os.path.join(
"/home/user/QubesIncoming/", self.proxy_vm_name, data["filename"]
)
# Return the tuple of sha256sum, filepath
# Returning empty string instead of sha256sum due to this
# SecureDrop server bug:
# https://github.com/freedomofpress/securedrop/issues/3877
return "", filepath

return headers['Etag'].strip('\"'), filepath

def flag_source(self, source: Source) -> bool:
"""
Expand Down Expand Up @@ -802,13 +800,14 @@ def get_all_replies(self) -> List[Reply]:

def download_reply(self, reply: Reply, path: str = "") -> Tuple[str, str]:
"""
Returns a tuple of sha256sum and file path for a given Reply object. This method
also requires a directory path in where it will save the reply file.
Returns a tuple of etag (format is algorithm:checksum) and file path for
a given Reply object. This method also requires a directory path
in where it will save the reply file.

:param reply: Reply object
:param path: Local directory path to save the reply

:returns: Tuple of sha256sum and path of the saved Reply.
:returns: Tuple of etag and path of the saved Reply.
"""
path_query = "api/v1/sources/{}/replies/{}/download".format(
reply.source_uuid, reply.uuid
Expand Down Expand Up @@ -847,11 +846,8 @@ def download_reply(self, reply: Reply, path: str = "") -> Tuple[str, str]:
filepath = os.path.join(
"/home/user/QubesIncoming/", self.proxy_vm_name, data["filename"]
)
# Return the tuple of sha256sum, filepath
# Returning empty string instead of sha256sum due to this
# SecureDrop server bug:
# https://github.com/freedomofpress/securedrop/issues/3877
return "", filepath

return headers['Etag'].strip('\"'), filepath

def delete_reply(self, reply: Reply) -> bool:
"""
Expand Down
22 changes: 17 additions & 5 deletions tests/test_api.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import datetime
import hashlib
import os
import pytest
import shutil
Expand Down Expand Up @@ -259,14 +260,19 @@ def test_download_submission(self):

# We need a temporary directory to download
tmpdir = tempfile.mkdtemp()
_, filepath = self.api.download_submission(s, tmpdir)
etag, filepath = self.api.download_submission(s, tmpdir)

# now let us read the downloaded file
with open(filepath, "rb") as fobj:
fobj.read()
content = fobj.read()

# Now the submission should have is_read as True.
# Verify the ETag contains the algorithm and the hash is correct
hasher = hashlib.sha256()
hasher.update(content)

assert etag == "sha256:{}".format(hasher.hexdigest())

# Now the submission should have is_read as True.
s = self.api.get_submission(s)
self.assertTrue(s.is_read)

Expand Down Expand Up @@ -304,11 +310,17 @@ def test_download_reply(self):

# We need a temporary directory to download
tmpdir = tempfile.mkdtemp()
_, filepath = self.api.download_reply(r, tmpdir)
etag, filepath = self.api.download_reply(r, tmpdir)

# now let us read the downloaded file
with open(filepath, "rb") as fobj:
fobj.read()
content = fobj.read()

# Verify the ETag contains the algorithm and the hash is correct
hasher = hashlib.sha256()
hasher.update(content)

assert etag == "sha256:{}".format(hasher.hexdigest())

# Let us remove the temporary directory
shutil.rmtree(tmpdir)
Expand Down