Refresh token workaround because expires to fast
This commit is contained in:
parent
e82c14ec99
commit
272556586e
2 changed files with 25 additions and 2 deletions
|
@ -3,6 +3,7 @@ import logging
|
||||||
import re
|
import re
|
||||||
import secrets
|
import secrets
|
||||||
import urllib
|
import urllib
|
||||||
|
from datetime import datetime, timedelta
|
||||||
from pprint import pformat
|
from pprint import pformat
|
||||||
from typing import List, Tuple
|
from typing import List, Tuple
|
||||||
from urllib import parse
|
from urllib import parse
|
||||||
|
@ -16,6 +17,9 @@ _LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class HonAuth:
|
class HonAuth:
|
||||||
|
_TOKEN_EXPIRES_AFTER_HOURS = 8
|
||||||
|
_TOKEN_EXPIRE_WARNING_HOURS = 7
|
||||||
|
|
||||||
def __init__(self, session, email, password, device) -> None:
|
def __init__(self, session, email, password, device) -> None:
|
||||||
self._session = session
|
self._session = session
|
||||||
self._email = email
|
self._email = email
|
||||||
|
@ -26,6 +30,7 @@ class HonAuth:
|
||||||
self._id_token = ""
|
self._id_token = ""
|
||||||
self._device = device
|
self._device = device
|
||||||
self._called_urls: List[Tuple[int, str]] = []
|
self._called_urls: List[Tuple[int, str]] = []
|
||||||
|
self._expires: datetime = datetime.utcnow()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def cognito_token(self):
|
def cognito_token(self):
|
||||||
|
@ -43,6 +48,17 @@ class HonAuth:
|
||||||
def refresh_token(self):
|
def refresh_token(self):
|
||||||
return self._refresh_token
|
return self._refresh_token
|
||||||
|
|
||||||
|
def _check_token_expiration(self, hours):
|
||||||
|
return datetime.utcnow() >= self._expires + timedelta(hours=hours)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def token_is_expired(self) -> bool:
|
||||||
|
return self._check_token_expiration(self._TOKEN_EXPIRES_AFTER_HOURS)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def token_expires_soon(self) -> bool:
|
||||||
|
return self._check_token_expiration(self._TOKEN_EXPIRE_WARNING_HOURS)
|
||||||
|
|
||||||
async def _error_logger(self, response, fail=True):
|
async def _error_logger(self, response, fail=True):
|
||||||
result = "hOn Authentication Error\n"
|
result = "hOn Authentication Error\n"
|
||||||
for i, (status, url) in enumerate(self._called_urls):
|
for i, (status, url) in enumerate(self._called_urls):
|
||||||
|
@ -72,6 +88,7 @@ class HonAuth:
|
||||||
) as response:
|
) as response:
|
||||||
self._called_urls.append((response.status, response.request_info.url))
|
self._called_urls.append((response.status, response.request_info.url))
|
||||||
text = await response.text()
|
text = await response.text()
|
||||||
|
self._expires = datetime.utcnow()
|
||||||
if not (login_url := re.findall("url = '(.+?)'", text)):
|
if not (login_url := re.findall("url = '(.+?)'", text)):
|
||||||
if "oauth/done#access_token=" in text:
|
if "oauth/done#access_token=" in text:
|
||||||
self._parse_token_data(text)
|
self._parse_token_data(text)
|
||||||
|
@ -237,12 +254,14 @@ class HonAuth:
|
||||||
await self._error_logger(response, fail=False)
|
await self._error_logger(response, fail=False)
|
||||||
return False
|
return False
|
||||||
data = await response.json()
|
data = await response.json()
|
||||||
|
self._expires = datetime.utcnow()
|
||||||
self._id_token = data["id_token"]
|
self._id_token = data["id_token"]
|
||||||
self._access_token = data["access_token"]
|
self._access_token = data["access_token"]
|
||||||
return await self._api_auth()
|
return await self._api_auth()
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
self._session.cookie_jar.clear_domain(const.AUTH_API.split("/")[-2])
|
self._session.cookie_jar.clear_domain(const.AUTH_API.split("/")[-2])
|
||||||
|
self._called_urls = []
|
||||||
self._cognito_token = ""
|
self._cognito_token = ""
|
||||||
self._id_token = ""
|
self._id_token = ""
|
||||||
self._access_token = ""
|
self._access_token = ""
|
||||||
|
|
|
@ -100,14 +100,18 @@ class HonConnectionHandler(HonBaseConnectionHandler):
|
||||||
) -> AsyncIterator:
|
) -> AsyncIterator:
|
||||||
kwargs["headers"] = await self._check_headers(kwargs.get("headers", {}))
|
kwargs["headers"] = await self._check_headers(kwargs.get("headers", {}))
|
||||||
async with method(*args, **kwargs) as response:
|
async with method(*args, **kwargs) as response:
|
||||||
if response.status in [401, 403] and loop == 0:
|
if (
|
||||||
|
self._auth.token_expires_soon or response.status in [401, 403]
|
||||||
|
) and loop == 0:
|
||||||
_LOGGER.info("Try refreshing token...")
|
_LOGGER.info("Try refreshing token...")
|
||||||
await self._auth.refresh()
|
await self._auth.refresh()
|
||||||
async with self._intercept(
|
async with self._intercept(
|
||||||
method, *args, loop=loop + 1, **kwargs
|
method, *args, loop=loop + 1, **kwargs
|
||||||
) as result:
|
) as result:
|
||||||
yield result
|
yield result
|
||||||
elif response.status in [401, 403] and loop == 1:
|
elif (
|
||||||
|
self._auth.token_is_expired or response.status in [401, 403]
|
||||||
|
) and loop == 1:
|
||||||
_LOGGER.warning(
|
_LOGGER.warning(
|
||||||
"%s - Error %s - %s",
|
"%s - Error %s - %s",
|
||||||
response.request_info.url,
|
response.request_info.url,
|
||||||
|
|
Loading…
Reference in a new issue