Skip to content

Commit

Permalink
💥 [#2617] Update changed setting names for setup-configuration
Browse files Browse the repository at this point in the history
The configuration settings are tightly coupled to the django model
fields (names and data types). The field names for the configuration
have been changed compared to the vendored library, and the structure
has been changed to be able to use claims with dots in their name.

Unfortunately, this means that breaking changes in the infrastructure/
configuration setup are required because of the way this config is
specified and used.
  • Loading branch information
sergei-maertens committed Aug 9, 2024
1 parent 78fb25b commit fd35173
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 137 deletions.
63 changes: 28 additions & 35 deletions docs/configuration/admin_oidc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ All settings:
ADMIN_OIDC_DEFAULT_GROUPS
ADMIN_OIDC_GROUPS_CLAIM
ADMIN_OIDC_MAKE_USERS_STAFF
ADMIN_OIDC_OIDC_EXEMPT_URLS
ADMIN_OIDC_OIDC_NONCE_SIZE
ADMIN_OIDC_OIDC_OP_AUTHORIZATION_ENDPOINT
ADMIN_OIDC_OIDC_OP_DISCOVERY_ENDPOINT
Expand All @@ -63,132 +62,126 @@ Detailed Information

Variable ADMIN_OIDC_CLAIM_MAPPING
Setting claim mapping
Description Mapping from user-model fields to OIDC claims
Possible values Mapping: {'some_key': 'Some value'}
Default value {'email': 'email', 'first_name': 'given_name', 'last_name': 'family_name'}
Description Mapping from user-model fields to OIDC claim paths
Possible values Mapping: {'some_key': ['Some value']}
Default value {'email': ['email'], 'first_name': ['given_name'], 'last_name': ['family_name']}

Variable ADMIN_OIDC_GROUPS_CLAIM
Setting groups claim
Description The name of the OIDC claim that holds the values to map to local user groups.
Possible values string
Default value roles
Possible values list of strings
Default value [roles]

Variable ADMIN_OIDC_MAKE_USERS_STAFF
Setting make users staff
Description Users will be flagged as being a staff user automatically. This allows users to login to the admin interface. By default they have no permissions, even if they are staff.
Possible values True, False
Default value False
Variable ADMIN_OIDC_OIDC_EXEMPT_URLS
Setting URLs exempt from session renewal
Description This is a list of absolute url paths, regular expressions for url paths, or Django view names. This plus the mozilla-django-oidc urls are exempted from the session renewal by the SessionRefresh middleware.
Possible values string, comma-delimited ('foo,bar,baz')
Default value

Variable ADMIN_OIDC_OIDC_NONCE_SIZE
Setting Nonce size
Description Sets the length of the random string used for OpenID Connect nonce verification
Possible values string representing a positive integer
Default value 32

Variable ADMIN_OIDC_OIDC_OP_AUTHORIZATION_ENDPOINT
Setting Authorization endpoint
Description URL of your OpenID Connect provider authorization endpoint
Possible values string (URL)
Default value No default

Variable ADMIN_OIDC_OIDC_OP_DISCOVERY_ENDPOINT
Setting Discovery endpoint
Description URL of your OpenID Connect provider discovery endpoint ending with a slash (`.well-known/...` will be added automatically). If this is provided, the remaining endpoints can be omitted, as they will be derived from this endpoint.
Possible values string (URL)
Default value No default

Variable ADMIN_OIDC_OIDC_OP_JWKS_ENDPOINT
Setting JSON Web Key Set endpoint
Description URL of your OpenID Connect provider JSON Web Key Set endpoint. Required if `RS256` is used as signing algorithm.
Possible values string (URL)
Default value No default

Variable ADMIN_OIDC_OIDC_OP_TOKEN_ENDPOINT
Setting Token endpoint
Description URL of your OpenID Connect provider token endpoint
Possible values string (URL)
Default value No default

Variable ADMIN_OIDC_OIDC_OP_USER_ENDPOINT
Setting User endpoint
Description URL of your OpenID Connect provider userinfo endpoint
Possible values string (URL)
Default value No default

Variable ADMIN_OIDC_OIDC_RP_CLIENT_ID
Setting OpenID Connect client ID
Description OpenID Connect client ID provided by the OIDC Provider
Possible values string
Default value No default

Variable ADMIN_OIDC_OIDC_RP_CLIENT_SECRET
Setting OpenID Connect secret
Description OpenID Connect secret provided by the OIDC Provider
Possible values string
Default value No default

Variable ADMIN_OIDC_OIDC_RP_IDP_SIGN_KEY
Setting Sign key
Description 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.
Possible values string
Default value No default

Variable ADMIN_OIDC_OIDC_RP_SCOPES_LIST
Setting OpenID Connect scopes
Description OpenID Connect scopes that are requested during login
Possible values string, comma-delimited ('foo,bar,baz')
Default value openid, email, profile

Variable ADMIN_OIDC_OIDC_RP_SIGN_ALGO
Setting OpenID sign algorithm
Description Algorithm the Identity Provider uses to sign ID tokens
Possible values string
Default value HS256

Variable ADMIN_OIDC_OIDC_STATE_SIZE
Setting State size
Description Sets the length of the random string used for OpenID Connect state verification
Possible values string representing a positive integer
Default value 32

Variable ADMIN_OIDC_OIDC_USE_NONCE
Setting Use nonce
Description Controls whether the OpenID Connect client uses nonce verification
Possible values True, False
Default value True

Variable ADMIN_OIDC_SUPERUSER_GROUP_NAMES
Setting Superuser group names
Description 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.
Possible values string, comma-delimited ('foo,bar,baz')
Default value
Default value

Variable ADMIN_OIDC_SYNC_GROUPS
Setting Create local user groups if they do not exist yet
Description If checked, local user groups will be created for group names present in the groups claim, if they do not exist yet locally.
Possible values True, False
Default value True

Variable ADMIN_OIDC_SYNC_GROUPS_GLOB_PATTERN
Setting groups glob pattern
Description The glob pattern that groups must match to be synchronized to the local database.
Possible values string
Default value *

Variable ADMIN_OIDC_USERINFO_CLAIMS_SOURCE
Setting user information claims extracted from
Description Indicates the source from which the user information claims should be extracted.
Possible values userinfo_endpoint, id_token
Default value userinfo_endpoint

Variable ADMIN_OIDC_USERNAME_CLAIM
Setting username claim
Description The name of the OIDC claim that is used as the username
Possible values string
Default value sub
Possible values list of strings
Default value [sub]
7 changes: 0 additions & 7 deletions docs/configuration/digid_oidc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ All settings:
DIGID_OIDC_ENABLED
DIGID_OIDC_ERROR_MESSAGE_MAPPING
DIGID_OIDC_IDENTIFIER_CLAIM_NAME
DIGID_OIDC_OIDC_EXEMPT_URLS
DIGID_OIDC_OIDC_KEYCLOAK_IDP_HINT
DIGID_OIDC_OIDC_NONCE_SIZE
DIGID_OIDC_OIDC_OP_AUTHORIZATION_ENDPOINT
Expand Down Expand Up @@ -75,12 +74,6 @@ Detailed Information
Possible values string
Default value bsn
Variable DIGID_OIDC_OIDC_EXEMPT_URLS
Setting URLs exempt from session renewal
Description This is a list of absolute url paths, regular expressions for url paths, or Django view names. This plus the mozilla-django-oidc urls are exempted from the session renewal by the SessionRefresh middleware.
Possible values No information available
Default value
Variable DIGID_OIDC_OIDC_KEYCLOAK_IDP_HINT
Setting Keycloak-identiteitsprovider hint
Description Specifiek voor Keycloak: parameter die aangeeft welke identiteitsprovider gebruikt moet worden (inlogscherm van Keycloak overslaan).
Expand Down
9 changes: 1 addition & 8 deletions docs/configuration/eherkenning_oidc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ All settings:
EHERKENNING_OIDC_ENABLED
EHERKENNING_OIDC_ERROR_MESSAGE_MAPPING
EHERKENNING_OIDC_IDENTIFIER_CLAIM_NAME
EHERKENNING_OIDC_OIDC_EXEMPT_URLS
EHERKENNING_OIDC_OIDC_KEYCLOAK_IDP_HINT
EHERKENNING_OIDC_OIDC_NONCE_SIZE
EHERKENNING_OIDC_OIDC_OP_AUTHORIZATION_ENDPOINT
Expand Down Expand Up @@ -74,13 +73,7 @@ Detailed Information
Description De naam van de claim waarin het KVK nummer van de gebruiker is opgeslagen
Possible values string
Default value kvk
Variable EHERKENNING_OIDC_OIDC_EXEMPT_URLS
Setting URLs exempt from session renewal
Description This is a list of absolute url paths, regular expressions for url paths, or Django view names. This plus the mozilla-django-oidc urls are exempted from the session renewal by the SessionRefresh middleware.
Possible values string, comma-delimited ('foo,bar,baz')
Default value

Variable EHERKENNING_OIDC_OIDC_KEYCLOAK_IDP_HINT
Setting Keycloak-identiteitsprovider hint
Description Specifiek voor Keycloak: parameter die aangeeft welke identiteitsprovider gebruikt moet worden (inlogscherm van Keycloak overslaan).
Expand Down
72 changes: 39 additions & 33 deletions src/open_inwoner/configurations/bootstrap/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,45 @@
EherkenningConfigurationAdmin,
)
from digid_eherkenning.models import DigidConfiguration, EherkenningConfiguration
from digid_eherkenning.oidc.admin import admin_modelform_factory
from django_jsonform.forms.fields import JSONFormField
from django_setup_configuration.config_settings import ConfigSettings
from django_setup_configuration.configuration import BaseConfigurationStep
from django_setup_configuration.exceptions import ConfigurationRunFailed
from mozilla_django_oidc_db.forms import OpenIDConnectConfigForm
from mozilla_django_oidc_db.models import OpenIDConnectConfig
from simple_certmanager.models import Certificate

from digid_eherkenning_oidc_generics.admin import (
OpenIDConnectDigiDConfigForm,
OpenIDConnectEHerkenningConfigForm,
)
from digid_eherkenning_oidc_generics.models import (
OpenIDConnectDigiDConfig,
OpenIDConnectEHerkenningConfig,
)
from open_inwoner.accounts.models import OpenIDDigiDConfig, OpenIDEHerkenningConfig
from open_inwoner.configurations.models import SiteConfiguration

from .utils import convert_setting_to_model_field_name


class LOAValueMappingField(JSONFormField):
def to_python(self, value):
value = super().to_python(value)
# super class treats [] as empty (not wrong), but converts it to None, which
# doesn't pass the schema validation
if value is None:
value = []
return value


def formfield_callback(model_field, **kwargs):
if model_field.name == "loa_value_mapping":
kwargs["form_class"] = LOAValueMappingField
return model_field.formfield(**kwargs)


OpenIDDigiDConfigForm = admin_modelform_factory(
OpenIDDigiDConfig, formfield_callback=formfield_callback
)
OpenIDEHerkenningConfigForm = admin_modelform_factory(
OpenIDEHerkenningConfig, formfield_callback=formfield_callback
)


#
# DigiD OIDC
#
Expand All @@ -41,16 +60,14 @@ class DigiDOIDCConfigurationStep(BaseConfigurationStep):
config_settings = ConfigSettings(
enable_setting="DIGID_OIDC_CONFIG_ENABLE",
namespace="DIGID_OIDC",
models=[OpenIDConnectDigiDConfig],
models=[OpenIDDigiDConfig],
required_settings=[
"DIGID_OIDC_OIDC_RP_CLIENT_ID",
"DIGID_OIDC_OIDC_RP_CLIENT_SECRET",
],
optional_settings=[
"DIGID_OIDC_ENABLED",
"DIGID_OIDC_ERROR_MESSAGE_MAPPING",
"DIGID_OIDC_IDENTIFIER_CLAIM_NAME",
"DIGID_OIDC_OIDC_EXEMPT_URLS",
"DIGID_OIDC_BSN_CLAIM",
"DIGID_OIDC_OIDC_KEYCLOAK_IDP_HINT",
"DIGID_OIDC_OIDC_NONCE_SIZE",
"DIGID_OIDC_OIDC_OP_AUTHORIZATION_ENDPOINT",
Expand All @@ -69,15 +86,15 @@ class DigiDOIDCConfigurationStep(BaseConfigurationStep):
)

def is_configured(self) -> bool:
return OpenIDConnectDigiDConfig.get_solo().enabled
return OpenIDDigiDConfig.get_solo().enabled

def configure(self):
config = OpenIDConnectDigiDConfig.get_solo()
config = OpenIDDigiDConfig.get_solo()

# Use the model defaults
form_data = {
field.name: getattr(config, field.name)
for field in OpenIDConnectDigiDConfig._meta.fields
for field in OpenIDDigiDConfig._meta.fields
}

# Only override field values with settings if they are defined
Expand All @@ -95,12 +112,8 @@ def configure(self):

form_data["enabled"] = True

# Saving the form with the default error_message_mapping `{}` causes the save to fail
if not form_data["error_message_mapping"]:
del form_data["error_message_mapping"]

# Use the admin form to apply validation and fetch URLs from the discovery endpoint
form = OpenIDConnectDigiDConfigForm(data=form_data)
form = OpenIDDigiDConfigForm(data=form_data)
if not form.is_valid():
raise ConfigurationRunFailed(
f"Something went wrong while saving configuration: {form.errors}"
Expand All @@ -127,15 +140,15 @@ class eHerkenningOIDCConfigurationStep(BaseConfigurationStep):
config_settings = ConfigSettings(
enable_setting="EHERKENNING_OIDC_CONFIG_ENABLE",
namespace="EHERKENNING_OIDC",
models=[OpenIDConnectEHerkenningConfig],
models=[OpenIDEHerkenningConfig],
update_fields=True,
required_settings=[
"EHERKENNING_OIDC_OIDC_RP_CLIENT_ID",
"EHERKENNING_OIDC_OIDC_RP_CLIENT_SECRET",
],
optional_settings=[
"EHERKENNING_OIDC_ENABLED",
"EHERKENNING_OIDC_IDENTIFIER_CLAIM_NAME",
"EHERKENNING_OIDC_LEGAL_SUBJECT_CLAIM",
"EHERKENNING_OIDC_OIDC_RP_SCOPES_LIST",
"EHERKENNING_OIDC_OIDC_RP_SIGN_ALGO",
"EHERKENNING_OIDC_OIDC_RP_IDP_SIGN_KEY",
Expand All @@ -146,25 +159,23 @@ class eHerkenningOIDCConfigurationStep(BaseConfigurationStep):
"EHERKENNING_OIDC_OIDC_OP_USER_ENDPOINT",
"EHERKENNING_OIDC_OIDC_OP_LOGOUT_ENDPOINT",
"EHERKENNING_OIDC_USERINFO_CLAIMS_SOURCE",
"EHERKENNING_OIDC_ERROR_MESSAGE_MAPPING",
"EHERKENNING_OIDC_OIDC_KEYCLOAK_IDP_HINT",
"EHERKENNING_OIDC_OIDC_USE_NONCE",
"EHERKENNING_OIDC_OIDC_NONCE_SIZE",
"EHERKENNING_OIDC_OIDC_STATE_SIZE",
"EHERKENNING_OIDC_OIDC_EXEMPT_URLS",
],
)

def is_configured(self) -> bool:
return OpenIDConnectEHerkenningConfig.get_solo().enabled
return OpenIDEHerkenningConfig.get_solo().enabled

def configure(self):
config = OpenIDConnectEHerkenningConfig.get_solo()
config = OpenIDEHerkenningConfig.get_solo()

# Use the model defaults
form_data = {
field.name: getattr(config, field.name)
for field in OpenIDConnectEHerkenningConfig._meta.fields
for field in OpenIDEHerkenningConfig._meta.fields
}

# Only override field values with settings if they are defined
Expand All @@ -182,12 +193,8 @@ def configure(self):

form_data["enabled"] = True

# Saving the form with the default error_message_mapping `{}` causes the save to fail
if not form_data["error_message_mapping"]:
del form_data["error_message_mapping"]

# Use the admin form to apply validation and fetch URLs from the discovery endpoint
form = OpenIDConnectEHerkenningConfigForm(data=form_data)
form = OpenIDEHerkenningConfigForm(data=form_data)
if not form.is_valid():
raise ConfigurationRunFailed(
f"Something went wrong while saving configuration: {form.errors}"
Expand Down Expand Up @@ -226,7 +233,6 @@ class AdminOIDCConfigurationStep(BaseConfigurationStep):
"ADMIN_OIDC_CLAIM_MAPPING",
"ADMIN_OIDC_GROUPS_CLAIM",
"ADMIN_OIDC_MAKE_USERS_STAFF",
"ADMIN_OIDC_OIDC_EXEMPT_URLS",
"ADMIN_OIDC_OIDC_NONCE_SIZE",
"ADMIN_OIDC_OIDC_OP_AUTHORIZATION_ENDPOINT",
"ADMIN_OIDC_OIDC_OP_DISCOVERY_ENDPOINT",
Expand Down
Loading

0 comments on commit fd35173

Please sign in to comment.