diff --git a/hass_nabucasa/__init__.py b/hass_nabucasa/__init__.py index d209889b9..fb1c32940 100644 --- a/hass_nabucasa/__init__.py +++ b/hass_nabucasa/__init__.py @@ -199,7 +199,7 @@ def write_user_info(self) -> None: if not base_path.exists(): base_path.mkdir() - with atomic_write(str(self.user_info_path), overwrite=True) as fp: + with atomic_write(self.user_info_path, overwrite=True) as fp: fp.write( json.dumps( { @@ -210,6 +210,7 @@ def write_user_info(self) -> None: indent=4, ) ) + self.user_info_path.chmod(0o600) async def start(self): """Start the cloud component.""" diff --git a/hass_nabucasa/acme.py b/hass_nabucasa/acme.py index 74f47c9be..3795898f0 100644 --- a/hass_nabucasa/acme.py +++ b/hass_nabucasa/acme.py @@ -9,6 +9,7 @@ import OpenSSL from acme import challenges, client, crypto_util, errors, messages import async_timeout +from atomicwrites import atomic_write import attr from cryptography import x509 from cryptography.hazmat.backends import default_backend @@ -280,7 +281,8 @@ def _finish_challenge(self, handler: ChallengeHandler) -> None: else: _LOGGER.info("Create new certificate: %s", self.path_fullchain) - self.path_fullchain.write_text(order.fullchain_pem) + with atomic_write(self.path_fullchain, overwrite=True) as fp: + fp.write(order.fullchain_pem) self.path_fullchain.chmod(0o600) async def load_certificate(self) -> None: @@ -368,9 +370,13 @@ async def issue_certificate(self) -> None: await self.cloud.run_executor(self._finish_challenge, challenge) await self.load_certificate() finally: - await cloud_api.async_remote_challenge_cleanup( - self.cloud, challenge.validation - ) + try: + async with async_timeout.timeout(30): + await cloud_api.async_remote_challenge_cleanup( + self.cloud, challenge.validation + ) + except asyncio.TimeoutError: + _LOGGER.error("Failed to clean up challenge from NabuCasa DNS!") async def reset_acme(self) -> None: """Revoke and deactivate acme certificate/account.""" diff --git a/hass_nabucasa/remote.py b/hass_nabucasa/remote.py index 33bcbc108..e94e51722 100644 --- a/hass_nabucasa/remote.py +++ b/hass_nabucasa/remote.py @@ -175,11 +175,14 @@ async def _finish_load_backend(self) -> None: await self._acme.hardening_files() + _LOGGER.debug("Waiting for aiohttp runner to come available") + # aiohttp_runner comes available when Home Assistant has started. while self.cloud.client.aiohttp_runner is None: await asyncio.sleep(1) # Setup snitun / aiohttp wrapper + _LOGGER.debug("Initializing remote backend") context = await self._create_context() self._snitun = SniTunClientAioHttp( self.cloud.client.aiohttp_runner, @@ -188,9 +191,13 @@ async def _finish_load_backend(self) -> None: snitun_port=443, ) + _LOGGER.debug("Starting remote backend") await self._snitun.start() self.cloud.client.dispatcher_message(const.DISPATCH_REMOTE_BACKEND_UP) + _LOGGER.debug( + "Connecting remote backend: %s", self.cloud.client.remote_autostart + ) # Connect to remote is autostart enabled if self.cloud.client.remote_autostart: self.cloud.run_task(self.connect()) diff --git a/tests/test_init.py b/tests/test_init.py index 01078a6d4..3e3dcb28b 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -176,7 +176,7 @@ def test_write_user_info(cloud_client): cl.access_token = "test-access-token" cl.refresh_token = "test-refresh-token" - with patch("hass_nabucasa.atomic_write",) as mock_write: + with patch("pathlib.Path.chmod"), patch("hass_nabucasa.atomic_write") as mock_write: cl.write_user_info() mock_file = mock_write.return_value.__enter__.return_value