"""Tests for certbot.plugins.dns_common."""
import collections
import logging
import unittest
import mock
from certbot import errors
from certbot import util
from certbot.compat import os
from certbot.display import util as display_util
from certbot.plugins import dns_common
from certbot.plugins import dns_test_common
from certbot.tests import util as test_util
class DNSAuthenticatorTest(test_util.TempDirTestCase, dns_test_common.BaseAuthenticatorTest):
# pylint: disable=protected-access
class _FakeDNSAuthenticator(dns_common.DNSAuthenticator):
_setup_credentials = mock.MagicMock()
_perform = mock.MagicMock()
_cleanup = mock.MagicMock()
def more_info(self): # pylint: disable=missing-docstring,no-self-use
return 'A fake authenticator for testing.'
class _FakeConfig(object):
fake_propagation_seconds = 0
fake_config_key = 1
fake_other_key = None
fake_file_path = None
def setUp(self):
super(DNSAuthenticatorTest, self).setUp()
self.config = DNSAuthenticatorTest._FakeConfig()
self.auth = DNSAuthenticatorTest._FakeDNSAuthenticator(self.config, "fake")
def test_perform(self):
self.auth.perform([self.achall])
self.auth._perform.assert_called_once_with(dns_test_common.DOMAIN, mock.ANY, mock.ANY)
def test_cleanup(self):
self.auth._attempt_cleanup = True
self.auth.cleanup([self.achall])
self.auth._cleanup.assert_called_once_with(dns_test_common.DOMAIN, mock.ANY, mock.ANY)
@test_util.patch_get_utility()
def test_prompt(self, mock_get_utility):
mock_display = mock_get_utility()
mock_display.input.side_effect = ((display_util.OK, "",),
(display_util.OK, "value",))
self.auth._configure("other_key", "")
self.assertEqual(self.auth.config.fake_other_key, "value")
@test_util.patch_get_utility()
def test_prompt_canceled(self, mock_get_utility):
mock_display = mock_get_utility()
mock_display.input.side_effect = ((display_util.CANCEL, "c",),)
self.assertRaises(errors.PluginError, self.auth._configure, "other_key", "")
@test_util.patch_get_utility()
def test_prompt_file(self, mock_get_utility):
path = os.path.join(self.tempdir, 'file.ini')
open(path, "wb").close()
mock_display = mock_get_utility()
mock_display.directory_select.side_effect = ((display_util.OK, "",),
(display_util.OK, "not-a-file.ini",),
(display_util.OK, self.tempdir),
(display_util.OK, path,))
self.auth._configure_file("file_path", "")
self.assertEqual(self.auth.config.fake_file_path, path)
@test_util.patch_get_utility()
def test_prompt_file_canceled(self, mock_get_utility):
mock_display = mock_get_utility()
mock_display.directory_select.side_effect = ((display_util.CANCEL, "c",),)
self.assertRaises(errors.PluginError, self.auth._configure_file, "file_path", "")
def test_configure_credentials(self):
path = os.path.join(self.tempdir, 'file.ini')
dns_test_common.write({"fake_test": "value"}, path)
setattr(self.config, "fake_credentials", path)
credentials = self.auth._configure_credentials("credentials", "", {"test": ""})
self.assertEqual(credentials.conf("test"), "value")
@test_util.patch_get_utility()
def test_prompt_credentials(self, mock_get_utility):
bad_path = os.path.join(self.tempdir, 'bad-file.ini')
dns_test_common.write({"fake_other": "other_value"}, bad_path)
path = os.path.join(self.tempdir, 'file.ini')
dns_test_common.write({"fake_test": "value"}, path)
setattr(self.config, "fake_credentials", "")
mock_display = mock_get_utility()
mock_display.directory_select.side_effect = ((display_util.OK, "",),
(display_util.OK, "not-a-file.ini",),
(display_util.OK, self.tempdir),
(display_util.OK, bad_path),
(display_util.OK, path,))
credentials = self.auth._configure_credentials("credentials", "", {"test": ""})
self.assertEqual(credentials.conf("test"), "value")
class CredentialsConfigurationTest(test_util.TempDirTestCase):
class _MockLoggingHandler(logging.Handler):
messages = None
def __init__(self, *args, **kwargs):
self.reset()
logging.Handler.__init__(self, *args, **kwargs)
def emit(self, record):
self.messages[record.levelname.lower()].append(record.getMessage())
def reset(self):
"""Allows the handler to be reset between tests."""
self.messages = collections.defaultdict(list)
def test_valid_file(self):
path = os.path.join(self.tempdir, 'too-permissive-file.ini')
dns_test_common.write({"test": "value", "other": 1}, path)
credentials_configuration = dns_common.CredentialsConfiguration(path)
self.assertEqual("value", credentials_configuration.conf("test"))
self.assertEqual("1", credentials_configuration.conf("other"))
def test_nonexistent_file(self):
path = os.path.join(self.tempdir, 'not-a-file.ini')
self.assertRaises(errors.PluginError, dns_common.CredentialsConfiguration, path)
def test_valid_file_with_unsafe_permissions(self):
log = self._MockLoggingHandler()
dns_common.logger.addHandler(log)
path = os.path.join(self.tempdir, 'too-permissive-file.ini')
util.safe_open(path, "wb", 0o744).close()
dns_common.CredentialsConfiguration(path)
self.assertEqual(1, len([_ for _ in log.messages['warning'] if _.startswith("Unsafe")]))
class CredentialsConfigurationRequireTest(test_util.TempDirTestCase):
def setUp(self):
super(CredentialsConfigurationRequireTest, self).setUp()
self.path = os.path.join(self.tempdir, 'file.ini')
def _write(self, values):
dns_test_common.write(values, self.path)
def test_valid(self):
self._write({"test": "value", "other": 1})
credentials_configuration = dns_common.CredentialsConfiguration(self.path)
credentials_configuration.require({"test": "", "other": ""})
def test_valid_but_extra(self):
self._write({"test": "value", "other": 1})
credentials_configuration = dns_common.CredentialsConfiguration(self.path)
credentials_configuration.require({"test": ""})
def test_valid_empty(self):
self._write({})
credentials_configuration = dns_common.CredentialsConfiguration(self.path)
credentials_configuration.require({})
def test_missing(self):
self._write({})
credentials_configuration = dns_common.CredentialsConfiguration(self.path)
self.assertRaises(errors.PluginError, credentials_configuration.require, {"test": ""})
def test_blank(self):
self._write({"test": ""})
credentials_configuration = dns_common.CredentialsConfiguration(self.path)
self.assertRaises(errors.PluginError, credentials_configuration.require, {"test": ""})
def test_typo(self):
self._write({"tets": "typo!"})
credentials_configuration = dns_common.CredentialsConfiguration(self.path)
self.assertRaises(errors.PluginError, credentials_configuration.require, {"test": ""})
class DomainNameGuessTest(unittest.TestCase):
def test_simple_case(self):
self.assertTrue(
'example.com' in
dns_common.base_domain_name_guesses("example.com")
)
def test_sub_domain(self):
self.assertTrue(
'example.com' in
dns_common.base_domain_name_guesses("foo.bar.baz.example.com")
)
def test_second_level_domain(self):
self.assertTrue(
'example.co.uk' in
dns_common.base_domain_name_guesses("foo.bar.baz.example.co.uk")
)
if __name__ == "__main__":
unittest.main() # pragma: no cover