From 084362e474a7e2830d8863ca0ceb9422b2d48955 Mon Sep 17 00:00:00 2001 From: Steven Bal Date: Fri, 10 Jan 2025 16:01:02 +0100 Subject: [PATCH] :memo: Use generated yaml directive for setup-config docs --- .readthedocs.yaml | 1 + docs/conf.py | 2 + docs/setup_configuration.rst | 80 ++----------------- .../setup_configuration/models.py | 40 +++++++--- .../setup_configuration/steps.py | 2 +- tox.ini | 2 +- 6 files changed, 41 insertions(+), 86 deletions(-) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 02394be..a047a87 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -19,3 +19,4 @@ python: extra_requirements: - tests - docs + - setup-configuration diff --git a/docs/conf.py b/docs/conf.py index 5751f7d..d7e25fc 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -22,6 +22,8 @@ django.setup() +from django_setup_configuration.documentation.model_directive import setup + # -- Project information ----------------------------------------------------- project = "mozilla_django_oidc_db" diff --git a/docs/setup_configuration.rst b/docs/setup_configuration.rst index 1bfdecb..609d57b 100644 --- a/docs/setup_configuration.rst +++ b/docs/setup_configuration.rst @@ -5,6 +5,10 @@ Django Setup Configuration There is optional support for `django-setup-configuration`_ that allows you to automatically configure the OpenID Connect configuration using that package's ``setup_configuration`` command. +.. autoclass:: mozilla_django_oidc_db.setup_configuration.steps.AdminOIDCConfigurationStep + :noindex: + + You must install the ``setup-configuration`` dependency group: .. _django-setup-configuration: https://pypi.org/project/django-setup-configuration/ @@ -39,84 +43,10 @@ The setup configuration source must contain the following base keys to use this Example: *setup_config.yml* -.. code-block:: YAML - - other_enable: True - other_config: - ... - oidc_db_config_enable: True - oidc_db_config_admin_auth: - items: - - identifier: admin-oidc - oidc_rp_client_id: client-id - oidc_rp_client_secret: secret - endpoint_config: - oidc_op_discovery_endpoint: https://keycloak.local/protocol/openid-connect/ - ... +.. pydantic-model-example:: mozilla_django_oidc_db.setup_configuration.steps.AdminOIDCConfigurationStep This is file is then used with the setup configuration command setup the OIDC admin: .. code-block:: Bash python manage.py setup_configuration --yaml-file path/to/setup_config.yml - - -Any field from the ``OpenIDConnectConfig`` can be added to ``oidc_db_config_admin_auth`` (except endpoints, see below) - -Required Fields: -"""""""""""""""" - - -* ``identifier``: a unique identifier for this configuration. -* ``oidc_rp_client_id``: OpenID Connect client ID from the OIDC Provider. -* ``oidc_rp_client_secret``: OpenID Connect secret from the OIDC Provider. -* ``endpoint_config``: Dictionary containing endpoint information - - * ``oidc_op_discovery_endpoint``: URL of your OpenID Connect provider discovery endpoint ending with a slash (`.well-known/...` will be added automatically). - - **OR** - - * ``oidc_op_authorization_endpoint``: URL of your OpenID Connect provider authorization endpoint - * ``oidc_op_token_endpoint``: URL of your OpenID Connect provider token endpoint - * ``oidc_op_user_endpoint``: URL of your OpenID Connect provider userinfo endpoint - - -The endpoints must be provided in the ``endpoint_config`` dictionary. -You can add the discovery endpoint to automatically fetch the other endpoints. -Otherwise the endpoints must be specified individually. -Providing both will cause the validation to fail. - -Optional Fields: -"""""""""""""""" - -.. warning:: - - Values that are not provided will use the default or empty value and will overwrite any setting changed in the admin. - Make sure settings that were manually changed in the admin are added to the configuration yaml. - -All the following keys are placed in the ``oidc_db_config_admin_auth`` dictionary. - -* ``enabled``: whether OIDC is enabled for admin login. Defaults to ``True``. -* ``oidc_op_jwks_endpoint``: URL of your OpenID Connect provider JSON Web Key Set endpoint. - Required if ``RS256`` is used as signing algorithm. No default value. -* ``claim_mapping``: Mapping from user-model fields to OIDC claims. - Defaults to ``{"email": ["email"], "first_name": ["given_name"], "last_name": ["family_name"]}`` -* ``username_claim``: The name of the OIDC claim that is used as the username. Defaults to ``["sub"]`` -* ``groups_claim``: The name of the OIDC claim that holds the values to map to local user groups. Defaults to ``["roles"]`` -* ``default_groups``: The default groups to which every user logging in with OIDC will be assigned. No default values. -* ``superuser_group_names``: If any of these group names are present in the claims upon login, the user will be marked as a superuser. - If none of these groups are present the user will lose superuser permissions. Defaults to empty list. -* ``make_users_staff``: Users will be flagged as being a staff user automatically. - This allows users to login to the admin interface. Defaults to ``False``. -* ``oidc_use_nonce``: Controls whether the OpenID Connect client uses nonce verification. Defaults to ``True``. -* ``oidc_nonce_size``: Sets the length of the random string used for OpenID Connect nonce verification. Defaults to ``32``. -* ``oidc_state_size``: Sets the length of the random string used for OpenID Connect state verification. Defaults to ``32``. -* ``oidc_rp_idp_sign_key``: Key the Identity Provider uses to sign ID tokens in the case of an RSA sign algorithm. - Should be the signing key in PEM or DER format. No default. -* ``oidc_rp_scopes_list``: OpenID Connect scopes that are requested during login. Defaults to ``["openid", "email", "profile"]``. -* ``oidc_rp_sign_algo``: Algorithm the Identity Provider uses to sign ID tokens. Defaults to ``"HS256"``. -* ``sync_groups``: If checked, local user groups will be created for group names present in the groups claim, - if they do not exist yet locally. Defaults to ``True``. -* ``sync_groups_glob_pattern``: The glob pattern that groups must match to be synchronized to the local database. Defaults to ``"*"``. -* ``userinfo_claims_source``: Indicates the source from which the user information claims should be extracted - (``"userinfo_endpoint"`` or ``"id_token"``). Defaults to ``"userinfo_endpoint"``. diff --git a/mozilla_django_oidc_db/setup_configuration/models.py b/mozilla_django_oidc_db/setup_configuration/models.py index e342645..ca4cd84 100644 --- a/mozilla_django_oidc_db/setup_configuration/models.py +++ b/mozilla_django_oidc_db/setup_configuration/models.py @@ -5,30 +5,45 @@ from pydantic import AnyUrl, Discriminator, Field, Tag from typing_extensions import Annotated -from mozilla_django_oidc_db.models import OpenIDConnectConfig +from mozilla_django_oidc_db.models import OpenIDConnectConfig, get_claim_mapping + +EXAMPLE_REALM = "http://keycloak.local:8080/realms/test" class OIDCFullEndpointConfig(ConfigurationModel): oidc_op_authorization_endpoint: AnyUrl = DjangoModelRef( - OpenIDConnectConfig, "oidc_op_authorization_endpoint" + OpenIDConnectConfig, + "oidc_op_authorization_endpoint", + examples=[f"{EXAMPLE_REALM}/openid-connect/auth"], ) oidc_op_token_endpoint: AnyUrl = DjangoModelRef( - OpenIDConnectConfig, "oidc_op_token_endpoint" + OpenIDConnectConfig, + "oidc_op_token_endpoint", + examples=[f"{EXAMPLE_REALM}/protocol/openid-connect/token"], ) oidc_op_user_endpoint: AnyUrl = DjangoModelRef( - OpenIDConnectConfig, "oidc_op_user_endpoint" + OpenIDConnectConfig, + "oidc_op_user_endpoint", + examples=[f"{EXAMPLE_REALM}/protocol/openid-connect/userinfo"], ) oidc_op_logout_endpoint: AnyUrl | Literal[""] = DjangoModelRef( - OpenIDConnectConfig, "oidc_op_logout_endpoint" + OpenIDConnectConfig, + "oidc_op_logout_endpoint", + examples=[f"{EXAMPLE_REALM}/protocol/openid-connect/logout"], ) oidc_op_jwks_endpoint: AnyUrl | Literal[""] = DjangoModelRef( - OpenIDConnectConfig, "oidc_op_jwks_endpoint" + OpenIDConnectConfig, + "oidc_op_jwks_endpoint", + examples=[f"{EXAMPLE_REALM}/protocol/openid-connect/certs"], ) class OIDCDiscoveryEndpoint(ConfigurationModel): oidc_op_discovery_endpoint: AnyUrl = DjangoModelRef( - OpenIDConnectConfig, "oidc_op_discovery_endpoint", default=None + OpenIDConnectConfig, + "oidc_op_discovery_endpoint", + default=None, + examples=[f"{EXAMPLE_REALM}/"], ) @@ -55,7 +70,10 @@ def get_endpoint_endpoint_model(endpoint_data): class AdminOIDCConfigurationModelItem(ConfigurationModel): # Currently unused because we use a SingletonModel, but this will be relevant in the # future - identifier: str = Field(description="a unique identifier for this configuration") + identifier: str = Field( + description="a unique identifier for this configuration", + examples=["admin-oidc"], + ) # Change default to True enabled: bool = DjangoModelRef(OpenIDConnectConfig, "enabled", default=True) @@ -64,7 +82,11 @@ class AdminOIDCConfigurationModelItem(ConfigurationModel): claim_mapping: dict = DjangoModelRef(OpenIDConnectConfig, "claim_mapping") # Arrays are overridden to make the typing simpler (the underlying Django field is an ArrayField, which is non-standard) - username_claim: list[str] = DjangoModelRef(OpenIDConnectConfig, "username_claim") + username_claim: list[str] = DjangoModelRef( + OpenIDConnectConfig, + "username_claim", + examples=[["nested", "username", "claim"]], + ) groups_claim: list[str] = DjangoModelRef(OpenIDConnectConfig, "groups_claim") superuser_group_names: list[str] = DjangoModelRef( OpenIDConnectConfig, "superuser_group_names" diff --git a/mozilla_django_oidc_db/setup_configuration/steps.py b/mozilla_django_oidc_db/setup_configuration/steps.py index b37ef96..6299569 100644 --- a/mozilla_django_oidc_db/setup_configuration/steps.py +++ b/mozilla_django_oidc_db/setup_configuration/steps.py @@ -12,7 +12,7 @@ class AdminOIDCConfigurationStep(BaseConfigurationStep[AdminOIDCConfigurationModel]): """ - Configure admin login via OpenID Connect + This step configures the necessary settings to enable OpenID Connect authentication for admin users """ verbose_name = "Configuration for admin login via OpenID Connect" diff --git a/tox.ini b/tox.ini index c5526e7..a1e123e 100644 --- a/tox.ini +++ b/tox.ini @@ -59,7 +59,7 @@ basepython=python changedir=docs skipsdist=true extras = - setupconfig + setup-configuration db docs tests