Improved config options for OIDC (#9)

Added many new configuration options, including claim configuration and client_secret/confidential client support. Also enables user linking & creates person entries upon first sign in.
This commit is contained in:
Christiaan Goossens
2024-12-28 21:37:00 +01:00
committed by GitHub
parent ca83e86acb
commit db4c6bcade
18 changed files with 631 additions and 183 deletions

View File

@@ -3,9 +3,25 @@
import logging
from typing import OrderedDict
import voluptuous as vol
from homeassistant.core import HomeAssistant
# Import and re-export config schema explictly
# pylint: disable=useless-import-alias
from .config import (
CONFIG_SCHEMA as CONFIG_SCHEMA,
DOMAIN,
DEFAULT_TITLE,
CLIENT_ID,
CLIENT_SECRET,
DISCOVERY_URL,
DISPLAY_NAME,
ID_TOKEN_SIGNING_ALGORITHM,
FEATURES,
CLAIMS,
)
# pylint: enable=useless-import-alias
from .endpoints.welcome import OIDCWelcomeView
from .endpoints.redirect import OIDCRedirectView
from .endpoints.finish import OIDCFinishView
@@ -14,52 +30,47 @@ from .endpoints.callback import OIDCCallbackView
from .oidc_client import OIDCClient
from .provider import OpenIDAuthProvider
DOMAIN = "auth_oidc"
_LOGGER = logging.getLogger(__name__)
CONFIG_SCHEMA = vol.Schema(
{
DOMAIN: vol.Schema(
{
vol.Required("client_id"): vol.Coerce(str),
vol.Optional("client_secret"): vol.Coerce(str),
vol.Required("discovery_url"): vol.Coerce(str),
}
)
},
extra=vol.ALLOW_EXTRA,
)
async def async_setup(hass: HomeAssistant, config):
"""Add the OIDC Auth Provider to the providers in Home Assistant"""
my_config = config[DOMAIN]
providers = OrderedDict()
# Use private APIs until there is a real auth platform
# pylint: disable=protected-access
provider = OpenIDAuthProvider(
hass,
hass.auth._store,
config[DOMAIN],
)
provider = OpenIDAuthProvider(hass, hass.auth._store, my_config)
providers[(provider.type, provider.id)] = provider
providers.update(hass.auth._providers)
hass.auth._providers = providers
# pylint: enable=protected-access
_LOGGER.debug("Added OIDC provider for Home Assistant")
_LOGGER.info("Registered OIDC provider")
# Define some fields
discovery_url: str = config[DOMAIN]["discovery_url"]
client_id: str = config[DOMAIN]["client_id"]
scope: str = "openid profile email"
# We only use openid & profile, never email
scope = "openid profile"
oidc_client = oidc_client = OIDCClient(discovery_url, client_id, scope)
oidc_client = oidc_client = OIDCClient(
discovery_url=my_config.get(DISCOVERY_URL),
client_id=my_config.get(CLIENT_ID),
scope=scope,
client_secret=my_config.get(CLIENT_SECRET),
id_token_signing_alg=my_config.get(ID_TOKEN_SIGNING_ALGORITHM),
features=my_config.get(FEATURES, {}),
claims=my_config.get(CLAIMS, {}),
)
hass.http.register_view(OIDCWelcomeView())
# Register the views
name = config[DOMAIN].get(DISPLAY_NAME, DEFAULT_TITLE)
hass.http.register_view(OIDCWelcomeView(name))
hass.http.register_view(OIDCRedirectView(oidc_client))
hass.http.register_view(OIDCCallbackView(oidc_client, provider))
hass.http.register_view(OIDCFinishView())
_LOGGER.info("Registered OIDC views")
return True