mirror of
https://github.com/certbot/certbot.git
synced 2026-06-05 14:54:24 -04:00
100% configurator coverage
This commit is contained in:
parent
aecb7b71d7
commit
647caba164
4 changed files with 317 additions and 94 deletions
|
|
@ -88,6 +88,9 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
private_ips_regex = re.compile(
|
||||
r"(^127\.0\.0\.1)|(^10\.)|(^172\.1[6-9]\.)|"
|
||||
r"(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^192\.168\.)")
|
||||
hostname_regex = re.compile(
|
||||
r"^(([a-z0-9]|[a-z0-9][a-z0-9\-]*[a-z0-9])\.)*[a-z]+$", re.IGNORECASE)
|
||||
|
||||
|
||||
@classmethod
|
||||
def add_parser_arguments(cls, add):
|
||||
|
|
@ -121,8 +124,8 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
|
||||
# Add name_server association dict
|
||||
self.assoc = dict()
|
||||
# Add number of outstanding challenges
|
||||
self._chall_out = 0
|
||||
# Outstanding challenges
|
||||
self._chall_out = set()
|
||||
|
||||
# These will be set in the prepare function
|
||||
self.parser = None
|
||||
|
|
@ -147,7 +150,10 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
|
||||
# Set Version
|
||||
if self.version is None:
|
||||
self.version = self.get_version() # pragma: no cover
|
||||
self.version = self.get_version()
|
||||
if self.version < (2, 2):
|
||||
raise errors.NotSupportedError(
|
||||
"Apache Version %s not supported.", str(self.version))
|
||||
|
||||
# Get all of the available vhosts
|
||||
self.vhosts = self.get_virtual_hosts()
|
||||
|
|
@ -208,11 +214,12 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
self.aug.set(path["chain_path"][-1], chain_path)
|
||||
|
||||
# Save notes about the transaction that took place
|
||||
self.save_notes += ("Changed vhost at %s with addresses of %s\n" %
|
||||
self.save_notes += ("Changed vhost at %s with addresses of %s\n"
|
||||
"\tSSLCertificateFile %s\n"
|
||||
"\tSSLCertificateKeyFile %s\n" %
|
||||
(vhost.filep,
|
||||
", ".join(str(addr) for addr in vhost.addrs)))
|
||||
self.save_notes += "\tSSLCertificateFile %s\n" % cert_path
|
||||
self.save_notes += "\tSSLCertificateKeyFile %s\n" % key_path
|
||||
", ".join(str(addr) for addr in vhost.addrs),
|
||||
cert_path, key_path))
|
||||
if chain_path is not None:
|
||||
self.save_notes += "\tSSLCertificateChainFile %s\n" % chain_path
|
||||
|
||||
|
|
@ -285,7 +292,8 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
points = 1
|
||||
else:
|
||||
# No points given if names can't be found.
|
||||
continue
|
||||
# This gets hit but doesn't register
|
||||
continue # pragma: no cover
|
||||
|
||||
if vhost.ssl:
|
||||
points += 2
|
||||
|
|
@ -309,19 +317,6 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
addr.get_addr() == "_default_" for addr in vh.addrs
|
||||
)]
|
||||
|
||||
def create_dn_server_assoc(self, domain, vhost):
|
||||
"""Create an association between a domain name and virtual host.
|
||||
|
||||
Helps to choose an appropriate vhost
|
||||
|
||||
:param str domain: domain name to associate
|
||||
|
||||
:param vhost: virtual host to associate with domain
|
||||
:type vhost: :class:`~letsencrypt_apache.obj.VirtualHost`
|
||||
|
||||
"""
|
||||
self.assoc[domain] = vhost
|
||||
|
||||
def get_all_names(self):
|
||||
"""Returns all names found in the Apache Configuration.
|
||||
|
||||
|
|
@ -334,10 +329,14 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
|
||||
for vhost in self.vhosts:
|
||||
all_names.update(vhost.get_names())
|
||||
|
||||
for addr in vhost.addrs:
|
||||
name = self.get_name_from_ip(addr)
|
||||
if name:
|
||||
all_names.add(name)
|
||||
if ApacheConfigurator.hostname_regex.match(addr.get_addr()):
|
||||
all_names.add(addr.get_addr())
|
||||
else:
|
||||
name = self.get_name_from_ip(addr)
|
||||
if name:
|
||||
all_names.add(name)
|
||||
|
||||
return all_names
|
||||
|
||||
|
|
@ -460,14 +459,17 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
|
||||
"""
|
||||
loc = parser.get_aug_path(self.parser.loc["name"])
|
||||
if addr.get_port == "443":
|
||||
|
||||
if addr.get_port() == "443":
|
||||
path = self.parser.add_dir_to_ifmodssl(
|
||||
loc, "NameVirtualHost", [str(addr)])
|
||||
else:
|
||||
path = self.parser.add_dir(loc, "NameVirtualHost", [str(addr)])
|
||||
|
||||
self.save_notes += "Setting %s to be NameBasedVirtualHost\n" % addr
|
||||
self.save_notes += "\tDirective added to %s\n" % path
|
||||
msg = ("Setting %s to be NameBasedVirtualHost\n"
|
||||
"\tDirective added to %s\n" % (addr, path))
|
||||
logger.debug(msg)
|
||||
self.save_notes += msg
|
||||
|
||||
def prepare_server_https(self, port):
|
||||
"""Prepare the server for HTTPS.
|
||||
|
|
@ -515,17 +517,6 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
if self.version >= (2, 4):
|
||||
return
|
||||
|
||||
# TODO: Review this 3-year old demo code
|
||||
# Check for NameVirtualHost
|
||||
# First see if any of the vhost addresses is a _default_ addr
|
||||
for addr in addrs:
|
||||
if addr.get_addr() == "_default_":
|
||||
if not self.is_name_vhost(default_addr):
|
||||
logger.debug("Setting all VirtualHosts on %s to be "
|
||||
"name based vhosts", default_addr)
|
||||
self.add_name_vhost(default_addr)
|
||||
|
||||
# No default addresses... so set each one individually
|
||||
for addr in addrs:
|
||||
if not self.is_name_vhost(addr):
|
||||
logger.debug("Setting VirtualHost at %s to be a name "
|
||||
|
|
@ -661,9 +652,11 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
need_to_save = False
|
||||
|
||||
# See if the exact address appears in any other vhost
|
||||
# Remember 1.1.1.1:* == 1.1.1.1 -> hence any()
|
||||
for addr in vhost.addrs:
|
||||
for test_vh in self.vhosts:
|
||||
if (vhost.filep != test_vh.filep and addr in test_vh.addrs and
|
||||
if (vhost.filep != test_vh.filep and
|
||||
any(test_addr == addr for test_addr in test_vh.addrs) and
|
||||
not self.is_name_vhost(addr)):
|
||||
self.add_name_vhost(addr)
|
||||
logger.info("Enabling NameVirtualHosts on %s", addr)
|
||||
|
|
@ -739,7 +732,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
"Unable to create one as intended addresses conflict; "
|
||||
"Current configuration does not support automated "
|
||||
"redirection")
|
||||
self._create_redirect_vhost(redirect_addrs)
|
||||
self._create_redirect_vhost(ssl_vhost)
|
||||
else:
|
||||
# Check if redirection already exists
|
||||
self._verify_no_redirects(general_vh)
|
||||
|
|
@ -817,6 +810,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
serveralias = ""
|
||||
servername = ""
|
||||
|
||||
|
||||
if ssl_vhost.name is not None:
|
||||
servername = "ServerName " + ssl_vhost.name
|
||||
if ssl_vhost.aliases:
|
||||
|
|
@ -833,9 +827,10 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
"ErrorLog /var/log/apache2/redirect.error.log\n"
|
||||
"LogLevel warn\n"
|
||||
"</VirtualHost>\n"
|
||||
% (" ".join(self._get_redirect_addrs(ssl_vhost)),
|
||||
servername, serveralias,
|
||||
" ".join(constants.REWRITE_HTTPS_ARGS)))
|
||||
% (
|
||||
" ".join(str(addr) for addr in self._get_redirect_addrs(ssl_vhost)),
|
||||
servername, serveralias,
|
||||
" ".join(constants.REWRITE_HTTPS_ARGS)))
|
||||
|
||||
def _write_out_redirect(self, ssl_vhost, text):
|
||||
# This is the default name
|
||||
|
|
@ -845,7 +840,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
if ssl_vhost.name is not None:
|
||||
# make sure servername doesn't exceed filename length restriction
|
||||
if len(ssl_vhost.name) < (255 - (len(redirect_filename) + 1)):
|
||||
redirect_filename = "le-redirect-%s.conf" % ssl_vhost.servername
|
||||
redirect_filename = "le-redirect-%s.conf" % ssl_vhost.name
|
||||
|
||||
redirect_filepath = os.path.join(
|
||||
self.parser.root, "sites-available", redirect_filename)
|
||||
|
|
@ -900,9 +895,9 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
for vhost in self.vhosts:
|
||||
if vhost.ssl:
|
||||
cert_path = self.parser.find_dir(
|
||||
"SSLCertificateFile", None, vhost.path)
|
||||
"SSLCertificateFile", None, vhost.path, exclude=False)
|
||||
key_path = self.parser.find_dir(
|
||||
"SSLCertificateKeyFile", None, vhost.path)
|
||||
"SSLCertificateKeyFile", None, vhost.path, exclude=False)
|
||||
|
||||
if cert_path and key_path:
|
||||
cert = os.path.abspath(self.parser.get_arg(cert_path[-1]))
|
||||
|
|
@ -940,12 +935,9 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
:param vhost: vhost to enable
|
||||
:type vhost: :class:`~letsencrypt_apache.obj.VirtualHost`
|
||||
|
||||
:returns: Success
|
||||
:rtype: bool
|
||||
|
||||
"""
|
||||
if self.is_site_enabled(vhost.filep):
|
||||
return True
|
||||
return
|
||||
|
||||
if vhost.ssl:
|
||||
# TODO: Make this based on addresses
|
||||
|
|
@ -961,8 +953,10 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
vhost.enabled = True
|
||||
logger.info("Enabling available site: %s", vhost.filep)
|
||||
self.save_notes += "Enabled site %s\n" % vhost.filep
|
||||
return True
|
||||
return False
|
||||
else:
|
||||
raise errors.MisconfigurationError(
|
||||
"Unsupported filesystem layout. "
|
||||
"sites-available/enabled expected.")
|
||||
|
||||
def enable_mod(self, mod_name):
|
||||
"""Enables module in Apache.
|
||||
|
|
@ -976,7 +970,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
if (not os.path.isdir(os.path.join(self.parser.root, "mods-available"))
|
||||
or not os.path.isdir(
|
||||
os.path.join(self.parser.root, "mods-enabled"))):
|
||||
raise errors.MisconfigurationError(
|
||||
raise errors.NotSupportedError(
|
||||
"Unsupported directory layout. You may try to enable mod %s "
|
||||
"and try again." % mod_name)
|
||||
|
||||
|
|
@ -1001,7 +995,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
elif mod_name == "rewrite":
|
||||
self._enable_mod_debian_files(["rewrite.load"], "rewrite_module")
|
||||
else:
|
||||
raise NotImplementedError
|
||||
raise errors.NotSupportedError
|
||||
|
||||
def _enable_mod_debian_files(self, filenames, mod_name):
|
||||
"""Move over all required files into mods-enabled."""
|
||||
|
|
@ -1011,7 +1005,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
# Check to see all files are available.
|
||||
for filename in filenames:
|
||||
if not os.path.isfile(os.path.join(mods_available, filename)):
|
||||
raise errors.MisconfigurationError(
|
||||
raise errors.NoInstallationError(
|
||||
"Unable to enable module. Required files missing from "
|
||||
"mods-available. %s" % str(filenames))
|
||||
|
||||
|
|
@ -1029,6 +1023,8 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
def restart(self):
|
||||
"""Restarts apache server.
|
||||
|
||||
.. todo:: This function will be converted to using reload
|
||||
|
||||
:returns: Success
|
||||
:rtype: bool
|
||||
|
||||
|
|
@ -1053,28 +1049,11 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
raise errors.PluginError("Unable to run apache2ctl")
|
||||
|
||||
if proc.returncode != 0:
|
||||
print proc.returncode
|
||||
# Enter recovery routine...
|
||||
logger.error("Apache Configtest failed\n%s\n%s", stdout, stderr)
|
||||
raise errors.MisconfigurationError(
|
||||
"Apache Configtest failure:\n%s\n%s" % (stdout, stderr))
|
||||
|
||||
def verify_setup(self):
|
||||
"""Verify the setup to ensure safe operating environment.
|
||||
|
||||
Make sure that files/directories are setup with appropriate permissions
|
||||
Aim for defensive coding... make sure all input files
|
||||
have permissions of root
|
||||
|
||||
"""
|
||||
uid = os.geteuid()
|
||||
le_util.make_or_verify_dir(
|
||||
self.config.config_dir, core_constants.CONFIG_DIRS_MODE, uid)
|
||||
le_util.make_or_verify_dir(
|
||||
self.config.work_dir, core_constants.CONFIG_DIRS_MODE, uid)
|
||||
le_util.make_or_verify_dir(
|
||||
self.config.backup_dir, core_constants.CONFIG_DIRS_MODE, uid)
|
||||
|
||||
def get_version(self):
|
||||
"""Return version of Apache Server.
|
||||
|
||||
|
|
@ -1129,7 +1108,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
outstanding challenges will have to be designed better.
|
||||
|
||||
"""
|
||||
self._chall_out += len(achalls)
|
||||
self._chall_out.update(achalls)
|
||||
responses = [None] * len(achalls)
|
||||
apache_dvsni = dvsni.ApacheDvsni(self)
|
||||
|
||||
|
|
@ -1157,10 +1136,10 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
|
||||
def cleanup(self, achalls):
|
||||
"""Revert all challenges."""
|
||||
self._chall_out -= len(achalls)
|
||||
self._chall_out.difference_update(achalls)
|
||||
|
||||
# If all of the challenges have been finished, clean up everything
|
||||
if self._chall_out <= 0:
|
||||
if not self._chall_out:
|
||||
self.revert_challenge_config()
|
||||
self.restart()
|
||||
|
||||
|
|
@ -1192,7 +1171,7 @@ def apache_restart(apache_init_script):
|
|||
except (OSError, ValueError):
|
||||
logger.fatal(
|
||||
"Unable to restart the Apache process with %s", apache_init_script)
|
||||
raise errors.PluginError(
|
||||
raise errors.MisconfigurationError(
|
||||
"Unable to restart Apache process with %s" % apache_init_script)
|
||||
|
||||
stdout, stderr = proc.communicate()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
"""Test for letsencrypt_apache.configurator."""
|
||||
import os
|
||||
import shutil
|
||||
import socket
|
||||
import unittest
|
||||
|
||||
import mock
|
||||
|
|
@ -36,6 +37,15 @@ class TwoVhost80Test(util.ApacheTest):
|
|||
shutil.rmtree(self.config_dir)
|
||||
shutil.rmtree(self.work_dir)
|
||||
|
||||
@mock.patch("letsencrypt_apache.parser.ApacheParser")
|
||||
def test_prepare_version(self, mock_parser):
|
||||
self.config.version = None
|
||||
self.config.config_test = mock.Mock()
|
||||
self.config.get_version = mock.Mock(return_value=(1, 1))
|
||||
|
||||
self.assertRaises(
|
||||
errors.NotSupportedError, self.config.prepare)
|
||||
|
||||
def test_add_parser_arguments(self):
|
||||
from letsencrypt_apache.configurator import ApacheConfigurator
|
||||
# Weak test..
|
||||
|
|
@ -46,6 +56,31 @@ class TwoVhost80Test(util.ApacheTest):
|
|||
self.assertEqual(names, set(
|
||||
["letsencrypt.demo", "encryption-example.demo", "ip-172-30-0-17"]))
|
||||
|
||||
@mock.patch("letsencrypt_apache.configurator.socket.gethostbyaddr")
|
||||
def test_get_all_names_addrs(self, mock_gethost):
|
||||
mock_gethost.side_effect = [("google.com","",""), socket.error]
|
||||
vh = obj.VirtualHost(
|
||||
"fp", "ap",
|
||||
set([obj.Addr(("8.8.8.8", "443")),
|
||||
obj.Addr(("zombo.com",)),
|
||||
obj.Addr(("192.168.1.2"))]),
|
||||
True, False)
|
||||
self.config.vhosts.append(vh)
|
||||
|
||||
names = self.config.get_all_names()
|
||||
self.assertEqual(len(names), 5)
|
||||
self.assertTrue("zombo.com" in names)
|
||||
self.assertTrue("google.com" in names)
|
||||
self.assertTrue("letsencrypt.demo" in names)
|
||||
|
||||
def test_add_servernames_alias(self):
|
||||
self.config.parser.add_dir(
|
||||
self.vh_truth[2].path, "ServerAlias", ["*.le.co"])
|
||||
self.config._add_servernames(self.vh_truth[2]) # pylint: disable=protected-access
|
||||
|
||||
self.assertEqual(
|
||||
self.vh_truth[2].get_names(), set(["*.le.co", "ip-172-30-0-17"]))
|
||||
|
||||
def test_get_virtual_hosts(self):
|
||||
"""Make sure all vhosts are being properly found.
|
||||
|
||||
|
|
@ -88,6 +123,13 @@ class TwoVhost80Test(util.ApacheTest):
|
|||
self.assertTrue(
|
||||
self.config._find_best_vhost("does-not-exist.com") is None)
|
||||
|
||||
def test_find_best_vhost_variety(self):
|
||||
ssl_vh = obj.VirtualHost(
|
||||
"fp", "ap", set([obj.Addr(("*", "443")), obj.Addr(("zombo.com",))]),
|
||||
True, False)
|
||||
self.config.vhosts.append(ssl_vh)
|
||||
self.assertEqual(self.config._find_best_vhost("zombo.com"), ssl_vh)
|
||||
|
||||
def test_find_best_vhost_default(self):
|
||||
# Assume only the two default vhosts.
|
||||
self.config.vhosts = [vh for vh in self.config.vhosts
|
||||
|
|
@ -129,6 +171,27 @@ class TwoVhost80Test(util.ApacheTest):
|
|||
self.assertTrue("ssl_module" in self.config.parser.modules)
|
||||
self.assertTrue("mod_ssl.c" in self.config.parser.modules)
|
||||
|
||||
def test_enable_mod_unsupported_dirs(self):
|
||||
os.removedirs(os.path.join(self.config.parser.root, "mods-enabled"))
|
||||
self.assertRaises(
|
||||
errors.NotSupportedError, self.config.enable_mod, "ssl")
|
||||
|
||||
def test_enable_mod_unsupported_mod(self):
|
||||
self.assertRaises(
|
||||
errors.NotSupportedError, self.config.enable_mod, "unknown")
|
||||
|
||||
def test_enable_mod_not_installed(self):
|
||||
os.remove(os.path.join(
|
||||
self.config.parser.root, "mods-available", "ssl.load"))
|
||||
self.assertRaises(
|
||||
errors.NoInstallationError, self.config.enable_mod, "ssl")
|
||||
|
||||
def test_enable_mod_files_already_exist(self):
|
||||
path = os.path.join(self.config.parser.root, "mods-enabled", "ssl.load")
|
||||
open(path, "w").close()
|
||||
self.assertRaises(
|
||||
errors.PluginError, self.config.enable_mod, "ssl")
|
||||
|
||||
@mock.patch("letsencrypt_apache.parser.subprocess.Popen")
|
||||
def test_enable_site(self, mock_popen):
|
||||
mock_popen().returncode = 0
|
||||
|
|
@ -139,6 +202,15 @@ class TwoVhost80Test(util.ApacheTest):
|
|||
self.config.enable_site(self.vh_truth[1])
|
||||
self.assertTrue(self.vh_truth[1].enabled)
|
||||
|
||||
# Go again to make sure nothing fails
|
||||
self.config.enable_site(self.vh_truth[1])
|
||||
|
||||
def test_enable_site_failure(self):
|
||||
self.assertRaises(
|
||||
errors.MisconfigurationError,
|
||||
self.config.enable_site,
|
||||
obj.VirtualHost("asdf", "afsaf", set(), False, False))
|
||||
|
||||
@mock.patch("letsencrypt_apache.parser.subprocess.Popen")
|
||||
def test_deploy_cert(self, mock_popen):
|
||||
mock_popen().returncode = 0
|
||||
|
|
@ -204,8 +276,11 @@ class TwoVhost80Test(util.ApacheTest):
|
|||
|
||||
def test_add_name_vhost(self):
|
||||
self.config.add_name_vhost(obj.Addr.fromstring("*:443"))
|
||||
self.config.add_name_vhost(obj.Addr.fromstring("*:80"))
|
||||
self.assertTrue(self.config.parser.find_dir(
|
||||
"NameVirtualHost", "*:443"))
|
||||
"NameVirtualHost", "*:443", exclude=False))
|
||||
self.assertTrue(self.config.parser.find_dir(
|
||||
"NameVirtualHost", "*:80"))
|
||||
|
||||
def test_prepare_server_https(self):
|
||||
self.config.parser.modules.add("ssl_module")
|
||||
|
|
@ -218,7 +293,8 @@ class TwoVhost80Test(util.ApacheTest):
|
|||
self.config.parser.add_dir_to_ifmodssl = mock_add_dir
|
||||
|
||||
self.config.prepare_server_https("443")
|
||||
self.assertTrue(mock_add_dir.called)
|
||||
self.config.prepare_server_https("8080")
|
||||
self.assertEqual(mock_add_dir.call_count, 2)
|
||||
|
||||
def test_make_vhost_ssl(self):
|
||||
ssl_vhost = self.config.make_vhost_ssl(self.vh_truth[0])
|
||||
|
|
@ -246,26 +322,37 @@ class TwoVhost80Test(util.ApacheTest):
|
|||
|
||||
self.assertEqual(len(self.config.vhosts), 5)
|
||||
|
||||
def test_make_vhost_ssl_extra_vhs(self):
|
||||
self.config.aug.match = mock.Mock(return_value=["p1", "p2"])
|
||||
self.assertRaises(
|
||||
errors.PluginError, self.config.make_vhost_ssl, self.vh_truth[0])
|
||||
|
||||
def test_make_vhost_ssl_bad_write(self):
|
||||
mock_open = mock.mock_open()
|
||||
# This calls open
|
||||
self.config.reverter.register_file_creation = mock.Mock()
|
||||
mock_open.side_effect = IOError
|
||||
with mock.patch("__builtin__.open", mock_open):
|
||||
self.assertRaises(
|
||||
errors.PluginError,
|
||||
self.config.make_vhost_ssl, self.vh_truth[0])
|
||||
|
||||
def test_get_ssl_vhost_path(self):
|
||||
self.assertTrue(
|
||||
self.config._get_ssl_vhost_path("example_path").endswith(".conf"))
|
||||
|
||||
def test_add_name_vhost_if_necessary(self):
|
||||
self.config.save = mock.Mock()
|
||||
self.config.version = (2, 2)
|
||||
self.config._add_name_vhost_if_necessary(self.vh_truth[0])
|
||||
self.assertTrue(self.config.save.called)
|
||||
|
||||
@mock.patch("letsencrypt_apache.configurator.dvsni.ApacheDvsni.perform")
|
||||
@mock.patch("letsencrypt_apache.configurator.ApacheConfigurator.restart")
|
||||
def test_perform(self, mock_restart, mock_dvsni_perform):
|
||||
# Only tests functionality specific to configurator.perform
|
||||
# Note: As more challenges are offered this will have to be expanded
|
||||
auth_key = le_util.Key(self.rsa256_file, self.rsa256_pem)
|
||||
achall1 = achallenges.DVSNI(
|
||||
challb=acme_util.chall_to_challb(
|
||||
challenges.DVSNI(
|
||||
r="jIq_Xy1mXGN37tb4L6Xj_es58fW571ZNyXekdZzhh7Q",
|
||||
nonce="37bc5eb75d3e00a19b4f6355845e5a18"),
|
||||
"pending"),
|
||||
domain="encryption-example.demo", key=auth_key)
|
||||
achall2 = achallenges.DVSNI(
|
||||
challb=acme_util.chall_to_challb(
|
||||
challenges.DVSNI(
|
||||
r="uqnaPzxtrndteOqtrXb0Asl5gOJfWAnnx6QJyvcmlDU",
|
||||
nonce="59ed014cac95f77057b1d7a1b2c596ba"),
|
||||
"pending"),
|
||||
domain="letsencrypt.demo", key=auth_key)
|
||||
auth_key, achall1, achall2 = self.get_achalls()
|
||||
|
||||
dvsni_ret_val = [
|
||||
challenges.DVSNIResponse(s="randomS1"),
|
||||
|
|
@ -280,6 +367,31 @@ class TwoVhost80Test(util.ApacheTest):
|
|||
|
||||
self.assertEqual(mock_restart.call_count, 1)
|
||||
|
||||
@mock.patch("letsencrypt_apache.configurator.ApacheConfigurator.restart")
|
||||
def test_cleanup(self, mock_restart):
|
||||
auth_key, achall1, achall2 = self.get_achalls()
|
||||
|
||||
self.config._chall_out.add(achall1)
|
||||
self.config._chall_out.add(achall2)
|
||||
|
||||
self.config.cleanup([achall1])
|
||||
self.assertFalse(mock_restart.called)
|
||||
|
||||
self.config.cleanup([achall2])
|
||||
self.assertTrue(mock_restart.called)
|
||||
|
||||
@mock.patch("letsencrypt_apache.configurator.ApacheConfigurator.restart")
|
||||
def test_cleanup_no_errors(self, mock_restart):
|
||||
auth_key, achall1, achall2 = self.get_achalls()
|
||||
|
||||
self.config._chall_out.add(achall1)
|
||||
|
||||
self.config.cleanup([achall2])
|
||||
self.assertFalse(mock_restart.called)
|
||||
|
||||
self.config.cleanup([achall1, achall2])
|
||||
self.assertTrue(mock_restart.called)
|
||||
|
||||
@mock.patch("letsencrypt_apache.configurator.subprocess.Popen")
|
||||
def test_get_version(self, mock_popen):
|
||||
mock_popen().communicate.return_value = (
|
||||
|
|
@ -301,7 +413,79 @@ class TwoVhost80Test(util.ApacheTest):
|
|||
mock_popen.side_effect = OSError("Can't find program")
|
||||
self.assertRaises(errors.PluginError, self.config.get_version)
|
||||
|
||||
@mock.patch("letsencrypt_apache.configurator.subprocess.Popen")
|
||||
def test_restart(self, mock_popen):
|
||||
"""These will be changed soon enough with reload."""
|
||||
mock_popen().returncode = 0
|
||||
mock_popen().communicate.return_value = ("", "")
|
||||
|
||||
self.config.restart()
|
||||
|
||||
@mock.patch("letsencrypt_apache.configurator.subprocess.Popen")
|
||||
def test_restart_bad_process(self, mock_popen):
|
||||
mock_popen.side_effect = OSError
|
||||
|
||||
self.assertRaises(errors.MisconfigurationError, self.config.restart)
|
||||
|
||||
@mock.patch("letsencrypt_apache.configurator.subprocess.Popen")
|
||||
def test_restart_failure(self, mock_popen):
|
||||
mock_popen().communicate.return_value = ("", "")
|
||||
mock_popen.returncode=1
|
||||
|
||||
self.assertRaises(errors.MisconfigurationError, self.config.restart)
|
||||
|
||||
@mock.patch("letsencrypt_apache.configurator.subprocess.Popen")
|
||||
def test_config_test(self, mock_popen):
|
||||
mock_popen().communicate.return_value = ("a", "b")
|
||||
mock_popen().returncode = 0
|
||||
|
||||
self.config.config_test()
|
||||
|
||||
@mock.patch("letsencrypt_apache.configurator.subprocess.Popen")
|
||||
def test_config_test_bad_process(self, mock_popen):
|
||||
mock_popen.side_effect = ValueError
|
||||
|
||||
self.assertRaises(errors.PluginError, self.config.config_test)
|
||||
|
||||
@mock.patch("letsencrypt_apache.configurator.subprocess.Popen")
|
||||
def test_config_test_failure(self, mock_popen):
|
||||
mock_popen().communicate.return_value = ("", "")
|
||||
mock_popen().returncode = -1
|
||||
|
||||
self.assertRaises(errors.MisconfigurationError, self.config.config_test)
|
||||
|
||||
|
||||
def test_get_all_certs_keys(self):
|
||||
c_k = self.config.get_all_certs_keys()
|
||||
|
||||
self.assertEqual(len(c_k), 1)
|
||||
cert, key, path = next(iter(c_k))
|
||||
self.assertTrue("cert" in cert)
|
||||
self.assertTrue("key" in key)
|
||||
self.assertTrue("default-ssl.conf" in path)
|
||||
|
||||
def test_get_all_certs_keys_malformed_conf(self):
|
||||
self.config.parser.find_dir = mock.Mock(side_effect=[["path"], []])
|
||||
c_k = self.config.get_all_certs_keys()
|
||||
|
||||
self.assertFalse(c_k)
|
||||
|
||||
def test_more_info(self):
|
||||
self.assertTrue(self.config.more_info())
|
||||
|
||||
def test_get_chall_pref(self):
|
||||
self.assertTrue(isinstance(self.config.get_chall_pref(""), list))
|
||||
|
||||
def test_temp_install(self):
|
||||
from letsencrypt_apache.configurator import temp_install
|
||||
path = os.path.join(self.work_dir, "test_it")
|
||||
temp_install(path)
|
||||
self.assertTrue(os.path.isfile(path))
|
||||
|
||||
# TEST ENHANCEMENTS
|
||||
def test_supported_enhancements(self):
|
||||
self.assertTrue(isinstance(self.config.supported_enhancements(), list))
|
||||
|
||||
def test_enhance_unknown_enhancement(self):
|
||||
self.assertRaises(
|
||||
errors.PluginError,
|
||||
|
|
@ -329,6 +513,17 @@ class TwoVhost80Test(util.ApacheTest):
|
|||
|
||||
self.assertTrue("rewrite_module" in self.config.parser.modules)
|
||||
|
||||
def test_redirect_with_conflict(self):
|
||||
self.config.parser.modules.add("rewrite_module")
|
||||
ssl_vh = obj.VirtualHost(
|
||||
"fp", "ap", set([obj.Addr(("*", "443")), obj.Addr(("zombo.com",))]),
|
||||
True, False)
|
||||
# No names ^ this guy should conflict.
|
||||
|
||||
# pylint: disable=protected-access
|
||||
self.assertRaises(
|
||||
errors.PluginError, self.config._enable_redirect, ssl_vh, "")
|
||||
|
||||
def test_redirect_twice(self):
|
||||
# Skip the enable mod
|
||||
self.config.parser.modules.add("rewrite_module")
|
||||
|
|
@ -346,6 +541,15 @@ class TwoVhost80Test(util.ApacheTest):
|
|||
self.assertRaises(
|
||||
errors.PluginError,
|
||||
self.config.enhance, "letsencrypt.demo", "redirect")
|
||||
def test_unknown_rewrite2(self):
|
||||
# Skip the enable mod
|
||||
self.config.parser.modules.add("rewrite_module")
|
||||
self.config.parser.add_dir(
|
||||
self.vh_truth[3].path, "RewriteRule", ["Unknown", "2", "3"])
|
||||
self.config.save()
|
||||
self.assertRaises(
|
||||
errors.PluginError,
|
||||
self.config.enhance, "letsencrypt.demo", "redirect")
|
||||
|
||||
def test_unknown_redirect(self):
|
||||
# Skip the enable mod
|
||||
|
|
@ -357,6 +561,43 @@ class TwoVhost80Test(util.ApacheTest):
|
|||
errors.PluginError,
|
||||
self.config.enhance, "letsencrypt.demo", "redirect")
|
||||
|
||||
def test_create_own_redirect(self):
|
||||
self.config.parser.modules.add("rewrite_module")
|
||||
# For full testing... give names...
|
||||
self.vh_truth[1].name = "default.com"
|
||||
self.vh_truth[1].aliases = set(["yes.default.com"])
|
||||
|
||||
self.config._enable_redirect(self.vh_truth[1], "") # pylint: disable=protected-access
|
||||
self.assertEqual(len(self.config.vhosts), 5)
|
||||
|
||||
def get_achalls(self):
|
||||
auth_key = le_util.Key(self.rsa256_file, self.rsa256_pem)
|
||||
achall1 = achallenges.DVSNI(
|
||||
challb=acme_util.chall_to_challb(
|
||||
challenges.DVSNI(
|
||||
r="jIq_Xy1mXGN37tb4L6Xj_es58fW571ZNyXekdZzhh7Q",
|
||||
nonce="37bc5eb75d3e00a19b4f6355845e5a18"),
|
||||
"pending"),
|
||||
domain="encryption-example.demo", key=auth_key)
|
||||
achall2 = achallenges.DVSNI(
|
||||
challb=acme_util.chall_to_challb(
|
||||
challenges.DVSNI(
|
||||
r="uqnaPzxtrndteOqtrXb0Asl5gOJfWAnnx6QJyvcmlDU",
|
||||
nonce="59ed014cac95f77057b1d7a1b2c596ba"),
|
||||
"pending"),
|
||||
domain="letsencrypt.demo", key=auth_key)
|
||||
|
||||
return auth_key, achall1, achall2
|
||||
|
||||
def test_make_addrs_sni_ready(self):
|
||||
self.config.version = (2, 2)
|
||||
self.config.make_addrs_sni_ready(
|
||||
set([obj.Addr.fromstring("*:443"), obj.Addr.fromstring("*:80")]))
|
||||
self.assertTrue(self.config.parser.find_dir(
|
||||
"NameVirtualHost", "*:80", exclude=False))
|
||||
self.assertTrue(self.config.parser.find_dir(
|
||||
"NameVirtualHost", "*:443", exclude=False))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main() # pragma: no cover
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ def run(args, config, plugins):
|
|||
authenticator = display_ops.pick_authenticator(
|
||||
config, args.authenticator, plugins)
|
||||
else:
|
||||
# TODO: this assume that user doesn't want to pick authenticator
|
||||
# TODO: this assumes that user doesn't want to pick authenticator
|
||||
# and installer separately...
|
||||
authenticator = installer = display_ops.pick_configurator(
|
||||
config, args.configurator, plugins)
|
||||
|
|
|
|||
|
|
@ -65,6 +65,9 @@ class NoInstallationError(PluginError):
|
|||
class MisconfigurationError(PluginError):
|
||||
"""Let's Encrypt Misconfiguration error."""
|
||||
|
||||
class NotSupportedError(PluginError):
|
||||
"""Let's Encrypt Plugin function not supported error."""
|
||||
|
||||
|
||||
class RevokerError(Error):
|
||||
"""Let's Encrypt Revoker error."""
|
||||
|
|
|
|||
Loading…
Reference in a new issue