class GetAuthorizationsTest(unittest.TestCase): """get_authorizations test. This tests everything except for all functions under _poll_challenges. """ def setUp(self): from certbot.auth_handler import AuthHandler self.mock_auth = mock.MagicMock(name="ApacheConfigurator") self.mock_auth.get_chall_pref.return_value = [challenges.TLSSNI01] self.mock_auth.perform.side_effect = gen_auth_resp self.mock_account = mock.Mock(key=util.Key("file_path", "PEM")) self.mock_net = mock.MagicMock(spec=acme_client.Client) self.handler = AuthHandler(self.mock_auth, self.mock_net, self.mock_account) logging.disable(logging.CRITICAL) def tearDown(self): logging.disable(logging.NOTSET) @mock.patch("certbot.auth_handler.AuthHandler._poll_challenges") def test_name1_tls_sni_01_1(self, mock_poll): self.mock_net.request_domain_challenges.side_effect = functools.partial( gen_dom_authzr, challs=acme_util.CHALLENGES) mock_poll.side_effect = self._validate_all authzr = self.handler.get_authorizations(["0"]) self.assertEqual(self.mock_net.answer_challenge.call_count, 1) self.assertEqual(mock_poll.call_count, 1) chall_update = mock_poll.call_args[0][0] self.assertEqual(chall_update.keys(), ["0"]) self.assertEqual(len(chall_update.values()), 1) self.assertEqual(self.mock_auth.cleanup.call_count, 1) # Test if list first element is TLSSNI01, use typ because it is an achall self.assertEqual(self.mock_auth.cleanup.call_args[0][0][0].typ, "tls-sni-01") self.assertEqual(len(authzr), 1) @mock.patch("certbot.auth_handler.AuthHandler._poll_challenges") def test_name1_tls_sni_01_1_http_01_1_dns_1(self, mock_poll): self.mock_net.request_domain_challenges.side_effect = functools.partial( gen_dom_authzr, challs=acme_util.CHALLENGES, combos=False) mock_poll.side_effect = self._validate_all self.mock_auth.get_chall_pref.return_value.append(challenges.HTTP01) self.mock_auth.get_chall_pref.return_value.append(challenges.DNS) authzr = self.handler.get_authorizations(["0"]) self.assertEqual(self.mock_net.answer_challenge.call_count, 3) self.assertEqual(mock_poll.call_count, 1) chall_update = mock_poll.call_args[0][0] self.assertEqual(chall_update.keys(), ["0"]) self.assertEqual(len(chall_update.values()), 1) self.assertEqual(self.mock_auth.cleanup.call_count, 1) # Test if list first element is TLSSNI01, use typ because it is an achall for achall in self.mock_auth.cleanup.call_args[0][0]: self.assertTrue(achall.typ in ["tls-sni-01", "http-01", "dns"]) # Length of authorizations list self.assertEqual(len(authzr), 1) @mock.patch("certbot.auth_handler.AuthHandler._poll_challenges") def test_name3_tls_sni_01_3(self, mock_poll): self.mock_net.request_domain_challenges.side_effect = functools.partial( gen_dom_authzr, challs=acme_util.CHALLENGES) mock_poll.side_effect = self._validate_all authzr = self.handler.get_authorizations(["0", "1", "2"]) self.assertEqual(self.mock_net.answer_challenge.call_count, 3) # Check poll call self.assertEqual(mock_poll.call_count, 1) chall_update = mock_poll.call_args[0][0] self.assertEqual(len(chall_update.keys()), 3) self.assertTrue("0" in chall_update.keys()) self.assertEqual(len(chall_update["0"]), 1) self.assertTrue("1" in chall_update.keys()) self.assertEqual(len(chall_update["1"]), 1) self.assertTrue("2" in chall_update.keys()) self.assertEqual(len(chall_update["2"]), 1) self.assertEqual(self.mock_auth.cleanup.call_count, 1) self.assertEqual(len(authzr), 3) def test_perform_failure(self): self.mock_net.request_domain_challenges.side_effect = functools.partial( gen_dom_authzr, challs=acme_util.CHALLENGES) self.mock_auth.perform.side_effect = errors.AuthorizationError self.assertRaises(errors.AuthorizationError, self.handler.get_authorizations, ["0"]) def test_no_domains(self): self.assertRaises(errors.AuthorizationError, self.handler.get_authorizations, []) def _validate_all(self, unused_1, unused_2): for dom in self.handler.authzr.keys(): azr = self.handler.authzr[dom] self.handler.authzr[dom] = acme_util.gen_authzr( messages.STATUS_VALID, dom, [challb.chall for challb in azr.body.challenges], [messages.STATUS_VALID] * len(azr.body.challenges), azr.body.combinations)
class GetAuthorizationsTest(unittest.TestCase): """get_authorizations test. This tests everything except for all functions under _poll_challenges. """ def setUp(self): from certbot.auth_handler import AuthHandler from certbot_external_auth.plugin import AuthenticatorOut self.name = 'certbot-external-auth' self.name_cfg = self.name.replace('-', '_') + '_' self.tempdir = tempfile.mkdtemp(dir=tempfile.gettempdir()) self.config = configuration.NamespaceConfig( mock.MagicMock(**constants.CLI_DEFAULTS)) self.patch_tls = mock.patch( 'acme.challenges.TLSSNI01Response.simple_verify') self.patch_http = mock.patch( 'acme.challenges.HTTP01Response.simple_verify') self.patch_dns = mock.patch( 'acme.challenges.DNS01Response.simple_verify') self.patch_tls.start() self.patch_http.start() self.patch_dns.start() self.config.verb = "certonly" self.config.config_dir = os.path.join(self.tempdir, 'config') self.config.work_dir = os.path.join(self.tempdir, 'work') self.config.logs_dir = os.path.join(self.tempdir, 'logs') self.config.cert_path = constants.CLI_DEFAULTS['auth_cert_path'] self.config.fullchain_path = constants.CLI_DEFAULTS['auth_chain_path'] self.config.chain_path = constants.CLI_DEFAULTS['auth_chain_path'] self.config.server = "example.com" self.config.__setattr__(self.name_cfg + 'handler', None) self.config.__setattr__(self.name_cfg + 'public_ip_logging_ok', True) self.config.__setattr__(self.name_cfg + 'test_mode', False) self.config.__setattr__(self.name_cfg + 'text_mode', False) self.config.__setattr__(self.name_cfg + 'dehydrated_dns', False) self.mock_display = mock.Mock() zope.component.provideUtility(self.mock_display, interfaces.IDisplay) zope.component.provideUtility(mock.Mock(debug_challenges=False), interfaces.IConfig) self.mock_auth = AuthenticatorOut(self.config, self.name) self.mock_auth.get_chall_pref = mock.MagicMock() self.mock_auth.get_chall_pref.return_value = [challenges.TLSSNI01] self.mock_data = [] self.mock_json_out = mock.MagicMock(side_effect=self._update_data) self.mock_auth._json_out_and_wait = self.mock_json_out self.mock_auth.cleanup = mock.Mock() self.key_mock = mock.Mock() self.key_mock.key = mock.Mock() self.key_mock.key.file_path = 'PEM' self.key_mock.thumbprint = mock.MagicMock( return_value=b'00001234567890000') self.mock_account = mock.Mock(key=self.key_mock) self.mock_net = mock.MagicMock(spec=acme_client.Client) self.handler = AuthHandler(self.mock_auth, self.mock_net, self.mock_account, []) self.input_patch = mock.patch('six.moves.input') self.input_patch.start() logging.disable(logging.CRITICAL) def tearDown(self): shutil.rmtree(self.tempdir) logging.disable(logging.NOTSET) self.input_patch.stop() self.patch_tls.stop() self.patch_http.stop() self.patch_dns.stop() def _help_output(self, args): "Run a command, and return the output string for scrutiny" output = six.StringIO() def write_msg(message, *args, **kwargs): # pylint: disable=missing-docstring,unused-argument output.write(message) with mock.patch('certbot.main.sys.stdout', new=output): with test_util.patch_get_utility() as mock_get_utility: mock_get_utility().notification.side_effect = write_msg with mock.patch('certbot.main.sys.stderr'): self.assertRaises(SystemExit, self._unmocked_parse, args, output) return output.getvalue() @mock.patch("certbot.auth_handler.AuthHandler._poll_challenges") def test_name1_tls_sni_01_1(self, mock_poll): self.mock_net.request_domain_challenges.side_effect = functools.partial( gen_dom_authzr, challs=acme_util.CHALLENGES) mock_poll.side_effect = self._validate_all authzr = self.handler.get_authorizations(["0"]) self.assertEqual(self.mock_net.answer_challenge.call_count, 1) self.assertEqual(mock_poll.call_count, 1) chall_update = mock_poll.call_args[0][0] self.assertEqual(list(six.iterkeys(chall_update)), ["0"]) self.assertEqual(len(chall_update.values()), 1) self.assertEqual(self.mock_auth.cleanup.call_count, 1) # Test if list first element is TLSSNI01, use typ because it is an achall self.assertEqual(self.mock_auth.cleanup.call_args[0][0][0].typ, "tls-sni-01") self.assertEqual(len(authzr), 1) self.assertEqual(self.mock_json_out.call_count, 1) self.assertEqual(len(self.mock_data), 1) self.assertIn('cmd', self.mock_data[0]) self.assertIn('token', self.mock_data[0]) self.assertIn('validation', self.mock_data[0]) self.assertTrue(len(self.mock_data[0]['validation']) > 5) @mock.patch("certbot.auth_handler.AuthHandler._poll_challenges") def test_name1_tls_sni_01_1_http_01_1_dns_1(self, mock_poll): self.mock_net.request_domain_challenges.side_effect = functools.partial( gen_dom_authzr, challs=acme_util.CHALLENGES, combos=False) mock_poll.side_effect = self._validate_all self.mock_auth.get_chall_pref.return_value.append(challenges.HTTP01) self.mock_auth.get_chall_pref.return_value.append(challenges.DNS01) authzr = self.handler.get_authorizations(["0"]) self.assertEqual(self.mock_net.answer_challenge.call_count, 3) self.assertEqual(mock_poll.call_count, 1) chall_update = mock_poll.call_args[0][0] self.assertEqual(list(six.iterkeys(chall_update)), ["0"]) self.assertEqual(len(chall_update.values()), 1) self.assertEqual(self.mock_auth.cleanup.call_count, 1) # Test if list first element is TLSSNI01, use typ because it is an achall for achall in self.mock_auth.cleanup.call_args[0][0]: self.assertTrue(achall.typ in ["tls-sni-01", "http-01", "dns-01"]) # Length of authorizations list self.assertEqual(len(authzr), 1) self.assertEqual(self.mock_json_out.call_count, 3) self.assertEqual(len(self.mock_data), 3) for msg in self.mock_data: self.assertIn('cmd', msg) self.assertIn('token', msg) self.assertIn('validation', msg) self.assertTrue(len(msg['validation']) > 5) @mock.patch("certbot.auth_handler.AuthHandler._poll_challenges") def test_name3_tls_sni_01_3(self, mock_poll): self.mock_net.request_domain_challenges.side_effect = functools.partial( gen_dom_authzr, challs=acme_util.CHALLENGES) mock_poll.side_effect = self._validate_all with mock.patch('certbot.util.safe_open') as mock_open: mock_open.return_value = mock.MagicMock() authzr = self.handler.get_authorizations(["0", "1", "2"]) self.assertEqual(self.mock_net.answer_challenge.call_count, 3) # Check poll call self.assertEqual(mock_poll.call_count, 1) chall_update = mock_poll.call_args[0][0] self.assertEqual(len(list(six.iterkeys(chall_update))), 3) self.assertTrue("0" in list(six.iterkeys(chall_update))) self.assertEqual(len(chall_update["0"]), 1) self.assertTrue("1" in list(six.iterkeys(chall_update))) self.assertEqual(len(chall_update["1"]), 1) self.assertTrue("2" in list(six.iterkeys(chall_update))) self.assertEqual(len(chall_update["2"]), 1) self.assertEqual(self.mock_auth.cleanup.call_count, 1) self.assertEqual(len(authzr), 3) self.assertEqual(self.mock_json_out.call_count, 3) self.assertEqual(len(self.mock_data), 3) for msg in self.mock_data: self.assertIn('cmd', msg) self.assertIn('token', msg) self.assertIn('validation', msg) self.assertTrue(len(msg['validation']) > 5) @mock.patch("certbot.auth_handler.AuthHandler._poll_challenges") def test_debug_challenges(self, mock_poll): zope.component.provideUtility(mock.Mock(debug_challenges=True), interfaces.IConfig) self.mock_net.request_domain_challenges.side_effect = functools.partial( gen_dom_authzr, challs=acme_util.CHALLENGES) mock_poll.side_effect = self._validate_all self.handler.get_authorizations(["0"]) self.assertEqual(self.mock_net.answer_challenge.call_count, 1) self.assertEqual(self.mock_display.notification.call_count, 1) def test_perform_failure(self): self.mock_net.request_domain_challenges.side_effect = functools.partial( gen_dom_authzr, challs=acme_util.CHALLENGES) self.mock_auth.perform = mock.Mock() self.mock_auth.perform.side_effect = errors.AuthorizationError self.assertRaises(errors.AuthorizationError, self.handler.get_authorizations, ["0"]) def test_no_domains(self): self.assertRaises(errors.AuthorizationError, self.handler.get_authorizations, []) @mock.patch("certbot.auth_handler.AuthHandler._poll_challenges") def test_preferred_challenge_choice(self, mock_poll): self.mock_net.request_domain_challenges.side_effect = functools.partial( gen_dom_authzr, challs=acme_util.CHALLENGES) mock_poll.side_effect = self._validate_all self.mock_auth.get_chall_pref.return_value.append(challenges.HTTP01) self.handler.pref_challs.extend(( challenges.HTTP01.typ, challenges.DNS01.typ, )) self.handler.get_authorizations(["0"]) self.assertEqual(self.mock_auth.cleanup.call_count, 1) self.assertEqual(self.mock_auth.cleanup.call_args[0][0][0].typ, "http-01") def test_preferred_challenges_not_supported(self): self.mock_net.request_domain_challenges.side_effect = functools.partial( gen_dom_authzr, challs=acme_util.CHALLENGES) self.handler.pref_challs.append(challenges.HTTP01.typ) self.assertRaises(errors.AuthorizationError, self.handler.get_authorizations, ["0"]) def _validate_all(self, unused_1, unused_2): for dom in six.iterkeys(self.handler.authzr): azr = self.handler.authzr[dom] self.handler.authzr[dom] = acme_util.gen_authzr( messages.STATUS_VALID, dom, [challb.chall for challb in azr.body.challenges], [messages.STATUS_VALID] * len(azr.body.challenges), azr.body.combinations) def _update_data(self, x): self.mock_data.append(x)
class GetAuthorizationsTest(unittest.TestCase): """get_authorizations test. This tests everything except for all functions under _poll_challenges. """ def setUp(self): from certbot.auth_handler import AuthHandler self.mock_auth = mock.MagicMock(name="ApacheConfigurator") self.mock_auth.get_chall_pref.return_value = [challenges.TLSSNI01] self.mock_auth.perform.side_effect = gen_auth_resp self.mock_account = mock.Mock(key=util.Key("file_path", "PEM")) self.mock_net = mock.MagicMock(spec=acme_client.Client) self.handler = AuthHandler( self.mock_auth, self.mock_net, self.mock_account, []) logging.disable(logging.CRITICAL) def tearDown(self): logging.disable(logging.NOTSET) @mock.patch("certbot.auth_handler.AuthHandler._poll_challenges") def test_name1_tls_sni_01_1(self, mock_poll): self.mock_net.request_domain_challenges.side_effect = functools.partial( gen_dom_authzr, challs=acme_util.CHALLENGES) mock_poll.side_effect = self._validate_all authzr = self.handler.get_authorizations(["0"]) self.assertEqual(self.mock_net.answer_challenge.call_count, 1) self.assertEqual(mock_poll.call_count, 1) chall_update = mock_poll.call_args[0][0] self.assertEqual(list(six.iterkeys(chall_update)), ["0"]) self.assertEqual(len(chall_update.values()), 1) self.assertEqual(self.mock_auth.cleanup.call_count, 1) # Test if list first element is TLSSNI01, use typ because it is an achall self.assertEqual( self.mock_auth.cleanup.call_args[0][0][0].typ, "tls-sni-01") self.assertEqual(len(authzr), 1) @mock.patch("certbot.auth_handler.AuthHandler._poll_challenges") def test_name1_tls_sni_01_1_http_01_1_dns_1(self, mock_poll): self.mock_net.request_domain_challenges.side_effect = functools.partial( gen_dom_authzr, challs=acme_util.CHALLENGES, combos=False) mock_poll.side_effect = self._validate_all self.mock_auth.get_chall_pref.return_value.append(challenges.HTTP01) self.mock_auth.get_chall_pref.return_value.append(challenges.DNS01) authzr = self.handler.get_authorizations(["0"]) self.assertEqual(self.mock_net.answer_challenge.call_count, 3) self.assertEqual(mock_poll.call_count, 1) chall_update = mock_poll.call_args[0][0] self.assertEqual(list(six.iterkeys(chall_update)), ["0"]) self.assertEqual(len(chall_update.values()), 1) self.assertEqual(self.mock_auth.cleanup.call_count, 1) # Test if list first element is TLSSNI01, use typ because it is an achall for achall in self.mock_auth.cleanup.call_args[0][0]: self.assertTrue(achall.typ in ["tls-sni-01", "http-01", "dns-01"]) # Length of authorizations list self.assertEqual(len(authzr), 1) @mock.patch("certbot.auth_handler.AuthHandler._poll_challenges") def test_name3_tls_sni_01_3(self, mock_poll): self.mock_net.request_domain_challenges.side_effect = functools.partial( gen_dom_authzr, challs=acme_util.CHALLENGES) mock_poll.side_effect = self._validate_all authzr = self.handler.get_authorizations(["0", "1", "2"]) self.assertEqual(self.mock_net.answer_challenge.call_count, 3) # Check poll call self.assertEqual(mock_poll.call_count, 1) chall_update = mock_poll.call_args[0][0] self.assertEqual(len(list(six.iterkeys(chall_update))), 3) self.assertTrue("0" in list(six.iterkeys(chall_update))) self.assertEqual(len(chall_update["0"]), 1) self.assertTrue("1" in list(six.iterkeys(chall_update))) self.assertEqual(len(chall_update["1"]), 1) self.assertTrue("2" in list(six.iterkeys(chall_update))) self.assertEqual(len(chall_update["2"]), 1) self.assertEqual(self.mock_auth.cleanup.call_count, 1) self.assertEqual(len(authzr), 3) def test_perform_failure(self): self.mock_net.request_domain_challenges.side_effect = functools.partial( gen_dom_authzr, challs=acme_util.CHALLENGES) self.mock_auth.perform.side_effect = errors.AuthorizationError self.assertRaises( errors.AuthorizationError, self.handler.get_authorizations, ["0"]) def test_no_domains(self): self.assertRaises(errors.AuthorizationError, self.handler.get_authorizations, []) @mock.patch("certbot.auth_handler.AuthHandler._poll_challenges") def test_preferred_challenge_choice(self, mock_poll): self.mock_net.request_domain_challenges.side_effect = functools.partial( gen_dom_authzr, challs=acme_util.CHALLENGES) mock_poll.side_effect = self._validate_all self.mock_auth.get_chall_pref.return_value.append(challenges.HTTP01) self.handler.pref_challs.extend((challenges.HTTP01.typ, challenges.DNS01.typ,)) self.handler.get_authorizations(["0"]) self.assertEqual(self.mock_auth.cleanup.call_count, 1) self.assertEqual( self.mock_auth.cleanup.call_args[0][0][0].typ, "http-01") def test_preferred_challenges_not_supported(self): self.mock_net.request_domain_challenges.side_effect = functools.partial( gen_dom_authzr, challs=acme_util.CHALLENGES) self.handler.pref_challs.append(challenges.HTTP01.typ) self.assertRaises( errors.AuthorizationError, self.handler.get_authorizations, ["0"]) def _validate_all(self, unused_1, unused_2): for dom in six.iterkeys(self.handler.authzr): azr = self.handler.authzr[dom] self.handler.authzr[dom] = acme_util.gen_authzr( messages.STATUS_VALID, dom, [challb.chall for challb in azr.body.challenges], [messages.STATUS_VALID] * len(azr.body.challenges), azr.body.combinations)