mirror of
https://github.com/home-assistant/core.git
synced 2025-07-15 17:27: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,
|
EntityInfo,
|
||||||
EntityState,
|
EntityState,
|
||||||
HomeassistantServiceCall,
|
HomeassistantServiceCall,
|
||||||
|
InvalidAuthAPIError,
|
||||||
InvalidEncryptionKeyAPIError,
|
InvalidEncryptionKeyAPIError,
|
||||||
ReconnectLogic,
|
ReconnectLogic,
|
||||||
RequiresEncryptionAPIError,
|
RequiresEncryptionAPIError,
|
||||||
@ -347,7 +348,14 @@ async def async_setup_entry( # noqa: C901
|
|||||||
|
|
||||||
async def on_connect_error(err: Exception) -> None:
|
async def on_connect_error(err: Exception) -> None:
|
||||||
"""Start reauth flow if appropriate connect error type."""
|
"""Start reauth flow if appropriate connect error type."""
|
||||||
if isinstance(err, (RequiresEncryptionAPIError, InvalidEncryptionKeyAPIError)):
|
if isinstance(
|
||||||
|
err,
|
||||||
|
(
|
||||||
|
RequiresEncryptionAPIError,
|
||||||
|
InvalidEncryptionKeyAPIError,
|
||||||
|
InvalidAuthAPIError,
|
||||||
|
),
|
||||||
|
):
|
||||||
entry.async_start_reauth(hass)
|
entry.async_start_reauth(hass)
|
||||||
|
|
||||||
reconnect_logic = ReconnectLogic(
|
reconnect_logic = ReconnectLogic(
|
||||||
|
@ -92,6 +92,19 @@ class EsphomeFlowHandler(ConfigFlow, domain=DOMAIN):
|
|||||||
self._name = entry.title
|
self._name = entry.title
|
||||||
self._device_name = entry.data.get(CONF_DEVICE_NAME)
|
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()
|
return await self.async_step_reauth_confirm()
|
||||||
|
|
||||||
async def 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
|
assert len(mock_get_encryption_key.mock_calls) == 1
|
||||||
|
|
||||||
|
|
||||||
async def test_reauth_fixed_via_dashboard_remove_password(
|
async def test_reauth_fixed_via_dashboard_add_encryption_remove_password(
|
||||||
hass, mock_client, mock_zeroconf, mock_dashboard
|
hass, mock_client, mock_zeroconf, mock_dashboard, mock_config_entry
|
||||||
):
|
):
|
||||||
"""Test reauth fixed automatically via dashboard with password removed."""
|
"""Test reauth fixed automatically via dashboard with password removed."""
|
||||||
|
mock_client.device_info.side_effect = (
|
||||||
entry = MockConfigEntry(
|
InvalidAuthAPIError,
|
||||||
domain=DOMAIN,
|
DeviceInfo(uses_password=False, name="test"),
|
||||||
data={
|
|
||||||
CONF_HOST: "127.0.0.1",
|
|
||||||
CONF_PORT: 6053,
|
|
||||||
CONF_PASSWORD: "hello",
|
|
||||||
CONF_DEVICE_NAME: "test",
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
entry.add_to_hass(hass)
|
|
||||||
|
|
||||||
mock_client.device_info.return_value = DeviceInfo(uses_password=False, name="test")
|
|
||||||
|
|
||||||
mock_dashboard["configured"].append(
|
mock_dashboard["configured"].append(
|
||||||
{
|
{
|
||||||
@ -554,19 +545,37 @@ async def test_reauth_fixed_via_dashboard_remove_password(
|
|||||||
"esphome",
|
"esphome",
|
||||||
context={
|
context={
|
||||||
"source": config_entries.SOURCE_REAUTH,
|
"source": config_entries.SOURCE_REAUTH,
|
||||||
"entry_id": entry.entry_id,
|
"entry_id": mock_config_entry.entry_id,
|
||||||
"unique_id": entry.unique_id,
|
"unique_id": mock_config_entry.unique_id,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result["type"] == FlowResultType.ABORT, result
|
assert result["type"] == FlowResultType.ABORT, result
|
||||||
assert result["reason"] == "reauth_successful"
|
assert result["reason"] == "reauth_successful"
|
||||||
assert entry.data[CONF_NOISE_PSK] == VALID_NOISE_PSK
|
assert mock_config_entry.data[CONF_NOISE_PSK] == VALID_NOISE_PSK
|
||||||
assert entry.data[CONF_PASSWORD] == ""
|
assert mock_config_entry.data[CONF_PASSWORD] == ""
|
||||||
|
|
||||||
assert len(mock_get_encryption_key.mock_calls) == 1
|
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(
|
async def test_reauth_fixed_via_dashboard_at_confirm(
|
||||||
hass, mock_client, mock_zeroconf, mock_dashboard
|
hass, mock_client, mock_zeroconf, mock_dashboard
|
||||||
):
|
):
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
"""Test ESPHome dashboard features."""
|
"""Test ESPHome dashboard features."""
|
||||||
from unittest.mock import patch
|
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.components.esphome import CONF_NOISE_PSK, dashboard
|
||||||
from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntryState
|
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
|
hass, mock_client, mock_config_entry, mock_dashboard
|
||||||
):
|
):
|
||||||
"""Test config entries waiting for reauth are triggered."""
|
"""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(
|
with patch(
|
||||||
"homeassistant.components.esphome.dashboard.ESPHomeDashboardAPI.get_encryption_key",
|
"homeassistant.components.esphome.dashboard.ESPHomeDashboardAPI.get_encryption_key",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user