Introduce reauthentication flow to UniFi integration (#45360)

* Improve site selection

* Reauth flow and tests
Add **kwargs to mock_aiohttp_client create_session to support inputting verify_ssl and cookie_jar

* Update homeassistant/components/unifi/config_flow.py

Co-authored-by: J. Nick Koston <nick@koston.org>

* Minor improvements

* Improve coverage

Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
Robert Svensson 2021-01-20 22:10:40 +01:00 committed by GitHub
parent 7ff02fe8d4
commit da4404e8cf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 157 additions and 38 deletions

View file

@ -28,6 +28,7 @@ import async_timeout
from homeassistant.components.device_tracker import DOMAIN as TRACKER_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
from homeassistant.const import CONF_HOST
from homeassistant.core import callback
from homeassistant.exceptions import ConfigEntryNotReady
@ -343,8 +344,14 @@ class UniFiController:
except CannotConnect as err:
raise ConfigEntryNotReady from err
except Exception as err: # pylint: disable=broad-except
LOGGER.error("Unknown error connecting with UniFi controller: %s", err)
except AuthenticationRequired:
self.hass.async_create_task(
self.hass.config_entries.flow.async_init(
UNIFI_DOMAIN,
context={"source": SOURCE_REAUTH},
data=self.config_entry,
)
)
return False
# Restore clients that is not a part of active clients list.
@ -419,7 +426,13 @@ class UniFiController:
@staticmethod
async def async_config_entry_updated(hass, config_entry) -> None:
"""Handle signals of config entry being updated."""
"""Handle signals of config entry being updated.
If config entry is updated due to reauth flow
the entry might already have been reset and thus is not available.
"""
if config_entry.entry_id not in hass.data[UNIFI_DOMAIN]:
return
controller = hass.data[UNIFI_DOMAIN][config_entry.entry_id]
async_dispatcher_send(hass, controller.signal_options_update)
@ -510,7 +523,7 @@ async def get_controller(
return controller
except aiounifi.Unauthorized as err:
LOGGER.warning("Connected to UniFi at %s but not registered.", host)
LOGGER.warning("Connected to UniFi at %s but not registered: %s", host, err)
raise AuthenticationRequired from err
except (
@ -519,9 +532,13 @@ async def get_controller(
aiounifi.ServiceUnavailable,
aiounifi.RequestError,
) as err:
LOGGER.error("Error connecting to the UniFi controller at %s", host)
LOGGER.error("Error connecting to the UniFi controller at %s: %s", host, err)
raise CannotConnect from err
except aiounifi.AiounifiException as err:
LOGGER.exception("Unknown UniFi communication error occurred")
except aiounifi.LoginRequired as err:
LOGGER.warning("Connected to UniFi at %s but login required: %s", host, err)
raise AuthenticationRequired from err
except aiounifi.AiounifiException as err:
LOGGER.exception("Unknown UniFi communication error occurred: %s", err)
raise AuthenticationRequired from err