Allow forcing HTTPS in URL generation (#92)

* Force HTTPS feature
* Add docs
This commit is contained in:
Christiaan Goossens
2025-07-16 12:21:11 +02:00
committed by Christiaan Goossens
parent f614092af2
commit c217e46909
6 changed files with 32 additions and 6 deletions

View File

@@ -23,6 +23,8 @@ from .config import (
ROLES,
NETWORK,
FEATURES_INCLUDE_GROUPS_SCOPE,
FEATURES_DISABLE_FRONTEND_INJECTION,
FEATURES_FORCE_HTTPS,
)
# pylint: enable=useless-import-alias

View File

@@ -14,6 +14,7 @@ FEATURES_AUTOMATIC_USER_LINKING = "automatic_user_linking"
FEATURES_AUTOMATIC_PERSON_CREATION = "automatic_person_creation"
FEATURES_DISABLE_PKCE = "disable_rfc7636"
FEATURES_INCLUDE_GROUPS_SCOPE = "include_groups_scope"
FEATURES_FORCE_HTTPS = "force_https"
CLAIMS = "claims"
CLAIMS_DISPLAY_NAME = "display_name"
CLAIMS_USERNAME = "username"
@@ -69,6 +70,10 @@ CONFIG_SCHEMA = vol.Schema(
vol.Optional(
FEATURES_INCLUDE_GROUPS_SCOPE, default=True
): vol.Coerce(bool),
# Force HTTPS on all generated URLs (like redirect_uri)
vol.Optional(FEATURES_FORCE_HTTPS, default=False): vol.Coerce(
bool
),
}
),
# Determine which specific claims will be used from the id_token

View File

@@ -17,10 +17,14 @@ class OIDCCallbackView(HomeAssistantView):
name = "auth:oidc:callback"
def __init__(
self, oidc_client: OIDCClient, oidc_provider: OpenIDAuthProvider
self,
oidc_client: OIDCClient,
oidc_provider: OpenIDAuthProvider,
force_https: bool,
) -> None:
self.oidc_client = oidc_client
self.oidc_provider = oidc_provider
self.force_https = force_https
async def get(self, request: web.Request) -> web.Response:
"""Receive response."""
@@ -38,7 +42,7 @@ class OIDCCallbackView(HomeAssistantView):
)
return web.Response(text=view_html, content_type="text/html")
redirect_uri = get_url("/auth/oidc/callback")
redirect_uri = get_url("/auth/oidc/callback", self.force_https)
user_details = await self.oidc_client.async_complete_token_flow(
redirect_uri, code, state
)
@@ -63,4 +67,6 @@ class OIDCCallbackView(HomeAssistantView):
return web.Response(text=view_html, content_type="text/html")
code = await self.oidc_provider.async_save_user_info(user_details)
return web.HTTPFound(get_url("/auth/oidc/finish?code=" + code))
return web.HTTPFound(
get_url("/auth/oidc/finish?code=" + code, self.force_https)
)

View File

@@ -17,13 +17,14 @@ class OIDCRedirectView(HomeAssistantView):
url = PATH
name = "auth:oidc:redirect"
def __init__(self, oidc_client: OIDCClient) -> None:
def __init__(self, oidc_client: OIDCClient, force_https: bool) -> None:
self.oidc_client = oidc_client
self.force_https = force_https
async def get(self, _: web.Request) -> web.Response:
"""Receive response."""
redirect_uri = get_url("/auth/oidc/callback")
redirect_uri = get_url("/auth/oidc/callback", self.force_https)
auth_url = await self.oidc_client.async_get_authorization_url(redirect_uri)
if auth_url:

View File

@@ -4,12 +4,14 @@ from homeassistant.components import http
from .views.loader import AsyncTemplateRenderer
def get_url(path: str) -> str:
def get_url(path: str, force_https: bool) -> str:
"""Returns the requested path appended to the current request base URL."""
if (req := http.current_request.get()) is None:
raise RuntimeError("No current request in context")
base_uri = str(req.url).split("/auth", 2)[0]
if force_https:
base_uri = base_uri.replace("http://", "https://")
return f"{base_uri}{path}"