From 9440bdc29de6e83e51c0ec5e77fca9460411ca1f Mon Sep 17 00:00:00 2001 From: Mischa Date: Sat, 4 Jul 2026 19:49:35 +0200 Subject: [PATCH] docs: capture Grav new-user --admin-type gotcha (api.* vs admin.*) On Admin2-only installs, login new-user auto-detects the admin permission type to api-only, so accounts lack admin.login and silently fail on access.admin.login-gated pages like /gpx-manager. Document the root cause, the --admin-type both fix baked into make test-account, and prevention. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01Np4cMQLF77i664CAQXySzU --- ...new-user-grants-api-not-admin-on-admin2.md | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 docs/solutions/test-failures/new-user-grants-api-not-admin-on-admin2.md diff --git a/docs/solutions/test-failures/new-user-grants-api-not-admin-on-admin2.md b/docs/solutions/test-failures/new-user-grants-api-not-admin-on-admin2.md new file mode 100644 index 0000000..890a6e0 --- /dev/null +++ b/docs/solutions/test-failures/new-user-grants-api-not-admin-on-admin2.md @@ -0,0 +1,82 @@ +--- +title: "Grav login new-user grants api.* but not admin.* on Admin2-only installs" +date: 2026-07-04 +category: docs/solutions/test-failures +module: testing / account provisioning +problem_type: test_failure +component: authentication +symptoms: + - "gpx-manager Playwright specs fail (401 / login form shown) after switching the suite onto a dedicated test account" + - "an authenticated account still sees the login form at /gpx-manager instead of the manager UI" + - "the generated accounts/*.yaml has an access.api block but no access.admin block" +root_cause: missing_permission +resolution_type: tooling_addition +severity: medium +related_components: + - testing_framework + - tooling +tags: + - grav + - login-plugin + - admin2 + - permissions + - playwright + - test-account + - gpx-manager +--- + +# Grav login new-user grants api.* but not admin.* on Admin2-only installs + +## Problem +When the Playwright suite was moved onto a dedicated local `testrunner` account, every `/gpx-manager` spec started failing — the account could authenticate but was treated as unauthorized for the manager page. The account had been created with `bin/plugin login new-user ... -P b` (Admin + Site access) but **without** `--admin-type`, and on this Admin2-only install that grants `api.*` permissions and no `admin.*` permissions. + +## Symptoms +- The `/gpx-manager` Playwright specs fail after switching from the real user to the `testrunner` account (they passed as the real user). +- An authenticated `testrunner` still gets the Login plugin's login form at `/gpx-manager` instead of the manager UI. +- The generated `user/accounts/testrunner.yaml` contains an `access.api` block (`login: true`, `super: true`) but **no** `access.admin` block. + +## What Didn't Work +- **Assuming `-P b` was enough.** `-P/--permissions b` selects the *category* of access (Admin + Site), but the *type* of admin permission — classic `admin.*` vs Admin2 `api.*` — is a separate axis controlled by `--admin-type`, which defaults to auto-detect. `-P b` alone does not guarantee `admin.login`. +- **Blaming the wrong specs.** In the same push, the home `H1`/map specs were also red, which looked like it might be the same auth problem. It was not — those were gated by `site.yaml` `travelling: false` hiding the active-trip view, a completely separate cause. Conflating the two delayed pinning the permission root cause. + +## Solution +Create the account with an explicit `--admin-type both`, and bake it into the idempotent `make test-account` target so every recreation is faithful: + +```make +test-account: + @docker exec intotheeast_grav sh -c 'test -f /var/www/html/user/accounts/$(GRAV_TEST_USER).yaml \ + || php bin/plugin login new-user -u $(GRAV_TEST_USER) -p "$(GRAV_TEST_PASS)" \ + -e $(GRAV_TEST_USER)@example.test -N "Test Runner" -P b --admin-type both -s enabled -n' +``` + +Verify the resulting permissions actually include `admin.login`: + +```bash +docker exec intotheeast_grav rm -f /var/www/html/user/accounts/testrunner.yaml +make test-account +docker exec intotheeast_grav sh -c 'grep -A6 "^access:" /var/www/html/user/accounts/testrunner.yaml' +# access: +# admin: +# login: true +# super: true +# api: +# login: true +# super: true +``` + +## Why This Works +The `login new-user` help text spells out the axis: + +> `--admin-type` — Which admin permission type to grant when permissions include Admin: `admin` (classic Admin plugin, `admin.*`), `api` (Admin2, `api.*`), or `both`. **If omitted, auto-detects from which admin plugin is installed.** + +This site runs **Admin2 only** (the classic `admin` plugin is disabled), so auto-detect resolves to `api` and emits `api.*` alone. `/gpx-manager` is gated by `access.admin.login: true` in its page frontmatter (enforced by the Login plugin), and that check looks specifically for the `admin.login` permission — `api.login` does not satisfy it. Passing `--admin-type both` forces both namespaces into the account, so the admin-gated page accepts the session. + +## Prevention +- **On Admin2-only Grav installs, always pass `--admin-type both` (or `admin`) to `login new-user`** when the account must reach any page gated by `access.admin.login` (e.g. `/gpx-manager`). Auto-detect will otherwise silently give you api-only. +- **Assert the permission, not the exit code.** After provisioning an account for admin-gated pages, check that `access.admin.login` exists in the generated YAML rather than trusting that account creation "succeeded." +- **Keep provisioning in one idempotent place.** The `make test-account` target is the single source of truth; `tests/global-setup.js` calls it, so `make test` and a bare `npx playwright test` both get identical permissions. Don't hand-create the account out-of-band with different flags — that reintroduces the drift this fix removed. + +## Related Issues +- `docs/working/plans/2026-07-04-grav-2.0.4-upgrade.md` — the self-contained test-account infrastructure shipped alongside the Grav 2.0.4 upgrade. +- `docs/solutions/architecture-patterns/dual-repo-submodule-workflow.md` — accounts live in the `user/` repo; the `testrunner` account is gitignored so it never reaches production. +- GPX manager auth model (`access.admin.login: true` frontmatter + Login plugin) — see the project's GPX manager notes.