From 58110a69f4820fcf70604c8c260caf03ad498fe8 Mon Sep 17 00:00:00 2001 From: sagi Date: Tue, 17 Nov 2015 07:23:19 +0000 Subject: [PATCH] more elegant enhance_config, add --no- flags to hsts and uir --- letsencrypt/cli.py | 11 ++++++++++- letsencrypt/client.py | 33 +++++++++++++++++--------------- letsencrypt/tests/client_test.py | 11 +++++++---- 3 files changed, 35 insertions(+), 20 deletions(-) diff --git a/letsencrypt/cli.py b/letsencrypt/cli.py index 8393d6dd0..ce419b393 100644 --- a/letsencrypt/cli.py +++ b/letsencrypt/cli.py @@ -914,11 +914,20 @@ def prepare_and_parse_args(plugins, args): help="Add the Strict-Transport-Security header to every HTTP response." " Forcing browser to use always use SSL for the domain." " Defends against SSL Stripping.", dest="hsts", default=False) + helpful.add( + "security", "--no-hsts", action="store_false", + help="Do not automaticcally add the Strict-Transport-Security header" + " to every HTTP response.", dest="hsts", default=False) helpful.add( "security", "--uir", action="store_true", help="Add the \"Content-Security-Policy: upgrade-insecure-requests\"" " header to every HTTP response. Forcing the browser to use" - " https:// for every http:// resource.", dest="uir", default=False) + " https:// for every http:// resource.", dest="uir", default=None) + helpful.add( + "security", "--no-uir", action="store_false", + help=" Do not automatically set the \"Content-Security-Policy:" + " upgrade-insecure-requests\" header to every HTTP response.", + dest="uir", default=None) helpful.add( "security", "--strict-permissions", action="store_true", help="Require that all configuration files are owned by the current " diff --git a/letsencrypt/client.py b/letsencrypt/client.py index e3e365bb8..be6fc7a22 100644 --- a/letsencrypt/client.py +++ b/letsencrypt/client.py @@ -354,13 +354,14 @@ class Client(object): with error_handler.ErrorHandler(self._rollback_and_restart, msg): # sites may have been enabled / final cleanup self.installer.restart() - def enhance_config(self, domains, config=None): + def enhance_config(self, domains, config): """Enhance the configuration. :param list domains: list of domains to configure :ivar config: Namespace typically produced by :meth:`argparse.ArgumentParser.parse_args`. + it must have the redirect, hsts and uir attributes. :type namespace: :class:`argparse.Namespace` :raises .errors.Error: if no installer is specified in the @@ -374,23 +375,25 @@ class Client(object): raise errors.Error("No installer available") if config is None: + logger.warning("No config is specified.") + raise errors.Error("No config available") + + redirect = config.redirect + hsts = config.hsts + uir = config.uir # Upgrade Insecure Requests + + if redirect is None: redirect = enhancements.ask("redirect") - if redirect: - self.apply_enhancement(domains, "redirect") - else: - redirect = config.redirect - hsts = config.hsts - uir = config.uir # Upgrade Insecure Requests - if redirect: - self.apply_enhancement(domains, "redirect") + if redirect: + self.apply_enhancement(domains, "redirect") - if hsts: - self.apply_enhancement(domains, "http-header", - "Strict-Transport-Security") - if uir: - self.apply_enhancement(domains, "http-header", - "Upgrade-Insecure-Requests") + if hsts: + self.apply_enhancement(domains, "http-header", + "Strict-Transport-Security") + if uir: + self.apply_enhancement(domains, "http-header", + "Upgrade-Insecure-Requests") msg = ("We were unable to restart web server") if redirect or hsts or uir: diff --git a/letsencrypt/tests/client_test.py b/letsencrypt/tests/client_test.py index c66ad1e08..4208027aa 100644 --- a/letsencrypt/tests/client_test.py +++ b/letsencrypt/tests/client_test.py @@ -220,22 +220,24 @@ class ClientTest(unittest.TestCase): @mock.patch("letsencrypt.client.enhancements") def test_enhance_config(self, mock_enhancements): + config = ConfigHelper(redirect=True, hsts=False, uir=False) self.assertRaises(errors.Error, - self.client.enhance_config, ["foo.bar"]) + self.client.enhance_config, ["foo.bar"], config) mock_enhancements.ask.return_value = True installer = mock.MagicMock() self.client.installer = installer - self.client.enhance_config(["foo.bar"]) + self.client.enhance_config(["foo.bar"], config) installer.enhance.assert_called_once_with("foo.bar", "redirect", None) self.assertEqual(installer.save.call_count, 1) installer.restart.assert_called_once_with() @mock.patch("letsencrypt.client.enhancements") def test_enhance_config_no_ask(self, mock_enhancements): + config = ConfigHelper(redirect=True, hsts=False, uir=False) self.assertRaises(errors.Error, - self.client.enhance_config, ["foo.bar"]) + self.client.enhance_config, ["foo.bar"], config) mock_enhancements.ask.return_value = True installer = mock.MagicMock() @@ -259,8 +261,9 @@ class ClientTest(unittest.TestCase): self.assertEqual(installer.restart.call_count, 3) def test_enhance_config_no_installer(self): + config = ConfigHelper(redirect=True, hsts=False, uir=False) self.assertRaises(errors.Error, - self.client.enhance_config, ["foo.bar"]) + self.client.enhance_config, ["foo.bar"], config) @mock.patch("letsencrypt.client.zope.component.getUtility") @mock.patch("letsencrypt.client.enhancements")