mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 00:37:53 +00:00
Accept known hosts for get_url for OAuth (#39936)
This commit is contained in:
parent
5117a16841
commit
101b5b3b35
@ -75,6 +75,38 @@ def get_url(
|
||||
except NoURLAvailableError:
|
||||
pass
|
||||
|
||||
# For current request, we accept loopback interfaces (e.g., 127.0.0.1),
|
||||
# the Supervisor hostname and localhost transparently
|
||||
request_host = _get_request_host()
|
||||
if (
|
||||
require_current_request
|
||||
and request_host is not None
|
||||
and hass.config.api is not None
|
||||
):
|
||||
scheme = "https" if hass.config.api.use_ssl else "http"
|
||||
current_url = yarl.URL.build(
|
||||
scheme=scheme, host=request_host, port=hass.config.api.port
|
||||
)
|
||||
|
||||
known_hostname = None
|
||||
if hass.components.hassio.is_hassio():
|
||||
host_info = hass.components.hassio.get_host_info()
|
||||
known_hostname = f"{host_info['hostname']}.local"
|
||||
|
||||
if (
|
||||
(
|
||||
(
|
||||
allow_ip
|
||||
and is_ip_address(request_host)
|
||||
and is_loopback(ip_address(request_host))
|
||||
)
|
||||
or request_host in ["localhost", known_hostname]
|
||||
)
|
||||
and (not require_ssl or current_url.scheme == "https")
|
||||
and (not require_standard_port or current_url.is_default_port())
|
||||
):
|
||||
return normalize_url(str(current_url))
|
||||
|
||||
# We have to be honest now, we have no viable option available
|
||||
raise NoURLAvailableError
|
||||
|
||||
|
@ -15,6 +15,7 @@ from homeassistant.helpers.network import (
|
||||
)
|
||||
|
||||
from tests.async_mock import Mock, patch
|
||||
from tests.common import mock_component
|
||||
|
||||
|
||||
async def test_get_url_internal(hass: HomeAssistant):
|
||||
@ -799,3 +800,55 @@ async def test_get_external_url_with_base_url_fallback(hass: HomeAssistant):
|
||||
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
|
||||
)
|
||||
assert hass.config.internal_url is None
|
||||
|
||||
with pytest.raises(NoURLAvailableError):
|
||||
get_url(hass, require_current_request=True)
|
||||
|
||||
# Ensure we accept localhost
|
||||
with patch(
|
||||
"homeassistant.helpers.network._get_request_host", return_value="localhost"
|
||||
):
|
||||
assert get_url(hass, require_current_request=True) == "http://localhost:8123"
|
||||
with pytest.raises(NoURLAvailableError):
|
||||
get_url(hass, require_current_request=True, require_ssl=True)
|
||||
with pytest.raises(NoURLAvailableError):
|
||||
get_url(hass, require_current_request=True, require_standard_port=True)
|
||||
|
||||
# Ensure we accept local loopback ip (e.g., 127.0.0.1)
|
||||
with patch(
|
||||
"homeassistant.helpers.network._get_request_host", return_value="127.0.0.8"
|
||||
):
|
||||
assert get_url(hass, require_current_request=True) == "http://127.0.0.8:8123"
|
||||
with pytest.raises(NoURLAvailableError):
|
||||
get_url(hass, require_current_request=True, allow_ip=False)
|
||||
|
||||
# Ensure hostname from Supervisor is accepted transparently
|
||||
mock_component(hass, "hassio")
|
||||
hass.components.hassio.is_hassio = Mock(return_value=True)
|
||||
hass.components.hassio.get_host_info = Mock(
|
||||
return_value={"hostname": "homeassistant"}
|
||||
)
|
||||
|
||||
with patch(
|
||||
"homeassistant.helpers.network._get_request_host",
|
||||
return_value="homeassistant.local",
|
||||
):
|
||||
assert (
|
||||
get_url(hass, require_current_request=True)
|
||||
== "http://homeassistant.local:8123"
|
||||
)
|
||||
|
||||
with patch(
|
||||
"homeassistant.helpers.network._get_request_host", return_value="unknown.local"
|
||||
), pytest.raises(NoURLAvailableError):
|
||||
get_url(hass, require_current_request=True)
|
||||
|
Loading…
x
Reference in New Issue
Block a user