def setUp(self): super().setUp() get_utility_patch = test_util.patch_get_utility() self.mock_get_utility = get_utility_patch.start() self.addCleanup(get_utility_patch.stop) self.http_achall = acme_util.HTTP01_A self.dns_achall = acme_util.DNS01_A self.dns_achall_2 = acme_util.DNS01_A_2 self.achalls = [self.http_achall, self.dns_achall, self.dns_achall_2] for d in ["config_dir", "work_dir", "in_progress"]: filesystem.mkdir(os.path.join(self.tempdir, d)) # "backup_dir" and "temp_checkpoint_dir" get created in # certbot.util.make_or_verify_dir() during the Reverter # initialization. self.config = mock.MagicMock( http01_port=0, manual_auth_hook=None, manual_cleanup_hook=None, noninteractive_mode=False, validate_hooks=False, config_dir=os.path.join(self.tempdir, "config_dir"), work_dir=os.path.join(self.tempdir, "work_dir"), backup_dir=os.path.join(self.tempdir, "backup_dir"), temp_checkpoint_dir=os.path.join(self.tempdir, "temp_checkpoint_dir"), in_progress_dir=os.path.join(self.tempdir, "in_progess")) from certbot._internal.plugins.manual import Authenticator self.auth = Authenticator(self.config, name='manual')
class AuthenticatorTest(test_util.TempDirTestCase): """Tests for certbot._internal.plugins.manual.Authenticator.""" def setUp(self): super().setUp() get_utility_patch = test_util.patch_get_utility() self.mock_get_utility = get_utility_patch.start() self.addCleanup(get_utility_patch.stop) self.http_achall = acme_util.HTTP01_A self.dns_achall = acme_util.DNS01_A self.dns_achall_2 = acme_util.DNS01_A_2 self.achalls = [self.http_achall, self.dns_achall, self.dns_achall_2] for d in ["config_dir", "work_dir", "in_progress"]: filesystem.mkdir(os.path.join(self.tempdir, d)) # "backup_dir" and "temp_checkpoint_dir" get created in # certbot.util.make_or_verify_dir() during the Reverter # initialization. self.config = mock.MagicMock( http01_port=0, manual_auth_hook=None, manual_cleanup_hook=None, noninteractive_mode=False, validate_hooks=False, config_dir=os.path.join(self.tempdir, "config_dir"), work_dir=os.path.join(self.tempdir, "work_dir"), backup_dir=os.path.join(self.tempdir, "backup_dir"), temp_checkpoint_dir=os.path.join(self.tempdir, "temp_checkpoint_dir"), in_progress_dir=os.path.join(self.tempdir, "in_progess")) from certbot._internal.plugins.manual import Authenticator self.auth = Authenticator(self.config, name='manual') def test_prepare_no_hook_noninteractive(self): self.config.noninteractive_mode = True self.assertRaises(errors.PluginError, self.auth.prepare) def test_prepare_bad_hook(self): self.config.manual_auth_hook = os.path.abspath(os.sep) # is / on UNIX self.config.validate_hooks = True self.assertRaises(errors.HookCommandNotFound, self.auth.prepare) def test_more_info(self): self.assertIsInstance(self.auth.more_info(), str) def test_get_chall_pref(self): self.assertEqual(self.auth.get_chall_pref('example.org'), [challenges.HTTP01, challenges.DNS01]) def test_script_perform(self): self.config.manual_auth_hook = ( '{0} -c "' 'from certbot.compat import os;' 'print(os.environ.get(\'CERTBOT_DOMAIN\'));' 'print(os.environ.get(\'CERTBOT_TOKEN\', \'notoken\'));' 'print(os.environ.get(\'CERTBOT_VALIDATION\', \'novalidation\'));' 'print(os.environ.get(\'CERTBOT_ALL_DOMAINS\'));' 'print(os.environ.get(\'CERTBOT_REMAINING_CHALLENGES\'));"'.format( sys.executable)) dns_expected = '{0}\n{1}\n{2}\n{3}\n{4}'.format( self.dns_achall.domain, 'notoken', self.dns_achall.validation(self.dns_achall.account_key), ','.join(achall.domain for achall in self.achalls), len(self.achalls) - self.achalls.index(self.dns_achall) - 1) http_expected = '{0}\n{1}\n{2}\n{3}\n{4}'.format( self.http_achall.domain, self.http_achall.chall.encode('token'), self.http_achall.validation(self.http_achall.account_key), ','.join(achall.domain for achall in self.achalls), len(self.achalls) - self.achalls.index(self.http_achall) - 1) self.assertEqual( self.auth.perform(self.achalls), [achall.response(achall.account_key) for achall in self.achalls]) self.assertEqual(self.auth.env[self.dns_achall]['CERTBOT_AUTH_OUTPUT'], dns_expected) self.assertEqual( self.auth.env[self.http_achall]['CERTBOT_AUTH_OUTPUT'], http_expected) # Successful hook output should be sent to notify self.assertEqual(self.mock_get_utility().notification.call_count, len(self.achalls)) for i, (args, _) in enumerate( self.mock_get_utility().notification.call_args_list): needle = textwrap.indent( self.auth.env[self.achalls[i]]['CERTBOT_AUTH_OUTPUT'], ' ') self.assertIn(needle, args[0]) def test_manual_perform(self): self.assertEqual( self.auth.perform(self.achalls), [achall.response(achall.account_key) for achall in self.achalls]) self.assertEqual(self.mock_get_utility().notification.call_count, len(self.achalls)) for i, (args, kwargs) in enumerate( self.mock_get_utility().notification.call_args_list): achall = self.achalls[i] self.assertIn(achall.validation(achall.account_key), args[0]) self.assertIs(kwargs['wrap'], False) def test_cleanup(self): self.config.manual_auth_hook = ( '{0} -c "import sys; sys.stdout.write(\'foo\')"'.format( sys.executable)) self.config.manual_cleanup_hook = '# cleanup' self.auth.perform(self.achalls) for achall in self.achalls: self.auth.cleanup([achall]) self.assertEqual(os.environ['CERTBOT_AUTH_OUTPUT'], 'foo') self.assertEqual(os.environ['CERTBOT_DOMAIN'], achall.domain) if isinstance(achall.chall, (challenges.HTTP01, challenges.DNS01)): self.assertEqual(os.environ['CERTBOT_VALIDATION'], achall.validation(achall.account_key)) if isinstance(achall.chall, challenges.HTTP01): self.assertEqual(os.environ['CERTBOT_TOKEN'], achall.chall.encode('token')) else: self.assertNotIn('CERTBOT_TOKEN', os.environ) def test_auth_hint_hook(self): self.config.manual_auth_hook = '/bin/true' self.assertEqual( self.auth.auth_hint([acme_util.DNS01_A, acme_util.HTTP01_A]), 'The Certificate Authority failed to verify the DNS TXT records and challenge ' 'files created by the --manual-auth-hook. Ensure that this hook is functioning ' 'correctly and that it waits a sufficient duration of time for DNS propagation. ' 'Refer to "certbot --help manual" and the Certbot User Guide.') self.assertEqual( self.auth.auth_hint([acme_util.HTTP01_A]), 'The Certificate Authority failed to verify the challenge files created by the ' '--manual-auth-hook. Ensure that this hook is functioning correctly. Refer to ' '"certbot --help manual" and the Certbot User Guide.') def test_auth_hint_no_hook(self): self.assertEqual( self.auth.auth_hint([acme_util.DNS01_A, acme_util.HTTP01_A]), 'The Certificate Authority failed to verify the manually created DNS TXT records ' 'and challenge files. Ensure that you created these in the correct location, or ' 'try waiting longer for DNS propagation on the next attempt.') self.assertEqual( self.auth.auth_hint( [acme_util.HTTP01_A, acme_util.HTTP01_A, acme_util.HTTP01_A]), 'The Certificate Authority failed to verify the manually created challenge files. ' 'Ensure that you created these in the correct location.')
class AuthenticatorTest(test_util.TempDirTestCase): """Tests for certbot._internal.plugins.manual.Authenticator.""" def setUp(self): super(AuthenticatorTest, self).setUp() self.http_achall = acme_util.HTTP01_A self.dns_achall = acme_util.DNS01_A self.dns_achall_2 = acme_util.DNS01_A_2 self.achalls = [self.http_achall, self.dns_achall, self.dns_achall_2] for d in ["config_dir", "work_dir", "in_progress"]: filesystem.mkdir(os.path.join(self.tempdir, d)) # "backup_dir" and "temp_checkpoint_dir" get created in # certbot.util.make_or_verify_dir() during the Reverter # initialization. self.config = mock.MagicMock( http01_port=0, manual_auth_hook=None, manual_cleanup_hook=None, manual_public_ip_logging_ok=False, noninteractive_mode=False, validate_hooks=False, config_dir=os.path.join(self.tempdir, "config_dir"), work_dir=os.path.join(self.tempdir, "work_dir"), backup_dir=os.path.join(self.tempdir, "backup_dir"), temp_checkpoint_dir=os.path.join(self.tempdir, "temp_checkpoint_dir"), in_progress_dir=os.path.join(self.tempdir, "in_progess")) from certbot._internal.plugins.manual import Authenticator self.auth = Authenticator(self.config, name='manual') def test_prepare_no_hook_noninteractive(self): self.config.noninteractive_mode = True self.assertRaises(errors.PluginError, self.auth.prepare) def test_prepare_bad_hook(self): self.config.manual_auth_hook = os.path.abspath(os.sep) # is / on UNIX self.config.validate_hooks = True self.assertRaises(errors.HookCommandNotFound, self.auth.prepare) def test_more_info(self): self.assertTrue(isinstance(self.auth.more_info(), six.string_types)) def test_get_chall_pref(self): self.assertEqual(self.auth.get_chall_pref('example.org'), [challenges.HTTP01, challenges.DNS01]) @test_util.patch_get_utility() def test_ip_logging_not_ok(self, mock_get_utility): mock_get_utility().yesno.return_value = False self.assertRaises(errors.PluginError, self.auth.perform, []) @test_util.patch_get_utility() def test_ip_logging_ok(self, mock_get_utility): mock_get_utility().yesno.return_value = True self.auth.perform([]) self.assertTrue(self.config.manual_public_ip_logging_ok) def test_script_perform(self): self.config.manual_public_ip_logging_ok = True self.config.manual_auth_hook = ( '{0} -c "from __future__ import print_function;' 'from certbot.compat import os; print(os.environ.get(\'CERTBOT_DOMAIN\'));' 'print(os.environ.get(\'CERTBOT_TOKEN\', \'notoken\'));' 'print(os.environ.get(\'CERTBOT_VALIDATION\', \'novalidation\'));"' .format(sys.executable)) dns_expected = '{0}\n{1}\n{2}'.format( self.dns_achall.domain, 'notoken', self.dns_achall.validation(self.dns_achall.account_key)) http_expected = '{0}\n{1}\n{2}'.format( self.http_achall.domain, self.http_achall.chall.encode('token'), self.http_achall.validation(self.http_achall.account_key)) self.assertEqual( self.auth.perform(self.achalls), [achall.response(achall.account_key) for achall in self.achalls]) self.assertEqual(self.auth.env[self.dns_achall]['CERTBOT_AUTH_OUTPUT'], dns_expected) self.assertEqual( self.auth.env[self.http_achall]['CERTBOT_AUTH_OUTPUT'], http_expected) @test_util.patch_get_utility() def test_manual_perform(self, mock_get_utility): self.config.manual_public_ip_logging_ok = True self.assertEqual( self.auth.perform(self.achalls), [achall.response(achall.account_key) for achall in self.achalls]) for i, (args, kwargs) in enumerate( mock_get_utility().notification.call_args_list): achall = self.achalls[i] self.assertTrue(achall.validation(achall.account_key) in args[0]) self.assertFalse(kwargs['wrap']) def test_cleanup(self): self.config.manual_public_ip_logging_ok = True self.config.manual_auth_hook = ( '{0} -c "import sys; sys.stdout.write(\'foo\')"'.format( sys.executable)) self.config.manual_cleanup_hook = '# cleanup' self.auth.perform(self.achalls) for achall in self.achalls: self.auth.cleanup([achall]) self.assertEqual(os.environ['CERTBOT_AUTH_OUTPUT'], 'foo') self.assertEqual(os.environ['CERTBOT_DOMAIN'], achall.domain) if isinstance(achall.chall, (challenges.HTTP01, challenges.DNS01)): self.assertEqual(os.environ['CERTBOT_VALIDATION'], achall.validation(achall.account_key)) if isinstance(achall.chall, challenges.HTTP01): self.assertEqual(os.environ['CERTBOT_TOKEN'], achall.chall.encode('token')) else: self.assertFalse('CERTBOT_TOKEN' in os.environ)