class AuthenticatorTest(unittest.TestCase): """Tests for letsencrypt.plugins.webroot.Authenticator.""" achall = achallenges.SimpleHTTP(challb=acme_util.SIMPLE_HTTP_P, domain=None, account_key=KEY) def setUp(self): from letsencrypt.plugins.webroot import Authenticator self.path = tempfile.mkdtemp() self.validation_path = os.path.join( self.path, ".well-known", "acme-challenge", "ZXZhR3hmQURzNnBTUmIyTEF2OUlaZjE3RHQzanV4R0orUEN0OTJ3citvQQ") self.config = mock.MagicMock(webroot_path=self.path) self.auth = Authenticator(self.config, "webroot") self.auth.prepare() def tearDown(self): shutil.rmtree(self.path) def test_more_info(self): more_info = self.auth.more_info() self.assertTrue(isinstance(more_info, str)) self.assertTrue(self.path in more_info) def test_add_parser_arguments(self): add = mock.MagicMock() self.auth.add_parser_arguments(add) self.assertEqual(1, add.call_count) def test_prepare_bad_root(self): self.config.webroot_path = os.path.join(self.path, "null") self.assertRaises(errors.PluginError, self.auth.prepare) def test_prepare_missing_root(self): self.config.webroot_path = None self.assertRaises(errors.PluginError, self.auth.prepare) def test_prepare_full_root_exists(self): # prepare() has already been called once in setUp() self.auth.prepare() # shouldn't raise any exceptions def test_prepare_reraises_other_errors(self): self.auth.full_path = os.path.join(self.path, "null") os.chmod(self.path, 0o000) self.assertRaises(errors.PluginError, self.auth.prepare) os.chmod(self.path, 0o700) def test_perform_cleanup(self): responses = self.auth.perform([self.achall]) self.assertEqual(1, len(responses)) self.assertTrue(os.path.exists(self.validation_path)) with open(self.validation_path) as validation_f: validation = jose.JWS.json_loads(validation_f.read()) self.assertTrue(responses[0].check_validation(validation, self.achall.chall, KEY.public_key())) self.auth.cleanup([self.achall]) self.assertFalse(os.path.exists(self.validation_path))
class AuthenticatorTest(unittest.TestCase): """Tests for letsencrypt.plugins.webroot.Authenticator.""" achall = achallenges.KeyAuthorizationAnnotatedChallenge( challb=acme_util.HTTP01_P, domain=None, account_key=KEY) def setUp(self): from letsencrypt.plugins.webroot import Authenticator self.path = tempfile.mkdtemp() self.validation_path = os.path.join( self.path, ".well-known", "acme-challenge", "ZXZhR3hmQURzNnBTUmIyTEF2OUlaZjE3RHQzanV4R0orUEN0OTJ3citvQQ") self.config = mock.MagicMock(webroot_path=self.path) self.auth = Authenticator(self.config, "webroot") self.auth.prepare() def tearDown(self): shutil.rmtree(self.path) def test_more_info(self): more_info = self.auth.more_info() self.assertTrue(isinstance(more_info, str)) self.assertTrue(self.path in more_info) def test_add_parser_arguments(self): add = mock.MagicMock() self.auth.add_parser_arguments(add) self.assertEqual(1, add.call_count) def test_prepare_bad_root(self): self.config.webroot_path = os.path.join(self.path, "null") self.assertRaises(errors.PluginError, self.auth.prepare) def test_prepare_missing_root(self): self.config.webroot_path = None self.assertRaises(errors.PluginError, self.auth.prepare) def test_prepare_full_root_exists(self): # prepare() has already been called once in setUp() self.auth.prepare() # shouldn't raise any exceptions def test_prepare_reraises_other_errors(self): self.auth.full_path = os.path.join(self.path, "null") os.chmod(self.path, 0o000) self.assertRaises(errors.PluginError, self.auth.prepare) os.chmod(self.path, 0o700) def test_perform_cleanup(self): responses = self.auth.perform([self.achall]) self.assertEqual(1, len(responses)) self.assertTrue(os.path.exists(self.validation_path)) with open(self.validation_path) as validation_f: validation = validation_f.read() self.assertTrue( challenges.KeyAuthorizationChallengeResponse( key_authorization=validation).verify( self.achall.chall, KEY.public_key())) self.auth.cleanup([self.achall]) self.assertFalse(os.path.exists(self.validation_path))
def setUp(self): from letsencrypt.plugins.webroot import Authenticator self.path = tempfile.mkdtemp() self.validation_path = os.path.join( self.path, ".well-known", "acme-challenge", "ZXZhR3hmQURzNnBTUmIyTEF2OUlaZjE3RHQzanV4R0orUEN0OTJ3citvQQ") self.config = mock.MagicMock(webroot_path=self.path, webroot_map={"thing.com": self.path}) self.auth = Authenticator(self.config, "webroot")
def setUp(self): from letsencrypt.plugins.webroot import Authenticator self.path = tempfile.mkdtemp() self.parser = argparse.ArgumentParser() self.parser.add_argument("-d", "--domains", action="append", default=[]) Authenticator.inject_parser_options(self.parser, "webroot")
class AuthenticatorTest(unittest.TestCase): """Tests for letsencrypt.plugins.webroot.Authenticator.""" achall = achallenges.KeyAuthorizationAnnotatedChallenge( challb=acme_util.HTTP01_P, domain="thing.com", account_key=KEY) def setUp(self): from letsencrypt.plugins.webroot import Authenticator self.path = tempfile.mkdtemp() self.validation_path = os.path.join( self.path, ".well-known", "acme-challenge", "ZXZhR3hmQURzNnBTUmIyTEF2OUlaZjE3RHQzanV4R0orUEN0OTJ3citvQQ") self.config = mock.MagicMock(webroot_path=self.path, webroot_map={"thing.com": self.path}) self.auth = Authenticator(self.config, "webroot") def tearDown(self): shutil.rmtree(self.path) def test_more_info(self): more_info = self.auth.more_info() self.assertTrue(isinstance(more_info, str)) self.assertTrue(self.path in more_info) def test_add_parser_arguments(self): add = mock.MagicMock() self.auth.add_parser_arguments(add) self.assertEqual(0, add.call_count) # args moved to cli.py! def test_prepare_bad_root(self): self.config.webroot_path = os.path.join(self.path, "null") self.config.webroot_map["thing.com"] = self.config.webroot_path self.assertRaises(errors.PluginError, self.auth.prepare) def test_prepare_missing_root(self): self.config.webroot_path = None self.config.webroot_map = {} self.assertRaises(errors.PluginError, self.auth.prepare) def test_prepare_full_root_exists(self): # prepare() has already been called once in setUp() self.auth.prepare() # shouldn't raise any exceptions def test_prepare_reraises_other_errors(self): self.auth.full_path = os.path.join(self.path, "null") os.chmod(self.path, 0o000) self.assertRaises(errors.PluginError, self.auth.prepare) os.chmod(self.path, 0o700) @mock.patch("letsencrypt.plugins.webroot.os.chown") def test_failed_chown_eacces(self, mock_chown): mock_chown.side_effect = OSError(errno.EACCES, "msg") self.auth.prepare() # exception caught and logged @mock.patch("letsencrypt.plugins.webroot.os.chown") def test_failed_chown_not_eacces(self, mock_chown): mock_chown.side_effect = OSError() self.assertRaises(errors.PluginError, self.auth.prepare) def test_prepare_permissions(self): self.auth.prepare() # Remove exec bit from permission check, so that it # matches the file self.auth.perform([self.achall]) path_permissions = stat.S_IMODE(os.stat(self.validation_path).st_mode) self.assertEqual(path_permissions, 0o644) # Check permissions of the directories for dirpath, dirnames, _ in os.walk(self.path): for directory in dirnames: full_path = os.path.join(dirpath, directory) dir_permissions = stat.S_IMODE(os.stat(full_path).st_mode) self.assertEqual(dir_permissions, 0o755) parent_gid = os.stat(self.path).st_gid parent_uid = os.stat(self.path).st_uid self.assertEqual(os.stat(self.validation_path).st_gid, parent_gid) self.assertEqual(os.stat(self.validation_path).st_uid, parent_uid) def test_perform_cleanup(self): self.auth.prepare() responses = self.auth.perform([self.achall]) self.assertEqual(1, len(responses)) self.assertTrue(os.path.exists(self.validation_path)) with open(self.validation_path) as validation_f: validation = validation_f.read() self.assertTrue( challenges.KeyAuthorizationChallengeResponse( key_authorization=validation).verify(self.achall.chall, KEY.public_key())) self.auth.cleanup([self.achall]) self.assertFalse(os.path.exists(self.validation_path))
class AuthenticatorTest(unittest.TestCase): """Tests for letsencrypt.plugins.webroot.Authenticator.""" achall = achallenges.KeyAuthorizationAnnotatedChallenge( challb=acme_util.HTTP01_P, domain="thing.com", account_key=KEY) def setUp(self): from letsencrypt.plugins.webroot import Authenticator self.path = tempfile.mkdtemp() self.validation_path = os.path.join( self.path, ".well-known", "acme-challenge", "ZXZhR3hmQURzNnBTUmIyTEF2OUlaZjE3RHQzanV4R0orUEN0OTJ3citvQQ") self.config = mock.MagicMock(webroot_path=self.path, webroot_map={"thing.com": self.path}) self.auth = Authenticator(self.config, "webroot") def tearDown(self): shutil.rmtree(self.path) def test_more_info(self): more_info = self.auth.more_info() self.assertTrue(isinstance(more_info, str)) self.assertTrue(self.path in more_info) def test_add_parser_arguments(self): add = mock.MagicMock() self.auth.add_parser_arguments(add) self.assertEqual(0, add.call_count) # args moved to cli.py! def test_prepare_bad_root(self): self.config.webroot_path = os.path.join(self.path, "null") self.config.webroot_map["thing.com"] = self.config.webroot_path self.assertRaises(errors.PluginError, self.auth.prepare) def test_prepare_missing_root(self): self.config.webroot_path = None self.config.webroot_map = {} self.assertRaises(errors.PluginError, self.auth.prepare) def test_prepare_full_root_exists(self): # prepare() has already been called once in setUp() self.auth.prepare() # shouldn't raise any exceptions def test_prepare_reraises_other_errors(self): self.auth.full_path = os.path.join(self.path, "null") permission_canary = os.path.join(self.path, "rnd") with open(permission_canary, "w") as f: f.write("thingimy") os.chmod(self.path, 0o000) try: open(permission_canary, "r") print "Warning, running tests as root skips permissions tests..." except IOError: # ok, permissions work, test away... self.assertRaises(errors.PluginError, self.auth.prepare) os.chmod(self.path, 0o700) @mock.patch("letsencrypt.plugins.webroot.os.chown") def test_failed_chown_eacces(self, mock_chown): mock_chown.side_effect = OSError(errno.EACCES, "msg") self.auth.prepare() # exception caught and logged @mock.patch("letsencrypt.plugins.webroot.os.chown") def test_failed_chown_not_eacces(self, mock_chown): mock_chown.side_effect = OSError() self.assertRaises(errors.PluginError, self.auth.prepare) def test_prepare_permissions(self): self.auth.prepare() # Remove exec bit from permission check, so that it # matches the file self.auth.perform([self.achall]) path_permissions = stat.S_IMODE(os.stat(self.validation_path).st_mode) self.assertEqual(path_permissions, 0o644) # Check permissions of the directories for dirpath, dirnames, _ in os.walk(self.path): for directory in dirnames: full_path = os.path.join(dirpath, directory) dir_permissions = stat.S_IMODE(os.stat(full_path).st_mode) self.assertEqual(dir_permissions, 0o755) parent_gid = os.stat(self.path).st_gid parent_uid = os.stat(self.path).st_uid self.assertEqual(os.stat(self.validation_path).st_gid, parent_gid) self.assertEqual(os.stat(self.validation_path).st_uid, parent_uid) def test_perform_missing_path(self): self.auth.prepare() missing_achall = achallenges.KeyAuthorizationAnnotatedChallenge( challb=acme_util.HTTP01_P, domain="thing2.com", account_key=KEY) self.assertRaises( errors.PluginError, self.auth.perform, [missing_achall]) self.auth.full_roots[self.achall.domain] = 'null' self.assertRaises( errors.PluginError, self.auth.perform, [self.achall]) def test_perform_cleanup(self): self.auth.prepare() responses = self.auth.perform([self.achall]) self.assertEqual(1, len(responses)) self.assertTrue(os.path.exists(self.validation_path)) with open(self.validation_path) as validation_f: validation = validation_f.read() self.assertTrue( challenges.KeyAuthorizationChallengeResponse( key_authorization=validation).verify( self.achall.chall, KEY.public_key())) self.auth.cleanup([self.achall]) self.assertFalse(os.path.exists(self.validation_path))
def _get_config_after_perform(self, config): from letsencrypt.plugins.webroot import Authenticator auth = Authenticator(config, "webroot") auth.perform([self.achall]) return auth.config
class AuthenticatorTest(unittest.TestCase): """Tests for letsencrypt.plugins.webroot.Authenticator.""" achall = achallenges.KeyAuthorizationAnnotatedChallenge( challb=acme_util.HTTP01_P, domain="thing.com", account_key=KEY) def setUp(self): from letsencrypt.plugins.webroot import Authenticator self.path = tempfile.mkdtemp() self.root_challenge_path = os.path.join(self.path, ".well-known", "acme-challenge") self.validation_path = os.path.join( self.root_challenge_path, "ZXZhR3hmQURzNnBTUmIyTEF2OUlaZjE3RHQzanV4R0orUEN0OTJ3citvQQ") self.config = mock.MagicMock(webroot_path=self.path, webroot_map={"thing.com": self.path}) self.auth = Authenticator(self.config, "webroot") def tearDown(self): shutil.rmtree(self.path) def test_more_info(self): more_info = self.auth.more_info() self.assertTrue(isinstance(more_info, str)) self.assertTrue(self.path in more_info) def test_add_parser_arguments(self): add = mock.MagicMock() self.auth.add_parser_arguments(add) self.assertEqual(2, add.call_count) def test_prepare(self): self.auth.prepare() # shouldn't raise any exceptions @mock.patch("letsencrypt.plugins.webroot.zope.component.getUtility") def test_webroot_from_list(self, mock_get_utility): self.config.webroot_path = [] self.config.webroot_map = {"otherthing.com": self.path} mock_display = mock_get_utility() mock_display.menu.return_value = ( display_util.OK, 1, ) self.auth.perform([self.achall]) self.assertTrue(mock_display.menu.called) for call in mock_display.menu.call_args_list: self.assertTrue(self.achall.domain in call[0][0]) self.assertTrue( all(webroot in call[0][1] for webroot in six.itervalues(self.config.webroot_map))) self.assertEqual(self.config.webroot_map[self.achall.domain], self.path) @mock.patch("letsencrypt.plugins.webroot.zope.component.getUtility") def test_webroot_from_list_help_and_cancel(self, mock_get_utility): self.config.webroot_path = [] self.config.webroot_map = {"otherthing.com": self.path} mock_display = mock_get_utility() mock_display.menu.side_effect = ( (display_util.HELP, -1), (display_util.CANCEL, -1), ) self.assertRaises(errors.PluginError, self.auth.perform, [self.achall]) self.assertTrue(mock_display.notification.called) self.assertTrue(mock_display.menu.called) for call in mock_display.menu.call_args_list: self.assertTrue(self.achall.domain in call[0][0]) self.assertTrue( all(webroot in call[0][1] for webroot in six.itervalues(self.config.webroot_map))) @mock.patch("letsencrypt.plugins.webroot.zope.component.getUtility") def test_new_webroot(self, mock_get_utility): self.config.webroot_path = [] self.config.webroot_map = {} imaginary_dir = os.path.join(os.sep, "imaginary", "dir") mock_display = mock_get_utility() mock_display.menu.return_value = ( display_util.OK, 0, ) mock_display.directory_select.side_effect = ( ( display_util.HELP, -1, ), ( display_util.CANCEL, -1, ), ( display_util.OK, imaginary_dir, ), ( display_util.OK, self.path, ), ) self.auth.perform([self.achall]) self.assertTrue(mock_display.notification.called) for call in mock_display.notification.call_args_list: self.assertTrue(imaginary_dir in call[0][0] or display_util.DSELECT_HELP == call[0][0]) self.assertTrue(mock_display.directory_select.called) for call in mock_display.directory_select.call_args_list: self.assertTrue(self.achall.domain in call[0][0]) def test_perform_missing_root(self): self.config.webroot_path = None self.config.webroot_map = {} self.assertRaises(errors.PluginError, self.auth.perform, []) def test_perform_reraises_other_errors(self): self.auth.full_path = os.path.join(self.path, "null") permission_canary = os.path.join(self.path, "rnd") with open(permission_canary, "w") as f: f.write("thingimy") os.chmod(self.path, 0o000) try: open(permission_canary, "r") print("Warning, running tests as root skips permissions tests...") except IOError: # ok, permissions work, test away... self.assertRaises(errors.PluginError, self.auth.perform, []) os.chmod(self.path, 0o700) @mock.patch("letsencrypt.plugins.webroot.os.chown") def test_failed_chown_eacces(self, mock_chown): mock_chown.side_effect = OSError(errno.EACCES, "msg") self.auth.perform([self.achall]) # exception caught and logged @mock.patch("letsencrypt.plugins.webroot.os.chown") def test_failed_chown_not_eacces(self, mock_chown): mock_chown.side_effect = OSError() self.assertRaises(errors.PluginError, self.auth.perform, []) def test_perform_permissions(self): self.auth.prepare() # Remove exec bit from permission check, so that it # matches the file self.auth.perform([self.achall]) path_permissions = stat.S_IMODE(os.stat(self.validation_path).st_mode) self.assertEqual(path_permissions, 0o644) # Check permissions of the directories for dirpath, dirnames, _ in os.walk(self.path): for directory in dirnames: full_path = os.path.join(dirpath, directory) dir_permissions = stat.S_IMODE(os.stat(full_path).st_mode) self.assertEqual(dir_permissions, 0o755) parent_gid = os.stat(self.path).st_gid parent_uid = os.stat(self.path).st_uid self.assertEqual(os.stat(self.validation_path).st_gid, parent_gid) self.assertEqual(os.stat(self.validation_path).st_uid, parent_uid) def test_perform_cleanup(self): self.auth.prepare() responses = self.auth.perform([self.achall]) self.assertEqual(1, len(responses)) self.assertTrue(os.path.exists(self.validation_path)) with open(self.validation_path) as validation_f: validation = validation_f.read() self.assertTrue( challenges.KeyAuthorizationChallengeResponse( key_authorization=validation).verify(self.achall.chall, KEY.public_key())) self.auth.cleanup([self.achall]) self.assertFalse(os.path.exists(self.validation_path)) self.assertFalse(os.path.exists(self.root_challenge_path)) def test_cleanup_leftovers(self): self.auth.prepare() self.auth.perform([self.achall]) leftover_path = os.path.join(self.root_challenge_path, 'leftover') os.mkdir(leftover_path) self.auth.cleanup([self.achall]) self.assertFalse(os.path.exists(self.validation_path)) self.assertTrue(os.path.exists(self.root_challenge_path)) os.rmdir(leftover_path) @mock.patch('os.rmdir') def test_cleanup_permission_denied(self, mock_rmdir): self.auth.prepare() self.auth.perform([self.achall]) os_error = OSError() os_error.errno = errno.EACCES mock_rmdir.side_effect = os_error self.auth.cleanup([self.achall]) self.assertFalse(os.path.exists(self.validation_path)) self.assertTrue(os.path.exists(self.root_challenge_path)) @mock.patch('os.rmdir') def test_cleanup_oserror(self, mock_rmdir): self.auth.prepare() self.auth.perform([self.achall]) os_error = OSError() os_error.errno = errno.ENOENT mock_rmdir.side_effect = os_error self.assertRaises(OSError, self.auth.cleanup, [self.achall]) self.assertFalse(os.path.exists(self.validation_path)) self.assertTrue(os.path.exists(self.root_challenge_path))