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
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 == {}
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)
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)
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)
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'
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()
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()
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)
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"
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)
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()
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")