Force Lyric token refresh on first authentication failure (#62100)

pull/62196/head
Aidan Timson 2021-12-17 11:33:41 +00:00 committed by GitHub
parent 8c777011b6
commit 0f2a3c074e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 4 deletions

View File

@ -2,6 +2,7 @@
from __future__ import annotations
from datetime import timedelta
from http import HTTPStatus
import logging
from aiohttp.client_exceptions import ClientResponseError
@ -30,7 +31,11 @@ from homeassistant.helpers.update_coordinator import (
UpdateFailed,
)
from .api import ConfigEntryLyricClient, LyricLocalOAuth2Implementation
from .api import (
ConfigEntryLyricClient,
LyricLocalOAuth2Implementation,
OAuth2SessionLyric,
)
from .config_flow import OAuth2FlowHandler
from .const import DOMAIN, OAUTH2_AUTHORIZE, OAUTH2_TOKEN
@ -84,21 +89,35 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
)
session = aiohttp_client.async_get_clientsession(hass)
oauth_session = config_entry_oauth2_flow.OAuth2Session(hass, entry, implementation)
oauth_session = OAuth2SessionLyric(hass, entry, implementation)
client = ConfigEntryLyricClient(session, oauth_session)
client_id = hass.data[DOMAIN][CONF_CLIENT_ID]
lyric = Lyric(client, client_id)
async def async_update_data() -> Lyric:
async def async_update_data(force_refresh_token: bool = False) -> Lyric:
"""Fetch data from Lyric."""
await oauth_session.async_ensure_token_valid()
try:
if not force_refresh_token:
await oauth_session.async_ensure_token_valid()
else:
await oauth_session.force_refresh_token()
except ClientResponseError as exception:
if exception.status in (HTTPStatus.UNAUTHORIZED, HTTPStatus.FORBIDDEN):
raise ConfigEntryAuthFailed from exception
raise UpdateFailed(exception) from exception
try:
async with async_timeout.timeout(60):
await lyric.get_locations()
return lyric
except LyricAuthenticationException as exception:
# Attempt to refresh the token before failing.
# Honeywell appear to have issues keeping tokens saved.
_LOGGER.debug("Authentication failed. Attempting to refresh token")
if not force_refresh_token:
return await async_update_data(force_refresh_token=True)
raise ConfigEntryAuthFailed from exception
except (LyricException, ClientResponseError) as exception:
raise UpdateFailed(exception) from exception

View File

@ -8,6 +8,18 @@ from homeassistant.helpers import config_entry_oauth2_flow
from homeassistant.helpers.aiohttp_client import async_get_clientsession
class OAuth2SessionLyric(config_entry_oauth2_flow.OAuth2Session):
"""OAuth2Session for Lyric."""
async def force_refresh_token(self) -> None:
"""Force a token refresh."""
new_token = await self.implementation.async_refresh_token(self.token)
self.hass.config_entries.async_update_entry(
self.config_entry, data={**self.config_entry.data, "token": new_token}
)
class ConfigEntryLyricClient(LyricClient):
"""Provide Honeywell Lyric authentication tied to an OAuth2 based config entry."""