def setUp(self): from letsencrypt.client.revoker import Revoker super(RevokerTest, self).setUp() with open(self.key_path) as key_file: self.key = le_util.Key(self.key_path, key_file.read()) self._store_certs() self.revoker = Revoker( mock.MagicMock(spec=configurator.ApacheConfigurator), self.mock_config)
def test_store_one_mixed(self): from letsencrypt.client.revoker import Revoker self._write_rows( [["5", "blank", "blank"], ["18", "dc", "dc"], ["21", "b", "b"]]) self._call(self.paths[0], self.key_path) self.assertEqual( self._get_rows()[3], ["22", self.paths[0], self.key_path]) # pylint: disable=protected-access self.assertTrue(os.path.isfile( Revoker._get_backup(self.backup_dir, 22, self.paths[0]))) self.assertTrue(os.path.isfile( Revoker._get_backup(self.backup_dir, 22, self.key_path)))
def test_store_one_mixed(self): from letsencrypt.client.revoker import Revoker self._write_rows([["5", "blank", "blank"], ["18", "dc", "dc"], ["21", "b", "b"]]) self._call(self.paths[0], self.key_path) self.assertEqual(self._get_rows()[3], ["22", self.paths[0], self.key_path]) # pylint: disable=protected-access self.assertTrue( os.path.isfile( Revoker._get_backup(self.backup_dir, 22, self.paths[0]))) self.assertTrue( os.path.isfile( Revoker._get_backup(self.backup_dir, 22, self.key_path)))
def test_store_two(self): from letsencrypt.client.revoker import Revoker self._call(self.paths[0], self.key_path) self._call(self.paths[1], self.key_path) self.assertTrue(os.path.isfile(self.list_path)) rows = self._get_rows() for i, row in enumerate(rows): # pylint: disable=protected-access self.assertTrue(os.path.isfile( Revoker._get_backup(self.backup_dir, i, self.paths[i]))) self.assertTrue(os.path.isfile( Revoker._get_backup(self.backup_dir, i, self.key_path))) self.assertEqual([str(i), self.paths[i], self.key_path], row) self.assertEqual(len(rows), 2)
def test_store_two(self): from letsencrypt.client.revoker import Revoker self._call(self.paths[0], self.key_path) self._call(self.paths[1], self.key_path) self.assertTrue(os.path.isfile(self.list_path)) rows = self._get_rows() for i, row in enumerate(rows): # pylint: disable=protected-access self.assertTrue( os.path.isfile( Revoker._get_backup(self.backup_dir, i, self.paths[i]))) self.assertTrue( os.path.isfile( Revoker._get_backup(self.backup_dir, i, self.key_path))) self.assertEqual([str(i), self.paths[i], self.key_path], row) self.assertEqual(len(rows), 2)
def _store_certs(self): # pylint: disable=protected-access from letsencrypt.client.revoker import Revoker Revoker.store_cert_key(self.paths[0], self.key_path, self.mock_config) Revoker.store_cert_key(self.paths[1], self.key_path, self.mock_config) # Set metadata for i in xrange(2): self.certs[i].add_meta( i, self.paths[i], self.key_path, Revoker._get_backup(self.backup_dir, i, self.paths[i]), Revoker._get_backup(self.backup_dir, i, self.key_path))
class RevokerTest(RevokerBase): def setUp(self): from letsencrypt.client.revoker import Revoker super(RevokerTest, self).setUp() with open(self.key_path) as key_file: self.key = le_util.Key(self.key_path, key_file.read()) self._store_certs() self.revoker = Revoker( mock.MagicMock(spec=configurator.ApacheConfigurator), self.mock_config) def tearDown(self): shutil.rmtree(self.backup_dir) @mock.patch("letsencrypt.client.revoker.network." "Network.send_and_receive_expected") @mock.patch("letsencrypt.client.revoker.revocation") def test_revoke_by_key_all(self, mock_display, mock_net): mock_display().confirm_revocation.return_value = True self.revoker.revoke_from_key(self.key) self.assertEqual(self._get_rows(), []) # Check to make sure backups were eliminated for i in xrange(2): self.assertFalse(self._backups_exist(self.certs[i].get_row())) self.assertEqual(mock_net.call_count, 2) @mock.patch("letsencrypt.client.revoker.Crypto.PublicKey.RSA.importKey") def test_revoke_by_invalid_keys(self, mock_import): mock_import.side_effect = ValueError self.assertRaises(errors.LetsEncryptRevokerError, self.revoker.revoke_from_key, self.key) mock_import.side_effect = [mock.Mock(), IndexError] self.assertRaises(errors.LetsEncryptRevokerError, self.revoker.revoke_from_key, self.key) @mock.patch("letsencrypt.client.revoker.network." "Network.send_and_receive_expected") @mock.patch("letsencrypt.client.revoker.revocation") def test_revoke_by_wrong_key(self, mock_display, mock_net): mock_display().confirm_revocation.return_value = True key_path = pkg_resources.resource_filename( "letsencrypt.client.tests", os.path.join("testdata", "rsa256_key.pem")) wrong_key = le_util.Key(key_path, open(key_path).read()) self.revoker.revoke_from_key(wrong_key) # Nothing was removed self.assertEqual(len(self._get_rows()), 2) # No revocation went through self.assertEqual(mock_net.call_count, 0) @mock.patch("letsencrypt.client.revoker.network." "Network.send_and_receive_expected") @mock.patch("letsencrypt.client.revoker.revocation") def test_revoke_by_cert(self, mock_display, mock_net): mock_display().confirm_revocation.return_value = True self.revoker.revoke_from_cert(self.paths[1]) row0 = self.certs[0].get_row() row1 = self.certs[1].get_row() self.assertEqual(self._get_rows(), [row0]) self.assertTrue(self._backups_exist(row0)) self.assertFalse(self._backups_exist(row1)) self.assertEqual(mock_net.call_count, 1) @mock.patch("letsencrypt.client.revoker.network." "Network.send_and_receive_expected") @mock.patch("letsencrypt.client.revoker.revocation") def test_revoke_by_cert_not_found(self, mock_display, mock_net): mock_display().confirm_revocation.return_value = True self.revoker.revoke_from_cert(self.paths[0]) self.revoker.revoke_from_cert(self.paths[0]) row0 = self.certs[0].get_row() row1 = self.certs[1].get_row() # Same check as last time... just reversed. self.assertEqual(self._get_rows(), [row1]) self.assertTrue(self._backups_exist(row1)) self.assertFalse(self._backups_exist(row0)) self.assertEqual(mock_net.call_count, 1) @mock.patch("letsencrypt.client.revoker.network." "Network.send_and_receive_expected") @mock.patch("letsencrypt.client.revoker.revocation") def test_revoke_by_menu(self, mock_display, mock_net): mock_display().confirm_revocation.return_value = True mock_display.display_certs.side_effect = [ (display_util.HELP, 0), (display_util.OK, 0), (display_util.CANCEL, -1), ] self.revoker.revoke_from_menu() row0 = self.certs[0].get_row() row1 = self.certs[1].get_row() self.assertEqual(self._get_rows(), [row1]) self.assertFalse(self._backups_exist(row0)) self.assertTrue(self._backups_exist(row1)) self.assertEqual(mock_net.call_count, 1) self.assertEqual(mock_display.more_info_cert.call_count, 1) @mock.patch("letsencrypt.client.revoker.logging") @mock.patch("letsencrypt.client.revoker.network." "Network.send_and_receive_expected") @mock.patch("letsencrypt.client.revoker.revocation") def test_revoke_by_menu_delete_all(self, mock_display, mock_net, mock_log): mock_display().confirm_revocation.return_value = True mock_display.display_certs.return_value = (display_util.OK, 0) self.revoker.revoke_from_menu() self.assertEqual(self._get_rows(), []) # Everything should be deleted... for i in xrange(2): self.assertFalse(self._backups_exist(self.certs[i].get_row())) self.assertEqual(mock_net.call_count, 2) # Info is called when there aren't any certs left... self.assertTrue(mock_log.info.called) @mock.patch("letsencrypt.client.revoker.revocation") @mock.patch("letsencrypt.client.revoker.Revoker._acme_revoke") @mock.patch("letsencrypt.client.revoker.logging") def test_safe_revoke_acme_fail(self, mock_log, mock_revoke, mock_display): # pylint: disable=protected-access mock_revoke.side_effect = errors.LetsEncryptClientError mock_display().confirm_revocation.return_value = True self.revoker._safe_revoke(self.certs) self.assertTrue(mock_log.error.called) @mock.patch("letsencrypt.client.revoker.Crypto.PublicKey.RSA.importKey") def test_acme_revoke_failure(self, mock_crypto): # pylint: disable=protected-access mock_crypto.side_effect = ValueError self.assertRaises(errors.LetsEncryptClientError, self.revoker._acme_revoke, self.certs[0]) def test_remove_certs_from_list_bad_certs(self): # pylint: disable=protected-access from letsencrypt.client.revoker import Cert new_cert = Cert(self.paths[0]) # This isn't stored in the db new_cert.idx = 10 new_cert.backup_path = self.paths[0] new_cert.backup_key_path = self.key_path new_cert.orig = Cert.PathStatus("false path", "not here") new_cert.orig_key = Cert.PathStatus("false path", "not here") self.assertRaises(errors.LetsEncryptRevokerError, self.revoker._remove_certs_from_list, [new_cert]) def _backups_exist(self, row): # pylint: disable=protected-access cert_path, key_path = self.revoker._row_to_backup(row) return os.path.isfile(cert_path) and os.path.isfile(key_path)
def _call(self, cert_path, key_path): from letsencrypt.client.revoker import Revoker Revoker.store_cert_key(cert_path, key_path, self.mock_config)
def _get_revoker(self, installer): from letsencrypt.client.revoker import Revoker return Revoker(installer, self.mock_config)
class RevokerTest(RevokerBase): def setUp(self): from letsencrypt.client.revoker import Revoker super(RevokerTest, self).setUp() with open(self.key_path) as key_file: self.key = le_util.Key(self.key_path, key_file.read()) self._store_certs() self.revoker = Revoker( mock.MagicMock(spec=configurator.ApacheConfigurator), self.mock_config) def tearDown(self): shutil.rmtree(self.backup_dir) @mock.patch("letsencrypt.client.revoker.network." "Network.send_and_receive_expected") @mock.patch("letsencrypt.client.revoker.revocation") def test_revoke_by_key_all(self, mock_display, mock_net): mock_display().confirm_revocation.return_value = True self.revoker.revoke_from_key(self.key) self.assertEqual(self._get_rows(), []) # Check to make sure backups were eliminated for i in xrange(2): self.assertFalse(self._backups_exist(self.certs[i].get_row())) self.assertEqual(mock_net.call_count, 2) @mock.patch("letsencrypt.client.revoker.Crypto.PublicKey.RSA.importKey") def test_revoke_by_invalid_keys(self, mock_import): mock_import.side_effect = ValueError self.assertRaises(errors.LetsEncryptRevokerError, self.revoker.revoke_from_key, self.key) mock_import.side_effect = [mock.Mock(), IndexError] self.assertRaises(errors.LetsEncryptRevokerError, self.revoker.revoke_from_key, self.key) @mock.patch("letsencrypt.client.revoker.network." "Network.send_and_receive_expected") @mock.patch("letsencrypt.client.revoker.revocation") def test_revoke_by_wrong_key(self, mock_display, mock_net): mock_display().confirm_revocation.return_value = True key_path = pkg_resources.resource_filename( "letsencrypt.acme.jose", os.path.join( "testdata", "rsa256_key.pem")) wrong_key = le_util.Key(key_path, open(key_path).read()) self.revoker.revoke_from_key(wrong_key) # Nothing was removed self.assertEqual(len(self._get_rows()), 2) # No revocation went through self.assertEqual(mock_net.call_count, 0) @mock.patch("letsencrypt.client.revoker.network." "Network.send_and_receive_expected") @mock.patch("letsencrypt.client.revoker.revocation") def test_revoke_by_cert(self, mock_display, mock_net): mock_display().confirm_revocation.return_value = True self.revoker.revoke_from_cert(self.paths[1]) row0 = self.certs[0].get_row() row1 = self.certs[1].get_row() self.assertEqual(self._get_rows(), [row0]) self.assertTrue(self._backups_exist(row0)) self.assertFalse(self._backups_exist(row1)) self.assertEqual(mock_net.call_count, 1) @mock.patch("letsencrypt.client.revoker.network." "Network.send_and_receive_expected") @mock.patch("letsencrypt.client.revoker.revocation") def test_revoke_by_cert_not_found(self, mock_display, mock_net): mock_display().confirm_revocation.return_value = True self.revoker.revoke_from_cert(self.paths[0]) self.revoker.revoke_from_cert(self.paths[0]) row0 = self.certs[0].get_row() row1 = self.certs[1].get_row() # Same check as last time... just reversed. self.assertEqual(self._get_rows(), [row1]) self.assertTrue(self._backups_exist(row1)) self.assertFalse(self._backups_exist(row0)) self.assertEqual(mock_net.call_count, 1) @mock.patch("letsencrypt.client.revoker.network." "Network.send_and_receive_expected") @mock.patch("letsencrypt.client.revoker.revocation") def test_revoke_by_menu(self, mock_display, mock_net): mock_display().confirm_revocation.return_value = True mock_display.display_certs.side_effect = [ (display_util.HELP, 0), (display_util.OK, 0), (display_util.CANCEL, -1), ] self.revoker.revoke_from_menu() row0 = self.certs[0].get_row() row1 = self.certs[1].get_row() self.assertEqual(self._get_rows(), [row1]) self.assertFalse(self._backups_exist(row0)) self.assertTrue(self._backups_exist(row1)) self.assertEqual(mock_net.call_count, 1) self.assertEqual(mock_display.more_info_cert.call_count, 1) @mock.patch("letsencrypt.client.revoker.logging") @mock.patch("letsencrypt.client.revoker.network." "Network.send_and_receive_expected") @mock.patch("letsencrypt.client.revoker.revocation") def test_revoke_by_menu_delete_all(self, mock_display, mock_net, mock_log): mock_display().confirm_revocation.return_value = True mock_display.display_certs.return_value = (display_util.OK, 0) self.revoker.revoke_from_menu() self.assertEqual(self._get_rows(), []) # Everything should be deleted... for i in xrange(2): self.assertFalse(self._backups_exist(self.certs[i].get_row())) self.assertEqual(mock_net.call_count, 2) # Info is called when there aren't any certs left... self.assertTrue(mock_log.info.called) @mock.patch("letsencrypt.client.revoker.revocation") @mock.patch("letsencrypt.client.revoker.Revoker._acme_revoke") @mock.patch("letsencrypt.client.revoker.logging") def test_safe_revoke_acme_fail(self, mock_log, mock_revoke, mock_display): # pylint: disable=protected-access mock_revoke.side_effect = errors.LetsEncryptClientError mock_display().confirm_revocation.return_value = True self.revoker._safe_revoke(self.certs) self.assertTrue(mock_log.error.called) @mock.patch("letsencrypt.client.revoker.Crypto.PublicKey.RSA.importKey") def test_acme_revoke_failure(self, mock_crypto): # pylint: disable=protected-access mock_crypto.side_effect = ValueError self.assertRaises(errors.LetsEncryptClientError, self.revoker._acme_revoke, self.certs[0]) def test_remove_certs_from_list_bad_certs(self): # pylint: disable=protected-access from letsencrypt.client.revoker import Cert new_cert = Cert(self.paths[0]) # This isn't stored in the db new_cert.idx = 10 new_cert.backup_path = self.paths[0] new_cert.backup_key_path = self.key_path new_cert.orig = Cert.PathStatus("false path", "not here") new_cert.orig_key = Cert.PathStatus("false path", "not here") self.assertRaises(errors.LetsEncryptRevokerError, self.revoker._remove_certs_from_list, [new_cert]) def _backups_exist(self, row): # pylint: disable=protected-access cert_path, key_path = self.revoker._row_to_backup(row) return os.path.isfile(cert_path) and os.path.isfile(key_path)