Refresh token workaround because expires to fast
This commit is contained in:
		@@ -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,
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user