def test_load(self, caplog):
        args = argparse.Namespace(
            site_config="tests/files/site-specific",
            ansible_path="tests/files",
            app_path=dirname(__file__),
        )
        site_config = securedrop_admin.SiteConfig(args)
        assert "app_hostname" in site_config.load()

        args = argparse.Namespace(site_config="UNKNOWN",
                                  ansible_path="tests/files",
                                  app_path=dirname(__file__))
        site_config = securedrop_admin.SiteConfig(args)
        with pytest.raises(IOError) as e:
            site_config.load()
        assert "No such file" in e.value.strerror
        assert "Config file missing" in caplog.text

        args = argparse.Namespace(
            site_config="tests/files/corrupted",
            ansible_path="tests/files",
            app_path=dirname(__file__),
        )
        site_config = securedrop_admin.SiteConfig(args)
        with pytest.raises(yaml.YAMLError) as e:
            site_config.load()
        assert "issue processing" in caplog.text
Example #2
0
    def test_load_and_update_config(self):
        args = argparse.Namespace(site_config='tests/files/site-specific',
                                  ansible_path='tests/files',
                                  app_path=dirname(__file__))
        site_config = securedrop_admin.SiteConfig(args)
        with mock.patch('securedrop_admin.SiteConfig.update_config'):
            site_config.load_and_update_config()
            assert site_config.config != {}

        args = argparse.Namespace(
            site_config='tests/files/site-specific-missing-entries',
            ansible_path='tests/files',
            app_path=dirname(__file__))
        site_config = securedrop_admin.SiteConfig(args)
        with mock.patch('securedrop_admin.SiteConfig.update_config'):
            site_config.load_and_update_config()
            assert site_config.config != {}

        args = argparse.Namespace(site_config='UNKNOWN',
                                  ansible_path='tests/files',
                                  app_path=dirname(__file__))
        site_config = securedrop_admin.SiteConfig(args)
        with mock.patch('securedrop_admin.SiteConfig.update_config'):
            site_config.load_and_update_config()
            assert site_config.config == {}
Example #3
0
 def test_exists(self):
     args = argparse.Namespace(site_config='DOES_NOT_EXIST',
                               ansible_path='.',
                               app_path=dirname(__file__))
     assert not securedrop_admin.SiteConfig(args).exists()
     args = argparse.Namespace(site_config=__file__,
                               ansible_path='.',
                               app_path=dirname(__file__))
     assert securedrop_admin.SiteConfig(args).exists()
    def test_validated_input(self):
        args = argparse.Namespace(site_config="UNKNOWN",
                                  ansible_path="tests/files",
                                  app_path=dirname(__file__))
        site_config = securedrop_admin.SiteConfig(args)

        def auto_prompt(prompt, default, **kwargs):
            return default

        with mock.patch("prompt_toolkit.prompt", side_effect=auto_prompt):
            value = "VALUE"
            assert value == site_config.validated_input(
                "", value, lambda: True, None)
            assert value.lower() == site_config.validated_input(
                "", value, lambda: True, str.lower)
            assert "yes" == site_config.validated_input(
                "", True, lambda: True, None)
            assert "no" == site_config.validated_input("", False, lambda: True,
                                                       None)
            assert "1234" == site_config.validated_input(
                "", 1234, lambda: True, None)
            assert "a b" == site_config.validated_input(
                "", ["a", "b"], lambda: True, None)
            assert "{}" == site_config.validated_input("", {}, lambda: True,
                                                       None)
Example #5
0
    def test_validate_gpg_key(self, caplog):
        args = argparse.Namespace(site_config='INVALID',
                                  ansible_path='tests/files',
                                  app_path=dirname(__file__))
        good_config = {
            'securedrop_app_gpg_public_key': 'test_journalist_key.pub',
            'securedrop_app_gpg_fingerprint':
            '65A1B5FF195B56353CC63DFFCC40EF1228271441',
            'ossec_alert_gpg_public_key': 'test_journalist_key.pub',
            'ossec_gpg_fpr': '65A1B5FF195B56353CC63DFFCC40EF1228271441',
            'journalist_alert_gpg_public_key': 'test_journalist_key.pub',
            'journalist_gpg_fpr': '65A1B5FF195B56353CC63DFFCC40EF1228271441',
        }
        site_config = securedrop_admin.SiteConfig(args)
        site_config.config = good_config
        assert site_config.validate_gpg_keys()

        for key in ('securedrop_app_gpg_fingerprint', 'ossec_gpg_fpr',
                    'journalist_gpg_fpr'):
            bad_config = good_config.copy()
            bad_config[key] = 'FAIL'
            site_config.config = bad_config
            with pytest.raises(securedrop_admin.FingerprintException) as e:
                site_config.validate_gpg_keys()
            assert 'FAIL does not match' in str(e)
    def test_validate_gpg_key(self, caplog):
        args = argparse.Namespace(site_config="INVALID",
                                  ansible_path="tests/files",
                                  app_path=dirname(__file__))
        good_config = {
            "securedrop_app_gpg_public_key": "test_journalist_key.pub",
            "securedrop_app_gpg_fingerprint":
            "65A1B5FF195B56353CC63DFFCC40EF1228271441",
            "ossec_alert_gpg_public_key": "test_journalist_key.pub",
            "ossec_gpg_fpr": "65A1B5FF195B56353CC63DFFCC40EF1228271441",
            "journalist_alert_gpg_public_key": "test_journalist_key.pub",
            "journalist_gpg_fpr": "65A1B5FF195B56353CC63DFFCC40EF1228271441",
        }
        site_config = securedrop_admin.SiteConfig(args)
        site_config.config = good_config
        assert site_config.validate_gpg_keys()

        for key in ("securedrop_app_gpg_fingerprint", "ossec_gpg_fpr",
                    "journalist_gpg_fpr"):
            bad_config = good_config.copy()
            bad_config[key] = "FAIL"
            site_config.config = bad_config
            with pytest.raises(securedrop_admin.FingerprintException) as e:
                site_config.validate_gpg_keys()
            assert "FAIL does not match" in str(e)
Example #7
0
    def test_validated_input(self):
        args = argparse.Namespace(site_config='UNKNOWN',
                                  ansible_path='tests/files',
                                  app_path=dirname(__file__))
        site_config = securedrop_admin.SiteConfig(args)

        def auto_prompt(prompt, default, **kwargs):
            return default

        with mock.patch('prompt_toolkit.prompt', side_effect=auto_prompt):
            value = 'VALUE'
            assert value == site_config.validated_input(
                '', value, lambda: True, None)
            assert value.lower() == site_config.validated_input(
                '', value, lambda: True, str.lower)
            assert 'yes' == site_config.validated_input(
                '', True, lambda: True, None)
            assert 'no' == site_config.validated_input('', False, lambda: True,
                                                       None)
            assert '1234' == site_config.validated_input(
                '', 1234, lambda: True, None)
            assert "a b" == site_config.validated_input(
                '', ['a', 'b'], lambda: True, None)
            assert "{}" == site_config.validated_input('', {}, lambda: True,
                                                       None)
Example #8
0
    def test_desc_conditional(self):
        """Ensure that conditional prompts behave correctly.

            Prompts which depend on another question should only be
            asked if the prior question was answered appropriately."""

        questions = [[
            'first_question', False, bool, u'Test Question 1', None,
            lambda x: x.lower() == 'yes', lambda config: True
        ],
                     [
                         'dependent_question', 'default_value', str,
                         u'Test Question 2', None, None,
                         lambda config: config.get('first_question', False)
                     ]]
        args = argparse.Namespace(site_config='tests/files/site-specific',
                                  ansible_path='tests/files',
                                  app_path=dirname(__file__))
        site_config = securedrop_admin.SiteConfig(args)
        site_config.desc = questions

        def auto_prompt(prompt, default, **kwargs):
            return default

        with mock.patch('prompt_toolkit.prompt', side_effect=auto_prompt):
            config = site_config.user_prompt_config()
            assert config['dependent_question'] != 'default_value'

            site_config.desc[0][1] = True

            config = site_config.user_prompt_config()
            assert config['dependent_question'] == 'default_value'
Example #9
0
    def test_journalist_alert_email(self):
        args = argparse.Namespace(site_config='INVALID',
                                  ansible_path='tests/files',
                                  app_path=dirname(__file__))
        site_config = securedrop_admin.SiteConfig(args)
        site_config.config = {
            'journalist_alert_gpg_public_key': '',
            'journalist_gpg_fpr': '',
        }
        assert site_config.validate_journalist_alert_email()
        site_config.config = {
            'journalist_alert_gpg_public_key': 'test_journalist_key.pub',
            'journalist_gpg_fpr': '65A1B5FF195B56353CC63DFFCC40EF1228271441',
        }
        site_config.config['journalist_alert_email'] = ''
        with pytest.raises(
                securedrop_admin.JournalistAlertEmailException) as e:
            site_config.validate_journalist_alert_email()
        assert 'not be empty' in str(e)

        site_config.config['journalist_alert_email'] = 'bademail'
        with pytest.raises(
                securedrop_admin.JournalistAlertEmailException) as e:
            site_config.validate_journalist_alert_email()
        assert 'Must contain a @' in str(e)

        site_config.config['journalist_alert_email'] = '*****@*****.**'
        assert site_config.validate_journalist_alert_email()
    def test_journalist_alert_email(self):
        args = argparse.Namespace(site_config="INVALID",
                                  ansible_path="tests/files",
                                  app_path=dirname(__file__))
        site_config = securedrop_admin.SiteConfig(args)
        site_config.config = {
            "journalist_alert_gpg_public_key": "",
            "journalist_gpg_fpr": "",
        }
        assert site_config.validate_journalist_alert_email()
        site_config.config = {
            "journalist_alert_gpg_public_key": "test_journalist_key.pub",
            "journalist_gpg_fpr": "65A1B5FF195B56353CC63DFFCC40EF1228271441",
        }
        site_config.config["journalist_alert_email"] = ""
        with pytest.raises(
                securedrop_admin.JournalistAlertEmailException) as e:
            site_config.validate_journalist_alert_email()
        assert "not be empty" in str(e)

        site_config.config["journalist_alert_email"] = "bademail"
        with pytest.raises(
                securedrop_admin.JournalistAlertEmailException) as e:
            site_config.validate_journalist_alert_email()
        assert "Must contain a @" in str(e)

        site_config.config["journalist_alert_email"] = "*****@*****.**"
        assert site_config.validate_journalist_alert_email()
Example #11
0
    def test_update_config(self, mock_save, mock_validate_input):
        args = argparse.Namespace(site_config='tests/files/site-specific',
                                  ansible_path='tests/files',
                                  app_path=dirname(__file__))
        site_config = securedrop_admin.SiteConfig(args)

        assert site_config.load_and_update_config()
        assert 'user_defined_variable' in site_config.config
        mock_save.assert_called_once()
        mock_validate_input.assert_called()
Example #12
0
 def test_update_config_no_site_specific(self, validate_gpg_keys,
                                         mock_validate_input, tmpdir):
     site_config_path = join(str(tmpdir), 'site_config')
     args = argparse.Namespace(site_config=site_config_path,
                               ansible_path='.',
                               app_path=dirname(__file__))
     site_config = securedrop_admin.SiteConfig(args)
     assert site_config.load_and_update_config()
     mock_validate_input.assert_called()
     validate_gpg_keys.assert_called_once()
     assert exists(site_config_path)
Example #13
0
 def test_save(self, tmpdir):
     site_config_path = join(str(tmpdir), 'site_config')
     args = argparse.Namespace(site_config=site_config_path,
                               ansible_path='.',
                               app_path=dirname(__file__))
     site_config = securedrop_admin.SiteConfig(args)
     site_config.config = {'var1': u'val1', 'var2': u'val2'}
     site_config.save()
     expected = textwrap.dedent("""\
     var1: val1
     var2: val2
     """)
     assert expected == io.open(site_config_path).read()
    def test_desc_conditional(self):
        """Ensure that conditional prompts behave correctly.

        Prompts which depend on another question should only be
        asked if the prior question was answered appropriately."""

        questions = [
            (
                "first_question",
                False,
                bool,
                "Test Question 1",
                None,
                lambda x: x.lower() == "yes",
                lambda config: True,
            ),
            (
                "dependent_question",
                "default_value",
                str,
                "Test Question 2",
                None,
                None,
                lambda config: config.get("first_question", False),
            ),
        ]
        args = argparse.Namespace(
            site_config="tests/files/site-specific",
            ansible_path="tests/files",
            app_path=dirname(__file__),
        )
        site_config = securedrop_admin.SiteConfig(args)
        site_config.desc = questions

        def auto_prompt(prompt, default, **kwargs):
            return default

        with mock.patch("prompt_toolkit.prompt", side_effect=auto_prompt):
            config = site_config.user_prompt_config()
            assert config["dependent_question"] != "default_value"

            edited_first_question = list(site_config.desc[0])
            edited_first_question[1] = True
            site_config.desc[0] = tuple(edited_first_question)

            config = site_config.user_prompt_config()
            assert config["dependent_question"] == "default_value"
Example #15
0
    def test_user_prompt_config_one(self):
        args = argparse.Namespace(site_config='UNKNOWN',
                                  ansible_path='tests/files',
                                  app_path=dirname(__file__))
        site_config = securedrop_admin.SiteConfig(args)

        def auto_prompt(prompt, default, **kwargs):
            if 'validator' in kwargs:
                assert kwargs['validator'].validate(Document(default))
            return default

        with mock.patch('prompt_toolkit.prompt', side_effect=auto_prompt):
            for desc in site_config.desc:
                (var, default, etype, prompt, validator, transform,
                 condition) = desc
                method = 'verify_prompt_' + var
                print("checking " + method)
                getattr(self, method)(site_config, desc)
Example #16
0
def test_v3_and_https_cert_message(tmpdir, capsys):
    args = argparse.Namespace(site_config='UNKNOWN',
                              ansible_path='tests/files',
                              app_path=dirname(__file__))
    site_config = securedrop_admin.SiteConfig(args)
    site_config.config = {
        "v3_onion_services": False,
        "securedrop_app_https_certificate_cert_src": "ab.crt"
    }  # noqa: E501
    # This should return True as v3 is not setup
    assert site_config.validate_https_and_v3()

    # This should return False as v3 and https are both setup
    site_config.config.update({"v3_onion_services": True})
    assert not site_config.validate_https_and_v3()

    # This should return True as https is not setup
    site_config.config.update(
        {"securedrop_app_https_certificate_cert_src": ""})  # noqa: E501
    assert site_config.validate_https_and_v3()
Example #17
0
 def test_sanitize_fingerprint(self):
     args = argparse.Namespace(site_config='DOES_NOT_EXIST',
                               ansible_path='.',
                               app_path=dirname(__file__))
     site_config = securedrop_admin.SiteConfig(args)
     assert "ABC" == site_config.sanitize_fingerprint("    A bc")