コード例 #1
0
def test__export_archive_does_not_raise_ExportError_when_CalledProcessError(
        mocker):
    '''
    Ensure ExportError is raised if a CalledProcessError is encountered.
    '''
    mock_error = subprocess.CalledProcessError('mock_cmd', 123)
    mocker.patch('subprocess.check_output', side_effect=mock_error)

    export = Export()

    with pytest.raises(ExportError, match='CALLED_PROCESS_ERROR'):
        export._export_archive('mock.sd-export')
コード例 #2
0
def test__create_archive(mocker):
    '''
    Ensure _create_archive creates an archive in the supplied directory.
    '''
    export = Export()
    archive_path = None
    with TemporaryDirectory() as temp_dir:
        archive_path = export._create_archive(temp_dir, 'mock.sd-export', {})
        assert archive_path == os.path.join(temp_dir, 'mock.sd-export')
        assert os.path.exists(archive_path)  # sanity check

    assert not os.path.exists(archive_path)
コード例 #3
0
ファイル: test_export.py プロジェクト: rmol/securedrop-client
def test__export_archive_with_evil_command(mocker):
    """
    Ensure shell command is shell-escaped.
    """
    export = Export()
    check_output = mocker.patch("subprocess.check_output", return_value=b"")

    export._export_archive("somefile; rm -rf ~")

    check_output.assert_called_once_with([
        "qvm-open-in-vm", "sd-devices", "'somefile; rm -rf ~'", "--view-only"
    ],
                                         stderr=-2)
コード例 #4
0
def test__export_archive_with_evil_command(mocker):
    '''
    Ensure shell command is shell-escaped.
    '''
    export = Export()
    check_output = mocker.patch('subprocess.check_output', return_value=b'')

    export._export_archive('somefile; rm -rf ~')

    check_output.assert_called_once_with([
        'qvm-open-in-vm', 'sd-devices', "'somefile; rm -rf ~'", '--view-only'
    ],
                                         stderr=-2)
コード例 #5
0
ファイル: test_export.py プロジェクト: rmol/securedrop-client
def test__create_archive_with_multiple_export_files(mocker):
    """
    Ensure an archive
    """
    export = Export()
    archive_path = None
    with TemporaryDirectory() as temp_dir, NamedTemporaryFile(
    ) as export_file_one, NamedTemporaryFile() as export_file_two:  # noqa
        archive_path = export._create_archive(
            temp_dir, "mock.sd-export", {},
            [export_file_one.name, export_file_two.name])
        assert archive_path == os.path.join(temp_dir, "mock.sd-export")
        assert os.path.exists(archive_path)  # sanity check

    assert not os.path.exists(archive_path)
コード例 #6
0
def test__run_print(mocker):
    '''
    Ensure _export_archive and _create_archive are called with the expected parameters and
    _export_archive is called with the return value of _create_archive.
    '''
    export = Export()
    export._create_archive = mocker.MagicMock(return_value='mock_archive_path')
    export._export_archive = mocker.MagicMock(return_value='')

    export._run_print('mock_archive_dir', ['mock_filepath'])

    export._export_archive.assert_called_once_with('mock_archive_path')
    export._create_archive.assert_called_once_with('mock_archive_dir',
                                                   'print_archive.sd-export', {
                                                       'device': 'printer',
                                                   }, ['mock_filepath'])
コード例 #7
0
def test__run_printer_preflight(mocker):
    '''
    Ensure _export_archive and _create_archive are called with the expected parameters,
    _export_archive is called with the return value of _create_archive, and
    _run_disk_test returns without error if 'USB_CONNECTED' is the return value of _export_archive.
    '''
    export = Export()
    export._create_archive = mocker.MagicMock(return_value='mock_archive_path')
    export._export_archive = mocker.MagicMock(return_value='')

    export._run_printer_preflight('mock_archive_dir')

    export._export_archive.assert_called_once_with('mock_archive_path')
    export._create_archive.assert_called_once_with(
        'mock_archive_dir', 'printer-preflight.sd-export',
        {'device': 'printer-preflight'})
コード例 #8
0
ファイル: test_export.py プロジェクト: rmol/securedrop-client
def test__run_printer_preflight(mocker):
    """
    Ensure _export_archive and _create_archive are called with the expected parameters,
    _export_archive is called with the return value of _create_archive, and
    _run_disk_test returns without error if 'USB_CONNECTED' is the return value of _export_archive.
    """
    export = Export()
    export._create_archive = mocker.MagicMock(return_value="mock_archive_path")
    export._export_archive = mocker.MagicMock(return_value="")

    export._run_printer_preflight("mock_archive_dir")

    export._export_archive.assert_called_once_with("mock_archive_path")
    export._create_archive.assert_called_once_with(
        "mock_archive_dir", "printer-preflight.sd-export",
        {"device": "printer-preflight"})
コード例 #9
0
ファイル: test_export.py プロジェクト: rmol/securedrop-client
def test__run_print(mocker):
    """
    Ensure _export_archive and _create_archive are called with the expected parameters and
    _export_archive is called with the return value of _create_archive.
    """
    export = Export()
    export._create_archive = mocker.MagicMock(return_value="mock_archive_path")
    export._export_archive = mocker.MagicMock(return_value="")

    export._run_print("mock_archive_dir", ["mock_filepath"])

    export._export_archive.assert_called_once_with("mock_archive_path")
    export._create_archive.assert_called_once_with("mock_archive_dir",
                                                   "print_archive.sd-export",
                                                   {"device": "printer"},
                                                   ["mock_filepath"])
コード例 #10
0
ファイル: test_export.py プロジェクト: rmol/securedrop-client
def test__run_disk_test(mocker):
    """
    Ensure _export_archive and _create_archive are called with the expected parameters,
    _export_archive is called with the return value of _create_archive, and
    _run_disk_test returns without error if 'USB_ENCRYPTED' is the ouput status of _export_archive.
    """
    export = Export()
    export._create_archive = mocker.MagicMock(return_value="mock_archive_path")
    export._export_archive = mocker.MagicMock(return_value="USB_ENCRYPTED")

    export._run_disk_test("mock_archive_dir")

    export._export_archive.assert_called_once_with("mock_archive_path")
    export._create_archive.assert_called_once_with("mock_archive_dir",
                                                   "disk-test.sd-export",
                                                   {"device": "disk-test"})
コード例 #11
0
def test__run_disk_test(mocker):
    '''
    Ensure _export_archive and _create_archive are called with the expected parameters,
    _export_archive is called with the return value of _create_archive, and
    _run_disk_test returns without error if 'USB_ENCRYPTED' is the ouput status of _export_archive.
    '''
    export = Export()
    export._create_archive = mocker.MagicMock(return_value='mock_archive_path')
    export._export_archive = mocker.MagicMock(return_value='USB_ENCRYPTED')

    export._run_disk_test('mock_archive_dir')

    export._export_archive.assert_called_once_with('mock_archive_path')
    export._create_archive.assert_called_once_with('mock_archive_dir',
                                                   'disk-test.sd-export',
                                                   {'device': 'disk-test'})
コード例 #12
0
def test_run_preflight_checks(mocker):
    '''
    Ensure TemporaryDirectory is used when creating and sending the archives during the preflight
    checks.
    '''
    mock_temp_dir = mocker.MagicMock()
    mock_temp_dir.__enter__ = mocker.MagicMock(return_value='mock_temp_dir')
    mocker.patch('securedrop_client.export.TemporaryDirectory',
                 return_value=mock_temp_dir)
    export = Export()
    _run_usb_export = mocker.patch.object(export, '_run_usb_test')
    _run_disk_export = mocker.patch.object(export, '_run_disk_test')

    export.run_preflight_checks()

    _run_usb_export.assert_called_once_with('mock_temp_dir')
    _run_disk_export.assert_called_once_with('mock_temp_dir')
コード例 #13
0
def test_send_file_to_usb_device(mocker):
    '''
    Ensure TemporaryDirectory is used when creating and sending the archive containing the export
    file.
    '''
    mock_temp_dir = mocker.MagicMock()
    mock_temp_dir.__enter__ = mocker.MagicMock(return_value='mock_temp_dir')
    mocker.patch('securedrop_client.export.TemporaryDirectory',
                 return_value=mock_temp_dir)
    export = Export()
    _run_disk_export = mocker.patch.object(export, '_run_disk_export')

    export.send_file_to_usb_device(['mock_filepath'], 'mock passphrase')

    _run_disk_export.assert_called_once_with('mock_temp_dir',
                                             ['mock_filepath'],
                                             'mock passphrase')
コード例 #14
0
ファイル: test_export.py プロジェクト: rmol/securedrop-client
def test_run_printer_preflight(mocker):
    """
    Ensure TemporaryDirectory is used when creating and sending the archives during the preflight
    checks and that the success signal is emitted by Export.
    """
    mock_temp_dir = mocker.MagicMock()
    mock_temp_dir.__enter__ = mocker.MagicMock(return_value="mock_temp_dir")
    mocker.patch("securedrop_client.export.TemporaryDirectory",
                 return_value=mock_temp_dir)
    export = Export()
    export.printer_preflight_success = mocker.MagicMock()
    export.printer_preflight_success.emit = mocker.MagicMock()
    _run_printer_preflight = mocker.patch.object(export,
                                                 "_run_printer_preflight")

    export.run_printer_preflight()

    _run_printer_preflight.assert_called_once_with("mock_temp_dir")
    export.printer_preflight_success.emit.assert_called_once_with()
コード例 #15
0
def test__run_disk_export(mocker):
    '''
    Ensure _export_archive and _create_archive are called with the expected parameters,
    _export_archive is called with the return value of _create_archive, and
    _run_disk_test returns without error if '' is the ouput status of _export_archive.
    '''
    export = Export()
    export._create_archive = mocker.MagicMock(return_value='mock_archive_path')
    export._export_archive = mocker.MagicMock(return_value='')

    export._run_disk_export('mock_archive_dir', ['mock_filepath'],
                            'mock_passphrase')

    export._export_archive.assert_called_once_with('mock_archive_path')
    export._create_archive.assert_called_once_with(
        'mock_archive_dir', 'archive.sd-export', {
            'encryption_key': 'mock_passphrase',
            'device': 'disk',
            'encryption_method': 'luks'
        }, ['mock_filepath'])
コード例 #16
0
def test_run_printer_preflight_error(mocker):
    '''
    Ensure TemporaryDirectory is used when creating and sending the archives during the preflight
    checks and that the failure signal is emitted by Export.
    '''
    mock_temp_dir = mocker.MagicMock()
    mock_temp_dir.__enter__ = mocker.MagicMock(return_value='mock_temp_dir')
    mocker.patch('securedrop_client.export.TemporaryDirectory',
                 return_value=mock_temp_dir)
    export = Export()
    export.printer_preflight_failure = mocker.MagicMock()
    export.printer_preflight_failure.emit = mocker.MagicMock()
    error = ExportError('bang!')
    _run_print_preflight = mocker.patch.object(export,
                                               '_run_printer_preflight',
                                               side_effect=error)

    export.run_printer_preflight()

    _run_print_preflight.assert_called_once_with('mock_temp_dir')
    export.printer_preflight_failure.emit.assert_called_once_with(error)
コード例 #17
0
ファイル: test_export.py プロジェクト: rmol/securedrop-client
def test_print(mocker):
    """
    Ensure TemporaryDirectory is used when creating and sending the archive containing the file to
    print and that the success signal is emitted.
    """
    mock_temp_dir = mocker.MagicMock()
    mock_temp_dir.__enter__ = mocker.MagicMock(return_value="mock_temp_dir")
    mocker.patch("securedrop_client.export.TemporaryDirectory",
                 return_value=mock_temp_dir)
    export = Export()
    export.print_call_success = mocker.MagicMock()
    export.print_call_success.emit = mocker.MagicMock()
    export.export_completed = mocker.MagicMock()
    export.export_completed.emit = mocker.MagicMock()
    _run_print = mocker.patch.object(export, "_run_print")
    mocker.patch("os.path.exists", return_value=True)

    export.print(["path1", "path2"])

    _run_print.assert_called_once_with("mock_temp_dir", ["path1", "path2"])
    export.print_call_success.emit.assert_called_once_with()
    export.export_completed.emit.assert_called_once_with(["path1", "path2"])
コード例 #18
0
def test_print(mocker):
    '''
    Ensure TemporaryDirectory is used when creating and sending the archive containing the file to
    print and that the success signal is emitted.
    '''
    mock_temp_dir = mocker.MagicMock()
    mock_temp_dir.__enter__ = mocker.MagicMock(return_value='mock_temp_dir')
    mocker.patch('securedrop_client.export.TemporaryDirectory',
                 return_value=mock_temp_dir)
    export = Export()
    export.print_call_success = mocker.MagicMock()
    export.print_call_success.emit = mocker.MagicMock()
    export.export_completed = mocker.MagicMock()
    export.export_completed.emit = mocker.MagicMock()
    _run_print = mocker.patch.object(export, '_run_print')
    mocker.patch('os.path.exists', return_value=True)

    export.print(['path1', 'path2'])

    _run_print.assert_called_once_with('mock_temp_dir', ['path1', 'path2'])
    export.print_call_success.emit.assert_called_once_with()
    export.export_completed.emit.assert_called_once_with(['path1', 'path2'])
コード例 #19
0
ファイル: test_export.py プロジェクト: rmol/securedrop-client
def test_run_preflight_checks_error(mocker):
    """
    Ensure TemporaryDirectory is used when creating and sending the archives during the preflight
    checks and that the failure signal is emitted by Export.
    """
    mock_temp_dir = mocker.MagicMock()
    mock_temp_dir.__enter__ = mocker.MagicMock(return_value="mock_temp_dir")
    mocker.patch("securedrop_client.export.TemporaryDirectory",
                 return_value=mock_temp_dir)
    export = Export()
    export.preflight_check_call_failure = mocker.MagicMock()
    export.preflight_check_call_failure.emit = mocker.MagicMock()
    error = ExportError("bang!")
    _run_usb_export = mocker.patch.object(export, "_run_usb_test")
    _run_disk_export = mocker.patch.object(export,
                                           "_run_disk_test",
                                           side_effect=error)

    export.run_preflight_checks()

    _run_usb_export.assert_called_once_with("mock_temp_dir")
    _run_disk_export.assert_called_once_with("mock_temp_dir")
    export.preflight_check_call_failure.emit.assert_called_once_with(error)
コード例 #20
0
ファイル: test_export.py プロジェクト: rmol/securedrop-client
def test__run_disk_export(mocker):
    """
    Ensure _export_archive and _create_archive are called with the expected parameters,
    _export_archive is called with the return value of _create_archive, and
    _run_disk_test returns without error if '' is the ouput status of _export_archive.
    """
    export = Export()
    export._create_archive = mocker.MagicMock(return_value="mock_archive_path")
    export._export_archive = mocker.MagicMock(return_value="")

    export._run_disk_export("mock_archive_dir", ["mock_filepath"],
                            "mock_passphrase")

    export._export_archive.assert_called_once_with("mock_archive_path")
    export._create_archive.assert_called_once_with(
        "mock_archive_dir",
        "archive.sd-export",
        {
            "encryption_key": "mock_passphrase",
            "device": "disk",
            "encryption_method": "luks"
        },
        ["mock_filepath"],
    )
コード例 #21
0
ファイル: logic.py プロジェクト: creviera/pyqt-sandbox
    def __init__(
        self, hostname: str, gui, session_maker: sessionmaker,
        home: str, proxy: bool = True, qubes: bool = True
    ) -> None:
        """
        The hostname, gui and session objects are used to coordinate with the
        various other layers of the application: the location of the SecureDrop
        proxy, the user interface and SqlAlchemy local storage respectively.
        """
        check_dir_permissions(home)
        super().__init__()

        # Controller is unauthenticated by default
        self.__is_authenticated = False

        # used for finding DB in sync thread
        self.home = home

        # boolean flag for whether or not the client is operating behind a proxy
        self.proxy = proxy

        # boolean flag for whether the client is running within Qubes
        # (regardless of proxy state, to support local dev in an AppVM)
        self.qubes = qubes

        # Location of the SecureDrop server.
        self.hostname = hostname

        # Reference to the UI window.
        self.gui = gui

        # Reference to the API for secure drop proxy.
        self.api = None  # type: sdclientapi.API

        # Reference to the SqlAlchemy `sessionmaker` and `session`
        self.session_maker = session_maker
        self.session = session_maker()

        # Queue that handles running API job
        self.api_job_queue = ApiJobQueue(self.api, self.session_maker)
        self.api_job_queue.paused.connect(self.on_queue_paused)

        # Contains active threads calling the API.
        self.api_threads = {}  # type: Dict[str, Dict]

        self.gpg = GpgHelper(home, self.session_maker, proxy)

        self.export = Export()

        # File data.
        self.data_dir = os.path.join(self.home, 'data')

        # Background sync to keep client up-to-date with server changes
        self.api_sync = ApiSync(self.api, self.session_maker, self.gpg, self.data_dir)
        self.api_sync.sync_started.connect(self.on_sync_started, type=Qt.QueuedConnection)
        self.api_sync.sync_success.connect(self.on_sync_success, type=Qt.QueuedConnection)
        self.api_sync.sync_failure.connect(self.on_sync_failure, type=Qt.QueuedConnection)

        # Create a timer to show the time since the last sync
        self.show_last_sync_timer = QTimer()
        self.show_last_sync_timer.timeout.connect(self.show_last_sync)

        # Path to the file containing the timestamp since the last sync with the server
        self.last_sync_filepath = os.path.join(home, 'sync_flag')