-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add setup configuraiton model and step * Add OIDCSetupConfigForm with only required fields * Create common create_missing_groups util
- Loading branch information
Showing
7 changed files
with
190 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
from typing import Optional, Union | ||
|
||
from django_setup_configuration.fields import DjangoModelRef | ||
from django_setup_configuration.models import ConfigurationModel | ||
from pydantic import AnyUrl, Discriminator, Tag | ||
from typing_extensions import Annotated | ||
|
||
from mozilla_django_oidc_db.models import OpenIDConnectConfig | ||
|
||
|
||
class OIDCFullEndpointConfig(ConfigurationModel): | ||
oidc_op_authorization_endpoint: AnyUrl = DjangoModelRef( | ||
OpenIDConnectConfig, "oidc_op_authorization_endpoint" | ||
) | ||
oidc_op_token_endpoint: AnyUrl = DjangoModelRef( | ||
OpenIDConnectConfig, "oidc_op_token_endpoint" | ||
) | ||
oidc_op_user_endpoint: AnyUrl = DjangoModelRef( | ||
OpenIDConnectConfig, "oidc_op_user_endpoint" | ||
) | ||
|
||
|
||
class OIDCDiscoveryEndpoint(ConfigurationModel): | ||
oidc_op_discovery_endpoint: AnyUrl = DjangoModelRef( | ||
OpenIDConnectConfig, "oidc_op_discovery_endpoint", default=None | ||
) | ||
|
||
|
||
def get_endpoint_endpoint_model(endpoint_data): | ||
|
||
if isinstance(endpoint_data, dict): | ||
discovery_endpoint = endpoint_data.get("oidc_op_discovery_endpoint") | ||
else: | ||
discovery_endpoint = getattr(endpoint_data, "oidc_op_discovery_endpoint", None) | ||
if discovery_endpoint: | ||
return "discovery" | ||
return "all" | ||
|
||
|
||
EndpointConfigUnion = Annotated[ | ||
Union[ | ||
Annotated[OIDCFullEndpointConfig, Tag("all")], | ||
Annotated[OIDCDiscoveryEndpoint, Tag("discovery")], | ||
], | ||
Discriminator(get_endpoint_endpoint_model), | ||
] | ||
|
||
|
||
class AdminOIDCConfigurationModel(ConfigurationModel): | ||
|
||
# Json | ||
claim_mapping: Optional[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: Optional[list[str]] = DjangoModelRef( | ||
OpenIDConnectConfig, "username_claim" | ||
) | ||
groups_claim: Optional[list[str]] = DjangoModelRef( | ||
OpenIDConnectConfig, "groups_claim" | ||
) | ||
superuser_group_names: Optional[list[str]] = DjangoModelRef( | ||
OpenIDConnectConfig, "superuser_group_names" | ||
) | ||
default_groups: Optional[list[str]] = DjangoModelRef( | ||
OpenIDConnectConfig, "superuser_group_names" | ||
) | ||
oidc_rp_scopes_list: Optional[list[str]] = DjangoModelRef( | ||
OpenIDConnectConfig, "oidc_rp_scopes_list" | ||
) | ||
|
||
endpoint_config: EndpointConfigUnion | ||
|
||
class Meta: | ||
django_model_refs = { | ||
OpenIDConnectConfig: [ | ||
"oidc_rp_client_id", | ||
"oidc_rp_client_secret", | ||
"oidc_token_use_basic_auth", | ||
"oidc_rp_sign_algo", | ||
"oidc_rp_idp_sign_key", | ||
"oidc_op_logout_endpoint", | ||
"oidc_op_jwks_endpoint", | ||
"oidc_use_nonce", | ||
"oidc_nonce_size", | ||
"oidc_state_size", | ||
"oidc_keycloak_idp_hint", | ||
"userinfo_claims_source", | ||
"sync_groups", | ||
"sync_groups_glob_pattern", | ||
"make_users_staff", | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
from django_setup_configuration.configuration import BaseConfigurationStep | ||
from django_setup_configuration.exceptions import ConfigurationRunFailed | ||
|
||
from mozilla_django_oidc_db.forms import OIDCSetupConfigForm | ||
from mozilla_django_oidc_db.models import OpenIDConnectConfig | ||
from mozilla_django_oidc_db.setup_configuration.models import ( | ||
AdminOIDCConfigurationModel, | ||
) | ||
from mozilla_django_oidc_db.utils import create_missing_groups | ||
|
||
|
||
class AdminOIDCConfigurationStep(BaseConfigurationStep[AdminOIDCConfigurationModel]): | ||
""" | ||
Configure admin login via OpenID Connect | ||
""" | ||
|
||
verbose_name = "Configuration for admin login via OpenID Connect" | ||
config_model = AdminOIDCConfigurationModel | ||
namespace = "ADMIN_OIDC" | ||
enable_setting = "ADMIN_OIDC_CONFIG_ENABLE" | ||
|
||
def execute(self, model: AdminOIDCConfigurationModel) -> None: | ||
|
||
config = OpenIDConnectConfig.get_solo() | ||
|
||
base_model_data = model.model_dump() | ||
endpoint_config_data = base_model_data.pop("endpoint_config") | ||
|
||
all_settings = { | ||
"sync_groups": config.sync_groups, | ||
"oidc_use_nonce": config.oidc_use_nonce, | ||
"enabled": True, | ||
"claim_mapping": config.claim_mapping, # JSONFormField widget cannot handle blank values with object schema | ||
"sync_groups_glob_pattern": config.sync_groups_glob_pattern, | ||
**base_model_data, | ||
**endpoint_config_data, | ||
} | ||
|
||
if groups := all_settings.get("default_groups"): | ||
all_settings["default_groups"] = create_missing_groups( | ||
groups, all_settings["sync_groups_glob_pattern"] | ||
) | ||
|
||
form = OIDCSetupConfigForm( | ||
instance=config, | ||
data=all_settings, | ||
) | ||
if not form.is_valid(): | ||
raise ConfigurationRunFailed( | ||
"Admin OIDC configuration field validation failed", | ||
form.errors.as_json(), | ||
) | ||
form.save() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters