Fix google calendar bug where expired tokens are not refreshed (#72994)

This commit is contained in:
Allen Porter 2022-06-03 16:33:12 -07:00 committed by GitHub
parent 04b2223f06
commit bdc41bf22a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 17 additions and 10 deletions

View file

@ -5,7 +5,6 @@ from __future__ import annotations
from collections.abc import Awaitable, Callable
import datetime
import logging
import time
from typing import Any, cast
import aiohttp
@ -50,12 +49,16 @@ class DeviceAuth(AuthImplementation):
async def async_resolve_external_data(self, external_data: Any) -> dict:
"""Resolve a Google API Credentials object to Home Assistant token."""
creds: Credentials = external_data[DEVICE_AUTH_CREDS]
delta = creds.token_expiry.replace(tzinfo=datetime.timezone.utc) - dt.utcnow()
_LOGGER.debug(
"Token expires at %s (in %s)", creds.token_expiry, delta.total_seconds()
)
return {
"access_token": creds.access_token,
"refresh_token": creds.refresh_token,
"scope": " ".join(creds.scopes),
"token_type": "Bearer",
"expires_in": creds.token_expiry.timestamp() - time.time(),
"expires_in": delta.total_seconds(),
}

View file

@ -16,7 +16,6 @@ from homeassistant.components.google import CONF_TRACK_NEW, DOMAIN
from homeassistant.const import CONF_CLIENT_ID, CONF_CLIENT_SECRET
from homeassistant.core import HomeAssistant
from homeassistant.setup import async_setup_component
from homeassistant.util.dt import utcnow
from tests.common import MockConfigEntry
from tests.test_util.aiohttp import AiohttpClientMocker
@ -136,7 +135,10 @@ def token_scopes() -> list[str]:
@pytest.fixture
def token_expiry() -> datetime.datetime:
"""Expiration time for credentials used in the test."""
return utcnow() + datetime.timedelta(days=7)
# OAuth library returns an offset-naive timestamp
return datetime.datetime.fromtimestamp(
datetime.datetime.utcnow().timestamp()
) + datetime.timedelta(hours=1)
@pytest.fixture

View file

@ -8,6 +8,7 @@ from typing import Any
from unittest.mock import Mock, patch
from aiohttp.client_exceptions import ClientError
from freezegun.api import FrozenDateTimeFactory
from oauth2client.client import (
FlowExchangeError,
OAuth2Credentials,
@ -94,11 +95,13 @@ async def fire_alarm(hass, point_in_time):
await hass.async_block_till_done()
@pytest.mark.freeze_time("2022-06-03 15:19:59-00:00")
async def test_full_flow_yaml_creds(
hass: HomeAssistant,
mock_code_flow: Mock,
mock_exchange: Mock,
component_setup: ComponentSetup,
freezer: FrozenDateTimeFactory,
) -> None:
"""Test successful creds setup."""
assert await component_setup()
@ -115,8 +118,8 @@ async def test_full_flow_yaml_creds(
"homeassistant.components.google.async_setup_entry", return_value=True
) as mock_setup:
# Run one tick to invoke the credential exchange check
now = utcnow()
await fire_alarm(hass, now + CODE_CHECK_ALARM_TIMEDELTA)
freezer.tick(CODE_CHECK_ALARM_TIMEDELTA)
await fire_alarm(hass, datetime.datetime.utcnow())
await hass.async_block_till_done()
result = await hass.config_entries.flow.async_configure(
flow_id=result["flow_id"]
@ -127,12 +130,11 @@ async def test_full_flow_yaml_creds(
assert "data" in result
data = result["data"]
assert "token" in data
assert 0 < data["token"]["expires_in"] < 8 * 86400
assert (
datetime.datetime.now().timestamp()
<= data["token"]["expires_at"]
< (datetime.datetime.now() + datetime.timedelta(days=8)).timestamp()
data["token"]["expires_in"]
== 60 * 60 - CODE_CHECK_ALARM_TIMEDELTA.total_seconds()
)
assert data["token"]["expires_at"] == 1654273199.0
data["token"].pop("expires_at")
data["token"].pop("expires_in")
assert data == {