diff --git a/homeassistant/components/http/__init__.py b/homeassistant/components/http/__init__.py index 63c88427a5b..d09cfe754a9 100644 --- a/homeassistant/components/http/__init__.py +++ b/homeassistant/components/http/__init__.py @@ -4,7 +4,6 @@ from ipaddress import ip_network import logging import os import ssl -from traceback import extract_stack from typing import Dict, Optional, cast from aiohttp import web @@ -125,69 +124,6 @@ class ApiConfig: self.port = port self.use_ssl = use_ssl - host = host.rstrip("/") - if host.startswith(("http://", "https://")): - self.deprecated_base_url = host - elif use_ssl: - self.deprecated_base_url = f"https://{host}" - else: - self.deprecated_base_url = f"http://{host}" - - if port is not None: - self.deprecated_base_url += f":{port}" - - @property - def base_url(self) -> str: - """Proxy property to find caller of this deprecated property.""" - found_frame = None - for frame in reversed(extract_stack()[:-1]): - for path in ("custom_components/", "homeassistant/components/"): - try: - index = frame.filename.index(path) - - # Skip webhook from the stack - if frame.filename[index:].startswith( - "homeassistant/components/webhook/" - ): - continue - - found_frame = frame - break - except ValueError: - continue - - if found_frame is not None: - break - - # Did not source from an integration? Hard error. - if found_frame is None: - raise RuntimeError( - "Detected use of deprecated `base_url` property in the Home Assistant core. Please report this issue." - ) - - # If a frame was found, it originated from an integration - if found_frame: - start = index + len(path) - end = found_frame.filename.index("/", start) - - integration = found_frame.filename[start:end] - - if path == "custom_components/": - extra = " to the custom component author" - else: - extra = "" - - _LOGGER.warning( - "Detected use of deprecated `base_url` property, use `homeassistant.helpers.network.get_url` method instead. Please report issue%s for %s using this method at %s, line %s: %s", - extra, - integration, - found_frame.filename[index:], - found_frame.lineno, - found_frame.line.strip(), - ) - - return self.deprecated_base_url - async def async_setup(hass, config): """Set up the HTTP API and debug interface.""" @@ -256,20 +192,16 @@ async def async_setup(hass, config): hass.http = server - host = conf.get(CONF_BASE_URL) local_ip = await hass.async_add_executor_job(hass_util.get_local_ip) - if host: - port = None - elif server_host is not None: + host = local_ip + if server_host is not None: # Assume the first server host name provided as API host host = server_host[0] - port = server_port - else: - host = local_ip - port = server_port - hass.config.api = ApiConfig(local_ip, host, port, ssl_certificate is not None) + hass.config.api = ApiConfig( + local_ip, host, server_port, ssl_certificate is not None + ) return True diff --git a/homeassistant/core.py b/homeassistant/core.py index 13f8b153047..fff16cdd31f 100644 --- a/homeassistant/core.py +++ b/homeassistant/core.py @@ -8,7 +8,6 @@ import asyncio import datetime import enum import functools -from ipaddress import ip_address import logging import os import pathlib @@ -70,7 +69,7 @@ from homeassistant.exceptions import ( ServiceNotFound, Unauthorized, ) -from homeassistant.util import location, network +from homeassistant.util import location from homeassistant.util.async_ import ( fire_coroutine_threadsafe, run_callback_threadsafe, @@ -1687,39 +1686,7 @@ class Config: ) data = await store.async_load() - async def migrate_base_url(_: Event) -> None: - """Migrate base_url to internal_url/external_url.""" - if self.hass.config.api is None: - return - - base_url = yarl.URL(self.hass.config.api.deprecated_base_url) - - # Check if this is an internal URL - if str(base_url.host).endswith(".local") or ( - network.is_ip_address(str(base_url.host)) - and network.is_private(ip_address(base_url.host)) - ): - await self.async_update( - internal_url=network.normalize_url(str(base_url)) - ) - return - - # External, ensure this is not a loopback address - if not ( - network.is_ip_address(str(base_url.host)) - and network.is_loopback(ip_address(base_url.host)) - ): - await self.async_update( - external_url=network.normalize_url(str(base_url)) - ) - if data: - # Try to migrate base_url to internal_url/external_url - if "external_url" not in data: - self.hass.bus.async_listen_once( - EVENT_HOMEASSISTANT_START, migrate_base_url - ) - self._update( source=SOURCE_STORAGE, latitude=data.get("latitude"), diff --git a/homeassistant/helpers/network.py b/homeassistant/helpers/network.py index 4e066eaa13c..21f69dc539a 100644 --- a/homeassistant/helpers/network.py +++ b/homeassistant/helpers/network.py @@ -8,13 +8,7 @@ from homeassistant.components import http from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.loader import bind_hass -from homeassistant.util.network import ( - is_ip_address, - is_local, - is_loopback, - is_private, - normalize_url, -) +from homeassistant.util.network import is_ip_address, is_loopback, normalize_url TYPE_URL_INTERNAL = "internal_url" TYPE_URL_EXTERNAL = "external_url" @@ -151,19 +145,6 @@ def _get_internal_url( ): return normalize_url(str(internal_url)) - # Fallback to old base_url - try: - return _get_deprecated_base_url( - hass, - internal=True, - allow_ip=allow_ip, - require_current_request=require_current_request, - require_ssl=require_ssl, - require_standard_port=require_standard_port, - ) - except NoURLAvailableError: - pass - # Fallback to detected local IP if allow_ip and not ( require_ssl or hass.config.api is None or hass.config.api.use_ssl @@ -217,17 +198,6 @@ def _get_external_url( ): return normalize_url(str(external_url)) - try: - return _get_deprecated_base_url( - hass, - allow_ip=allow_ip, - require_current_request=require_current_request, - require_ssl=require_ssl, - require_standard_port=require_standard_port, - ) - except NoURLAvailableError: - pass - if allow_cloud: try: return _get_cloud_url(hass, require_current_request=require_current_request) @@ -250,50 +220,3 @@ def _get_cloud_url(hass: HomeAssistant, require_current_request: bool = False) - return normalize_url(str(cloud_url)) raise NoURLAvailableError - - -@bind_hass -def _get_deprecated_base_url( - hass: HomeAssistant, - *, - internal: bool = False, - allow_ip: bool = True, - require_current_request: bool = False, - require_ssl: bool = False, - require_standard_port: bool = False, -) -> str: - """Work with the deprecated `base_url`, used as fallback.""" - if hass.config.api is None or not hass.config.api.deprecated_base_url: - raise NoURLAvailableError - - base_url = yarl.URL(hass.config.api.deprecated_base_url) - # Rules that apply to both internal and external - if ( - (allow_ip or not is_ip_address(str(base_url.host))) - and (not require_current_request or base_url.host == _get_request_host()) - and (not require_ssl or base_url.scheme == "https") - and (not require_standard_port or base_url.is_default_port()) - ): - # Check to ensure an internal URL - if internal and ( - str(base_url.host).endswith(".local") - or ( - is_ip_address(str(base_url.host)) - and not is_loopback(ip_address(base_url.host)) - and is_private(ip_address(base_url.host)) - ) - ): - return normalize_url(str(base_url)) - - # Check to ensure an external URL (a little) - if ( - not internal - and not str(base_url.host).endswith(".local") - and not ( - is_ip_address(str(base_url.host)) - and is_local(ip_address(str(base_url.host))) - ) - ): - return normalize_url(str(base_url)) - - raise NoURLAvailableError diff --git a/tests/components/ambiclimate/test_config_flow.py b/tests/components/ambiclimate/test_config_flow.py index b87c2171815..3a325490064 100644 --- a/tests/components/ambiclimate/test_config_flow.py +++ b/tests/components/ambiclimate/test_config_flow.py @@ -5,6 +5,7 @@ import ambiclimate from homeassistant import data_entry_flow from homeassistant.components.ambiclimate import config_flow +from homeassistant.config import async_process_ha_core_config from homeassistant.const import CONF_CLIENT_ID, CONF_CLIENT_SECRET from homeassistant.setup import async_setup_component from homeassistant.util import aiohttp @@ -12,9 +13,11 @@ from homeassistant.util import aiohttp async def init_config_flow(hass): """Init a configuration flow.""" - await async_setup_component( - hass, "http", {"http": {"base_url": "https://hass.com"}} + await async_process_ha_core_config( + hass, + {"external_url": "https://example.com"}, ) + await async_setup_component(hass, "http", {}) config_flow.register_flow_implementation(hass, "id", "secret") flow = config_flow.AmbiclimateFlowHandler() @@ -58,20 +61,20 @@ async def test_full_flow_implementation(hass): assert result["step_id"] == "auth" assert ( result["description_placeholders"]["cb_url"] - == "https://hass.com/api/ambiclimate" + == "https://example.com/api/ambiclimate" ) url = result["description_placeholders"]["authorization_url"] assert "https://api.ambiclimate.com/oauth2/authorize" in url assert "client_id=id" in url assert "response_type=code" in url - assert "redirect_uri=https%3A%2F%2Fhass.com%2Fapi%2Fambiclimate" in url + assert "redirect_uri=https%3A%2F%2Fexample.com%2Fapi%2Fambiclimate" in url with patch("ambiclimate.AmbiclimateOAuth.get_access_token", return_value="test"): result = await flow.async_step_code("123ABC") assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY assert result["title"] == "Ambiclimate" - assert result["data"]["callback_url"] == "https://hass.com/api/ambiclimate" + assert result["data"]["callback_url"] == "https://example.com/api/ambiclimate" assert result["data"][CONF_CLIENT_SECRET] == "secret" assert result["data"][CONF_CLIENT_ID] == "id" diff --git a/tests/components/http/test_init.py b/tests/components/http/test_init.py index e7a3884c481..9621b269081 100644 --- a/tests/components/http/test_init.py +++ b/tests/components/http/test_init.py @@ -60,73 +60,6 @@ async def test_registering_view_while_running( hass.http.register_view(TestView) -def test_api_base_url_with_domain(mock_stack): - """Test setting API URL with domain.""" - api_config = http.ApiConfig("127.0.0.1", "example.com") - assert api_config.base_url == "http://example.com:8123" - - -def test_api_base_url_with_ip(mock_stack): - """Test setting API URL with IP.""" - api_config = http.ApiConfig("127.0.0.1", "1.1.1.1") - assert api_config.base_url == "http://1.1.1.1:8123" - - -def test_api_base_url_with_ip_and_port(mock_stack): - """Test setting API URL with IP and port.""" - api_config = http.ApiConfig("127.0.0.1", "1.1.1.1", 8124) - assert api_config.base_url == "http://1.1.1.1:8124" - - -def test_api_base_url_with_protocol(mock_stack): - """Test setting API URL with protocol.""" - api_config = http.ApiConfig("127.0.0.1", "https://example.com") - assert api_config.base_url == "https://example.com:8123" - - -def test_api_base_url_with_protocol_and_port(mock_stack): - """Test setting API URL with protocol and port.""" - api_config = http.ApiConfig("127.0.0.1", "https://example.com", 433) - assert api_config.base_url == "https://example.com:433" - - -def test_api_base_url_with_ssl_enable(mock_stack): - """Test setting API URL with use_ssl enabled.""" - api_config = http.ApiConfig("127.0.0.1", "example.com", use_ssl=True) - assert api_config.base_url == "https://example.com:8123" - - -def test_api_base_url_with_ssl_enable_and_port(mock_stack): - """Test setting API URL with use_ssl enabled and port.""" - api_config = http.ApiConfig("127.0.0.1", "1.1.1.1", use_ssl=True, port=8888) - assert api_config.base_url == "https://1.1.1.1:8888" - - -def test_api_base_url_with_protocol_and_ssl_enable(mock_stack): - """Test setting API URL with specific protocol and use_ssl enabled.""" - api_config = http.ApiConfig("127.0.0.1", "http://example.com", use_ssl=True) - assert api_config.base_url == "http://example.com:8123" - - -def test_api_base_url_removes_trailing_slash(mock_stack): - """Test a trialing slash is removed when setting the API URL.""" - api_config = http.ApiConfig("127.0.0.1", "http://example.com/") - assert api_config.base_url == "http://example.com:8123" - - -def test_api_local_ip(mock_stack): - """Test a trialing slash is removed when setting the API URL.""" - api_config = http.ApiConfig("127.0.0.1", "http://example.com/") - assert api_config.local_ip == "127.0.0.1" - - -async def test_api_no_base_url(hass, mock_stack): - """Test setting api url.""" - result = await async_setup_component(hass, "http", {"http": {}}) - assert result - assert hass.config.api.base_url == "http://127.0.0.1:8123" - - async def test_not_log_password(hass, aiohttp_client, caplog, legacy_auth): """Test access with password doesn't get logged.""" assert await async_setup_component(hass, "api", {"http": {}}) @@ -263,127 +196,3 @@ async def test_storing_config(hass, aiohttp_client, aiohttp_unused_port): restored["trusted_proxies"][0] = ip_network(restored["trusted_proxies"][0]) assert restored == http.HTTP_SCHEMA(config) - - -async def test_use_of_base_url(hass): - """Test detection base_url usage when called without integration context.""" - await async_setup_component(hass, "http", {"http": {}}) - with patch( - "homeassistant.components.http.extract_stack", - return_value=[ - Mock( - filename="/home/frenck/homeassistant/core.py", - lineno="21", - line="do_something()", - ), - Mock( - filename="/home/frenck/homeassistant/core.py", - lineno="42", - line="url = hass.config.api.base_url", - ), - Mock( - filename="/home/frenck/example/client.py", - lineno="21", - line="something()", - ), - ], - ), pytest.raises(RuntimeError): - hass.config.api.base_url - - -async def test_use_of_base_url_integration(hass, caplog): - """Test detection base_url usage when called with integration context.""" - await async_setup_component(hass, "http", {"http": {}}) - with patch( - "homeassistant.components.http.extract_stack", - return_value=[ - Mock( - filename="/home/frenck/homeassistant/core.py", - lineno="21", - line="do_something()", - ), - Mock( - filename="/home/frenck/homeassistant/components/example/__init__.py", - lineno="42", - line="url = hass.config.api.base_url", - ), - Mock( - filename="/home/frenck/example/client.py", - lineno="21", - line="something()", - ), - ], - ): - assert hass.config.api.base_url == "http://127.0.0.1:8123" - - assert ( - "Detected use of deprecated `base_url` property, use `homeassistant.helpers.network.get_url` method instead. Please report issue for example using this method at homeassistant/components/example/__init__.py, line 42: url = hass.config.api.base_url" - in caplog.text - ) - - -async def test_use_of_base_url_integration_webhook(hass, caplog): - """Test detection base_url usage when called with integration context.""" - await async_setup_component(hass, "http", {"http": {}}) - with patch( - "homeassistant.components.http.extract_stack", - return_value=[ - Mock( - filename="/home/frenck/homeassistant/core.py", - lineno="21", - line="do_something()", - ), - Mock( - filename="/home/frenck/homeassistant/components/example/__init__.py", - lineno="42", - line="url = hass.config.api.base_url", - ), - Mock( - filename="/home/frenck/homeassistant/components/webhook/__init__.py", - lineno="42", - line="return get_url(hass)", - ), - Mock( - filename="/home/frenck/example/client.py", - lineno="21", - line="something()", - ), - ], - ): - assert hass.config.api.base_url == "http://127.0.0.1:8123" - - assert ( - "Detected use of deprecated `base_url` property, use `homeassistant.helpers.network.get_url` method instead. Please report issue for example using this method at homeassistant/components/example/__init__.py, line 42: url = hass.config.api.base_url" - in caplog.text - ) - - -async def test_use_of_base_url_custom_component(hass, caplog): - """Test detection base_url usage when called with custom component context.""" - await async_setup_component(hass, "http", {"http": {}}) - with patch( - "homeassistant.components.http.extract_stack", - return_value=[ - Mock( - filename="/home/frenck/homeassistant/core.py", - lineno="21", - line="do_something()", - ), - Mock( - filename="/home/frenck/.homeassistant/custom_components/example/__init__.py", - lineno="42", - line="url = hass.config.api.base_url", - ), - Mock( - filename="/home/frenck/example/client.py", - lineno="21", - line="something()", - ), - ], - ): - assert hass.config.api.base_url == "http://127.0.0.1:8123" - - assert ( - "Detected use of deprecated `base_url` property, use `homeassistant.helpers.network.get_url` method instead. Please report issue to the custom component author for example using this method at custom_components/example/__init__.py, line 42: url = hass.config.api.base_url" - in caplog.text - ) diff --git a/tests/components/ifttt/test_init.py b/tests/components/ifttt/test_init.py index d10df2492d4..41885f0cd26 100644 --- a/tests/components/ifttt/test_init.py +++ b/tests/components/ifttt/test_init.py @@ -1,17 +1,20 @@ """Test the init file of IFTTT.""" -from unittest.mock import patch - from homeassistant import data_entry_flow from homeassistant.components import ifttt +from homeassistant.config import async_process_ha_core_config from homeassistant.core import callback async def test_config_flow_registers_webhook(hass, aiohttp_client): """Test setting up IFTTT and sending webhook.""" - with patch("homeassistant.util.get_local_ip", return_value="example.com"): - result = await hass.config_entries.flow.async_init( - "ifttt", context={"source": "user"} - ) + await async_process_ha_core_config( + hass, + {"internal_url": "http://example.local:8123"}, + ) + + result = await hass.config_entries.flow.async_init( + "ifttt", context={"source": "user"} + ) assert result["type"] == data_entry_flow.RESULT_TYPE_FORM, result result = await hass.config_entries.flow.async_configure(result["flow_id"], {}) diff --git a/tests/components/twilio/test_init.py b/tests/components/twilio/test_init.py index ee7f072a65c..580e5f83ebf 100644 --- a/tests/components/twilio/test_init.py +++ b/tests/components/twilio/test_init.py @@ -1,17 +1,19 @@ """Test the init file of Twilio.""" -from unittest.mock import patch - from homeassistant import data_entry_flow from homeassistant.components import twilio +from homeassistant.config import async_process_ha_core_config from homeassistant.core import callback async def test_config_flow_registers_webhook(hass, aiohttp_client): """Test setting up Twilio and sending webhook.""" - with patch("homeassistant.util.get_local_ip", return_value="example.com"): - result = await hass.config_entries.flow.async_init( - "twilio", context={"source": "user"} - ) + await async_process_ha_core_config( + hass, + {"internal_url": "http://example.local:8123"}, + ) + result = await hass.config_entries.flow.async_init( + "twilio", context={"source": "user"} + ) assert result["type"] == data_entry_flow.RESULT_TYPE_FORM, result result = await hass.config_entries.flow.async_configure(result["flow_id"], {}) diff --git a/tests/helpers/test_network.py b/tests/helpers/test_network.py index 06158558d5e..aad37e2fd49 100644 --- a/tests/helpers/test_network.py +++ b/tests/helpers/test_network.py @@ -9,7 +9,6 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers.network import ( NoURLAvailableError, _get_cloud_url, - _get_deprecated_base_url, _get_external_url, _get_internal_url, _get_request_host, @@ -166,9 +165,7 @@ async def test_get_url_internal_fallback(hass: HomeAssistant): """Test getting an instance URL when the user has not set an internal URL.""" assert hass.config.internal_url is None - hass.config.api = Mock( - use_ssl=False, port=8123, deprecated_base_url=None, local_ip="192.168.123.123" - ) + hass.config.api = Mock(use_ssl=False, port=8123, local_ip="192.168.123.123") assert _get_internal_url(hass) == "http://192.168.123.123:8123" with pytest.raises(NoURLAvailableError): @@ -180,9 +177,7 @@ async def test_get_url_internal_fallback(hass: HomeAssistant): with pytest.raises(NoURLAvailableError): _get_internal_url(hass, require_ssl=True) - hass.config.api = Mock( - use_ssl=False, port=80, deprecated_base_url=None, local_ip="192.168.123.123" - ) + hass.config.api = Mock(use_ssl=False, port=80, local_ip="192.168.123.123") assert _get_internal_url(hass) == "http://192.168.123.123" assert ( _get_internal_url(hass, require_standard_port=True) == "http://192.168.123.123" @@ -194,7 +189,7 @@ async def test_get_url_internal_fallback(hass: HomeAssistant): with pytest.raises(NoURLAvailableError): _get_internal_url(hass, require_ssl=True) - hass.config.api = Mock(use_ssl=True, port=443, deprecated_base_url=None) + hass.config.api = Mock(use_ssl=True, port=443) with pytest.raises(NoURLAvailableError): _get_internal_url(hass) @@ -208,9 +203,7 @@ async def test_get_url_internal_fallback(hass: HomeAssistant): _get_internal_url(hass, require_ssl=True) # Do no accept any local loopback address as fallback - hass.config.api = Mock( - use_ssl=False, port=80, deprecated_base_url=None, local_ip="127.0.0.1" - ) + hass.config.api = Mock(use_ssl=False, port=80, local_ip="127.0.0.1") with pytest.raises(NoURLAvailableError): _get_internal_url(hass) @@ -457,9 +450,7 @@ async def test_get_url(hass: HomeAssistant): with pytest.raises(NoURLAvailableError): get_url(hass) - hass.config.api = Mock( - use_ssl=False, port=8123, deprecated_base_url=None, local_ip="192.168.123.123" - ) + hass.config.api = Mock(use_ssl=False, port=8123, local_ip="192.168.123.123") assert get_url(hass) == "http://192.168.123.123:8123" assert get_url(hass, prefer_external=True) == "http://192.168.123.123:8123" @@ -543,274 +534,11 @@ async def test_get_request_host(hass: HomeAssistant): assert _get_request_host() == "example.com" -async def test_get_deprecated_base_url_internal(hass: HomeAssistant): - """Test getting an internal instance URL from the deprecated base_url.""" - # Test with SSL local URL - hass.config.api = Mock(deprecated_base_url="https://example.local") - assert _get_deprecated_base_url(hass, internal=True) == "https://example.local" - assert ( - _get_deprecated_base_url(hass, internal=True, allow_ip=False) - == "https://example.local" - ) - assert ( - _get_deprecated_base_url(hass, internal=True, require_ssl=True) - == "https://example.local" - ) - assert ( - _get_deprecated_base_url(hass, internal=True, require_standard_port=True) - == "https://example.local" - ) - - # Test with no SSL, local IP URL - hass.config.api = Mock(deprecated_base_url="http://10.10.10.10:8123") - assert _get_deprecated_base_url(hass, internal=True) == "http://10.10.10.10:8123" - - with pytest.raises(NoURLAvailableError): - _get_deprecated_base_url(hass, internal=True, allow_ip=False) - - with pytest.raises(NoURLAvailableError): - _get_deprecated_base_url(hass, internal=True, require_ssl=True) - - with pytest.raises(NoURLAvailableError): - _get_deprecated_base_url(hass, internal=True, require_standard_port=True) - - # Test with SSL, local IP URL - hass.config.api = Mock(deprecated_base_url="https://10.10.10.10") - assert _get_deprecated_base_url(hass, internal=True) == "https://10.10.10.10" - assert ( - _get_deprecated_base_url(hass, internal=True, require_ssl=True) - == "https://10.10.10.10" - ) - assert ( - _get_deprecated_base_url(hass, internal=True, require_standard_port=True) - == "https://10.10.10.10" - ) - - # Test external URL - hass.config.api = Mock(deprecated_base_url="https://example.com") - with pytest.raises(NoURLAvailableError): - _get_deprecated_base_url(hass, internal=True) - - with pytest.raises(NoURLAvailableError): - _get_deprecated_base_url(hass, internal=True, require_ssl=True) - - with pytest.raises(NoURLAvailableError): - _get_deprecated_base_url(hass, internal=True, require_standard_port=True) - - with pytest.raises(NoURLAvailableError): - _get_deprecated_base_url(hass, internal=True, allow_ip=False) - - # Test with loopback - hass.config.api = Mock(deprecated_base_url="https://127.0.0.42") - with pytest.raises(NoURLAvailableError): - assert _get_deprecated_base_url(hass, internal=True) - - with pytest.raises(NoURLAvailableError): - _get_deprecated_base_url(hass, internal=True, allow_ip=False) - - with pytest.raises(NoURLAvailableError): - _get_deprecated_base_url(hass, internal=True, require_ssl=True) - - with pytest.raises(NoURLAvailableError): - _get_deprecated_base_url(hass, internal=True, require_standard_port=True) - - -async def test_get_deprecated_base_url_external(hass: HomeAssistant): - """Test getting an external instance URL from the deprecated base_url.""" - # Test with SSL and external domain on standard port - hass.config.api = Mock(deprecated_base_url="https://example.com:443/") - assert _get_deprecated_base_url(hass) == "https://example.com" - assert _get_deprecated_base_url(hass, require_ssl=True) == "https://example.com" - assert ( - _get_deprecated_base_url(hass, require_standard_port=True) - == "https://example.com" - ) - - # Test without SSL and external domain on non-standard port - hass.config.api = Mock(deprecated_base_url="http://example.com:8123/") - assert _get_deprecated_base_url(hass) == "http://example.com:8123" - - with pytest.raises(NoURLAvailableError): - _get_deprecated_base_url(hass, require_ssl=True) - - with pytest.raises(NoURLAvailableError): - _get_deprecated_base_url(hass, require_standard_port=True) - - # Test SSL on external IP - hass.config.api = Mock(deprecated_base_url="https://1.1.1.1") - assert _get_deprecated_base_url(hass) == "https://1.1.1.1" - assert _get_deprecated_base_url(hass, require_ssl=True) == "https://1.1.1.1" - assert ( - _get_deprecated_base_url(hass, require_standard_port=True) == "https://1.1.1.1" - ) - - with pytest.raises(NoURLAvailableError): - _get_deprecated_base_url(hass, allow_ip=False) - - # Test with private IP - hass.config.api = Mock(deprecated_base_url="https://10.10.10.10") - with pytest.raises(NoURLAvailableError): - assert _get_deprecated_base_url(hass) - - with pytest.raises(NoURLAvailableError): - _get_deprecated_base_url(hass, allow_ip=False) - - with pytest.raises(NoURLAvailableError): - _get_deprecated_base_url(hass, require_ssl=True) - - with pytest.raises(NoURLAvailableError): - _get_deprecated_base_url(hass, require_standard_port=True) - - # Test with local domain - hass.config.api = Mock(deprecated_base_url="https://example.local") - with pytest.raises(NoURLAvailableError): - assert _get_deprecated_base_url(hass) - - with pytest.raises(NoURLAvailableError): - _get_deprecated_base_url(hass, allow_ip=False) - - with pytest.raises(NoURLAvailableError): - _get_deprecated_base_url(hass, require_ssl=True) - - with pytest.raises(NoURLAvailableError): - _get_deprecated_base_url(hass, require_standard_port=True) - - # Test with loopback - hass.config.api = Mock(deprecated_base_url="https://127.0.0.42") - with pytest.raises(NoURLAvailableError): - assert _get_deprecated_base_url(hass) - - with pytest.raises(NoURLAvailableError): - _get_deprecated_base_url(hass, allow_ip=False) - - with pytest.raises(NoURLAvailableError): - _get_deprecated_base_url(hass, require_ssl=True) - - with pytest.raises(NoURLAvailableError): - _get_deprecated_base_url(hass, require_standard_port=True) - - -async def test_get_internal_url_with_base_url_fallback(hass: HomeAssistant): - """Test getting an internal instance URL with the deprecated base_url fallback.""" - hass.config.api = Mock( - use_ssl=False, port=8123, deprecated_base_url=None, local_ip="192.168.123.123" - ) - assert hass.config.internal_url is None - assert _get_internal_url(hass) == "http://192.168.123.123:8123" - - with pytest.raises(NoURLAvailableError): - _get_internal_url(hass, allow_ip=False) - - with pytest.raises(NoURLAvailableError): - _get_internal_url(hass, require_standard_port=True) - - with pytest.raises(NoURLAvailableError): - _get_internal_url(hass, require_ssl=True) - - # Add base_url - hass.config.api = Mock( - use_ssl=False, port=8123, deprecated_base_url="https://example.local" - ) - assert _get_internal_url(hass) == "https://example.local" - assert _get_internal_url(hass, allow_ip=False) == "https://example.local" - assert ( - _get_internal_url(hass, require_standard_port=True) == "https://example.local" - ) - assert _get_internal_url(hass, require_ssl=True) == "https://example.local" - - # Add internal URL - await async_process_ha_core_config( - hass, - {"internal_url": "https://internal.local"}, - ) - assert _get_internal_url(hass) == "https://internal.local" - assert _get_internal_url(hass, allow_ip=False) == "https://internal.local" - assert ( - _get_internal_url(hass, require_standard_port=True) == "https://internal.local" - ) - assert _get_internal_url(hass, require_ssl=True) == "https://internal.local" - - # Add internal URL, mixed results - await async_process_ha_core_config( - hass, - {"internal_url": "http://internal.local:8123"}, - ) - assert _get_internal_url(hass) == "http://internal.local:8123" - assert _get_internal_url(hass, allow_ip=False) == "http://internal.local:8123" - assert ( - _get_internal_url(hass, require_standard_port=True) == "https://example.local" - ) - assert _get_internal_url(hass, require_ssl=True) == "https://example.local" - - # Add internal URL set to an IP - await async_process_ha_core_config( - hass, - {"internal_url": "http://10.10.10.10:8123"}, - ) - assert _get_internal_url(hass) == "http://10.10.10.10:8123" - assert _get_internal_url(hass, allow_ip=False) == "https://example.local" - assert ( - _get_internal_url(hass, require_standard_port=True) == "https://example.local" - ) - assert _get_internal_url(hass, require_ssl=True) == "https://example.local" - - -async def test_get_external_url_with_base_url_fallback(hass: HomeAssistant): - """Test getting an external instance URL with the deprecated base_url fallback.""" - hass.config.api = Mock(use_ssl=False, port=8123, deprecated_base_url=None) - assert hass.config.internal_url is None - - with pytest.raises(NoURLAvailableError): - _get_external_url(hass) - - # Test with SSL and external domain on standard port - hass.config.api = Mock(deprecated_base_url="https://example.com:443/") - assert _get_external_url(hass) == "https://example.com" - assert _get_external_url(hass, allow_ip=False) == "https://example.com" - assert _get_external_url(hass, require_ssl=True) == "https://example.com" - assert _get_external_url(hass, require_standard_port=True) == "https://example.com" - - # Add external URL - await async_process_ha_core_config( - hass, - {"external_url": "https://external.example.com"}, - ) - assert _get_external_url(hass) == "https://external.example.com" - assert _get_external_url(hass, allow_ip=False) == "https://external.example.com" - assert ( - _get_external_url(hass, require_standard_port=True) - == "https://external.example.com" - ) - assert _get_external_url(hass, require_ssl=True) == "https://external.example.com" - - # Add external URL, mixed results - await async_process_ha_core_config( - hass, - {"external_url": "http://external.example.com:8123"}, - ) - assert _get_external_url(hass) == "http://external.example.com:8123" - assert _get_external_url(hass, allow_ip=False) == "http://external.example.com:8123" - assert _get_external_url(hass, require_standard_port=True) == "https://example.com" - assert _get_external_url(hass, require_ssl=True) == "https://example.com" - - # Add external URL set to an IP - await async_process_ha_core_config( - hass, - {"external_url": "http://1.1.1.1:8123"}, - ) - assert _get_external_url(hass) == "http://1.1.1.1:8123" - assert _get_external_url(hass, allow_ip=False) == "https://example.com" - assert _get_external_url(hass, require_standard_port=True) == "https://example.com" - assert _get_external_url(hass, require_ssl=True) == "https://example.com" - - async def test_get_current_request_url_with_known_host( hass: HomeAssistant, current_request ): """Test getting current request URL with known hosts addresses.""" - hass.config.api = Mock( - use_ssl=False, port=8123, local_ip="127.0.0.1", deprecated_base_url=None - ) + hass.config.api = Mock(use_ssl=False, port=8123, local_ip="127.0.0.1") assert hass.config.internal_url is None with pytest.raises(NoURLAvailableError): diff --git a/tests/test_core.py b/tests/test_core.py index 0bf00d92c45..dfd5b925e1c 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -1294,41 +1294,6 @@ def test_valid_entity_id(): assert ha.valid_entity_id(valid), valid -async def test_migration_base_url(hass, hass_storage): - """Test that we migrate base url to internal/external url.""" - config = ha.Config(hass) - stored = {"version": 1, "data": {}} - hass_storage[ha.CORE_STORAGE_KEY] = stored - with patch.object(hass.bus, "async_listen_once") as mock_listen: - # Empty config - await config.async_load() - assert len(mock_listen.mock_calls) == 0 - - # With just a name - stored["data"] = {"location_name": "Test Name"} - await config.async_load() - assert len(mock_listen.mock_calls) == 1 - - # With external url - stored["data"]["external_url"] = "https://example.com" - await config.async_load() - assert len(mock_listen.mock_calls) == 1 - - # Test that the event listener works - assert mock_listen.mock_calls[0][1][0] == EVENT_HOMEASSISTANT_START - - # External - hass.config.api = Mock(deprecated_base_url="https://loaded-example.com") - await mock_listen.mock_calls[0][1][1](None) - assert config.external_url == "https://loaded-example.com" - - # Internal - for internal in ("http://hass.local", "http://192.168.1.100:8123"): - hass.config.api = Mock(deprecated_base_url=internal) - await mock_listen.mock_calls[0][1][1](None) - assert config.internal_url == internal - - async def test_additional_data_in_core_config(hass, hass_storage): """Test that we can handle additional data in core configuration.""" config = ha.Config(hass)