Skip to content

A saved mapping result may not address an existing object - #1826

Merged
rubenvdlinde merged 1 commit into
developmentfrom
fix/mapping-save-cannot-address-an-object
Sep 3, 2026
Merged

A saved mapping result may not address an existing object#1826
rubenvdlinde merged 1 commit into
developmentfrom
fix/mapping-save-cannot-address-an-object

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

Third app in a sweep that began in dossiq (ConductionNL/dossiq#1687, #1690) and continued in openregister (ConductionNL/openregister#3345).

The defect

MappingsController::saveObject() saves the output of a mapping test as an object. The UI button reads save result as object, and the frontend posts object: this.result — the transformed output.

A mapping transforms source data, and source records very often carry an id. OpenRegister's ObjectService::saveObject() resolves its target from the payload:

$providedId = $object['@self']['id'] ?? $object['id'] ?? null;

The write is PUT-semantic, so a result carrying either silently replaced whatever object shared that identifier, nulled every field the result omitted, and reported success.

Identity here belongs to the object being created, not to the source record the mapping happened to read.

Behaviour change, stated plainly

This endpoint now always creates. If anyone relies on it as an upsert, this breaks that. I do not believe anyone can: the surface it serves is a mapping-test result panel, and an upsert keyed on the source system's id is not something that panel can have meant. Flagging it so a reviewer who knows otherwise can say so.

Severity

Admin-only (#[AuthorizedAdminSetting]), so this is data integrity, not privilege escalation. An administrator testing a mapping against real source data could destroy an unrelated object and see a success toast.

Evidence

One test with a negative control: removing the strip makes it fail. It asserts @self as well as id, because @self.id is the key saveObject reads first.

phpcs and phpmd clean on the changed file.

🤖 Generated with Claude Code

Found sweeping a defect class out of dossiq (ConductionNL/dossiq#1687, #1690)
and openregister (#3345).

`MappingsController::saveObject()` saves the OUTPUT OF A MAPPING TEST as an
object — the UI button reads "save result as object", and the frontend posts
`object: this.result`, the transformed output.

A mapping transforms SOURCE data, and source records very often carry an `id`.
`ObjectService::saveObject()` resolves its target from the payload
(`@self.id` first, then `id`) and the write is PUT-semantic, so a result
carrying either silently REPLACED whatever object shared that identifier,
nulled every field the result omitted, and reported success. Identity here
belongs to the object being created, not to the source record the mapping
happened to read.

BEHAVIOUR CHANGE, stated plainly: this endpoint now always creates. If anyone
relies on it as an upsert, this breaks that — but the surface it serves is a
mapping-test result panel, and an upsert keyed on the SOURCE system's id is
not something that panel can have meant.

Admin-only (`#[AuthorizedAdminSetting]`), so this is data integrity rather than
privilege escalation. The test carries a negative control: removing the strip
makes it fail.
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/integriq @ dde41f5

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
build
check-specs
test-l10n
format
check-schema-l10n
check-l10n-js
composer ✅ 141/141
npm ✅ 537/537
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman
Playwright ⏭️ deferred — runs on the promotion into beta/main, not on a pull request into development
Hydra gates

Quality workflow — 2026-09-03 05:31 UTC

Download the full PDF report from the workflow artifacts.

@rubenvdlinde
rubenvdlinde merged commit ae2dd18 into development Sep 3, 2026
52 checks passed
@rubenvdlinde
rubenvdlinde deleted the fix/mapping-save-cannot-address-an-object branch September 3, 2026 05:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant