From d3c359064da0ca5fb5900c4b8ee91406b4c38a85 Mon Sep 17 00:00:00 2001 From: Christiaan Goossens <9487666+christiaangoossens@users.noreply.github.com> Date: Fri, 1 May 2026 14:27:23 +0200 Subject: [PATCH] Do not reveal existance of trusted networks provider (#302) * Skip welcome page if the only other provider is trusted networks * Add test --- custom_components/auth_oidc/__init__.py | 17 ++++++++---- tests/test_hass_auth_provider.py | 37 +++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/custom_components/auth_oidc/__init__.py b/custom_components/auth_oidc/__init__.py index 9d87e0e..51f9e79 100644 --- a/custom_components/auth_oidc/__init__.py +++ b/custom_components/auth_oidc/__init__.py @@ -100,10 +100,10 @@ async def _register_oidc_provider(hass: HomeAssistant, my_config: dict): existing_auth_providers = hass.auth._providers.copy() _LOGGER.debug("Current auth providers: %s", list(existing_auth_providers.keys())) - has_other_auth_providers = len(existing_auth_providers) > 0 + auth_provider_count = len(existing_auth_providers) has_trusted_networks_provider_first = False - if has_other_auth_providers: + if auth_provider_count > 0: # Pop the first provider from the existing providers to check if it's trusted_networks first_provider_key, first_provider_obj = next( iter(existing_auth_providers.items()) @@ -133,14 +133,15 @@ async def _register_oidc_provider(hass: HomeAssistant, my_config: dict): # pylint: enable=protected-access _LOGGER.info("Registered OIDC provider") - return provider, has_other_auth_providers, has_trusted_networks_provider_first + return provider, auth_provider_count, has_trusted_networks_provider_first +# pylint: disable=too-many-locals async def _setup_oidc_provider(hass: HomeAssistant, my_config: dict, display_name: str): """Set up the OIDC provider with the given configuration.""" ( provider, - has_other_auth_providers, + auth_provider_count, has_trusted_networks_provider_first, ) = await _register_oidc_provider(hass, my_config) @@ -195,14 +196,18 @@ async def _setup_oidc_provider(hass: HomeAssistant, my_config: dict, display_nam ] ) + has_only_trusted_networks = ( + auth_provider_count == 1 and has_trusted_networks_provider_first + ) + hass.http.register_view( OIDCWelcomeView( provider, OIDCWelcomeOptions( name=name, force_https=force_https, - has_other_auth_providers=has_other_auth_providers, - prefers_skipping=default_redirect, + has_other_auth_providers=auth_provider_count > 0, + prefers_skipping=default_redirect or has_only_trusted_networks, ), ) ) diff --git a/tests/test_hass_auth_provider.py b/tests/test_hass_auth_provider.py index 13296d6..49cdcec 100644 --- a/tests/test_hass_auth_provider.py +++ b/tests/test_hass_auth_provider.py @@ -194,6 +194,43 @@ async def test_provider_is_trusted_network_host_false_without_trusted_provider( assert provider.is_trusted_network_host() is False +@pytest.mark.asyncio +async def test_welcome_redirects_when_only_trusted_networks_and_not_in_trusted_network( + hass: HomeAssistant, hass_client +): + """When only trusted_networks is present, welcome should redirect regardless of IP.""" + + class TrustedNetworksDenyProvider: + def async_validate_access(self, _ip_addr): + raise InvalidAuthError("Not in trusted_networks") + + # Simulate that only trusted_networks is registered before OIDC provider setup + # pylint: disable=protected-access + hass.auth._providers = OrderedDict( + [ + (("trusted_networks", None), TrustedNetworksDenyProvider()), + ] + ) + # pylint: enable=protected-access + + # Now setup the OIDC provider which should detect trusted_networks as the only other provider + await setup(hass, DEFAULT_CONFIG, True) + + client = await hass_client() + encoded_redirect_uri = base64.b64encode(FAKE_REDIR_URL.encode("utf-8")).decode( + "utf-8" + ) + + resp = await client.get( + f"/auth/oidc/welcome?redirect_uri={encoded_redirect_uri}", + allow_redirects=False, + ) + + # Should redirect straight to the OIDC redirect endpoint + assert resp.status == 302 + assert resp.headers["Location"].endswith("/auth/oidc/redirect") + + async def login_user(hass: HomeAssistant, state_id: str): """Helper to login a user from the stored OIDC state."""