Fix OAuth reauth in Tesla Fleet (#124744)
* Fix auth failure * Test * Fix test * Only reauth on 401 * Cover 401 and others * Update homeassistant/components/tesla_fleet/strings.json Co-authored-by: Jan Bouwhuis <jbouwh@users.noreply.github.com> --------- Co-authored-by: Jan Bouwhuis <jbouwh@users.noreply.github.com>
This commit is contained in:
parent
11370979e5
commit
e39b3796f3
5 changed files with 61 additions and 5 deletions
|
@ -3,6 +3,7 @@
|
|||
import asyncio
|
||||
from typing import Final
|
||||
|
||||
from aiohttp.client_exceptions import ClientResponseError
|
||||
import jwt
|
||||
from tesla_fleet_api import EnergySpecific, TeslaFleetApi, VehicleSpecific
|
||||
from tesla_fleet_api.const import Scope
|
||||
|
@ -66,7 +67,12 @@ async def async_setup_entry(hass: HomeAssistant, entry: TeslaFleetConfigEntry) -
|
|||
|
||||
async def _refresh_token() -> str:
|
||||
async with refresh_lock:
|
||||
await oauth_session.async_ensure_token_valid()
|
||||
try:
|
||||
await oauth_session.async_ensure_token_valid()
|
||||
except ClientResponseError as e:
|
||||
if e.status == 401:
|
||||
raise ConfigEntryAuthFailed from e
|
||||
raise ConfigEntryNotReady from e
|
||||
token: str = oauth_session.token[CONF_ACCESS_TOKEN]
|
||||
return token
|
||||
|
||||
|
|
|
@ -83,5 +83,8 @@ class OAuth2FlowHandler(
|
|||
) -> ConfigFlowResult:
|
||||
"""Confirm reauth dialog."""
|
||||
if user_input is None:
|
||||
return self.async_show_form(step_id="reauth_confirm")
|
||||
return self.async_show_form(
|
||||
step_id="reauth_confirm",
|
||||
description_placeholders={"name": "Tesla Fleet"},
|
||||
)
|
||||
return await self.async_step_user()
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
},
|
||||
"reauth_confirm": {
|
||||
"title": "[%key:common::config_flow::title::reauth%]",
|
||||
"description": "The Withings integration needs to re-authenticate your account"
|
||||
"description": "The {name} integration needs to re-authenticate your account"
|
||||
}
|
||||
},
|
||||
"create_entry": {
|
||||
|
|
|
@ -124,7 +124,7 @@ def mock_site_info() -> Generator[AsyncMock]:
|
|||
yield mock_live_status
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
@pytest.fixture
|
||||
def mock_find_server() -> Generator[AsyncMock]:
|
||||
"""Mock Tesla Fleet find server method."""
|
||||
with patch(
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
"""Test the Tesla Fleet init."""
|
||||
|
||||
from unittest.mock import AsyncMock
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
from aiohttp import RequestInfo
|
||||
from aiohttp.client_exceptions import ClientResponseError
|
||||
from freezegun.api import FrozenDateTimeFactory
|
||||
import pytest
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
|
@ -16,6 +18,7 @@ from tesla_fleet_api.exceptions import (
|
|||
VehicleOffline,
|
||||
)
|
||||
|
||||
from homeassistant.components.tesla_fleet.const import AUTHORIZE_URL
|
||||
from homeassistant.components.tesla_fleet.coordinator import (
|
||||
ENERGY_INTERVAL,
|
||||
ENERGY_INTERVAL_SECONDS,
|
||||
|
@ -72,6 +75,50 @@ async def test_init_error(
|
|||
assert normal_config_entry.state is state
|
||||
|
||||
|
||||
async def test_oauth_refresh_expired(
|
||||
hass: HomeAssistant,
|
||||
normal_config_entry: MockConfigEntry,
|
||||
mock_products: AsyncMock,
|
||||
) -> None:
|
||||
"""Test init with expired Oauth token."""
|
||||
|
||||
# Patch the token refresh to raise an error
|
||||
with patch(
|
||||
"homeassistant.components.tesla_fleet.OAuth2Session.async_ensure_token_valid",
|
||||
side_effect=ClientResponseError(
|
||||
RequestInfo(AUTHORIZE_URL, "POST", {}, AUTHORIZE_URL), None, status=401
|
||||
),
|
||||
) as mock_async_ensure_token_valid:
|
||||
# Trigger an unmocked function call
|
||||
mock_products.side_effect = InvalidRegion
|
||||
await setup_platform(hass, normal_config_entry)
|
||||
|
||||
mock_async_ensure_token_valid.assert_called_once()
|
||||
assert normal_config_entry.state is ConfigEntryState.SETUP_ERROR
|
||||
|
||||
|
||||
async def test_oauth_refresh_error(
|
||||
hass: HomeAssistant,
|
||||
normal_config_entry: MockConfigEntry,
|
||||
mock_products: AsyncMock,
|
||||
) -> None:
|
||||
"""Test init with Oauth refresh failure."""
|
||||
|
||||
# Patch the token refresh to raise an error
|
||||
with patch(
|
||||
"homeassistant.components.tesla_fleet.OAuth2Session.async_ensure_token_valid",
|
||||
side_effect=ClientResponseError(
|
||||
RequestInfo(AUTHORIZE_URL, "POST", {}, AUTHORIZE_URL), None, status=400
|
||||
),
|
||||
) as mock_async_ensure_token_valid:
|
||||
# Trigger an unmocked function call
|
||||
mock_products.side_effect = InvalidRegion
|
||||
await setup_platform(hass, normal_config_entry)
|
||||
|
||||
mock_async_ensure_token_valid.assert_called_once()
|
||||
assert normal_config_entry.state is ConfigEntryState.SETUP_RETRY
|
||||
|
||||
|
||||
# Test devices
|
||||
async def test_devices(
|
||||
hass: HomeAssistant,
|
||||
|
|
Loading…
Add table
Reference in a new issue