Skip to content

Commit

Permalink
Raise ConfigEntryAuthFailed during setup or coordinator update to sta…
Browse files Browse the repository at this point in the history
…rt reauth (#48962)
  • Loading branch information
bdraco authored Apr 10, 2021
1 parent 7cc857a commit 4cd7f9b
Show file tree
Hide file tree
Showing 51 changed files with 532 additions and 515 deletions.
1 change: 1 addition & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,7 @@ omit =
homeassistant/components/poolsense/__init__.py
homeassistant/components/poolsense/sensor.py
homeassistant/components/poolsense/binary_sensor.py
homeassistant/components/powerwall/__init__.py
homeassistant/components/proliphix/climate.py
homeassistant/components/progettihwsw/__init__.py
homeassistant/components/progettihwsw/binary_sensor.py
Expand Down
15 changes: 4 additions & 11 deletions homeassistant/components/abode/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from requests.exceptions import ConnectTimeout, HTTPError
import voluptuous as vol

from homeassistant.config_entries import SOURCE_IMPORT, SOURCE_REAUTH
from homeassistant.config_entries import SOURCE_IMPORT
from homeassistant.const import (
ATTR_ATTRIBUTION,
ATTR_DATE,
Expand All @@ -20,7 +20,7 @@
CONF_USERNAME,
EVENT_HOMEASSISTANT_STOP,
)
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.dispatcher import dispatcher_send
from homeassistant.helpers.entity import Entity
Expand Down Expand Up @@ -124,17 +124,10 @@ async def async_setup_entry(hass, config_entry):
)

except AbodeAuthenticationException as ex:
LOGGER.error("Invalid credentials: %s", ex)
await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_REAUTH},
data=config_entry.data,
)
return False
raise ConfigEntryAuthFailed(f"Invalid credentials: {ex}") from ex

except (AbodeException, ConnectTimeout, HTTPError) as ex:
LOGGER.error("Unable to connect to Abode: %s", ex)
raise ConfigEntryNotReady from ex
raise ConfigEntryNotReady(f"Unable to connect to Abode: {ex}") from ex

hass.data[DOMAIN] = AbodeSystem(abode, polling)

Expand Down
25 changes: 3 additions & 22 deletions homeassistant/components/airvisual/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
NodeProError,
)

from homeassistant.config_entries import SOURCE_REAUTH
from homeassistant.const import (
ATTR_ATTRIBUTION,
CONF_API_KEY,
Expand All @@ -23,6 +22,7 @@
CONF_STATE,
)
from homeassistant.core import callback
from homeassistant.exceptions import ConfigEntryAuthFailed
from homeassistant.helpers import aiohttp_client, config_validation as cv
from homeassistant.helpers.update_coordinator import (
CoordinatorEntity,
Expand Down Expand Up @@ -206,27 +206,8 @@ async def async_update_data():

try:
return await api_coro
except (InvalidKeyError, KeyExpiredError):
matching_flows = [
flow
for flow in hass.config_entries.flow.async_progress()
if flow["context"]["source"] == SOURCE_REAUTH
and flow["context"]["unique_id"] == config_entry.unique_id
]

if not matching_flows:
hass.async_create_task(
hass.config_entries.flow.async_init(
DOMAIN,
context={
"source": SOURCE_REAUTH,
"unique_id": config_entry.unique_id,
},
data=config_entry.data,
)
)

return {}
except (InvalidKeyError, KeyExpiredError) as ex:
raise ConfigEntryAuthFailed from ex
except AirVisualError as err:
raise UpdateFailed(f"Error while retrieving data: {err}") from err

Expand Down
34 changes: 10 additions & 24 deletions homeassistant/components/august/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@
from yalexs.pubnub_activity import activities_from_pubnub_message
from yalexs.pubnub_async import AugustPubNub, async_create_pubnub

from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntry
from homeassistant.const import CONF_PASSWORD, HTTP_UNAUTHORIZED
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_PASSWORD
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import ConfigEntryNotReady, HomeAssistantError
from homeassistant.exceptions import (
ConfigEntryAuthFailed,
ConfigEntryNotReady,
HomeAssistantError,
)

from .activity import ActivityStream
from .const import DATA_AUGUST, DOMAIN, MIN_TIME_BETWEEN_DETAIL_UPDATES, PLATFORMS
Expand Down Expand Up @@ -43,28 +47,10 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
try:
await august_gateway.async_setup(entry.data)
return await async_setup_august(hass, entry, august_gateway)
except ClientResponseError as err:
if err.status == HTTP_UNAUTHORIZED:
_async_start_reauth(hass, entry)
return False

except (RequireValidation, InvalidAuth) as err:
raise ConfigEntryAuthFailed from err
except (ClientResponseError, CannotConnect, asyncio.TimeoutError) as err:
raise ConfigEntryNotReady from err
except (RequireValidation, InvalidAuth):
_async_start_reauth(hass, entry)
return False
except (CannotConnect, asyncio.TimeoutError) as err:
raise ConfigEntryNotReady from err


def _async_start_reauth(hass: HomeAssistant, entry: ConfigEntry):
hass.async_create_task(
hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_REAUTH},
data=entry.data,
)
)
_LOGGER.error("Password is no longer valid. Please reauthenticate")


async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry):
Expand Down
24 changes: 2 additions & 22 deletions homeassistant/components/awair/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
from python_awair import Awair
from python_awair.exceptions import AuthError

from homeassistant.config_entries import SOURCE_REAUTH
from homeassistant.const import CONF_ACCESS_TOKEN
from homeassistant.exceptions import ConfigEntryAuthFailed
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed

Expand Down Expand Up @@ -74,27 +74,7 @@ async def _async_update_data(self) -> Any | None:
)
return {result.device.uuid: result for result in results}
except AuthError as err:
flow_context = {
"source": SOURCE_REAUTH,
"unique_id": self._config_entry.unique_id,
}

matching_flows = [
flow
for flow in self.hass.config_entries.flow.async_progress()
if flow["context"] == flow_context
]

if not matching_flows:
self.hass.async_create_task(
self.hass.config_entries.flow.async_init(
DOMAIN,
context=flow_context,
data=self._config_entry.data,
)
)

raise UpdateFailed(err) from err
raise ConfigEntryAuthFailed from err
except Exception as err:
raise UpdateFailed(err) from err

Expand Down
10 changes: 3 additions & 7 deletions homeassistant/components/awair/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,9 @@ async def async_step_reauth(self, user_input: dict | None = None):
_, error = await self._check_connection(access_token)

if error is None:
for entry in self._async_current_entries():
if entry.unique_id == self.unique_id:
self.hass.config_entries.async_update_entry(
entry, data=user_input
)

return self.async_abort(reason="reauth_successful")
entry = await self.async_set_unique_id(self.unique_id)
self.hass.config_entries.async_update_entry(entry, data=user_input)
return self.async_abort(reason="reauth_successful")

if error != "invalid_access_token":
return self.async_abort(reason=error)
Expand Down
14 changes: 3 additions & 11 deletions homeassistant/components/axis/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
from homeassistant.components import mqtt
from homeassistant.components.mqtt import DOMAIN as MQTT_DOMAIN
from homeassistant.components.mqtt.models import Message
from homeassistant.config_entries import SOURCE_REAUTH
from homeassistant.const import (
CONF_HOST,
CONF_NAME,
Expand All @@ -23,7 +22,7 @@
CONF_USERNAME,
)
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC
from homeassistant.helpers.dispatcher import async_dispatcher_send
from homeassistant.helpers.httpx_client import get_async_client
Expand Down Expand Up @@ -221,15 +220,8 @@ async def async_setup(self):
except CannotConnect as err:
raise ConfigEntryNotReady from err

except AuthenticationRequired:
self.hass.async_create_task(
self.hass.config_entries.flow.async_init(
AXIS_DOMAIN,
context={"source": SOURCE_REAUTH},
data=self.config_entry.data,
)
)
return False
except AuthenticationRequired as err:
raise ConfigEntryAuthFailed from err

self.fw_version = self.api.vapix.firmware_version
self.product_type = self.api.vapix.product_type
Expand Down
14 changes: 3 additions & 11 deletions homeassistant/components/azure_devops/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
DATA_AZURE_DEVOPS_CLIENT,
DOMAIN,
)
from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntry
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.config_entries import ConfigEntry
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.typing import ConfigType, HomeAssistantType

Expand All @@ -30,17 +30,9 @@ async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry) -> bool
if entry.data[CONF_PAT] is not None:
await client.authorize(entry.data[CONF_PAT], entry.data[CONF_ORG])
if not client.authorized:
_LOGGER.warning(
raise ConfigEntryAuthFailed(
"Could not authorize with Azure DevOps. You may need to update your token"
)
hass.async_create_task(
hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_REAUTH},
data=entry.data,
)
)
return False
await client.get_project(entry.data[CONF_ORG], entry.data[CONF_PROJECT])
except aiohttp.ClientError as exception:
_LOGGER.warning(exception)
Expand Down
21 changes: 10 additions & 11 deletions homeassistant/components/azure_devops/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,17 +105,16 @@ async def async_step_reauth(self, user_input):
if errors is not None:
return await self._show_reauth_form(errors)

for entry in self._async_current_entries():
if entry.unique_id == self.unique_id:
self.hass.config_entries.async_update_entry(
entry,
data={
CONF_ORG: self._organization,
CONF_PROJECT: self._project,
CONF_PAT: self._pat,
},
)
return self.async_abort(reason="reauth_successful")
entry = await self.async_set_unique_id(self.unique_id)
self.hass.config_entries.async_update_entry(
entry,
data={
CONF_ORG: self._organization,
CONF_PROJECT: self._project,
CONF_PAT: self._pat,
},
)
return self.async_abort(reason="reauth_successful")

def _async_create_entry(self):
"""Handle create entry."""
Expand Down
14 changes: 3 additions & 11 deletions homeassistant/components/deconz/gateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@
import async_timeout
from pydeconz import DeconzSession, errors

from homeassistant.config_entries import SOURCE_REAUTH
from homeassistant.const import CONF_API_KEY, CONF_HOST, CONF_PORT
from homeassistant.core import callback
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
from homeassistant.helpers import aiohttp_client
from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC
from homeassistant.helpers.dispatcher import async_dispatcher_send
Expand Down Expand Up @@ -174,15 +173,8 @@ async def async_setup(self) -> bool:
except CannotConnect as err:
raise ConfigEntryNotReady from err

except AuthenticationRequired:
self.hass.async_create_task(
self.hass.config_entries.flow.async_init(
DECONZ_DOMAIN,
context={"source": SOURCE_REAUTH},
data=self.config_entry.data,
)
)
return False
except AuthenticationRequired as err:
raise ConfigEntryAuthFailed from err

for platform in PLATFORMS:
self.hass.async_create_task(
Expand Down
20 changes: 6 additions & 14 deletions homeassistant/components/fireservicerota/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@
from homeassistant.components.binary_sensor import DOMAIN as BINARYSENSOR_DOMAIN
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntry
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_TOKEN, CONF_URL, CONF_USERNAME
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryAuthFailed
from homeassistant.helpers.dispatcher import dispatcher_send
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator

Expand Down Expand Up @@ -109,19 +110,10 @@ async def async_refresh_tokens(self) -> bool:
self._fsr.refresh_tokens
)

except (InvalidAuthError, InvalidTokenError):
_LOGGER.error("Error refreshing tokens, triggered reauth workflow")
self._hass.async_create_task(
self._hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_REAUTH},
data={
**self._entry.data,
},
)
)

return False
except (InvalidAuthError, InvalidTokenError) as err:
raise ConfigEntryAuthFailed(
"Error refreshing tokens, triggered reauth workflow"
) from err

_LOGGER.debug("Saving new tokens in config entry")
self._hass.config_entries.async_update_entry(
Expand Down
9 changes: 4 additions & 5 deletions homeassistant/components/fireservicerota/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,10 @@ async def _validate_and_create_entry(self, user_input, step_id):
if step_id == "user":
return self.async_create_entry(title=self._username, data=data)

for entry in self.hass.config_entries.async_entries(DOMAIN):
if entry.unique_id == self.unique_id:
self.hass.config_entries.async_update_entry(entry, data=data)
await self.hass.config_entries.async_reload(entry.entry_id)
return self.async_abort(reason="reauth_successful")
entry = await self.async_set_unique_id(self.unique_id)
self.hass.config_entries.async_update_entry(entry, data=data)
await self.hass.config_entries.async_reload(entry.entry_id)
return self.async_abort(reason="reauth_successful")

def _show_setup_form(self, user_input=None, errors=None, step_id="user"):
"""Show the setup form to the user."""
Expand Down
Loading

0 comments on commit 4cd7f9b

Please sign in to comment.