%PDF- %PDF-
Direktori : /usr/lib/python3/dist-packages/certbot_apache/tests/ |
Current File : //usr/lib/python3/dist-packages/certbot_apache/tests/autohsts_test.py |
# pylint: disable=too-many-public-methods,too-many-lines """Test for certbot_apache.configurator AutoHSTS functionality""" import re import unittest import mock # six is used in mock.patch() import six # pylint: disable=unused-import from certbot import errors from certbot_apache import constants from certbot_apache.tests import util class AutoHSTSTest(util.ApacheTest): """Tests for AutoHSTS feature""" # pylint: disable=protected-access def setUp(self): # pylint: disable=arguments-differ super(AutoHSTSTest, self).setUp() self.config = util.get_apache_configurator( self.config_path, self.vhost_path, self.config_dir, self.work_dir) self.config.parser.modules.add("headers_module") self.config.parser.modules.add("mod_headers.c") self.config.parser.modules.add("ssl_module") self.config.parser.modules.add("mod_ssl.c") self.vh_truth = util.get_vh_truth( self.temp_dir, "debian_apache_2_4/multiple_vhosts") def get_autohsts_value(self, vh_path): """ Get value from Strict-Transport-Security header """ header_path = self.config.parser.find_dir("Header", None, vh_path) if header_path: pat = '(?:[ "]|^)(strict-transport-security)(?:[ "]|$)' for head in header_path: if re.search(pat, self.config.parser.aug.get(head).lower()): return self.config.parser.aug.get( head.replace("arg[3]", "arg[4]")) return None # pragma: no cover @mock.patch("certbot_apache.configurator.ApacheConfigurator.restart") @mock.patch("certbot_apache.configurator.ApacheConfigurator.enable_mod") def test_autohsts_enable_headers_mod(self, mock_enable, _restart): self.config.parser.modules.discard("headers_module") self.config.parser.modules.discard("mod_header.c") self.config.enable_autohsts(mock.MagicMock(), ["ocspvhost.com"]) self.assertTrue(mock_enable.called) @mock.patch("certbot_apache.configurator.ApacheConfigurator.restart") def test_autohsts_deploy_already_exists(self, _restart): self.config.enable_autohsts(mock.MagicMock(), ["ocspvhost.com"]) self.assertRaises(errors.PluginEnhancementAlreadyPresent, self.config.enable_autohsts, mock.MagicMock(), ["ocspvhost.com"]) @mock.patch("certbot_apache.constants.AUTOHSTS_FREQ", 0) @mock.patch("certbot_apache.configurator.ApacheConfigurator.restart") @mock.patch("certbot_apache.configurator.ApacheConfigurator.prepare") def test_autohsts_increase(self, mock_prepare, _mock_restart): self.config._prepared = False maxage = "\"max-age={0}\"" initial_val = maxage.format(constants.AUTOHSTS_STEPS[0]) inc_val = maxage.format(constants.AUTOHSTS_STEPS[1]) self.config.enable_autohsts(mock.MagicMock(), ["ocspvhost.com"]) # Verify initial value self.assertEqual(self.get_autohsts_value(self.vh_truth[7].path), initial_val) # Increase self.config.update_autohsts(mock.MagicMock()) # Verify increased value self.assertEqual(self.get_autohsts_value(self.vh_truth[7].path), inc_val) self.assertTrue(mock_prepare.called) @mock.patch("certbot_apache.configurator.ApacheConfigurator.restart") @mock.patch("certbot_apache.configurator.ApacheConfigurator._autohsts_increase") def test_autohsts_increase_noop(self, mock_increase, _restart): maxage = "\"max-age={0}\"" initial_val = maxage.format(constants.AUTOHSTS_STEPS[0]) self.config.enable_autohsts(mock.MagicMock(), ["ocspvhost.com"]) # Verify initial value self.assertEqual(self.get_autohsts_value(self.vh_truth[7].path), initial_val) self.config.update_autohsts(mock.MagicMock()) # Freq not patched, so value shouldn't increase self.assertFalse(mock_increase.called) @mock.patch("certbot_apache.configurator.ApacheConfigurator.restart") @mock.patch("certbot_apache.constants.AUTOHSTS_FREQ", 0) def test_autohsts_increase_no_header(self, _restart): self.config.enable_autohsts(mock.MagicMock(), ["ocspvhost.com"]) # Remove the header dir_locs = self.config.parser.find_dir("Header", None, self.vh_truth[7].path) dir_loc = "/".join(dir_locs[0].split("/")[:-1]) self.config.parser.aug.remove(dir_loc) self.assertRaises(errors.PluginError, self.config.update_autohsts, mock.MagicMock()) @mock.patch("certbot_apache.constants.AUTOHSTS_FREQ", 0) @mock.patch("certbot_apache.configurator.ApacheConfigurator.restart") def test_autohsts_increase_and_make_permanent(self, _mock_restart): maxage = "\"max-age={0}\"" max_val = maxage.format(constants.AUTOHSTS_PERMANENT) mock_lineage = mock.MagicMock() mock_lineage.key_path = "/etc/apache2/ssl/key-certbot_15.pem" self.config.enable_autohsts(mock.MagicMock(), ["ocspvhost.com"]) for i in range(len(constants.AUTOHSTS_STEPS)-1): # Ensure that value is not made permanent prematurely self.config.deploy_autohsts(mock_lineage) self.assertNotEqual(self.get_autohsts_value(self.vh_truth[7].path), max_val) self.config.update_autohsts(mock.MagicMock()) # Value should match pre-permanent increment step cur_val = maxage.format(constants.AUTOHSTS_STEPS[i+1]) self.assertEqual(self.get_autohsts_value(self.vh_truth[7].path), cur_val) # Ensure that the value is raised to max self.assertEqual(self.get_autohsts_value(self.vh_truth[7].path), maxage.format(constants.AUTOHSTS_STEPS[-1])) # Make permanent self.config.deploy_autohsts(mock_lineage) self.assertEqual(self.get_autohsts_value(self.vh_truth[7].path), max_val) def test_autohsts_update_noop(self): with mock.patch("time.time") as mock_time: # Time mock is used to make sure that the execution does not # continue when no autohsts entries exist in pluginstorage self.config.update_autohsts(mock.MagicMock()) self.assertFalse(mock_time.called) def test_autohsts_make_permanent_noop(self): self.config.storage.put = mock.MagicMock() self.config.deploy_autohsts(mock.MagicMock()) # Make sure that the execution does not continue when no entries in store self.assertFalse(self.config.storage.put.called) @mock.patch("certbot_apache.display_ops.select_vhost") def test_autohsts_no_ssl_vhost(self, mock_select): mock_select.return_value = self.vh_truth[0] with mock.patch("certbot_apache.configurator.logger.warning") as mock_log: self.assertRaises(errors.PluginError, self.config.enable_autohsts, mock.MagicMock(), "invalid.example.com") self.assertTrue( "Certbot was not able to find SSL" in mock_log.call_args[0][0]) @mock.patch("certbot_apache.configurator.ApacheConfigurator.restart") @mock.patch("certbot_apache.configurator.ApacheConfigurator.add_vhost_id") def test_autohsts_dont_enhance_twice(self, mock_id, _restart): mock_id.return_value = "1234567" self.config.enable_autohsts(mock.MagicMock(), ["ocspvhost.com", "ocspvhost.com"]) self.assertEqual(mock_id.call_count, 1) def test_autohsts_remove_orphaned(self): # pylint: disable=protected-access self.config._autohsts_fetch_state() self.config._autohsts["orphan_id"] = {"laststep": 0, "timestamp": 0} self.config._autohsts_save_state() self.config.update_autohsts(mock.MagicMock()) self.assertFalse("orphan_id" in self.config._autohsts) # Make sure it's removed from the pluginstorage file as well self.config._autohsts = None self.config._autohsts_fetch_state() self.assertFalse(self.config._autohsts) def test_autohsts_make_permanent_vhost_not_found(self): # pylint: disable=protected-access self.config._autohsts_fetch_state() self.config._autohsts["orphan_id"] = {"laststep": 999, "timestamp": 0} self.config._autohsts_save_state() with mock.patch("certbot_apache.configurator.logger.warning") as mock_log: self.config.deploy_autohsts(mock.MagicMock()) self.assertTrue(mock_log.called) self.assertTrue( "VirtualHost with id orphan_id was not" in mock_log.call_args[0][0]) if __name__ == "__main__": unittest.main() # pragma: no cover