Skip to content

Commit

Permalink
testing etags on downloaded files
Browse files Browse the repository at this point in the history
  • Loading branch information
heartsucker committed May 22, 2019
1 parent e6a379c commit 41faea7
Showing 1 changed file with 163 additions and 1 deletion.
164 changes: 163 additions & 1 deletion tests/test_queue.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
'''
Testing for the ApiJobQueue and related classes.
'''
import os
import pytest
import sdclientapi

from . import factory
from queue import Queue
from sdclientapi import AuthError, RequestTimeoutError
from typing import Tuple

from securedrop_client.queue import ApiInaccessibleError, ApiJob, RunnableQueue
from securedrop_client import db
from securedrop_client.crypto import GpgHelper
from securedrop_client.queue import ApiInaccessibleError, ApiJob, RunnableQueue, \
DownloadSubmissionJob


def test_ApiInaccessibleError_init():
Expand Down Expand Up @@ -202,3 +209,158 @@ def test_RunnableQueue_job_timeout(mocker):

# ensure we don't have stale mocks
assert mock_process_events.called


def test_DownloadSubmissionJob_happy_path_no_etag(mocker, homedir, session, session_maker):
source = factory.Source()
file_ = factory.File(source=source)
session.add(source)
session.add(file_)
session.commit()

gpg = GpgHelper(homedir, session_maker, is_qubes=False)

def fake_download(sdk_obj: sdclientapi.Submission) -> Tuple[str, str]:
'''
:return: (etag, path_to_dl)
'''
full_path = os.path.join(homedir, 'somepath')
with open(full_path, 'wb') as f:
f.write(b'')
return ('', full_path)

api_client = mocker.MagicMock()
api_client.download_submission = fake_download

job = DownloadSubmissionJob(
db.File,
file_.uuid,
homedir,
gpg,
)

mock_decrypt = mocker.patch.object(job, '_decrypt_file')
mock_logger = mocker.patch('securedrop_client.queue.logger')

job.call_api(api_client, session)

log_msg = mock_logger.debug.call_args_list[0][0][0]
assert log_msg.startswith('No ETag. Skipping integrity check')

# ensure mocks aren't stale
assert mock_decrypt.called


def test_DownloadSubmissionJob_happy_path_sha256_etag(mocker, homedir, session, session_maker):
source = factory.Source()
file_ = factory.File(source=source)
session.add(source)
session.add(file_)
session.commit()

gpg = GpgHelper(homedir, session_maker, is_qubes=False)

def fake_download(sdk_obj: sdclientapi.Submission) -> Tuple[str, str]:
'''
:return: (etag, path_to_dl)
'''
full_path = os.path.join(homedir, 'somepath')
with open(full_path, 'wb') as f:
f.write(b'wat')

# sha256 of b'wat'
return ('sha256:f00a787f7492a95e165b470702f4fe9373583fbdc025b2c8bdf0262cc48fcff4',
full_path)

api_client = mocker.MagicMock()
api_client.download_submission = fake_download

job = DownloadSubmissionJob(
db.File,
file_.uuid,
homedir,
gpg,
)

mock_decrypt = mocker.patch.object(job, '_decrypt_file')

job.call_api(api_client, session)

# ensure mocks aren't stale
assert mock_decrypt.called


def test_DownloadSubmissionJob_bad_sha256_etag(mocker, homedir, session, session_maker):
source = factory.Source()
file_ = factory.File(source=source)
session.add(source)
session.add(file_)
session.commit()

gpg = GpgHelper(homedir, session_maker, is_qubes=False)

def fake_download(sdk_obj: sdclientapi.Submission) -> Tuple[str, str]:
'''
:return: (etag, path_to_dl)
'''
full_path = os.path.join(homedir, 'somepath')
with open(full_path, 'wb') as f:
f.write(b'')

return ('sha256:not-a-sha-sum',
full_path)

api_client = mocker.MagicMock()
api_client.download_submission = fake_download

job = DownloadSubmissionJob(
db.File,
file_.uuid,
homedir,
gpg,
)

# we currently don't handle errors in the checksum
with pytest.raises(RuntimeError):
job.call_api(api_client, session)


def test_DownloadSubmissionJob_happy_path_unknown_etag(mocker, homedir, session, session_maker):
source = factory.Source()
file_ = factory.File(source=source)
session.add(source)
session.add(file_)
session.commit()

gpg = GpgHelper(homedir, session_maker, is_qubes=False)

def fake_download(sdk_obj: sdclientapi.Submission) -> Tuple[str, str]:
'''
:return: (etag, path_to_dl)
'''
full_path = os.path.join(homedir, 'somepath')
with open(full_path, 'wb') as f:
f.write(b'')
return ('UNKNOWN:abc123',
full_path)

api_client = mocker.MagicMock()
api_client.download_submission = fake_download

job = DownloadSubmissionJob(
db.File,
file_.uuid,
homedir,
gpg,
)

mock_decrypt = mocker.patch.object(job, '_decrypt_file')
mock_logger = mocker.patch('securedrop_client.queue.logger')

job.call_api(api_client, session)

log_msg = mock_logger.debug.call_args_list[0][0][0]
assert log_msg.startswith('Unknown hash algorithm')

# ensure mocks aren't stale
assert mock_decrypt.called

0 comments on commit 41faea7

Please sign in to comment.