mirror of
https://github.com/home-assistant/core.git
synced 2025-07-21 20:27:08 +00:00
Make sure we can set up OAuth based integrations via discovery (#145144)
This commit is contained in:
parent
a2b02537a6
commit
e2a916ff9d
@ -11,6 +11,9 @@
|
||||
"reauth_confirm": {
|
||||
"title": "[%key:common::config_flow::title::reauth%]",
|
||||
"description": "The Home Connect integration needs to re-authenticate your account"
|
||||
},
|
||||
"oauth_discovery": {
|
||||
"description": "Home Assistant has found a Home Connect device on your network. Press **Submit** to continue setting up Home Connect."
|
||||
}
|
||||
},
|
||||
"abort": {
|
||||
|
@ -7,6 +7,9 @@
|
||||
"reauth_confirm": {
|
||||
"title": "[%key:common::config_flow::title::reauth%]",
|
||||
"description": "The Lyric integration needs to re-authenticate your account."
|
||||
},
|
||||
"oauth_discovery": {
|
||||
"description": "Home Assistant has found a Honeywell Lyric device on your network. Press **Submit** to continue setting up Honeywell Lyric."
|
||||
}
|
||||
},
|
||||
"abort": {
|
||||
|
@ -13,6 +13,9 @@
|
||||
"reauth_confirm": {
|
||||
"title": "[%key:common::config_flow::title::reauth%]",
|
||||
"description": "The Miele integration needs to re-authenticate your account"
|
||||
},
|
||||
"oauth_discovery": {
|
||||
"description": "Home Assistant has found a Miele device on your network. Press **Submit** to continue setting up Miele."
|
||||
}
|
||||
},
|
||||
"abort": {
|
||||
|
@ -31,6 +31,7 @@ from homeassistant.helpers.selector import (
|
||||
SelectSelectorConfig,
|
||||
SelectSelectorMode,
|
||||
)
|
||||
from homeassistant.helpers.service_info.dhcp import DhcpServiceInfo
|
||||
from homeassistant.util import get_random_string
|
||||
|
||||
from . import api
|
||||
@ -440,3 +441,9 @@ class NestFlowHandler(
|
||||
if self._structure_config_title:
|
||||
title = self._structure_config_title
|
||||
return self.async_create_entry(title=title, data=self._data)
|
||||
|
||||
async def async_step_dhcp(
|
||||
self, discovery_info: DhcpServiceInfo
|
||||
) -> ConfigFlowResult:
|
||||
"""Handle a flow initialized by discovery."""
|
||||
return await self.async_step_user()
|
||||
|
@ -7,6 +7,9 @@
|
||||
"reauth_confirm": {
|
||||
"title": "[%key:common::config_flow::title::reauth%]",
|
||||
"description": "The Spotify integration needs to re-authenticate with Spotify for account: {account}"
|
||||
},
|
||||
"oauth_discovery": {
|
||||
"description": "Home Assistant has found Spotify on your network. Press **Submit** to continue setting up Spotify."
|
||||
}
|
||||
},
|
||||
"abort": {
|
||||
|
@ -7,6 +7,9 @@
|
||||
"reauth_confirm": {
|
||||
"title": "[%key:common::config_flow::title::reauth%]",
|
||||
"description": "The Withings integration needs to re-authenticate your account"
|
||||
},
|
||||
"oauth_discovery": {
|
||||
"description": "Home Assistant has found a Withings device on your network. Press **Submit** to continue setting up Withings."
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
|
@ -22,6 +22,7 @@ import time
|
||||
from typing import Any, cast
|
||||
|
||||
from aiohttp import ClientError, ClientResponseError, client, web
|
||||
from habluetooth import BluetoothServiceInfoBleak
|
||||
import jwt
|
||||
import voluptuous as vol
|
||||
from yarl import URL
|
||||
@ -34,6 +35,9 @@ from homeassistant.util.hass_dict import HassKey
|
||||
from . import http
|
||||
from .aiohttp_client import async_get_clientsession
|
||||
from .network import NoURLAvailableError
|
||||
from .service_info.dhcp import DhcpServiceInfo
|
||||
from .service_info.ssdp import SsdpServiceInfo
|
||||
from .service_info.zeroconf import ZeroconfServiceInfo
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@ -493,6 +497,45 @@ class AbstractOAuth2FlowHandler(config_entries.ConfigFlow, metaclass=ABCMeta):
|
||||
"""Handle a flow start."""
|
||||
return await self.async_step_pick_implementation(user_input)
|
||||
|
||||
async def async_step_bluetooth(
|
||||
self, discovery_info: BluetoothServiceInfoBleak
|
||||
) -> config_entries.ConfigFlowResult:
|
||||
"""Handle a flow initialized by Bluetooth discovery."""
|
||||
return await self.async_step_oauth_discovery()
|
||||
|
||||
async def async_step_dhcp(
|
||||
self, discovery_info: DhcpServiceInfo
|
||||
) -> config_entries.ConfigFlowResult:
|
||||
"""Handle a flow initialized by DHCP discovery."""
|
||||
return await self.async_step_oauth_discovery()
|
||||
|
||||
async def async_step_homekit(
|
||||
self, discovery_info: ZeroconfServiceInfo
|
||||
) -> config_entries.ConfigFlowResult:
|
||||
"""Handle a flow initialized by Homekit discovery."""
|
||||
return await self.async_step_oauth_discovery()
|
||||
|
||||
async def async_step_ssdp(
|
||||
self, discovery_info: SsdpServiceInfo
|
||||
) -> config_entries.ConfigFlowResult:
|
||||
"""Handle a flow initialized by SSDP discovery."""
|
||||
return await self.async_step_oauth_discovery()
|
||||
|
||||
async def async_step_zeroconf(
|
||||
self, discovery_info: ZeroconfServiceInfo
|
||||
) -> config_entries.ConfigFlowResult:
|
||||
"""Handle a flow initialized by Zeroconf discovery."""
|
||||
return await self.async_step_oauth_discovery()
|
||||
|
||||
async def async_step_oauth_discovery(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> config_entries.ConfigFlowResult:
|
||||
"""Handle a flow initialized by a discovery method."""
|
||||
if user_input is not None:
|
||||
return await self.async_step_user()
|
||||
await self._async_handle_discovery_without_unique_id()
|
||||
return self.async_show_form(step_id="oauth_discovery")
|
||||
|
||||
@classmethod
|
||||
def async_register_implementation(
|
||||
cls, hass: HomeAssistant, local_impl: LocalOAuth2Implementation
|
||||
|
@ -279,6 +279,15 @@ async def test_zeroconf_flow(
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": config_entries.SOURCE_ZEROCONF}
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "oauth_discovery"
|
||||
assert not result["errors"]
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{},
|
||||
)
|
||||
state = config_entry_oauth2_flow._encode_jwt(
|
||||
hass,
|
||||
{
|
||||
@ -351,6 +360,15 @@ async def test_dhcp_flow(
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": config_entries.SOURCE_DHCP}, data=dhcp_discovery
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "oauth_discovery"
|
||||
assert not result["errors"]
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{},
|
||||
)
|
||||
state = config_entry_oauth2_flow._encode_jwt(
|
||||
hass,
|
||||
{
|
||||
|
@ -225,6 +225,16 @@ async def test_zeroconf_flow(
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_ZEROCONF}
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "oauth_discovery"
|
||||
assert not result["errors"]
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{},
|
||||
)
|
||||
|
||||
state = config_entry_oauth2_flow._encode_jwt(
|
||||
hass,
|
||||
{
|
||||
|
@ -38,13 +38,6 @@ async def test_abort_if_no_configuration(hass: HomeAssistant) -> None:
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
assert result["reason"] == "missing_credentials"
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_ZEROCONF}, data=BLANK_ZEROCONF_INFO
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
assert result["reason"] == "missing_credentials"
|
||||
|
||||
|
||||
async def test_zeroconf_abort_if_existing_entry(hass: HomeAssistant) -> None:
|
||||
"""Check zeroconf flow aborts when an entry already exist."""
|
||||
@ -265,3 +258,18 @@ async def test_reauth_account_mismatch(
|
||||
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
assert result["reason"] == "reauth_account_mismatch"
|
||||
|
||||
|
||||
async def test_zeroconf(hass: HomeAssistant) -> None:
|
||||
"""Check zeroconf flow aborts when an entry already exist."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_ZEROCONF}, data=BLANK_ZEROCONF_INFO
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "oauth_discovery"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
|
||||
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
assert result["reason"] == "missing_credentials"
|
||||
|
@ -312,6 +312,15 @@ async def test_dhcp(
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_DHCP}, data=service_info
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "oauth_discovery"
|
||||
assert not result["errors"]
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{},
|
||||
)
|
||||
state = config_entry_oauth2_flow._encode_jwt(
|
||||
hass,
|
||||
{
|
||||
|
@ -397,6 +397,14 @@ async def test_step_discovery(
|
||||
data=data_entry_flow.BaseServiceInfo(),
|
||||
)
|
||||
|
||||
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
||||
assert result["step_id"] == "oauth_discovery"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={},
|
||||
)
|
||||
|
||||
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
||||
assert result["step_id"] == "pick_implementation"
|
||||
|
||||
@ -418,6 +426,11 @@ async def test_abort_discovered_multiple(
|
||||
data=data_entry_flow.BaseServiceInfo(),
|
||||
)
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={},
|
||||
)
|
||||
|
||||
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
||||
assert result["step_id"] == "pick_implementation"
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user