mirror of
https://github.com/certbot/certbot.git
synced 2026-01-21 19:01:07 +03:00
Fix test cases; along the way, have --csr save fullchain.pem
This commit is contained in:
@@ -267,21 +267,29 @@ def _treat_as_renewal(config, domains):
|
||||
return None
|
||||
|
||||
|
||||
def _report_new_cert(lineage):
|
||||
def _report_new_cert(cert_path, fullchain_path):
|
||||
"""
|
||||
Reports the creation of a new certificate to the user.
|
||||
:param RenewableCert lineage: the lineage of the new cert
|
||||
:param string cert_path: path to cert
|
||||
:param string fullchain_path: path to full chain
|
||||
"""
|
||||
expiry = crypto_util.notAfter(lineage.cert).date()
|
||||
expiry = crypto_util.notAfter(cert_path).date()
|
||||
reporter_util = zope.component.getUtility(interfaces.IReporter)
|
||||
# Tell the user about fullchain.pem because that's what modern webservers
|
||||
# (Nginx and Apache2.4) will want.
|
||||
if fullchain_path:
|
||||
# Print the path to fullchain.pem because that's what modern webservers
|
||||
# (Nginx and Apache2.4) will want.
|
||||
and_chain = "and chain have"
|
||||
path = fullchain_path
|
||||
else:
|
||||
# Unless we're in .csr mode and there really isn't one
|
||||
and_chain = "has "
|
||||
path = cert_path
|
||||
# XXX Perhaps one day we could detect the presence of known old webservers
|
||||
# and say something more informative here.
|
||||
msg = ("Congratulations! Your certificate and chain have been saved at {0}."
|
||||
" Your cert will expire on {1}. To obtain a new version of the "
|
||||
msg = ("Congratulations! Your certificate {0} been saved at {1}."
|
||||
" Your cert will expire on {2}. To obtain a new version of the "
|
||||
"certificate in the future, simply run Let's Encrypt again."
|
||||
.format(lineage.fullchain, expiry))
|
||||
.format(and_chain, path, expiry))
|
||||
reporter_util.add_message(msg, reporter_util.MEDIUM_PRIORITY)
|
||||
|
||||
|
||||
@@ -310,7 +318,7 @@ def _auth_from_domains(le_client, config, domains, plugins):
|
||||
if not lineage:
|
||||
raise Error("Certificate could not be obtained")
|
||||
|
||||
_report_new_cert(lineage)
|
||||
_report_new_cert(lineage.cert, lineage.fullchain)
|
||||
|
||||
return lineage
|
||||
|
||||
@@ -461,9 +469,9 @@ def auth(args, config, plugins):
|
||||
if args.csr is not None:
|
||||
certr, chain = le_client.obtain_certificate_from_csr(le_util.CSR(
|
||||
file=args.csr[0], data=args.csr[1], form="der"))
|
||||
cert_path, _ = le_client.save_certificate(
|
||||
certr, chain, args.cert_path, args.chain_path)
|
||||
_report_new_cert(cert_path)
|
||||
cert_path, _, cert_fullchain = le_client.save_certificate(
|
||||
certr, chain, args.cert_path, args.chain_path, args.fullchain_path)
|
||||
_report_new_cert(cert_path, cert_fullchain)
|
||||
else:
|
||||
domains = _find_domains(args, installer)
|
||||
_auth_from_domains(le_client, config, domains, plugins)
|
||||
|
||||
@@ -258,7 +258,7 @@ class Client(object):
|
||||
params, config, cli_config)
|
||||
return lineage
|
||||
|
||||
def save_certificate(self, certr, chain_cert, cert_path, chain_path):
|
||||
def save_certificate(self, certr, chain_cert, cert_path, chain_path, fullchain_path):
|
||||
# pylint: disable=no-self-use
|
||||
"""Saves the certificate received from the ACME server.
|
||||
|
||||
@@ -268,20 +268,22 @@ class Client(object):
|
||||
:param list chain_cert:
|
||||
:param str cert_path: Candidate path to a certificate.
|
||||
:param str chain_path: Candidate path to a certificate chain.
|
||||
:param str fullchain_path: Candidate path to a full cert chain.
|
||||
|
||||
:returns: cert_path, chain_path (absolute paths to the actual files)
|
||||
:returns: cert_path, chain_path, fullchain_path (absolute paths to the actual files)
|
||||
:rtype: `tuple` of `str`
|
||||
|
||||
:raises IOError: If unable to find room to write the cert files
|
||||
|
||||
"""
|
||||
for path in cert_path, chain_path:
|
||||
for path in cert_path, chain_path, fullchain_path:
|
||||
le_util.make_or_verify_dir(
|
||||
os.path.dirname(path), 0o755, os.geteuid(),
|
||||
self.config.strict_permissions)
|
||||
|
||||
# try finally close
|
||||
cert_chain_abspath = None
|
||||
fullchain_abspath = None
|
||||
cert_file, act_cert_path = le_util.unique_file(cert_path, 0o644)
|
||||
# TODO: Except
|
||||
cert_pem = OpenSSL.crypto.dump_certificate(
|
||||
@@ -294,8 +296,7 @@ class Client(object):
|
||||
act_cert_path)
|
||||
|
||||
if chain_cert:
|
||||
chain_file, act_chain_path = le_util.unique_file(
|
||||
chain_path, 0o644)
|
||||
chain_file, act_chain_path = le_util.unique_file(chain_path, 0o644)
|
||||
# TODO: Except
|
||||
chain_pem = crypto_util.dump_pyopenssl_chain(chain_cert)
|
||||
try:
|
||||
@@ -308,7 +309,17 @@ class Client(object):
|
||||
# This expects a valid chain file
|
||||
cert_chain_abspath = os.path.abspath(act_chain_path)
|
||||
|
||||
return os.path.abspath(act_cert_path), cert_chain_abspath
|
||||
# fullchain is cert + chain
|
||||
fullchain_file, act_fullchain_path = le_util.unique_file(
|
||||
fullchain_path, 0o644)
|
||||
try:
|
||||
fullchain_file.write(cert_pem + chain_pem)
|
||||
finally:
|
||||
fullchain_file.close()
|
||||
logger.info("Cert chain written to %s", act_fullchain_path)
|
||||
fullchain_abspath = os.path.abspath(act_fullchain_path)
|
||||
|
||||
return os.path.abspath(act_cert_path), cert_chain_abspath, fullchain_abspath
|
||||
|
||||
def deploy_certificate(self, domains, privkey_path,
|
||||
cert_path, chain_path, fullchain_path):
|
||||
|
||||
@@ -149,7 +149,7 @@ class CLITest(unittest.TestCase):
|
||||
date = '1970-01-01'
|
||||
mock_notAfter().date.return_value = date
|
||||
|
||||
mock_lineage = mock.MagicMock(cert=cert_path)
|
||||
mock_lineage = mock.MagicMock(cert=cert_path, fullchain=cert_path)
|
||||
mock_client = mock.MagicMock()
|
||||
mock_client.obtain_and_enroll_certificate.return_value = mock_lineage
|
||||
self._auth_new_request_common(mock_client)
|
||||
@@ -177,9 +177,10 @@ class CLITest(unittest.TestCase):
|
||||
@mock.patch('letsencrypt.cli._treat_as_renewal')
|
||||
@mock.patch('letsencrypt.cli._init_le_client')
|
||||
def test_auth_renewal(self, mock_init, mock_renewal, mock_get_utility):
|
||||
cert_path = '/etc/letsencrypt/live/foo.bar'
|
||||
cert_path = '/etc/letsencrypt/live/foo.bar/cert.pem'
|
||||
chain_path = '/etc/letsencrypt/live/foo.bar/fullchain.pem'
|
||||
|
||||
mock_lineage = mock.MagicMock(cert=cert_path)
|
||||
mock_lineage = mock.MagicMock(cert=cert_path,fullchain=chain_path)
|
||||
mock_cert = mock.MagicMock(body='body')
|
||||
mock_key = mock.MagicMock(pem='pem_key')
|
||||
mock_renewal.return_value = mock_lineage
|
||||
@@ -195,7 +196,7 @@ class CLITest(unittest.TestCase):
|
||||
mock_lineage.update_all_links_to.assert_called_once_with(
|
||||
mock_lineage.latest_common_version())
|
||||
self.assertTrue(
|
||||
cert_path in mock_get_utility().add_message.call_args[0][0])
|
||||
chain_path in mock_get_utility().add_message.call_args[0][0])
|
||||
|
||||
@mock.patch('letsencrypt.crypto_util.notAfter')
|
||||
@mock.patch('letsencrypt.cli.display_ops.pick_installer')
|
||||
@@ -203,23 +204,24 @@ class CLITest(unittest.TestCase):
|
||||
@mock.patch('letsencrypt.cli._init_le_client')
|
||||
def test_auth_csr(self, mock_init, mock_get_utility,
|
||||
mock_pick_installer, mock_notAfter):
|
||||
cert_path = '/etc/letsencrypt/live/foo.bar'
|
||||
cert_path = '/etc/letsencrypt/live/blahcert.pem'
|
||||
date = '1970-01-01'
|
||||
mock_notAfter().date.return_value = date
|
||||
|
||||
mock_client = mock.MagicMock()
|
||||
mock_client.obtain_certificate_from_csr.return_value = ('certr',
|
||||
'chain')
|
||||
mock_client.save_certificate.return_value = cert_path, None
|
||||
mock_client.save_certificate.return_value = cert_path, None, None
|
||||
mock_init.return_value = mock_client
|
||||
|
||||
installer = 'installer'
|
||||
self._call(
|
||||
['-a', 'standalone', '-i', installer, 'auth', '--csr', CSR,
|
||||
'--cert-path', cert_path, '--chain-path', '/'])
|
||||
'--cert-path', cert_path, '--fullchain-path', '/',
|
||||
'--chain-path', '/'])
|
||||
self.assertEqual(mock_pick_installer.call_args[0][1], installer)
|
||||
mock_client.save_certificate.assert_called_once_with(
|
||||
'certr', 'chain', cert_path, '/')
|
||||
'certr', 'chain', cert_path, '/', '/')
|
||||
self.assertTrue(
|
||||
cert_path in mock_get_utility().add_message.call_args[0][0])
|
||||
self.assertTrue(
|
||||
|
||||
@@ -124,14 +124,18 @@ class ClientTest(unittest.TestCase):
|
||||
cert2 = test_util.load_cert(certs[2])
|
||||
candidate_cert_path = os.path.join(tmp_path, "certs", "cert.pem")
|
||||
candidate_chain_path = os.path.join(tmp_path, "chains", "chain.pem")
|
||||
candidate_fullchain_path = os.path.join(tmp_path, "chains", "fullchain.pem")
|
||||
|
||||
cert_path, chain_path = self.client.save_certificate(
|
||||
certr, [cert1, cert2], candidate_cert_path, candidate_chain_path)
|
||||
cert_path, chain_path, fullchain_path = self.client.save_certificate(
|
||||
certr, [cert1, cert2], candidate_cert_path, candidate_chain_path,
|
||||
candidate_fullchain_path)
|
||||
|
||||
self.assertEqual(os.path.dirname(cert_path),
|
||||
os.path.dirname(candidate_cert_path))
|
||||
self.assertEqual(os.path.dirname(chain_path),
|
||||
os.path.dirname(candidate_chain_path))
|
||||
self.assertEqual(os.path.dirname(fullchain_path),
|
||||
os.path.dirname(candidate_fullchain_path))
|
||||
|
||||
with open(cert_path, "r") as cert_file:
|
||||
cert_contents = cert_file.read()
|
||||
|
||||
Reference in New Issue
Block a user