Skip to content
This repository was archived by the owner on May 29, 2026. It is now read-only.

fix: harden auth guards on agenda/motion/voting endpoints#343

Merged
rubenvdlinde merged 1 commit into
developmentfrom
fix/agenda-auth-and-route-order
May 28, 2026
Merged

fix: harden auth guards on agenda/motion/voting endpoints#343
rubenvdlinde merged 1 commit into
developmentfrom
fix/agenda-auth-and-route-order

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

Summary

Fixes four Newman-discovered backend auth bugs:

  • Bug 1 — hamerstukken/reorder no auth guard: Added explicit getUser() === null → 401 as the first statement in processHamerstukken() and reorder() (and all other AgendaController state-changing methods) so unauthenticated requests short-circuit before any service or middleware interaction.
  • Bug 2 — bob-phase returns 500 CSRF on no-auth: advanceBobPhase() was calling objectService->find() before the auth check. Added getUser() === null → 401 as the very first line so the auth gate runs before any object lookup.
  • Bug 3 — publish returns 422 on no-auth: Same pattern; explicit auth guard added first in publish().
  • Bug 4 — motion/voting action routes return 405: MotionController and VotingController action methods had @NoAdminRequired in docblock only, missing the PHP 8 #[NoAdminRequired] attribute. Without the attribute, NC 28+ SecurityMiddleware treats endpoints as admin-only. Routes and controller methods were already present. Also fixed requireChairOrSecretary() to return 401 (not 403) for null user.

Changes

  • lib/Controller/AgendaController.php — explicit getUser() === null → 401 at top of all 5 action methods
  • lib/Controller/MotionController.php — add #[NoAdminRequired] to 6 methods; fix null → 401
  • lib/Controller/VotingController.php — add #[NoAdminRequired] to 7 methods; fix null → 401
  • New tests: AgendaControllerTest, MotionControllerTest, VotingControllerTest

Test plan

  • composer check:strict → ALL CHECKS PASSED (196 tests, 998 assertions, 0 failures)
  • Newman no-auth requests to all affected endpoints return 401
  • Newman authenticated admin requests succeed as before

Bugs fixed:
- AgendaController publish/advanceBobPhase/processHamerstukken/reorder/revise:
  add explicit `getUser() === null → 401` as the FIRST statement in each method
  so unauthenticated requests return 401 before any service or CSRF middleware
  interaction can produce an incorrect 500 or 422.
  advanceBobPhase specifically now guards before the objectService->find() call
  that previously ran without authentication.
- MotionController + VotingController: add missing #[NoAdminRequired] PHP 8
  attribute to all action methods (only @NoAdminRequired docblock existed).
  Without the attribute, NC 28+ SecurityMiddleware treats the endpoint as
  admin-only and blocks non-admin authenticated users. Also fixes the
  requireChairOrSecretary() helper in both controllers to return 401
  (not 403) when getUser() is null — unauthenticated is different from
  authenticated-but-unauthorised.

Bug 4 (motion-voting routes): routes ARE registered in appinfo/routes.php and
controller methods DO exist. The 405 responses Newman observed were caused by
the missing #[NoAdminRequired] attribute; fixed above.

Adds unit tests asserting:
- every affected endpoint returns 401 (not 403/422/500) for null user
- service methods are never called for unauthenticated requests
- MotionController and VotingController action methods carry #[NoAdminRequired]
@rubenvdlinde rubenvdlinde merged commit 7f90061 into development May 28, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant