Skip to content

refactor(store): consume OpenRegister's GenericStoreService, delete the app-local proxy (ADR-080) - #109

Merged
rubenvdlinde merged 2 commits into
developmentfrom
feat/adr-079-080-store-and-settings
Aug 3, 2026
Merged

refactor(store): consume OpenRegister's GenericStoreService, delete the app-local proxy (ADR-080)#109
rubenvdlinde merged 2 commits into
developmentfrom
feat/adr-079-080-store-and-settings

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

StoreController now extends AppHost's GenericStoreControllerBase and inherits search() plus the SSRF-guarded, redirect-refusing, token-private fetch. RemoteTemplateStoreService (331 lines) and its test file are deleted; the behaviour and the SSRF controls live in OpenRegister's GenericStoreServiceTest.

Install stays here, and only install — cloning a template into a local virtual app is OpenBuild-specific and differently authorized from the connector-adapter and agent-template installs in other apps.

Depends on ConductionNL/openregister#2310.

Three things the tests caught that review would not have

1. The suite could not load StoreController at all. extends is resolved by the autoloader, not the container, and the OR AppHost classes are stubbed here rather than autoloaded — so every test in the class errored before it ran. Added stubs for the three new classes.

This is the same mechanism by which a missing sibling app 500s every route in production, which is why ADR-080 restricts subclassing to apps declaring openregister a hard <app> dependency. This app qualifies — 8 controllers already type-hint OR classes — but an app where OR is optional must use composition instead.

2. The search test's getParam mock returned one value for any key, so kind silently received the query string. Made it key-aware; the action reads q and kind separately.

3. tests/stubs/openregister-stubs.php defines a NO-OP SecurityService, because the real guard does DNS lookups that fail for .test fixture hostnames. Any "SSRF negative control" written against that stub passes regardless of what the guard does — so this app's SSRF tests were never testing the guard. Corrected the docblock to say so and to point at the OpenRegister suite where the real guard is exercised. The new store stub is deliberately non-behaving for the same reason.

Verification

743/743 unit tests · 7/7 on the store controller.

Companion PRs: hydra (ADR-079/080), nextcloud-vue, openregister, openconnector.

…he app-local proxy (ADR-080)

StoreController now extends AppHost's GenericStoreControllerBase and inherits
search() plus the SSRF-guarded, redirect-refusing, token-private fetch.
RemoteTemplateStoreService (331 lines) and its test file are deleted; the
behaviour and the SSRF controls live in OpenRegister's GenericStoreServiceTest.

Install stays here, and only install — cloning a template into a local virtual
app is OpenBuild-specific and differently authorized from the connector-adapter
and agent-template installs in other apps.

Three things the tests caught that review would not have:

1. The suite could not load StoreController at all — `extends` is resolved by
   the AUTOLOADER, not the container, and the OR AppHost classes are stubbed
   here rather than autoloaded. Added stubs for GenericStoreService,
   StoreDescriptor and GenericStoreControllerBase. This is the same mechanism
   by which a missing sibling app 500s EVERY route in production, which is why
   ADR-080 restricts subclassing to apps declaring openregister a hard <app>
   dependency — this app qualifies (8 controllers already type-hint OR classes).

2. The search test's `getParam` mock returned one value for ANY key, so `kind`
   silently received the query string. Made it key-aware; the action reads `q`
   and `kind` separately.

3. tests/stubs/openregister-stubs.php defines a NO-OP SecurityService, because
   the real guard does DNS lookups that fail for .test fixture hostnames. Any
   "SSRF negative control" written against that stub passes regardless of what
   the guard does. Corrected the docblock to say so, and to point at the
   OpenRegister suite where the real guard is exercised. The new store stub is
   deliberately non-behaving for the same reason.

743/743 unit tests, 7/7 on the store controller.
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/openbuild @ f46132b

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
composer ✅ 100/100
npm ✅ 662/662
PHPUnit ⏭️
Newman ⏭️
Playwright ⏭️

Quality workflow — 2026-08-03 18:50 UTC

Download the full PDF report from the workflow artifacts.

StoreController is a plain Controller injecting GenericStoreService, with its
own ~30-line search() action, rather than subclassing a cross-app base. The
inheritance broke phpstan ('extends unknown class', which it refuses to let you
ignore), psalm, and the unit suite's class loading — one stub entry now covers
the injected type-hint instead.

phpstan OK, psalm no errors, 743/743 tests.
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/openbuild @ 4f39a0c

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
composer ✅ 100/100
npm ✅ 662/662
PHPUnit
Newman ⏭️
Playwright ⏭️

Coverage: 89.4% (17/19 statements)


Quality workflow — 2026-08-03 18:58 UTC

Download the full PDF report from the workflow artifacts.

@rubenvdlinde
rubenvdlinde merged commit 6fcde66 into development Aug 3, 2026
33 checks passed
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.

2 participants