Move Local OAuth http endpoint registration to auth component (#69507)

This commit is contained in:
Allen Porter 2022-04-06 22:34:31 -07:00 committed by GitHub
parent 8ef7ac1877
commit c07100e519
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 25 additions and 24 deletions

View File

@ -3,7 +3,7 @@
"name": "Almond", "name": "Almond",
"config_flow": true, "config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/almond", "documentation": "https://www.home-assistant.io/integrations/almond",
"dependencies": ["http", "conversation"], "dependencies": ["auth", "conversation"],
"codeowners": ["@gcampax", "@balloob"], "codeowners": ["@gcampax", "@balloob"],
"requirements": ["pyalmond==0.0.2"], "requirements": ["pyalmond==0.0.2"],
"iot_class": "local_polling", "iot_class": "local_polling",

View File

@ -113,6 +113,12 @@ Result will be a long-lived access token:
"result": "ABCDEFGH" "result": "ABCDEFGH"
} }
# POST /auth/external/callback
This is an endpoint for OAuth2 Authorization callbacks used by integrations
that link accounts with other cloud providers using LocalOAuth2Implementation
as part of a config flow.
""" """
from __future__ import annotations from __future__ import annotations
@ -134,6 +140,7 @@ from homeassistant.components.http.ban import log_invalid_auth
from homeassistant.components.http.data_validator import RequestDataValidator from homeassistant.components.http.data_validator import RequestDataValidator
from homeassistant.components.http.view import HomeAssistantView from homeassistant.components.http.view import HomeAssistantView
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.config_entry_oauth2_flow import OAuth2AuthorizeCallbackView
from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.typing import ConfigType
from homeassistant.loader import bind_hass from homeassistant.loader import bind_hass
from homeassistant.util import dt as dt_util from homeassistant.util import dt as dt_util
@ -195,6 +202,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
hass.http.register_view(TokenView(retrieve_result)) hass.http.register_view(TokenView(retrieve_result))
hass.http.register_view(LinkUserView(retrieve_result)) hass.http.register_view(LinkUserView(retrieve_result))
hass.http.register_view(OAuth2AuthorizeCallbackView())
websocket_api.async_register_command( websocket_api.async_register_command(
hass, WS_TYPE_CURRENT_USER, websocket_current_user, SCHEMA_WS_CURRENT_USER hass, WS_TYPE_CURRENT_USER, websocket_current_user, SCHEMA_WS_CURRENT_USER

View File

@ -2,7 +2,7 @@
"domain": "google", "domain": "google",
"name": "Google Calendars", "name": "Google Calendars",
"config_flow": true, "config_flow": true,
"dependencies": ["http"], "dependencies": ["auth"],
"documentation": "https://www.home-assistant.io/integrations/calendar.google/", "documentation": "https://www.home-assistant.io/integrations/calendar.google/",
"requirements": [ "requirements": [
"google-api-python-client==2.38.0", "google-api-python-client==2.38.0",

View File

@ -2,7 +2,7 @@
"domain": "home_connect", "domain": "home_connect",
"name": "Home Connect", "name": "Home Connect",
"documentation": "https://www.home-assistant.io/integrations/home_connect", "documentation": "https://www.home-assistant.io/integrations/home_connect",
"dependencies": ["http"], "dependencies": ["auth"],
"codeowners": ["@DavidMStraub"], "codeowners": ["@DavidMStraub"],
"requirements": ["homeconnect==0.7.0"], "requirements": ["homeconnect==0.7.0"],
"config_flow": true, "config_flow": true,

View File

@ -4,7 +4,7 @@
"config_flow": true, "config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/home_plus_control", "documentation": "https://www.home-assistant.io/integrations/home_plus_control",
"requirements": ["homepluscontrol==0.0.5"], "requirements": ["homepluscontrol==0.0.5"],
"dependencies": ["http"], "dependencies": ["auth"],
"codeowners": ["@chemaaa"], "codeowners": ["@chemaaa"],
"iot_class": "cloud_polling", "iot_class": "cloud_polling",
"loggers": ["homepluscontrol"] "loggers": ["homepluscontrol"]

View File

@ -3,7 +3,7 @@
"name": "Honeywell Lyric", "name": "Honeywell Lyric",
"config_flow": true, "config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/lyric", "documentation": "https://www.home-assistant.io/integrations/lyric",
"dependencies": ["http"], "dependencies": ["auth"],
"requirements": ["aiolyric==1.0.8"], "requirements": ["aiolyric==1.0.8"],
"codeowners": ["@timmo001"], "codeowners": ["@timmo001"],
"quality_scale": "silver", "quality_scale": "silver",

View File

@ -5,7 +5,7 @@
"documentation": "https://www.home-assistant.io/integrations/neato", "documentation": "https://www.home-assistant.io/integrations/neato",
"requirements": ["pybotvac==0.0.23"], "requirements": ["pybotvac==0.0.23"],
"codeowners": ["@dshokouhi", "@Santobert"], "codeowners": ["@dshokouhi", "@Santobert"],
"dependencies": ["http"], "dependencies": ["auth"],
"iot_class": "cloud_polling", "iot_class": "cloud_polling",
"loggers": ["pybotvac"] "loggers": ["pybotvac"]
} }

View File

@ -2,7 +2,7 @@
"domain": "nest", "domain": "nest",
"name": "Nest", "name": "Nest",
"config_flow": true, "config_flow": true,
"dependencies": ["ffmpeg", "http"], "dependencies": ["ffmpeg", "http", "auth"],
"after_dependencies": ["media_source"], "after_dependencies": ["media_source"],
"documentation": "https://www.home-assistant.io/integrations/nest", "documentation": "https://www.home-assistant.io/integrations/nest",
"requirements": ["python-nest==4.2.0", "google-nest-sdm==1.8.0"], "requirements": ["python-nest==4.2.0", "google-nest-sdm==1.8.0"],

View File

@ -4,7 +4,7 @@
"documentation": "https://www.home-assistant.io/integrations/netatmo", "documentation": "https://www.home-assistant.io/integrations/netatmo",
"requirements": ["pyatmo==6.2.4"], "requirements": ["pyatmo==6.2.4"],
"after_dependencies": ["cloud", "media_source"], "after_dependencies": ["cloud", "media_source"],
"dependencies": ["webhook"], "dependencies": ["auth", "webhook"],
"codeowners": ["@cgtobi"], "codeowners": ["@cgtobi"],
"config_flow": true, "config_flow": true,
"homekit": { "homekit": {

View File

@ -4,7 +4,7 @@
"config_flow": true, "config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/ondilo_ico", "documentation": "https://www.home-assistant.io/integrations/ondilo_ico",
"requirements": ["ondilo==0.2.0"], "requirements": ["ondilo==0.2.0"],
"dependencies": ["http"], "dependencies": ["auth"],
"codeowners": ["@JeromeHXP"], "codeowners": ["@JeromeHXP"],
"iot_class": "cloud_polling", "iot_class": "cloud_polling",
"loggers": ["ondilo"] "loggers": ["ondilo"]

View File

@ -3,7 +3,7 @@
"name": "Smappee", "name": "Smappee",
"config_flow": true, "config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/smappee", "documentation": "https://www.home-assistant.io/integrations/smappee",
"dependencies": ["http"], "dependencies": ["auth"],
"requirements": ["pysmappee==0.2.29"], "requirements": ["pysmappee==0.2.29"],
"codeowners": ["@bsmappee"], "codeowners": ["@bsmappee"],
"zeroconf": [ "zeroconf": [

View File

@ -3,7 +3,7 @@
"name": "Somfy", "name": "Somfy",
"config_flow": true, "config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/somfy", "documentation": "https://www.home-assistant.io/integrations/somfy",
"dependencies": ["http"], "dependencies": ["auth"],
"codeowners": ["@tetienne"], "codeowners": ["@tetienne"],
"requirements": ["pymfy==0.11.0"], "requirements": ["pymfy==0.11.0"],
"zeroconf": [ "zeroconf": [

View File

@ -4,7 +4,7 @@
"documentation": "https://www.home-assistant.io/integrations/spotify", "documentation": "https://www.home-assistant.io/integrations/spotify",
"requirements": ["spotipy==2.19.0"], "requirements": ["spotipy==2.19.0"],
"zeroconf": ["_spotify-connect._tcp.local."], "zeroconf": ["_spotify-connect._tcp.local."],
"dependencies": ["http"], "dependencies": ["auth"],
"codeowners": ["@frenck"], "codeowners": ["@frenck"],
"config_flow": true, "config_flow": true,
"quality_scale": "silver", "quality_scale": "silver",

View File

@ -4,7 +4,7 @@
"config_flow": true, "config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/toon", "documentation": "https://www.home-assistant.io/integrations/toon",
"requirements": ["toonapi==0.2.1"], "requirements": ["toonapi==0.2.1"],
"dependencies": ["http"], "dependencies": ["auth"],
"after_dependencies": ["cloud"], "after_dependencies": ["cloud"],
"codeowners": [], "codeowners": [],
"dhcp": [ "dhcp": [

View File

@ -4,7 +4,7 @@
"config_flow": true, "config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/withings", "documentation": "https://www.home-assistant.io/integrations/withings",
"requirements": ["withings-api==2.4.0"], "requirements": ["withings-api==2.4.0"],
"dependencies": ["http", "webhook"], "dependencies": ["auth", "http", "webhook"],
"codeowners": ["@vangorra"], "codeowners": ["@vangorra"],
"iot_class": "cloud_polling", "iot_class": "cloud_polling",
"loggers": ["withings_api"] "loggers": ["withings_api"]

View File

@ -4,7 +4,7 @@
"config_flow": true, "config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/xbox", "documentation": "https://www.home-assistant.io/integrations/xbox",
"requirements": ["xbox-webapi==2.0.11"], "requirements": ["xbox-webapi==2.0.11"],
"dependencies": ["http"], "dependencies": ["auth"],
"codeowners": ["@hunterjm"], "codeowners": ["@hunterjm"],
"iot_class": "cloud_polling" "iot_class": "cloud_polling"
} }

View File

@ -32,7 +32,6 @@ from .network import NoURLAvailableError
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
DATA_JWT_SECRET = "oauth2_jwt_secret" DATA_JWT_SECRET = "oauth2_jwt_secret"
DATA_VIEW_REGISTERED = "oauth2_view_reg"
DATA_IMPLEMENTATIONS = "oauth2_impl" DATA_IMPLEMENTATIONS = "oauth2_impl"
DATA_PROVIDERS = "oauth2_providers" DATA_PROVIDERS = "oauth2_providers"
AUTH_CALLBACK_PATH = "/auth/external/callback" AUTH_CALLBACK_PATH = "/auth/external/callback"
@ -331,12 +330,6 @@ def async_register_implementation(
hass: HomeAssistant, domain: str, implementation: AbstractOAuth2Implementation hass: HomeAssistant, domain: str, implementation: AbstractOAuth2Implementation
) -> None: ) -> None:
"""Register an OAuth2 flow implementation for an integration.""" """Register an OAuth2 flow implementation for an integration."""
if isinstance(implementation, LocalOAuth2Implementation) and not hass.data.get(
DATA_VIEW_REGISTERED, False
):
hass.http.register_view(OAuth2AuthorizeCallbackView())
hass.data[DATA_VIEW_REGISTERED] = True
implementations = hass.data.setdefault(DATA_IMPLEMENTATIONS, {}) implementations = hass.data.setdefault(DATA_IMPLEMENTATIONS, {})
implementations.setdefault(domain, {})[implementation.domain] = implementation implementations.setdefault(domain, {})[implementation.domain] = implementation

View File

@ -173,7 +173,7 @@ def _custom_tasks(template, info: Info) -> None:
) )
elif template == "config_flow_oauth2": elif template == "config_flow_oauth2":
info.update_manifest(config_flow=True, dependencies=["http"]) info.update_manifest(config_flow=True, dependencies=["auth"])
info.update_strings( info.update_strings(
config={ config={
"step": { "step": {

View File

@ -26,7 +26,7 @@ TOKEN_URL = "https://example.como/auth/token"
@pytest.fixture @pytest.fixture
async def local_impl(hass): async def local_impl(hass):
"""Local implementation.""" """Local implementation."""
assert await setup.async_setup_component(hass, "http", {}) assert await setup.async_setup_component(hass, "auth", {})
return config_entry_oauth2_flow.LocalOAuth2Implementation( return config_entry_oauth2_flow.LocalOAuth2Implementation(
hass, TEST_DOMAIN, CLIENT_ID, CLIENT_SECRET, AUTHORIZE_URL, TOKEN_URL hass, TEST_DOMAIN, CLIENT_ID, CLIENT_SECRET, AUTHORIZE_URL, TOKEN_URL
) )