diff --git a/anchor/app.py b/anchor/app.py index e1063d9..61710eb 100644 --- a/anchor/app.py +++ b/anchor/app.py @@ -22,6 +22,18 @@ class ConfigValidationException(Exception): pass +def config_check_domains(conf): + # gc.validators[0]['steps'][0][1]['allowed_domains'] + + for validator in conf.validators: + for step in validator['steps']: + if 'allowed_domains' in step[1]: + for domain in step[1]['allowed_domains']: + if not domain.startswith('.'): + raise ConfigValidationException("Domain that does not start with " + "a '.' <%s>", domain) + + def validate_config(conf): if not hasattr(conf, "auth") or not conf.auth: raise ConfigValidationException("No authentication configured") @@ -54,10 +66,8 @@ def validate_config(conf): raise ConfigValidationException("Validator set <%s> contains " "an unknown validator <%s>", name, step[0]) - for domain in allowed_domains: - if not domain.startswith('.'): - raise ConfigValidationException("Domain that does not start with " - "a '.' <%s>", domain) + + config_check_domains(conf) def setup_app(config): diff --git a/tests/controllers/__init__.py b/tests/controllers/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/controllers/bad_config_domains.py b/tests/controllers/bad_config_domains.py new file mode 100644 index 0000000..5ead4fa --- /dev/null +++ b/tests/controllers/bad_config_domains.py @@ -0,0 +1,86 @@ +server = { + 'port': '5000', + 'host': '0.0.0.0' +} + +# Pecan Application Configurations +app = { + 'root': 'anchor.controllers.RootController', + 'modules': ['anchor'], + # 'static_root': '%(confdir)s/public', + # 'template_path': '%(confdir)s/${package}/templates', + 'debug': True, + 'errors': { + '404': '/error/404', + '__force_dict__': True + } +} + +auth = { + 'static': { + 'user': 'woot', + 'secret': 'woot', + }, +} + +validators = [ + { + "name": "common", + "steps": [ + ('common_name', {'allowed_domains': ['example.com']}), # example.com should start with a '.' + ('alternative_names', {'allowed_domains': ['example.com']}), + ('server_group', {'group_prefixes': { + 'nv': 'Nova_Team', + 'sw': 'Swift_Team', + 'bk': 'Bock_Team', + 'gl': 'Glance_Team', + 'cs': 'CS_Team', + 'mb': 'MB_Team', + 'ops': 'SysEng_Team', + 'qu': 'Neutron_Team', + }}), + ('extensions', {'allowed_extensions': ['keyUsage', 'subjectAltName', 'basicConstraints', 'subjectKeyIdentifier']}), + ('key_usage', {'allowed_usage': ['Digital Signature', 'Key Encipherment', 'Non Repudiation', 'Certificate Sign', 'CRL Sign']}), + ('ca_status', {'ca_requested': False}), + ('source_cidrs', {'cidrs': ["127.0.0.0/8"]}), + ] + }, + { + "name": "ip", + "steps": [ + ('common_name', {'allowed_networks': ['127/8']}), + ('alternative_names', {'allowed_networks': ['127/8']}), + ('ca_status', {'ca_requested': False}), + ('source_cidrs', {'cidrs': ["127.0.0.0/8"]}), + ] + }, +] + +ca = { + 'cert_path': "CA/root-ca.crt", + 'key_path': "CA/root-ca-unwrapped.key", + 'output_path': "certs", + 'valid_hours': 24, + 'signing_hash': "sha1", +} + +logging = { + 'root': {'level': 'INFO', 'handlers': ['console']}, + 'loggers': { + 'anchor': {'level': 'DEBUG'}, + 'wsgi': {'level': 'INFO'}, + }, + 'handlers': { + 'console': { + 'level': 'DEBUG', + 'class': 'logging.StreamHandler', + 'formatter': 'simple' + } + }, + 'formatters': { + 'simple': { + 'format': ('%(asctime)s %(levelname)-5.5s [%(name)s]' + '[%(process)d/%(threadName)s] %(message)s') + } + } +} diff --git a/tests/controllers/good_config_domains.py b/tests/controllers/good_config_domains.py new file mode 100644 index 0000000..a091614 --- /dev/null +++ b/tests/controllers/good_config_domains.py @@ -0,0 +1,94 @@ +server = { + 'port': '5000', + 'host': '0.0.0.0' +} + +# Pecan Application Configurations +app = { + 'root': 'anchor.controllers.RootController', + 'modules': ['anchor'], + # 'static_root': '%(confdir)s/public', + # 'template_path': '%(confdir)s/${package}/templates', + 'debug': True, + 'errors': { + '404': '/error/404', + '__force_dict__': True + } +} + +auth = { + 'static': { + 'user': 'woot', + 'secret': 'woot', + }, + # 'ldap': { + # 'host': "ldap.host.com", + # 'domain': "host.com", + # 'base': "CN=Users,DC=host,DC=com", + # }, + # 'keystone': { + # 'url': 'https://keystone.example.com:35357', + # }, +} + +validators = [ + { + "name": "common", + "steps": [ + ('common_name', {'allowed_domains': ['.example.com']}), + ('alternative_names', {'allowed_domains': ['.example.com']}), + ('server_group', {'group_prefixes': { + 'nv': 'Nova_Team', + 'sw': 'Swift_Team', + 'bk': 'Bock_Team', + 'gl': 'Glance_Team', + 'cs': 'CS_Team', + 'mb': 'MB_Team', + 'ops': 'SysEng_Team', + 'qu': 'Neutron_Team', + }}), + ('extensions', {'allowed_extensions': ['keyUsage', 'subjectAltName', 'basicConstraints', 'subjectKeyIdentifier']}), + ('key_usage', {'allowed_usage': ['Digital Signature', 'Key Encipherment', 'Non Repudiation', 'Certificate Sign', 'CRL Sign']}), + ('ca_status', {'ca_requested': False}), + ('source_cidrs', {'cidrs': ["127.0.0.0/8"]}), + ] + }, + { + "name": "ip", + "steps": [ + ('common_name', {'allowed_networks': ['127/8']}), + ('alternative_names', {'allowed_networks': ['127/8']}), + ('ca_status', {'ca_requested': False}), + ('source_cidrs', {'cidrs': ["127.0.0.0/8"]}), + ] + }, +] + +ca = { + 'cert_path': "CA/root-ca.crt", + 'key_path': "CA/root-ca-unwrapped.key", + 'output_path': "certs", + 'valid_hours': 24, + 'signing_hash': "sha1", +} + +logging = { + 'root': {'level': 'INFO', 'handlers': ['console']}, + 'loggers': { + 'anchor': {'level': 'DEBUG'}, + 'wsgi': {'level': 'INFO'}, + }, + 'handlers': { + 'console': { + 'level': 'DEBUG', + 'class': 'logging.StreamHandler', + 'formatter': 'simple' + } + }, + 'formatters': { + 'simple': { + 'format': ('%(asctime)s %(levelname)-5.5s [%(name)s]' + '[%(process)d/%(threadName)s] %(message)s') + } + } +} diff --git a/tests/controllers/test_app.py b/tests/controllers/test_app.py index e0a5fc8..ac8136a 100644 --- a/tests/controllers/test_app.py +++ b/tests/controllers/test_app.py @@ -20,27 +20,11 @@ import unittest from anchor.app import ConfigValidationException from anchor.app import validate_config +import bad_config_domains +import good_config_domains + class TestValidDN(unittest.TestCase): - test_bad_validator = [ - { - "name": "default", - "steps": [ - ('common_name', {'allowed_domains': ['badexample.com']}), - ('alternative_names', {'allowed_domains': ['.example.com']}) - ] - }, - ] - - test_good_validator = [ - { - "name": "default", - "steps": [ - ('common_name', {'allowed_domains': ['.example.com']}), - ('alternative_names', {'allowed_domains': ['.example.com']}) - ] - }, - ] def setUp(self): super(TestValidDN, self).setUp() @@ -48,11 +32,15 @@ class TestValidDN(unittest.TestCase): def tearDown(self): pass - def test_testing(self): + def test_self_test(self): self.assertTrue(True) - def test_validate_bad_config(self): - self.assertRaises(ConfigValidationException, validate_config, TestValidDN.test_validator) + def test_config_check_domains_good(self): + self.assertEqual(validate_config(good_config_domains), None) - def test_validate_good_config(self): - validate_config(test_good_validator) + def test_config_check_domains_bad(self): + self.assertRaises( + ConfigValidationException, + validate_config, + bad_config_domains + )