From ec0cd4d5383203c440d6528e1308c5e2281e5300 Mon Sep 17 00:00:00 2001 From: Mario Villaplana Date: Wed, 30 Nov 2016 13:50:16 -0500 Subject: [PATCH] Warn early if a selected enhancement is unsupported by the current plugin (#3688) Certbot currently silently allows a user to specify enhancements that are unsupported by the chosen plugin. This adds an early warning message indicating when a selected enhancement isn't supported by a plugin. --- certbot/client.py | 34 +++++++++++++++++++++++++++++++++- certbot/tests/client_test.py | 11 +++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/certbot/client.py b/certbot/client.py index 880cfe7df..b9dbaf480 100644 --- a/certbot/client.py +++ b/certbot/client.py @@ -196,6 +196,11 @@ class Client(object): else: self.auth_handler = None + # Warn if the client is using unsupported config options with an + # installer + if self.installer is not None: + self._verify_all_config_options_supported(config) + def obtain_certificate_from_csr(self, domains, csr, typ=OpenSSL.crypto.FILETYPE_ASN1, authzr=None): """Obtain certificate. @@ -411,9 +416,10 @@ class Client(object): raise errors.Error("No config available") supported = self.installer.supported_enhancements() + redirect = config.redirect if "redirect" in supported else False hsts = config.hsts if "ensure-http-header" in supported else False - uir = config.uir if "ensure-http-header" in supported else False + uir = config.uir if "ensure-http-header" in supported else False staple = config.staple if "staple-ocsp" in supported else False if redirect is None: @@ -502,6 +508,32 @@ class Client(object): raise reporter.add_message(success_msg, reporter.HIGH_PRIORITY) + def _verify_all_config_options_supported(self, config): + """Verifies that all config options are supported in current installer. + + :ivar config: Namespace typically produced by + :meth:`argparse.ArgumentParser.parse_args`. + :type namespace: :class:`argparse.Namespace` + """ + # Mapping between config options and string describing config option + # support in installer supported_enhancements. + option_support = { + "redirect": "redirect", + "hsts": "ensure-http-header", + "uir": "ensure-http-header", + "staple": "staple-ocsp" + } + + supported = self.installer.supported_enhancements() + + for config_name, support_string in option_support.items(): + config_value = getattr(config, config_name, None) + if config_value and support_string not in supported: + msg = ("Option %s is not allowed with the current installer. " + "Please disable the option and try again." % + config_name) + logger.warning(msg) + def validate_key_csr(privkey, csr=None): """Validate Key and CSR files. diff --git a/certbot/tests/client_test.py b/certbot/tests/client_test.py index d61025116..02e0bedf9 100644 --- a/certbot/tests/client_test.py +++ b/certbot/tests/client_test.py @@ -120,6 +120,17 @@ class ClientTest(unittest.TestCase): config=self.config, account_=self.account, auth=None, installer=None) + def test__init___warn_unsupported_config_options(self): + config = ConfigHelper(redirect=True, hsts=True) + installer = mock.MagicMock() + installer.supported_enhancements.return_value = ["redirect"] + + with mock.patch('certbot.client.logger') as mock_logger: + from certbot.client import Client + Client(config=config, account_=self.account, auth=None, + installer=installer, acme=self.acme) + mock_logger.warning.assert_called_once_with(mock.ANY) + def test_init_acme_verify_ssl(self): net = self.acme_client.call_args[1]["net"] self.assertTrue(net.verify_ssl)