diff --git a/Puppetfile b/Puppetfile --- a/Puppetfile +++ b/Puppetfile @@ -113,7 +113,7 @@ mod 'keycloak', :git => 'https://forge.softwareheritage.org/source/puppet-treydock-keycloak', - :ref => 'v6.2.0' + :ref => 'v6.10.0' mod 'letsencrypt', :git => 'https://forge.softwareheritage.org/source/puppet-puppet-letsencrypt', diff --git a/data/defaults.yaml b/data/defaults.yaml --- a/data/defaults.yaml +++ b/data/defaults.yaml @@ -611,12 +611,14 @@ letsencrypt::certificates: archive_production: domains: + # Should match with keycloak::resources::realms.SoftwareHeritage.clients.swh-web.redirect_uris - archive.softwareheritage.org - base.softwareheritage.org - archive.internal.softwareheritage.org - webapp0.softwareheritage.org archive_staging: domains: + # Should match with keycloak::resources::realms.SoftwareHeritageStaging.clients.swh-web.redirect_uris - webapp.staging.swh.network - webapp.internal.staging.swh.network deposit_production: @@ -2652,6 +2654,56 @@ keycloak::postgres::user: keycloak # keycloak::postgres::password in private-data +keycloak::resources::realms::common_settings: + remember_me: true + login_with_email_allowed: true + internationalization_enabled: true + +keycloak::resources::clients::common_settings: + public_client: true + default_client_scopes: + - profile + - email + - roles + - web-origins + optional_client_scopes: + - microprofile-jwt + - offline_access + +keycloak::resources::protocol_mappers::webapp: + audience: + type: oidc-audience-mapper + included_client_audience: __client_id__ + user groups: + type: oidc-group-membership-mapper + claim_name: groups + full_path: true + +keycloak::resources::realms: + SoftwareHeritage: + settings: + display_name: Software Heritage + clients: + swh-web: + settings: + redirect_uris: + # Should match letsencrypt::certificates.archive_production.domains + - https://archive.softwareheritage.org/* + - https://base.softwareheritage.org/* + - https://archive.internal.softwareheritage.org/* + - https://webapp0.softwareheritage.org/* + protocol_mappers: "%{alias('keycloak::resources::protocol_mappers::webapp')}" + SoftwareHeritageStaging: + settings: + display_name: Software Heritage (Staging) + clients: + swh-web: + settings: + redirect_uris: + # Should match letsencrypt::certificates.archive_staging.domains + - https://webapp.staging.swh.network/* + - https://webapp.internal.staging.swh.network/* + protocol_mappers: "%{alias('keycloak::resources::protocol_mappers::webapp')}" cassandra::release: 311x cassandra::cluster: azure diff --git a/site-modules/profile/manifests/keycloak/primary.pp b/site-modules/profile/manifests/keycloak/primary.pp --- a/site-modules/profile/manifests/keycloak/primary.pp +++ b/site-modules/profile/manifests/keycloak/primary.pp @@ -33,4 +33,6 @@ # Don't manage the PostgreSQL database manage_datasource => false, } + + include ::profile::keycloak::resources } diff --git a/site-modules/profile/manifests/keycloak/resources.pp b/site-modules/profile/manifests/keycloak/resources.pp new file mode 100644 --- /dev/null +++ b/site-modules/profile/manifests/keycloak/resources.pp @@ -0,0 +1,71 @@ +# Definition of keycloak resources +class profile::keycloak::resources { + $realms = lookup({ + name => 'keycloak::resources::realms', + value_type => Hash, + merge => { + strategy => 'deep', + knockout_prefix => '--', + }, + default_value => {}, + }) + + $realm_common_settings = lookup({ + name => 'keycloak::resources::realms::common_settings', + value_type => Hash, + merge => { + strategy => 'deep', + knockout_prefix => '--', + }, + default_value => {}, + }) + + $client_common_settings = lookup({ + name => 'keycloak::resources::clients::common_settings', + value_type => Hash, + merge => { + strategy => 'deep', + knockout_prefix => '--', + }, + default_value => {}, + }) + + $realms.each |$realm_name, $realm_data| { + $_local_realm_settings = pick($realm_data['settings'], {}) + $_full_realm_settings = deep_merge($realm_common_settings, $_local_realm_settings) + + keycloak_realm {$realm_name: + ensure => 'present', + * => $_full_realm_settings, + } + + $clients = pick($realm_data['clients'], {}) + $realm_client_common_settings = deep_merge($client_common_settings, + pick($realm_data['client_settings'], {})) + + $clients.each |$client_name, $client_data| { + $_local_client_settings = pick($client_data['settings'], {}) + $_full_client_settings = deep_merge($realm_client_common_settings, $_local_client_settings) + + keycloak_client {"${client_name} on ${realm_name}": + ensure => 'present', + name => $client_name, + realm => $realm_name, + * => $_full_client_settings, + } + + $protocol_mappers = pick($client_data['protocol_mappers'], {}) + + $protocol_mappers.each |$protocol_mapper_name, $protocol_mapper_data| { + $_pm_data = Hash($protocol_mapper_data.map |$key, $value| { + [$key, $value ? {'__client_id__' => $client_name, default => $value}] + }) + + keycloak_protocol_mapper {"${protocol_mapper_name} for ${client_name} on ${realm_name}": + ensure => present, + * => $_pm_data, + } + } + } + } +}