Skip to content

Fix config form value & Simplify CspConfigForm#5533

Open
TheSyscall wants to merge 5 commits into
mainfrom
fix-config-form-value
Open

Fix config form value & Simplify CspConfigForm#5533
TheSyscall wants to merge 5 commits into
mainfrom
fix-config-form-value

Conversation

@TheSyscall

@TheSyscall TheSyscall commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

ConfigForm's ON_ELEMENT_REGISTERED handler skipped seeding an element with its config value whenever the element already had some value set ($element->hasValue()), even on initial render. When it did seed the value, it called $element->setValue() directly instead of $this->populate(), so the value was visible on the element but not through getPopulatedValue().

This broke forms that read defaults via getPopulatedValue() during rendering, most notably CspConfigForm, where checkboxes ended up rendering with the wrong checked state.

Changes

  • ConfigForm: No longer skip populating the value of form elements when the element, has a default value.
  • ConfigForm: on initial render, populate the form with the config value instead of setting it only on the element, so getPopulatedValue() reflects it too.
  • CspConfigForm/ConfigController: now that ConfigForm handles this correctly, remove the workaround that manually computed and populated default values for the CSP enable checkboxes in the controller, and simplify form construction into a fluent chain.

Requires

@cla-bot cla-bot Bot added the cla/signed label Jul 6, 2026
@TheSyscall
TheSyscall force-pushed the fix-config-form-value branch from 3735397 to 5daeece Compare July 7, 2026 13:34
@TheSyscall
TheSyscall requested a review from jrauh01 July 8, 2026 08:09
Comment thread library/Icinga/Web/Form/ConfigForm.php Outdated
Comment thread library/Icinga/Web/Form/ConfigForm.php Outdated
Comment thread application/forms/Config/Security/CspConfigForm.php Outdated
@TheSyscall
TheSyscall requested a review from jrauh01 July 9, 2026 06:37

@jrauh01 jrauh01 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would make sense to add a test case to avoid the "default override" error in future changes.

@TheSyscall
TheSyscall force-pushed the fix-config-form-value branch from cf4993d to 21f87b6 Compare July 10, 2026 12:43
};
$form->ensureAssembled();

$this->assertSame('defaultvalue', $form->getElement('mysection__key')->getValue());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use this?

Suggested change
$this->assertSame('defaultvalue', $form->getElement('mysection__key')->getValue());
$this->assertSame('defaultvalue', $form->getValue('mysection__key'));

@TheSyscall
TheSyscall force-pushed the fix-config-form-value branch from 21f87b6 to 932b316 Compare July 13, 2026 06:23
jrauh01
jrauh01 previously approved these changes Jul 15, 2026

@jrauh01 jrauh01 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@TheSyscall
TheSyscall marked this pull request as draft July 15, 2026 09:48
@TheSyscall
TheSyscall force-pushed the fix-config-form-value branch from 932b316 to 0ddfc99 Compare July 15, 2026 11:06
@lippserd
lippserd force-pushed the fix-config-form-value branch from 0ddfc99 to 94384e3 Compare July 16, 2026 12:13
@TheSyscall
TheSyscall force-pushed the fix-config-form-value branch 2 times, most recently from a48aaba to 2ae7c28 Compare July 17, 2026 12:49
@TheSyscall TheSyscall changed the title Fix config form value Fix config form value & Simplify CspConfigForm Jul 17, 2026
This is mainly done to catch a point before ON_ELEMENT_REGISTERED is
called

In `ConfigForm`s `ON_ELEMENT_REGISTERED` handler, the early return
checked `$element->hasValue(`) in addition to `$key === null`. This
meant that if an element already had a value (e.g. a default set by the
element itself), the handler would skip seeding it with the config value
entirely, and skip setting value candidates.

- Dropped the `hasValue()` check from the early-return condition, so the
config value is always considered for a keyed element, regardless of any
pre-existing default.
- On initial render (no value candidates yet), replaced the direct
`$element->setValue($configValue)` call with
`$this->populate([$element->getName() => $configValue])`, so the value
also becomes visible via `getPopulatedValue()`, not just on the element
instance itself.
The old `registerElement` implementation read the submitted value via
`getPopulatedValue`, cleared the queue, pushed the config value, then
pushed the submitted value back. This dropped any intermediate populate
calls made before assembly and never put the config value into
`ValueCandidates`, which broke `PasswordElement`: submitting
`DUMMYPASSWORD` could not be resolved back to the stored password
because the real value was missing from the candidates list.

Since `populatedValues` is now protected on the `FormElements` trait, we
can prepend the config value directly to the queue before delegating to
`parent::registerElement`. The parent then applies the last queued value
as the element's current value and passes the full queue to
`setValueCandidates` — which now includes the config value at the front,
giving `PasswordElement` the history it needs to resolve dummy passwords
correctly.

A `stdClass` sentinel replaces `null` as the `Config::get` fallback so
that a config key explicitly absent from the file is distinguishable
from one that holds a `null` value, avoiding a spurious prepend in that
case.
Use the element's default as the `Config::get` fallback in `ConfigForm`

Previously `registerElement` passed no fallback to `Config::get`, so the
config value was always `null` when the key was absent. This caused
elements with declared defaults to lose their value: the element
attribute was set, but the populate queue remained empty, leaving
`getPopulatedValue` returning `null`.

Passing `$this->originalValues[$name]` as the fallback preserves the
element's declared default when no config key exists.

The check that decides whether to re-apply the submitted value over the
config value is also tightened from `!== null` to `! Str::isEmpty` so
that
empty and whitespace-only submitted values are not pushed back onto the
queue.
@TheSyscall
TheSyscall force-pushed the fix-config-form-value branch from 2ae7c28 to 5502979 Compare July 17, 2026 12:53
@TheSyscall
TheSyscall marked this pull request as ready for review July 17, 2026 13:12
@TheSyscall
TheSyscall requested a review from jrauh01 July 17, 2026 13:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants