From 0c345fc6151aec313670f4d234814a54f0e63631 Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Sun, 19 Aug 2018 22:05:42 +0200 Subject: [PATCH 1/6] Bump version 128 --- hassio/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hassio/const.py b/hassio/const.py index 002805399..443627d30 100644 --- a/hassio/const.py +++ b/hassio/const.py @@ -2,7 +2,7 @@ from pathlib import Path from ipaddress import ip_network -HASSIO_VERSION = '127' +HASSIO_VERSION = '128' URL_HASSIO_ADDONS = "https://github.com/home-assistant/hassio-addons" URL_HASSIO_VERSION = \ From a66af6e9039cddb67306b58cbcc9156fc4a912ff Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Tue, 28 Aug 2018 01:18:38 +0200 Subject: [PATCH 2/6] Update aiohttp to 3.4.0 (#668) Update: aiohttp to 3.4.0 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 32ebcdc4f..e3353366f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ attr==0.3.1 async_timeout==3.0.0 -aiohttp==3.3.2 +aiohttp==3.4.0 docker==3.5.0 colorlog==3.1.2 voluptuous==0.11.5 From b1e8722ead774b00883071d614953f06a9dd4716 Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Tue, 28 Aug 2018 12:04:32 +0200 Subject: [PATCH 3/6] Update: pycryptodome to 3.6.6 (#670) --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index e3353366f..eae7f825f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,7 +7,7 @@ voluptuous==0.11.5 gitpython==2.1.10 pytz==2018.4 pyudev==0.21.0 -pycryptodome==3.6.4 +pycryptodome==3.6.6 cpe==1.2.1 uvloop==0.11.2 cchardet==2.1.1 From 1a208a20b6cb604e5c05fdda9bbfd131c8b74e06 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Tue, 28 Aug 2018 12:14:40 +0200 Subject: [PATCH 4/6] Handle access token expiration (#671) --- hassio/homeassistant.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/hassio/homeassistant.py b/hassio/homeassistant.py index 660603632..1449f2bf3 100644 --- a/hassio/homeassistant.py +++ b/hassio/homeassistant.py @@ -1,6 +1,7 @@ """HomeAssistant control object.""" import asyncio from contextlib import asynccontextmanager, suppress +from datetime import datetime, timedelta import logging import os import re @@ -46,6 +47,7 @@ class HomeAssistant(JsonConfig, CoreSysAttributes): self._error_state = False # We don't persist access tokens. Instead we fetch new ones when needed self.access_token = None + self.access_token_expires = None async def load(self): """Prepare HomeAssistant object.""" @@ -352,7 +354,8 @@ class HomeAssistant(JsonConfig, CoreSysAttributes): async def ensure_access_token(self): """Ensures there is an access token.""" - if self.access_token is not None: + if (self.access_token is not None and + self.access_token_expires < datetime.utcnow()): return with suppress(asyncio.TimeoutError, aiohttp.ClientError): @@ -364,14 +367,15 @@ class HomeAssistant(JsonConfig, CoreSysAttributes): "refresh_token": self.refresh_token } ) as resp: - if resp.status == 200: - _LOGGER.info("Updated HomeAssistant API token") - tokens = await resp.json() - self.access_token = tokens['access_token'] - return + if resp.status != 200: + _LOGGER.error("Can't update HomeAssistant access token!") + raise HomeAssistantAuthError() - _LOGGER.error("Can't update HomeAssistant access token!") - raise HomeAssistantAuthError() + _LOGGER.info("Updated HomeAssistant API token") + tokens = await resp.json() + self.access_token = tokens['access_token'] + self.access_token_expires = \ + datetime.utcnow() + timedelta(seconds=tokens['expires_in']) @asynccontextmanager async def make_request(self, method, path, json=None, content_type=None, From aac4b9b24a9170c5d18c8aa3b87bd8e2fb158aef Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Tue, 28 Aug 2018 16:32:17 +0200 Subject: [PATCH 5/6] Snapshot/Restore Home-Assistant token (#672) * Snapshot/Restore Home-Assistant token * Encrypt token & check api * fix lint --- hassio/snapshots/__init__.py | 14 +++++++++++--- hassio/snapshots/snapshot.py | 6 +++++- hassio/snapshots/validate.py | 2 ++ 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/hassio/snapshots/__init__.py b/hassio/snapshots/__init__.py index 749e3bb7f..f7f6c322f 100644 --- a/hassio/snapshots/__init__.py +++ b/hassio/snapshots/__init__.py @@ -293,6 +293,7 @@ class SnapshotManager(CoreSysAttributes): # Stop Home-Assistant if they will be restored later if homeassistant and FOLDER_HOMEASSISTANT in folders: await self.sys_homeassistant.stop() + snapshot.restore_homeassistant() # Process folders if folders: @@ -304,7 +305,6 @@ class SnapshotManager(CoreSysAttributes): if homeassistant: _LOGGER.info("Restore %s run Home-Assistant", snapshot.slug) - snapshot.restore_homeassistant() task_hass = self.sys_create_task( self.sys_homeassistant.update( snapshot.homeassistant_version)) @@ -322,12 +322,20 @@ class SnapshotManager(CoreSysAttributes): _LOGGER.info("Restore %s old add-ons", snapshot.slug) await snapshot.restore_addons(addon_list) - # make sure homeassistant run agen + # Make sure homeassistant run agen if task_hass: _LOGGER.info("Restore %s wait for Home-Assistant", snapshot.slug) await task_hass - await self.sys_homeassistant.start() + + # Do we need start HomeAssistant? + if not await self.sys_homeassistant.is_running(): + await self.sys_homeassistant.start() + + # Check If we can access to API / otherwise restart + if not await self.sys_homeassistant.check_api_state(): + _LOGGER.warning("Need restart HomeAssistant for API") + await self.sys_homeassistant.restart() except Exception: # pylint: disable=broad-except _LOGGER.exception("Restore %s error", snapshot.slug) diff --git a/hassio/snapshots/snapshot.py b/hassio/snapshots/snapshot.py index e737cb72a..11a6b5e68 100644 --- a/hassio/snapshots/snapshot.py +++ b/hassio/snapshots/snapshot.py @@ -20,7 +20,7 @@ from ..const import ( ATTR_HOMEASSISTANT, ATTR_FOLDERS, ATTR_VERSION, ATTR_TYPE, ATTR_IMAGE, ATTR_PORT, ATTR_SSL, ATTR_PASSWORD, ATTR_WATCHDOG, ATTR_BOOT, ATTR_CRYPTO, ATTR_LAST_VERSION, ATTR_PROTECTED, ATTR_WAIT_BOOT, ATTR_SIZE, - CRYPTO_AES128) + ATTR_REFRESH_TOKEN, CRYPTO_AES128) from ..coresys import CoreSysAttributes from ..utils.json import write_json_file from ..utils.tar import SecureTarFile @@ -387,6 +387,8 @@ class Snapshot(CoreSysAttributes): # API/Proxy self.homeassistant[ATTR_PORT] = self.sys_homeassistant.api_port self.homeassistant[ATTR_SSL] = self.sys_homeassistant.api_ssl + self.homeassistant[ATTR_REFRESH_TOKEN] = \ + self._encrypt_data(self.sys_homeassistant.refresh_token) self.homeassistant[ATTR_PASSWORD] = \ self._encrypt_data(self.sys_homeassistant.api_password) @@ -405,6 +407,8 @@ class Snapshot(CoreSysAttributes): # API/Proxy self.sys_homeassistant.api_port = self.homeassistant[ATTR_PORT] self.sys_homeassistant.api_ssl = self.homeassistant[ATTR_SSL] + self.sys_homeassistant.refresh_token = \ + self._decrypt_data(self.homeassistant[ATTR_REFRESH_TOKEN]) self.sys_homeassistant.api_password = \ self._decrypt_data(self.homeassistant[ATTR_PASSWORD]) diff --git a/hassio/snapshots/validate.py b/hassio/snapshots/validate.py index fa1681cba..8f8e39c34 100644 --- a/hassio/snapshots/validate.py +++ b/hassio/snapshots/validate.py @@ -7,6 +7,7 @@ from ..const import ( ATTR_VERSION, ATTR_HOMEASSISTANT, ATTR_FOLDERS, ATTR_TYPE, ATTR_IMAGE, ATTR_PASSWORD, ATTR_PORT, ATTR_SSL, ATTR_WATCHDOG, ATTR_BOOT, ATTR_SIZE, ATTR_LAST_VERSION, ATTR_WAIT_BOOT, ATTR_PROTECTED, ATTR_CRYPTO, + ATTR_REFRESH_TOKEN, FOLDER_SHARE, FOLDER_HOMEASSISTANT, FOLDER_ADDONS, FOLDER_SSL, SNAPSHOT_FULL, SNAPSHOT_PARTIAL, CRYPTO_AES128) from ..validate import NETWORK_PORT, REPOSITORIES, DOCKER_IMAGE @@ -40,6 +41,7 @@ SCHEMA_SNAPSHOT = vol.Schema({ vol.Optional(ATTR_SSL, default=False): vol.Boolean(), vol.Optional(ATTR_PORT, default=8123): NETWORK_PORT, vol.Optional(ATTR_PASSWORD): vol.Maybe(vol.Coerce(str)), + vol.Optional(ATTR_REFRESH_TOKEN): vol.Maybe(vol.Coerce(str)), vol.Optional(ATTR_WATCHDOG, default=True): vol.Boolean(), vol.Optional(ATTR_WAIT_BOOT, default=600): vol.All(vol.Coerce(int), vol.Range(min=60)), From 051b63c7cc8b4dda7ab07706b635e27da7d50783 Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Tue, 28 Aug 2018 17:04:39 +0200 Subject: [PATCH 6/6] Fix access token property (#673) * Fix access token property * revert --- hassio/homeassistant.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hassio/homeassistant.py b/hassio/homeassistant.py index 1449f2bf3..bc94be29d 100644 --- a/hassio/homeassistant.py +++ b/hassio/homeassistant.py @@ -47,7 +47,7 @@ class HomeAssistant(JsonConfig, CoreSysAttributes): self._error_state = False # We don't persist access tokens. Instead we fetch new ones when needed self.access_token = None - self.access_token_expires = None + self._access_token_expires = None async def load(self): """Prepare HomeAssistant object.""" @@ -355,7 +355,7 @@ class HomeAssistant(JsonConfig, CoreSysAttributes): async def ensure_access_token(self): """Ensures there is an access token.""" if (self.access_token is not None and - self.access_token_expires < datetime.utcnow()): + self._access_token_expires > datetime.utcnow()): return with suppress(asyncio.TimeoutError, aiohttp.ClientError): @@ -374,7 +374,7 @@ class HomeAssistant(JsonConfig, CoreSysAttributes): _LOGGER.info("Updated HomeAssistant API token") tokens = await resp.json() self.access_token = tokens['access_token'] - self.access_token_expires = \ + self._access_token_expires = \ datetime.utcnow() + timedelta(seconds=tokens['expires_in']) @asynccontextmanager