From 1a208a20b6cb604e5c05fdda9bbfd131c8b74e06 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Tue, 28 Aug 2018 12:14:40 +0200 Subject: [PATCH] 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,