From b8013d6fc618718b6a561cd98c1e8ee2e364e83a Mon Sep 17 00:00:00 2001 From: redshiftzero Date: Thu, 10 Oct 2019 12:48:05 -0400 Subject: [PATCH 1/2] ci: parallel stretch/buster jobs --- .circleci/config.yml | 76 +++++++++++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 29 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index efc433193..923742cb9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,6 +1,35 @@ +--- +common-steps: + - &run_tests + run: + name: Install requirements and run tests + command: | + set -e + virtualenv .venv + source .venv/bin/activate + pip install --require-hashes -r dev-requirements.txt + export PYTHONPATH=$PYTHONPATH:. # so alembic can get to Base metadata + make check --keep-going + + - &check_python_dependencies_for_vulns + run: + name: Check Python dependencies for known vulnerabilities + command: | + set -e + source .venv/bin/activate + make safety + + - &run_static_analysis + run: + name: Run static analysis on source code to find security issues + command: | + set -e + source .venv/bin/activate + make bandit + version: 2 jobs: - build: + build-stretch: docker: - image: circleci/python:3.5-stretch steps: @@ -30,41 +59,30 @@ jobs: export PKG_PATH=~/project/dist/securedrop-client-$PKG_VERSION.tar.gz make securedrop-client - test: + test-stretch: docker: - - image: circleci/python:3.5 + - image: circleci/python:3.5-stretch steps: - checkout - - run: sudo apt-get install -y sqlite3 libqt5x11extras5 + - *run_tests + - *check_python_dependencies_for_vulns + - *run_static_analysis - - run: - name: Install requirements and run tests - command: | - set -e - virtualenv .venv - source .venv/bin/activate - pip install --require-hashes -r dev-requirements.txt - export PYTHONPATH=$PYTHONPATH:. # so alembic can get to Base metadata - make check --keep-going - - - run: - name: Check Python dependencies for known vulnerabilities - command: | - set -e - source .venv/bin/activate - make safety - - - run: - name: Run static analysis on source code to find security issues - command: | - set -e - source .venv/bin/activate - make bandit + test-buster: + docker: + - image: circleci/python:3.7-buster + steps: + - checkout + - run: sudo apt-get install -y sqlite3 libqt5x11extras5 + - *run_tests + - *check_python_dependencies_for_vulns + - *run_static_analysis workflows: version: 2 securedrop_client_ci: jobs: - - test - - build + - test-stretch + - build-stretch + - test-buster From c41c7b0402ff761fddad0c50c482aea239f5e9b1 Mon Sep 17 00:00:00 2001 From: redshiftzero Date: Wed, 16 Oct 2019 10:42:13 -0400 Subject: [PATCH 2/2] app: buster + python 3.7 support --- securedrop_client/utils.py | 16 ++++++++++++---- tests/test_app.py | 11 +++++++---- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/securedrop_client/utils.py b/securedrop_client/utils.py index f65f5f6f2..9f872a091 100644 --- a/securedrop_client/utils.py +++ b/securedrop_client/utils.py @@ -6,15 +6,23 @@ def safe_mkdir(sdc_home: str, relative_path: str = None) -> None: ''' Safely create directories while checking permissions along the way. ''' - check_dir_permissions(sdc_home) - if not relative_path: - return + if relative_path: + full_path = os.path.join(sdc_home, relative_path) + else: + full_path = sdc_home - full_path = os.path.join(sdc_home, relative_path) if not full_path == os.path.abspath(full_path): raise ValueError('Path is not absolute: {}'.format(full_path)) + if not os.path.exists(sdc_home): + os.makedirs(sdc_home, 0o700) + + check_dir_permissions(sdc_home) + + if not relative_path: + return + path_components = split_path(relative_path) path_so_far = sdc_home diff --git a/tests/test_app.py b/tests/test_app.py index 4a9263b50..7e96a0594 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -39,7 +39,6 @@ def test_configure_logging(homedir, mocker): expected (rotating logs) manner. """ mock_log_conf = mocker.patch('securedrop_client.app.TimedRotatingFileHandler') - mocker.patch('securedrop_client.app.os.path.exists', return_value=False) mock_logging = mocker.patch('securedrop_client.app.logging') mock_log_file = os.path.join(homedir, 'logs', 'client.log') configure_logging(homedir) @@ -120,6 +119,8 @@ def test_start_app(homedir, mocker): mocker.patch('securedrop_client.app.configure_logging') mock_app = mocker.patch('securedrop_client.app.QApplication') mock_win = mocker.patch('securedrop_client.app.Window') + mocker.patch('securedrop_client.resources.path', + return_value=mock_args.sdc_home + 'dummy.jpg') mock_controller = mocker.patch('securedrop_client.app.Controller') mocker.patch('securedrop_client.app.prevent_second_instance') mocker.patch('securedrop_client.app.sys') @@ -172,12 +173,12 @@ def test_create_app_dir_permissions(tmpdir, mocker): for idx, case in enumerate(PERMISSIONS_CASES): mock_session_maker = mocker.MagicMock() mock_args = mocker.MagicMock() - mock_qt_args = mocker.MagicMock() - sdc_home = os.path.join(str(tmpdir), 'case-{}'.format(idx)) + mock_args.sdc_home = sdc_home + mock_qt_args = mocker.MagicMock() # optionally create the dir - if case['home_perms'] is not None: + if case['home_perms']: os.mkdir(sdc_home, case['home_perms']) mock_args.sdc_home = sdc_home @@ -191,6 +192,8 @@ def test_create_app_dir_permissions(tmpdir, mocker): mocker.patch('securedrop_client.app.Window') mocker.patch('securedrop_client.app.Controller') mocker.patch('securedrop_client.app.sys') + mocker.patch('securedrop_client.resources.path', + return_value=sdc_home + 'dummy.jpg') mocker.patch('securedrop_client.app.prevent_second_instance') mocker.patch('securedrop_client.app.make_session_maker', return_value=mock_session_maker)