Do not reveal existance of trusted networks provider (#302)
* Skip welcome page if the only other provider is trusted networks * Add test
This commit is contained in:
committed by
GitHub
parent
c7370ed266
commit
d3c359064d
@@ -100,10 +100,10 @@ async def _register_oidc_provider(hass: HomeAssistant, my_config: dict):
|
|||||||
|
|
||||||
existing_auth_providers = hass.auth._providers.copy()
|
existing_auth_providers = hass.auth._providers.copy()
|
||||||
_LOGGER.debug("Current auth providers: %s", list(existing_auth_providers.keys()))
|
_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
|
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
|
# Pop the first provider from the existing providers to check if it's trusted_networks
|
||||||
first_provider_key, first_provider_obj = next(
|
first_provider_key, first_provider_obj = next(
|
||||||
iter(existing_auth_providers.items())
|
iter(existing_auth_providers.items())
|
||||||
@@ -133,14 +133,15 @@ async def _register_oidc_provider(hass: HomeAssistant, my_config: dict):
|
|||||||
# pylint: enable=protected-access
|
# pylint: enable=protected-access
|
||||||
|
|
||||||
_LOGGER.info("Registered OIDC provider")
|
_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):
|
async def _setup_oidc_provider(hass: HomeAssistant, my_config: dict, display_name: str):
|
||||||
"""Set up the OIDC provider with the given configuration."""
|
"""Set up the OIDC provider with the given configuration."""
|
||||||
(
|
(
|
||||||
provider,
|
provider,
|
||||||
has_other_auth_providers,
|
auth_provider_count,
|
||||||
has_trusted_networks_provider_first,
|
has_trusted_networks_provider_first,
|
||||||
) = await _register_oidc_provider(hass, my_config)
|
) = 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(
|
hass.http.register_view(
|
||||||
OIDCWelcomeView(
|
OIDCWelcomeView(
|
||||||
provider,
|
provider,
|
||||||
OIDCWelcomeOptions(
|
OIDCWelcomeOptions(
|
||||||
name=name,
|
name=name,
|
||||||
force_https=force_https,
|
force_https=force_https,
|
||||||
has_other_auth_providers=has_other_auth_providers,
|
has_other_auth_providers=auth_provider_count > 0,
|
||||||
prefers_skipping=default_redirect,
|
prefers_skipping=default_redirect or has_only_trusted_networks,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -194,6 +194,43 @@ async def test_provider_is_trusted_network_host_false_without_trusted_provider(
|
|||||||
assert provider.is_trusted_network_host() is False
|
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):
|
async def login_user(hass: HomeAssistant, state_id: str):
|
||||||
"""Helper to login a user from the stored OIDC state."""
|
"""Helper to login a user from the stored OIDC state."""
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user