Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

♻️ [#125] Modify setup-config format to accept list of configs #126

Merged
merged 4 commits into from
Dec 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions docs/setup_configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,12 @@ Example: *setup_config.yml*
...
oidc_db_config_enable: True
oidc_db_config_admin_auth:
oidc_rp_client_id: client-id
oidc_rp_client_secret: secret
endpoint_config:
oidc_op_discovery_endpoint: https://keycloak.local/protocol/openid-connect/
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/
...

This is file is then used with the setup configuration command setup the OIDC admin:
Expand All @@ -65,6 +67,7 @@ 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
Expand Down
3 changes: 3 additions & 0 deletions mozilla_django_oidc_db/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,9 @@ class OpenIDConnectConfig(OpenIDConnectConfigBase):
Configuration for authentication/authorization via OpenID connect
"""

# reserve this for when it will be added in the future
identifier: ClassVar[str] = "admin-oidc"

username_claim = ClaimField(
verbose_name=_("username claim"),
default=ClaimFieldDefault("sub"),
Expand Down
11 changes: 9 additions & 2 deletions mozilla_django_oidc_db/setup_configuration/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from django_setup_configuration.fields import DjangoModelRef
from django_setup_configuration.models import ConfigurationModel
from pydantic import AnyUrl, Discriminator, Tag
from pydantic import AnyUrl, Discriminator, Field, Tag
from typing_extensions import Annotated

from mozilla_django_oidc_db.models import OpenIDConnectConfig
Expand Down Expand Up @@ -46,7 +46,10 @@ def get_endpoint_endpoint_model(endpoint_data):
]


class AdminOIDCConfigurationModel(ConfigurationModel):
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")

# Change default to True
enabled: bool = DjangoModelRef(OpenIDConnectConfig, "enabled", default=True)
Expand Down Expand Up @@ -89,3 +92,7 @@ class Meta:
"make_users_staff",
]
}


class AdminOIDCConfigurationModel(ConfigurationModel):
items: list[AdminOIDCConfigurationModelItem] = Field(default_factory=list)
62 changes: 35 additions & 27 deletions mozilla_django_oidc_db/setup_configuration/steps.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,43 +21,51 @@ class AdminOIDCConfigurationStep(BaseConfigurationStep[AdminOIDCConfigurationMod
enable_setting = "oidc_db_config_enable"

def execute(self, model: AdminOIDCConfigurationModel) -> None:
if len(model.items) != 1:
raise ConfigurationRunFailed(
"You must specify exactly one OIDC configuration"
)

config_model = model.items[0]

all_settings = {
"enabled": model.enabled,
"oidc_rp_client_id": model.oidc_rp_client_id,
"oidc_rp_client_secret": model.oidc_rp_client_secret,
"oidc_rp_sign_algo": model.oidc_rp_sign_algo,
"oidc_rp_scopes_list": model.oidc_rp_scopes_list,
"oidc_op_jwks_endpoint": model.oidc_op_jwks_endpoint,
"oidc_token_use_basic_auth": model.oidc_token_use_basic_auth,
"oidc_rp_idp_sign_key": model.oidc_rp_idp_sign_key,
"oidc_op_logout_endpoint": model.oidc_op_logout_endpoint,
"oidc_use_nonce": model.oidc_use_nonce,
"oidc_nonce_size": model.oidc_nonce_size,
"oidc_state_size": model.oidc_state_size,
"oidc_keycloak_idp_hint": model.oidc_keycloak_idp_hint,
"userinfo_claims_source": model.userinfo_claims_source,
"username_claim": model.username_claim,
"claim_mapping": model.claim_mapping,
"groups_claim": model.groups_claim,
"sync_groups": model.sync_groups,
"sync_groups_glob_pattern": model.sync_groups_glob_pattern,
"make_users_staff": model.make_users_staff,
"superuser_group_names": model.superuser_group_names,
"enabled": config_model.enabled,
"oidc_rp_client_id": config_model.oidc_rp_client_id,
"oidc_rp_client_secret": config_model.oidc_rp_client_secret,
"oidc_rp_sign_algo": config_model.oidc_rp_sign_algo,
"oidc_rp_scopes_list": config_model.oidc_rp_scopes_list,
"oidc_op_jwks_endpoint": config_model.oidc_op_jwks_endpoint,
"oidc_token_use_basic_auth": config_model.oidc_token_use_basic_auth,
"oidc_rp_idp_sign_key": config_model.oidc_rp_idp_sign_key,
"oidc_op_logout_endpoint": config_model.oidc_op_logout_endpoint,
"oidc_use_nonce": config_model.oidc_use_nonce,
"oidc_nonce_size": config_model.oidc_nonce_size,
"oidc_state_size": config_model.oidc_state_size,
"oidc_keycloak_idp_hint": config_model.oidc_keycloak_idp_hint,
"userinfo_claims_source": config_model.userinfo_claims_source,
"username_claim": config_model.username_claim,
"claim_mapping": config_model.claim_mapping,
"groups_claim": config_model.groups_claim,
"sync_groups": config_model.sync_groups,
"sync_groups_glob_pattern": config_model.sync_groups_glob_pattern,
"make_users_staff": config_model.make_users_staff,
"superuser_group_names": config_model.superuser_group_names,
"default_groups": get_groups_by_name(
model.default_groups, model.sync_groups_glob_pattern, model.sync_groups
config_model.default_groups,
config_model.sync_groups_glob_pattern,
config_model.sync_groups,
),
}

if isinstance(model.endpoint_config, OIDCDiscoveryEndpoint):
if isinstance(config_model.endpoint_config, OIDCDiscoveryEndpoint):
all_settings.update(
oidc_op_discovery_endpoint=model.endpoint_config.oidc_op_discovery_endpoint,
oidc_op_discovery_endpoint=config_model.endpoint_config.oidc_op_discovery_endpoint,
)
else:
all_settings.update(
oidc_op_authorization_endpoint=model.endpoint_config.oidc_op_authorization_endpoint,
oidc_op_token_endpoint=model.endpoint_config.oidc_op_token_endpoint,
oidc_op_user_endpoint=model.endpoint_config.oidc_op_user_endpoint,
oidc_op_authorization_endpoint=config_model.endpoint_config.oidc_op_authorization_endpoint,
oidc_op_token_endpoint=config_model.endpoint_config.oidc_op_token_endpoint,
oidc_op_user_endpoint=config_model.endpoint_config.oidc_op_user_endpoint,
)

form = OpenIDConnectConfigForm(
Expand Down
10 changes: 10 additions & 0 deletions tests/setupconfig/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,16 @@ def sync_groups_config_yml():
return "tests/setupconfig/files/sync_groups.yml"


@pytest.fixture()
def multiple_configs_yml():
return "tests/setupconfig/files/multiple_configs.yml"


@pytest.fixture()
def missing_identifier_yml():
return "tests/setupconfig/files/missing_identifier.yml"


@pytest.fixture
def set_config_to_non_default_values():
"""
Expand Down
14 changes: 8 additions & 6 deletions tests/setupconfig/files/defaults.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
oidc_db_config_enable: True
oidc_db_config_admin_auth:
oidc_rp_client_id: client-id
oidc_rp_client_secret: secret
endpoint_config:
oidc_op_authorization_endpoint: http://localhost:8080/realms/test/protocol/openid-connect/auth
oidc_op_token_endpoint: http://localhost:8080/realms/test/protocol/openid-connect/token
oidc_op_user_endpoint: http://localhost:8080/realms/test/protocol/openid-connect/userinfo
items:
- identifier: admin-oidc
oidc_rp_client_id: client-id
oidc_rp_client_secret: secret
endpoint_config:
oidc_op_authorization_endpoint: http://localhost:8080/realms/test/protocol/openid-connect/auth
oidc_op_token_endpoint: http://localhost:8080/realms/test/protocol/openid-connect/token
oidc_op_user_endpoint: http://localhost:8080/realms/test/protocol/openid-connect/userinfo
10 changes: 6 additions & 4 deletions tests/setupconfig/files/discovery.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
oidc_db_config_enable: True
oidc_db_config_admin_auth:
oidc_rp_client_id: testid
oidc_rp_client_secret: 7DB3KUAAizYCcmZufpHRVOcD0TOkNO3I
endpoint_config:
oidc_op_discovery_endpoint: http://localhost:8080/realms/test/
items:
- identifier: admin-oidc
oidc_rp_client_id: testid
oidc_rp_client_secret: 7DB3KUAAizYCcmZufpHRVOcD0TOkNO3I
endpoint_config:
oidc_op_discovery_endpoint: http://localhost:8080/realms/test/
70 changes: 36 additions & 34 deletions tests/setupconfig/files/full_setup.yml
Original file line number Diff line number Diff line change
@@ -1,37 +1,39 @@
oidc_db_config_enable: True
oidc_db_config_admin_auth:
enabled: False
oidc_rp_client_id: client-id
oidc_rp_client_secret: secret
oidc_rp_scopes_list:
- open_id
- email
- profile
- extra_scope
oidc_rp_sign_algo: RS256
oidc_rp_idp_sign_key: key
oidc_op_jwks_endpoint: http://localhost:8080/realms/test/protocol/openid-connect/certs
endpoint_config:
oidc_op_authorization_endpoint: http://localhost:8080/realms/test/protocol/openid-connect/auth
oidc_op_token_endpoint: http://localhost:8080/realms/test/protocol/openid-connect/token
oidc_op_user_endpoint: http://localhost:8080/realms/test/protocol/openid-connect/userinfo
username_claim:
- claim_name
groups_claim:
- groups_claim_name
claim_mapping:
first_name:
- given_name
sync_groups: false
sync_groups_glob_pattern: local.groups.*
default_groups:
- local.groups.Admins
- local.groups.Read-only
make_users_staff: true
superuser_group_names:
- superuser
oidc_use_nonce: false
oidc_nonce_size: 48
oidc_state_size: 48
userinfo_claims_source: id_token
items:
- identifier: admin-oidc
enabled: False
oidc_rp_client_id: client-id
oidc_rp_client_secret: secret
oidc_rp_scopes_list:
- open_id
- email
- profile
- extra_scope
oidc_rp_sign_algo: RS256
oidc_rp_idp_sign_key: key
oidc_op_jwks_endpoint: http://localhost:8080/realms/test/protocol/openid-connect/certs
endpoint_config:
oidc_op_authorization_endpoint: http://localhost:8080/realms/test/protocol/openid-connect/auth
oidc_op_token_endpoint: http://localhost:8080/realms/test/protocol/openid-connect/token
oidc_op_user_endpoint: http://localhost:8080/realms/test/protocol/openid-connect/userinfo
username_claim:
- claim_name
groups_claim:
- groups_claim_name
claim_mapping:
first_name:
- given_name
sync_groups: false
sync_groups_glob_pattern: local.groups.*
default_groups:
- local.groups.Admins
- local.groups.Read-only
make_users_staff: true
superuser_group_names:
- superuser
oidc_use_nonce: false
oidc_nonce_size: 48
oidc_state_size: 48
userinfo_claims_source: id_token

9 changes: 9 additions & 0 deletions tests/setupconfig/files/missing_identifier.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
oidc_db_config_enable: True
oidc_db_config_admin_auth:
items:
- oidc_rp_client_id: client-id
oidc_rp_client_secret: secret
endpoint_config:
oidc_op_authorization_endpoint: http://localhost:8080/realms/test/protocol/openid-connect/auth
oidc_op_token_endpoint: http://localhost:8080/realms/test/protocol/openid-connect/token
oidc_op_user_endpoint: http://localhost:8080/realms/test/protocol/openid-connect/userinfo
17 changes: 17 additions & 0 deletions tests/setupconfig/files/multiple_configs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
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_authorization_endpoint: http://localhost:8080/realms/test/protocol/openid-connect/auth
oidc_op_token_endpoint: http://localhost:8080/realms/test/protocol/openid-connect/token
oidc_op_user_endpoint: http://localhost:8080/realms/test/protocol/openid-connect/userinfo
- identifier: admin-oidc
oidc_rp_client_id: client-id2
oidc_rp_client_secret: secret2
endpoint_config:
oidc_op_authorization_endpoint: http://localhost:8080/realms/test/protocol/openid-connect/auth
oidc_op_token_endpoint: http://localhost:8080/realms/test/protocol/openid-connect/token
oidc_op_user_endpoint: http://localhost:8080/realms/test/protocol/openid-connect/userinfo
22 changes: 12 additions & 10 deletions tests/setupconfig/files/no_sync_groups.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
oidc_db_config_enable: True
oidc_db_config_admin_auth:
oidc_rp_client_id: client-id
oidc_rp_client_secret: secret
endpoint_config:
oidc_op_authorization_endpoint: http://localhost:8080/realms/test/protocol/openid-connect/auth
oidc_op_token_endpoint: http://localhost:8080/realms/test/protocol/openid-connect/token
oidc_op_user_endpoint: http://localhost:8080/realms/test/protocol/openid-connect/userinfo
sync_groups: false
default_groups:
- SuperAdmins
- NormalUsers
items:
- identifier: admin-oidc
oidc_rp_client_id: client-id
oidc_rp_client_secret: secret
endpoint_config:
oidc_op_authorization_endpoint: http://localhost:8080/realms/test/protocol/openid-connect/auth
oidc_op_token_endpoint: http://localhost:8080/realms/test/protocol/openid-connect/token
oidc_op_user_endpoint: http://localhost:8080/realms/test/protocol/openid-connect/userinfo
sync_groups: false
default_groups:
- SuperAdmins
- NormalUsers
28 changes: 15 additions & 13 deletions tests/setupconfig/files/sync_groups.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
oidc_db_config_enable: True
oidc_db_config_admin_auth:
oidc_rp_client_id: client-id
oidc_rp_client_secret: secret
endpoint_config:
oidc_op_authorization_endpoint: http://localhost:8080/realms/test/protocol/openid-connect/auth
oidc_op_token_endpoint: http://localhost:8080/realms/test/protocol/openid-connect/token
oidc_op_user_endpoint: http://localhost:8080/realms/test/protocol/openid-connect/userinfo
sync_groups: true
sync_groups_glob_pattern: local.groups.*
default_groups:
- local.groups.SuperAdmins
- local.WeirdAdmins
- local.groups.NormalUsers
- local.WeirdUsers
items:
- identifier: admin-oidc
oidc_rp_client_id: client-id
oidc_rp_client_secret: secret
endpoint_config:
oidc_op_authorization_endpoint: http://localhost:8080/realms/test/protocol/openid-connect/auth
oidc_op_token_endpoint: http://localhost:8080/realms/test/protocol/openid-connect/token
oidc_op_user_endpoint: http://localhost:8080/realms/test/protocol/openid-connect/userinfo
sync_groups: true
sync_groups_glob_pattern: local.groups.*
default_groups:
- local.groups.SuperAdmins
- local.WeirdAdmins
- local.groups.NormalUsers
- local.WeirdUsers
Loading
Loading