diff --git a/CHANGELOG.md b/CHANGELOG.md
index 64a4b5676..4ebeda9ea 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,8 @@ Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
+- [PR-385](https://github.com/itk-dev/os2loop/pull/385)
+ Cleaned up OpenID Connect settings and removed some obsolete custom settings
- [PR-384](https://github.com/itk-dev/os2loop/pull/384)
Set access permission on search view
- [PR-383](https://github.com/itk-dev/os2loop/pull/383)
diff --git a/config/sync/openid_connect.client.generic.yml b/config/sync/openid_connect.client.generic.yml
index b1f0647a7..d31117759 100644
--- a/config/sync/openid_connect.client.generic.yml
+++ b/config/sync/openid_connect.client.generic.yml
@@ -10,10 +10,12 @@ settings:
client_secret: '[client-secret]'
iss_allowed_domains: ''
issuer_url: ''
- authorization_endpoint: 'https://idp-citizen.os2loop.local.itkdev.dk/connect/authorize'
- token_endpoint: 'https://idp-citizen.os2loop.local.itkdev.dk/connect/token'
+ authorization_endpoint: 'https://idp-employee.os2loop.local.itkdev.dk/oauth2/authorize'
+ token_endpoint: 'http://idp-employee:9400/oauth2/token'
userinfo_endpoint: ''
- end_session_endpoint: 'https://idp-citizen.os2loop.local.itkdev.dk/connect/endsession'
+ end_session_endpoint: 'https://idp-employee.os2loop.local.itkdev.dk/oauth2/end_session'
scopes:
- openid
- email
+ prompt:
+ - login
diff --git a/config/sync/openid_connect.client.windows_aad.yml b/config/sync/openid_connect.client.windows_aad.yml
deleted file mode 100644
index 471e77834..000000000
--- a/config/sync/openid_connect.client.windows_aad.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-uuid: 7a551b1d-f957-45bc-a54e-11d227cce0d8
-langcode: en
-status: false
-dependencies: { }
-id: windows_aad
-label: windows_aad
-plugin: generic
-settings:
- client_id: "file:///settings.local.php#$config['openid_connect.client.windows_aad']['settings']['client_id']"
- client_secret: "file:///settings.local.php#$config['openid_connect.client.windows_aad']['settings']['client_secret']"
- issuer_url: ''
- authorization_endpoint: "file:///settings.local.php#$config['openid_connect.client.windows_aad]['settings']['client_id']"
- token_endpoint: "file:///settings.local.php#$config['openid_connect.client.windows_aad]['settings'][token_endpoint']"
- userinfo_endpoint: ''
- end_session_endpoint: ''
- scopes:
- - openid
- - email
diff --git a/config/sync/openid_connect.settings.yml b/config/sync/openid_connect.settings.yml
index 3f0a95e0d..d60a88b58 100644
--- a/config/sync/openid_connect.settings.yml
+++ b/config/sync/openid_connect.settings.yml
@@ -2,13 +2,12 @@ always_save_userinfo: true
connect_existing_users: true
override_registration_settings: true
end_session_enabled: true
-user_login_display: above
+user_login_display: replace
redirect_login: /user
redirect_logout: /
userinfo_mappings:
- timezone: zoneinfo
- os2loop_user_family_name: family_name
- os2loop_user_given_name: given_name
+ os2loop_user_city: family_name
+ os2loop_user_external_list: given_name
role_mappings:
os2loop_user_administrator:
- administrator
@@ -28,3 +27,4 @@ role_mappings:
- post_author
os2loop_user_user_administrator:
- user_administrator
+autostart_login: true
diff --git a/docker-compose.oidc.yml b/docker-compose.oidc.yml
new file mode 100644
index 000000000..86d2fff74
--- /dev/null
+++ b/docker-compose.oidc.yml
@@ -0,0 +1,34 @@
+services:
+ idp-employee:
+ image: ghcr.io/geigerzaehler/oidc-provider-mock:latest
+ networks:
+ - app
+ - frontend
+ labels:
+ - "traefik.enable=true"
+ - "traefik.docker.network=frontend"
+ - "traefik.http.routers.idp-employee_${COMPOSE_PROJECT_NAME:?}.rule=Host(`idp-employee.${COMPOSE_DOMAIN:?}`)"
+ - "traefik.http.services.idp-employee_${COMPOSE_PROJECT_NAME:?}.loadbalancer.server.port=9400"
+ command:
+ [
+ "--user-claims",
+ '{"sub": "user", "email": "user@example.com", "groups": ["authenticated"]}',
+ "--user-claims",
+ '{"sub": "administrator", "email": "administrator@example.com", "groups": ["os2loop_user_administrator"]}',
+ "--user-claims",
+ '{"sub": "user_administrator", "email": "user_administrator@example.com", "groups": ["os2loop_user_user_administrator"]}',
+ "--user-claims",
+ '{"sub": "manager", "email": "manager@example.com", "groups": ["os2loop_user_manager"]}',
+ "--user-claims",
+ '{"sub": "documentation_coordinator", "email": "documentation_coordinator@example.com", "groups": ["os2loop_user_documentation_coordinator"]}',
+ "--user-claims",
+ '{"sub": "document_collection_editor", "email": "document_collection_editor@example.com", "groups": ["os2loop_user_document_collection_editor"]}',
+ "--user-claims",
+ '{"sub": "document_author", "email": "document_author@example.com", "groups": ["os2loop_user_document_author"]}',
+ "--user-claims",
+ '{"sub": "external_sources_editor", "email": "external_sources_editor@example.com", "groups": ["os2loop_user_external_sources_editor"]}',
+ "--user-claims",
+ '{"sub": "post_author", "email": "post_author@example.com", "groups": ["os2loop_user_post_author"]}',
+ "--user-claims",
+ '{"sub": "read_only", "email": "read_only@example.com", "groups": ["os2loop_user_read_only"]}',
+ ]
diff --git a/docker-compose.override.yml b/docker-compose.override.yml
index d602498b8..8a6fc4a59 100644
--- a/docker-compose.override.yml
+++ b/docker-compose.override.yml
@@ -1,3 +1,6 @@
+include:
+ - docker-compose.oidc.yml
+
services:
node:
image: node:20
@@ -16,123 +19,3 @@ services:
environment:
# Match PHP_MAX_EXECUTION_TIME above
- NGINX_FASTCGI_READ_TIMEOUT=300
-
- idp-citizen:
- image: ghcr.io/soluto/oidc-server-mock:0.8.6
- profiles:
- - oidc
- - test
- # Let this container be accessible both internally and externally on the same domain.
- container_name: idp-citizen.${COMPOSE_DOMAIN}
- networks:
- - app
- - frontend
- ports:
- # https://github.com/Soluto/oidc-server-mock?tab=readme-ov-file#https
- # - '80'
- - "443"
- volumes:
- - .:/tmp/config:ro
- labels:
- - "traefik.enable=true"
- - "traefik.docker.network=frontend"
- - "traefik.http.routers.${COMPOSE_PROJECT_NAME}_idp-citizen.rule=Host(`idp-citizen.${COMPOSE_DOMAIN}`)"
- - "traefik.http.services.${COMPOSE_PROJECT_NAME}_idp-citizen.loadbalancer.server.port=443"
- - "traefik.http.services.${COMPOSE_PROJECT_NAME}_idp-citizen.loadbalancer.server.scheme=https"
- - "traefik.http.routers.${COMPOSE_PROJECT_NAME}_idp-citizen.middlewares=redirect-to-https"
- - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
-
- environment:
- # https://github.com/Soluto/oidc-server-mock?tab=readme-ov-file#https
- ASPNETCORE_URLS: https://+:443;http://+:80
- ASPNETCORE_Kestrel__Certificates__Default__Password: mock
- ASPNETCORE_Kestrel__Certificates__Default__Path: /tmp/config/.docker/oidc-server-mock/cert/docker.pfx
-
- ASPNETCORE_ENVIRONMENT: Development
- SERVER_OPTIONS_INLINE: |
- AccessTokenJwtType: JWT
- Discovery:
- ShowKeySet: true
- Authentication:
- CookieSameSiteMode: Lax
- CheckSessionCookieSameSiteMode: Lax
-
- LOGIN_OPTIONS_INLINE: |
- {
- "AllowRememberLogin": false
- }
-
- LOGOUT_OPTIONS_INLINE: |
- {
- "AutomaticRedirectAfterSignOut": true
- }
-
- CLIENTS_CONFIGURATION_INLINE: |
- - ClientId: client-id
- ClientSecrets: [client-secret]
- Description: Mock IdP
- AllowedGrantTypes:
- # - client_credentials
- # - implicit
- - authorization_code
- # https://github.com/Soluto/oidc-server-mock/issues/46#issuecomment-704963181
- RequireClientSecret: false
- AllowAccessTokensViaBrowser: true
- # https://github.com/Soluto/oidc-server-mock/issues/26#issuecomment-705022941
- AlwaysIncludeUserClaimsInIdToken: true
- AllowedScopes:
- - openid
- - profile
- - email
- ClientClaimsPrefix: ''
- RedirectUris:
- - '*'
- # https://github.com/Soluto/oidc-server-mock/issues/60
- PostLogoutRedirectUris:
- - '*'
- # https://github.com/Soluto/oidc-server-mock/issues/46#issuecomment-704845375
- RequirePkce: false
-
- # Needed to set custom claim types in "profile"
- # https://github.com/Soluto/oidc-server-mock/issues/123#issuecomment-1427129278
- # https://github.com/Soluto/oidc-server-mock/blob/master/README.md#simple-configuration
- # https://docs.docker.com/compose/compose-file/compose-file-v3/#environment
- OVERRIDE_STANDARD_IDENTITY_RESOURCES: "true"
- IDENTITY_RESOURCES_INLINE: |
- # https://auth0.com/docs/get-started/apis/scopes/openid-connect-scopes#standard-claims
- - Name: openid
- ClaimTypes:
- - sub
- - Name: email
- ClaimTypes:
- - email
- - Name: profile
- ClaimTypes:
- # Add your custom claims here
- - dk_ssn
- - name
- - email
- - zip
- - uuid
-
- USERS_CONFIGURATION_INLINE: |
- - SubjectId: 1
- Username: citizen1
- Password: citizen1
- Claims:
- # Claims added here must be defined above in IDENTITY_RESOURCES_INLINE
- - Type: dk_ssn
- Value: '1111111111'
- ValueType: string
- - Type: name
- Value: 'Anders And'
- ValueType: string
- - Type: email
- Value: admin@example.com
- ValueType: string
- - Type: zip
- Value: '1111'
- ValueType: string
- - Type: uuid
- Value: '11111111-1111-1111-1111-111111111111'
- ValueType: string
diff --git a/web/profiles/custom/os2loop/modules/os2loop_user_login/README.md b/web/profiles/custom/os2loop/modules/os2loop_user_login/README.md
index 18e8c4b55..52f624f4a 100644
--- a/web/profiles/custom/os2loop/modules/os2loop_user_login/README.md
+++ b/web/profiles/custom/os2loop/modules/os2loop_user_login/README.md
@@ -7,14 +7,10 @@ Go to Administration › Configuration › OS2Loop › OS2Loop user login settin
## OpenID Connect
-The modules [OpenID Connect](https://www.drupal.org/project/openid_connect) and
-[OpenID Connect Microsoft Azure Active Directory
-client](https://www.drupal.org/project/openid_connect_windows_aad) are used for
-OpenID Connect login. *Note*: Eventhough it's called “OpenID Connect Microsoft
-Azure Active Directory client” it also work with other OpenID Connect identity
-providers.
-
-In the default configuration both login methods assume that the identitity
+The module [OpenID Connect](https://www.drupal.org/project/openid_connect) is
+used for OpenID Connect login.
+
+In the default configuration the login method assumes that the identitity
provider returns a `name` claim which is used as the Drupal user name and that a
`groups` claim is a list of groups that can be mapped to Drupal roles.
@@ -83,12 +79,16 @@ $config['openid_connect.client.generic']['settings']['authorization_endpoint'] =
$config['openid_connect.client.generic']['settings']['token_endpoint'] = …; // Get this from your OpenID Connect Discovery endpoint
// Optional
$config['openid_connect.client.generic']['settings']['end_session_endpoint'] = …; // Get this from your OpenID Connect Discovery endpoint
+
+// Disable "Autostart login process"
+$config['openid_connect.settings']['autostart_login'] = false;
```
Check your overwrites by running
```sh
vendor/bin/drush config:get --include-overridden openid_connect.client.generic
+vendor/bin/drush config:get --include-overridden openid_connect.settings
```
#### Groups to roles mapping
diff --git a/web/profiles/custom/os2loop/modules/os2loop_user_login/os2loop_user_login.module b/web/profiles/custom/os2loop/modules/os2loop_user_login/os2loop_user_login.module
index 9f700a40d..578693d48 100644
--- a/web/profiles/custom/os2loop/modules/os2loop_user_login/os2loop_user_login.module
+++ b/web/profiles/custom/os2loop/modules/os2loop_user_login/os2loop_user_login.module
@@ -5,18 +5,8 @@
* The module file for os2loop_user_login.
*/
-use Drupal\Core\Form\FormStateInterface;
use Drupal\user\UserInterface;
-/**
- * Implements hook_form_alter().
- *
- * @see \Drupal\os2loop_user_login\Helper\Helper::alterForm()
- */
-function os2loop_user_login_form_alter(&$form, FormStateInterface $form_state, $form_id) {
- Drupal::service('os2loop_user_login.helper')->alterForm($form, $form_state, $form_id);
-}
-
/**
* Implements hook_menu_local_tasks_alter().
*
diff --git a/web/profiles/custom/os2loop/modules/os2loop_user_login/src/Form/SettingsForm.php b/web/profiles/custom/os2loop/modules/os2loop_user_login/src/Form/SettingsForm.php
index 5dd65143b..96942ef5c 100644
--- a/web/profiles/custom/os2loop/modules/os2loop_user_login/src/Form/SettingsForm.php
+++ b/web/profiles/custom/os2loop/modules/os2loop_user_login/src/Form/SettingsForm.php
@@ -73,37 +73,43 @@ public function buildForm(array $form, FormStateInterface $form_state) {
$form['show_drupal_login'] = [
'#type' => 'checkbox',
'#title' => $this->t('Show Drupal login'),
- '#default_value' => $config->get('show_drupal_login'),
+ '#default_value' => FALSE,
+ '#disabled' => TRUE,
'#description' => $this->t(
- 'Show Drupal (username and password) login on user login page. If not enabled, the login form will still be visible if #drupal-login is appended to the url (@login_url).',
+ 'This option has been removed. This is now controlled by the "@config_title" setting in the OpenID Connect settings.',
[
- '@login_url' => Url::fromRoute('user.login', [], [
- 'absolute' => TRUE,
- 'fragment' => 'drupal-login',
- ])->toString(),
- ]),
+ '@config_title' => $this->t('OpenID buttons display in user login form'),
+ ':config_url' => Url::fromRoute('openid_connect.admin_settings')->toString(),
+ ],
+ ),
];
$form['show_oidc_login'] = [
'#type' => 'checkbox',
'#title' => $this->t('Show OpenID Connect login'),
- '#default_value' => $config->get('show_oidc_login'),
+ '#default_value' => FALSE,
+ '#disabled' => TRUE,
'#description' => $this->t(
- 'Show OpenID Connect login button on user login page. Set up proper OpenID Connect configuration before enabling this.',
+ 'This option has been removed. This is now controlled by the "@config_title" setting in the OpenID Connect settings.',
[
- '@config_url' => Url::fromRoute('openid_connect.admin_settings')->toString(),
- ]
+ '@config_title' => $this->t('OpenID buttons display in user login form'),
+ ':config_url' => Url::fromRoute('openid_connect.admin_settings')->toString(),
+ ],
),
];
- $options['oidc'] = $this->t('OpenID Connect');
$form['default_login_method'] = [
'#type' => 'select',
'#title' => $this->t('Default login method'),
- '#options' => $options,
- '#empty_value' => '',
- '#default_value' => $config->get('default_login_method'),
- '#description' => $this->t('The default login method to use. If specified, anonymous users will automatically be logged in with this method.'),
+ '#default_value' => FALSE,
+ '#disabled' => TRUE,
+ '#description' => $this->t(
+ 'This option has been removed. This is now controlled by the "@config_title" setting in the OpenID Connect settings.',
+ [
+ '@config_title' => $this->t('Autostart login process'),
+ ':config_url' => Url::fromRoute('openid_connect.admin_settings')->toString(),
+ ],
+ ),
];
$form['hide_logout_menu_item'] = [
@@ -121,9 +127,6 @@ public function buildForm(array $form, FormStateInterface $form_state) {
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$this->configFactory->getEditable(static::SETTINGS_NAME)
- ->set('show_drupal_login', $form_state->getValue('show_drupal_login'))
- ->set('show_oidc_login', $form_state->getValue('show_oidc_login'))
- ->set('default_login_method', $form_state->getValue('default_login_method'))
->set('hide_logout_menu_item', $form_state->getValue('hide_logout_menu_item'))
->save();
diff --git a/web/profiles/custom/os2loop/modules/os2loop_user_login/src/Helper/Helper.php b/web/profiles/custom/os2loop/modules/os2loop_user_login/src/Helper/Helper.php
index 20d81f120..2fd7cafc2 100644
--- a/web/profiles/custom/os2loop/modules/os2loop_user_login/src/Helper/Helper.php
+++ b/web/profiles/custom/os2loop/modules/os2loop_user_login/src/Helper/Helper.php
@@ -5,7 +5,6 @@
use Drupal\Core\Entity\EntityFieldManager;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
-use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Path\CurrentPathStack;
use Drupal\Core\Session\AccountInterface;
@@ -28,6 +27,13 @@ class Helper {
*/
private $config;
+ /**
+ * The OpenID Connect config.
+ *
+ * @var \Drupal\Core\Config\ImmutableConfig
+ */
+ private $openIdConnectConfig;
+
/**
* The entity type manager.
*
@@ -75,6 +81,7 @@ class Helper {
*/
public function __construct(Settings $settings, ModuleHandlerInterface $module_handler, EntityTypeManagerInterface $entity_type_manager, EntityFieldManager $entity_field_manager, MessengerInterface $messenger, RequestStack $requestStack, CurrentPathStack $currentPathStack) {
$this->config = $settings->getConfig(SettingsForm::SETTINGS_NAME);
+ $this->openIdConnectConfig = $settings->getConfig('openid_connect.settings');
$this->moduleHandler = $module_handler;
$this->entityTypeManager = $entity_type_manager;
$this->entityFieldManager = $entity_field_manager;
@@ -83,39 +90,6 @@ public function __construct(Settings $settings, ModuleHandlerInterface $module_h
$this->currentPathStack = $currentPathStack;
}
- /**
- * Implements hook_form_alter().
- *
- * Show different login options depending on the site configuration.
- */
- public function alterForm(&$form, FormStateInterface $form_state, $form_id) {
- if ('openid_connect_login_form' === $form_id) {
- if (!$this->config->get('show_oidc_login')) {
- $form['#access'] = FALSE;
- }
- }
- elseif ('user_login_form' === $form_id) {
- if (!$this->config->get('show_drupal_login')) {
- $form['#attached']['library'][] = 'os2loop_user_login/user-login-form';
-
- // Wrap default Drupal login form in an element with a known id
- // (drupal-login) so we can visually hide it.
- foreach ($form as $key => $value) {
- if (0 !== strpos($key, '#')) {
- $form['drupal_login'][$key] = array_merge($value);
- unset($form[$key]);
- }
- }
- $form['drupal_login'] += [
- '#type' => 'fieldset',
- '#title' => $this->t('Drupal login'),
- '#weight' => 100,
- '#attributes' => ['id' => 'drupal-login'],
- ];
- }
- }
- }
-
/**
* Implements hook_preprocess_block().
*/
@@ -138,7 +112,12 @@ public function preprocessBlock(array &$variables) {
return;
}
- $defaultLoginMethod = $this->config->get('default_login_method');
+ // The OpenID Connect module's "Autostart login process" triggers only on
+ // login, register or password reset pages. We need to trigger it in the
+ // userlogin block as well and use JavaScript to submit the (OIDC) login
+ // form if found on the page
+ // (cf. @os2loop_theme/templates/block/block--user-login-block.html.twig).
+ $defaultLoginMethod = TRUE === $this->openIdConnectConfig->get('autostart_login') ? 'oidc' : NULL;
switch ($defaultLoginMethod) {
case 'oidc':
$variables['default_login_form_id'] = 'openid-connect-login-form';