fix(web-app-wordpress): write the OIDC settings to every site of a network

Variant 1 of run 37440146966 leaves the persona on the login page:

    Expected substring: "/wp-admin"
    Received string:    "https://blog.main.infinito.test/wp-login.php"

The rescue bundle shows 62 requests to /wp-login.php, all 200, and not one
OIDC request. Every login asset loads, so the page renders in full and simply
offers no SSO entry point; the flow never reaches Keycloak.

Variant 1 is the Multisite variant, and that is the whole difference. The
plugin reads its configuration with get_option, not get_site_option:

    includes/openid-connect-generic-option-settings.php:125
    $this->values = (array) get_option( self::OPTION_NAME, $this->default_settings );

The option is therefore per site. The addon stored it once, so a subsite read
an empty openid_connect_generic_settings and rendered a login page without an
OIDC entry point. Variants 0 and 2 are single-site, which is why only #1
failed.

Three shell tasks collapse into one PHP payload, following the pattern
ai-engine-stack-host.yml already uses in this role: the settings ride as
base64 in an env var and the body streams on stdin into `wp eval-file -`.
The payload walks the network with get_sites()/switch_to_blog() instead of
enumerating sites in the shell and passing --url per site, which removes the
nested quoting that broke this task once before (03ed52eea5).

The task that seeded a PHP-serialized empty array is gone: update_option
creates an absent option by itself.

Writing to a site whose option does not persist used to be silent. The
payload now reads each site back and names the blog ids that stayed empty, so
a failed write fails the deploy instead of producing a login page nobody can
use.

The settings carry OIDC.CLIENT.SECRET and the three old tasks had no no_log
at all, so the base64 secret reached every deploy log; the task now masks when
MASK_CREDENTIALS_IN_LOGS is on.

Static only. No deploy has run this.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
kevinveenbirkenbachandClaude Opus 5 committed 2026-10-06 20:47:00 +02:00
1 parent ae66b25927
commit e1901fb88e
2 files changed
+44 -16

No files matched your search

@@ -0,0 +1,33 @@
<?php
/**
* Environment:
* WP_OIDC_SETTINGS: base64 of the daggerhart openid_connect_generic_settings map.
*/
// nocheck: mirrored-unit-test - runs through `wp eval-file`, calling WP_CLI and the
// multisite switch_to_blog/update_option pair of the booted network; the WordPress
// runtime it needs is only present inside the container
$settings = json_decode(base64_decode(getenv('WP_OIDC_SETTINGS')), true);
if (!is_array($settings)) {
WP_CLI::error('WP_OIDC_SETTINGS did not decode to a settings map');
}
if (!is_multisite()) {
update_option('openid_connect_generic_settings', $settings);
return;
}
$missing = array();
foreach (get_sites(array('fields' => 'ids', 'number' => 0)) as $blog_id) {
switch_to_blog($blog_id);
update_option('openid_connect_generic_settings', $settings);
if (!get_option('openid_connect_generic_settings')) {
$missing[] = $blog_id;
}
restore_current_blog();
}
if ($missing) {
WP_CLI::error('openid_connect_generic_settings did not persist on blog ' . implode(', ', $missing));
}
@@ -1,18 +1,13 @@
---
- name: "🖥️ WP OIDC: stack-host container ops"
- name: "📌 WP OIDC: write the settings to every site of the network"
when: IS_STACK_HOST | bool
block:
- name: "✅ Ensure the OIDC settings option exists as a PHP-serialized empty array"
ansible.builtin.shell: >
container exec -u {{ WORDPRESS_USER }} {{ WORDPRESS_CONTAINER_ADDRESS }} bash -lc
"serialized_empty_array=$(wp eval 'echo serialize(array());' --path={{ WORDPRESS_DOCKER_HTML_PATH }}); \
wp option add openid_connect_generic_settings \"$serialized_empty_array\" --path={{ WORDPRESS_DOCKER_HTML_PATH }} \
|| wp option update openid_connect_generic_settings \"$serialized_empty_array\" --path={{ WORDPRESS_DOCKER_HTML_PATH }};"
- name: "📌 Apply all OIDC settings via WP-CLI eval (safe via base64)"
vars:
oidc_settings_json_b64: "{{ lookup('config', application_id, 'addons.daggerhart-openid-connect-generic.config.oidc_settings') | to_json | b64encode }}"
ansible.builtin.shell: >
container exec -u {{ WORDPRESS_USER }} {{ WORDPRESS_CONTAINER_ADDRESS }} bash -lc
"wp eval \"update_option('openid_connect_generic_settings', json_decode(base64_decode('{{ oidc_settings_json_b64 }}'), true));\" --path={{ WORDPRESS_DOCKER_HTML_PATH
}}"
ansible.builtin.shell:
cmd: >
container exec -i --user {{ WORDPRESS_USER | quote }}
-e {{ ('WP_OIDC_SETTINGS=' ~ (lookup('config', application_id, 'addons.daggerhart-openid-connect-generic.config.oidc_settings') | to_json | b64encode)) | quote
}}
{{ WORDPRESS_CONTAINER_ADDRESS }}
wp eval-file - --path={{ WORDPRESS_DOCKER_HTML_PATH | quote }}
stdin: "{{ lookup('file', 'php/oidc/settings.php') }}"
changed_when: true
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"