mirror of
https://github.com/home-assistant/core.git
synced 2025-07-14 16:57:10 +00:00
ESPHome handle remove password and no encryption (#86995)
* ESPHome handle remove password and no encryption * Start reauth for invalid api password --------- Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
parent
e706696271
commit
d88849fb04
@ -17,6 +17,7 @@ from aioesphomeapi import (
|
||||
EntityInfo,
|
||||
EntityState,
|
||||
HomeassistantServiceCall,
|
||||
InvalidAuthAPIError,
|
||||
InvalidEncryptionKeyAPIError,
|
||||
ReconnectLogic,
|
||||
RequiresEncryptionAPIError,
|
||||
@ -347,7 +348,14 @@ async def async_setup_entry( # noqa: C901
|
||||
|
||||
async def on_connect_error(err: Exception) -> None:
|
||||
"""Start reauth flow if appropriate connect error type."""
|
||||
if isinstance(err, (RequiresEncryptionAPIError, InvalidEncryptionKeyAPIError)):
|
||||
if isinstance(
|
||||
err,
|
||||
(
|
||||
RequiresEncryptionAPIError,
|
||||
InvalidEncryptionKeyAPIError,
|
||||
InvalidAuthAPIError,
|
||||
),
|
||||
):
|
||||
entry.async_start_reauth(hass)
|
||||
|
||||
reconnect_logic = ReconnectLogic(
|
||||
|
@ -92,6 +92,19 @@ class EsphomeFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
self._name = entry.title
|
||||
self._device_name = entry.data.get(CONF_DEVICE_NAME)
|
||||
|
||||
# Device without encryption allows fetching device info. We can then check
|
||||
# if the device is no longer using a password. If we did try with a password,
|
||||
# we know setting password to empty will allow us to authenticate.
|
||||
error = await self.fetch_device_info()
|
||||
if (
|
||||
error is None
|
||||
and self._password
|
||||
and self._device_info
|
||||
and not self._device_info.uses_password
|
||||
):
|
||||
self._password = ""
|
||||
return await self._async_authenticate_or_add()
|
||||
|
||||
return await self.async_step_reauth_confirm()
|
||||
|
||||
async def async_step_reauth_confirm(
|
||||
|
@ -519,23 +519,14 @@ async def test_reauth_fixed_via_dashboard(
|
||||
assert len(mock_get_encryption_key.mock_calls) == 1
|
||||
|
||||
|
||||
async def test_reauth_fixed_via_dashboard_remove_password(
|
||||
hass, mock_client, mock_zeroconf, mock_dashboard
|
||||
async def test_reauth_fixed_via_dashboard_add_encryption_remove_password(
|
||||
hass, mock_client, mock_zeroconf, mock_dashboard, mock_config_entry
|
||||
):
|
||||
"""Test reauth fixed automatically via dashboard with password removed."""
|
||||
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
data={
|
||||
CONF_HOST: "127.0.0.1",
|
||||
CONF_PORT: 6053,
|
||||
CONF_PASSWORD: "hello",
|
||||
CONF_DEVICE_NAME: "test",
|
||||
},
|
||||
mock_client.device_info.side_effect = (
|
||||
InvalidAuthAPIError,
|
||||
DeviceInfo(uses_password=False, name="test"),
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
mock_client.device_info.return_value = DeviceInfo(uses_password=False, name="test")
|
||||
|
||||
mock_dashboard["configured"].append(
|
||||
{
|
||||
@ -554,19 +545,37 @@ async def test_reauth_fixed_via_dashboard_remove_password(
|
||||
"esphome",
|
||||
context={
|
||||
"source": config_entries.SOURCE_REAUTH,
|
||||
"entry_id": entry.entry_id,
|
||||
"unique_id": entry.unique_id,
|
||||
"entry_id": mock_config_entry.entry_id,
|
||||
"unique_id": mock_config_entry.unique_id,
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] == FlowResultType.ABORT, result
|
||||
assert result["reason"] == "reauth_successful"
|
||||
assert entry.data[CONF_NOISE_PSK] == VALID_NOISE_PSK
|
||||
assert entry.data[CONF_PASSWORD] == ""
|
||||
assert mock_config_entry.data[CONF_NOISE_PSK] == VALID_NOISE_PSK
|
||||
assert mock_config_entry.data[CONF_PASSWORD] == ""
|
||||
|
||||
assert len(mock_get_encryption_key.mock_calls) == 1
|
||||
|
||||
|
||||
async def test_reauth_fixed_via_remove_password(hass, mock_client, mock_config_entry):
|
||||
"""Test reauth fixed automatically by seeing password removed."""
|
||||
mock_client.device_info.return_value = DeviceInfo(uses_password=False, name="test")
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
"esphome",
|
||||
context={
|
||||
"source": config_entries.SOURCE_REAUTH,
|
||||
"entry_id": mock_config_entry.entry_id,
|
||||
"unique_id": mock_config_entry.unique_id,
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] == FlowResultType.ABORT, result
|
||||
assert result["reason"] == "reauth_successful"
|
||||
assert mock_config_entry.data[CONF_PASSWORD] == ""
|
||||
|
||||
|
||||
async def test_reauth_fixed_via_dashboard_at_confirm(
|
||||
hass, mock_client, mock_zeroconf, mock_dashboard
|
||||
):
|
||||
|
@ -1,7 +1,7 @@
|
||||
"""Test ESPHome dashboard features."""
|
||||
from unittest.mock import patch
|
||||
|
||||
from aioesphomeapi import DeviceInfo
|
||||
from aioesphomeapi import DeviceInfo, InvalidAuthAPIError
|
||||
|
||||
from homeassistant.components.esphome import CONF_NOISE_PSK, dashboard
|
||||
from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntryState
|
||||
@ -31,7 +31,10 @@ async def test_new_dashboard_fix_reauth(
|
||||
hass, mock_client, mock_config_entry, mock_dashboard
|
||||
):
|
||||
"""Test config entries waiting for reauth are triggered."""
|
||||
mock_client.device_info.return_value = DeviceInfo(uses_password=False, name="test")
|
||||
mock_client.device_info.side_effect = (
|
||||
InvalidAuthAPIError,
|
||||
DeviceInfo(uses_password=False, name="test"),
|
||||
)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.esphome.dashboard.ESPHomeDashboardAPI.get_encryption_key",
|
||||
|
Loading…
x
Reference in New Issue
Block a user