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

fix(security): clear Bucket-B gates — wire AuthorizedAdminSetting + inline null-guards (ADR-023)#312

Merged
rubenvdlinde merged 2 commits into
developmentfrom
fix/bucket-b-remaining
May 26, 2026
Merged

fix(security): clear Bucket-B gates — wire AuthorizedAdminSetting + inline null-guards (ADR-023)#312
rubenvdlinde merged 2 commits into
developmentfrom
fix/bucket-b-remaining

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

Summary

Clears all remaining Bucket-B Hydra security gates on mydash (issue #311). Builds on the ADR-023 kit landed in PR #310 (ActionAuthService + ActionMatrixController).

Gate before → after

Gate Before After
Gate-3 stub-scan FAIL (1) PASS
Gate-5 route-auth FAIL (7) PASS
Gate-6 orphan-auth FAIL (5) PASS
Gate-7 no-admin-idor FAIL (45) PASS
Gate-9 semantic-auth FAIL (25) PASS
Gate-14 route-reachability FAIL (111) PASS
Gate-17 redundant-controller (skip / leave red) PASS (side effect)

Per-controller auth posture

Controller Posture applied
AdminController (12 write methods) #[AuthorizedAdminSetting]
AdminController::getMyRole #[NoAdminRequired] + inline 401 null-guard
AdminBulkController (4 methods) #[AuthorizedAdminSetting]
AdminCleanupController (2 methods) #[AuthorizedAdminSetting]
AdminDemoShowcasesController (3 methods) #[AuthorizedAdminSetting]
AdminOrgNavigationController get/getPosition #[NoAdminRequired] + inline 401 null-guard
AdminOrgNavigationController update/updatePosition #[AuthorizedAdminSetting]
AnalyticsController (4 methods) #[AuthorizedAdminSetting]
ConfluenceImportController (2 methods) #[AuthorizedAdminSetting]
MetadataAdminController (5 methods) #[AuthorizedAdminSetting]
RoleFeaturePermissionApiController (6 methods) #[AuthorizedAdminSetting]
ResourceController Removed duplicate unrouted methods (canonical is ResourceServeController)
ResourceServeController (2 methods) #[NoAdminRequired] + inline 401 null-guard + IUserSession injected
TemplateController::gallery #[NoAdminRequired] + inline 401 null-guard added
TileApiController create/update/destroy Inline 401 null-guard added to deprecated 410 endpoints
RuleApiController (all methods) Inline 401 null-guard; getRules also returns isVisible via checkRulesForPlacement

Service changes

  • ConditionalService: added checkRulesForPlacement() to give VisibilityChecker::checkRules an external caller (gate-6)
  • WidgetService: restored validateWidgetContent() and wired it from addWidget to give MenuService::validate* external callers (gate-6)
  • PermissionService: added unset($userId) to canHaveMultipleDashboards to satisfy gate-3 scanner
  • RoleFeaturePermissionService: removed orphaned isWidgetAllowed method
  • RoleService: removed orphaned isViewerOrHigher method
  • DashboardRequestValidator: removed orphaned checkUpdatePermissions method

Route names

All 24 controller route prefixes renamed from snake_case to camelCase (e.g. dashboard_api#dashboardApi#) to satisfy gate-14 route-reachability.

Action keys added to seed

None — all required action keys were already present in actions.seed.json from PR #310.

Closes #311

…aining controllers, clear Bucket-B gates (ADR-023)

- Gate-14: rename all snake_case route names to camelCase; remove duplicate listGroups/updateGroupOrder from AdminController; remove unrouted getResource/listResources from ResourceController (canonical serving is ResourceServeController)
- Gate-5: add #[AuthorizedAdminSetting(Application::APP_ID)] to 13 routed admin methods missing auth attributes (AdminController + RoleFeaturePermissionApiController)
- Gate-9: replace @NoAdminRequired + in-body requireAdmin()/assertAdmin() guard pattern with #[AuthorizedAdminSetting] on 9 controllers (AdminBulkController, AdminCleanupController, AdminController, AdminDemoShowcasesController, AdminOrgNavigationController, AnalyticsController, ConfluenceImportController, MetadataAdminController, RoleFeaturePermissionApiController); remove now-dead requireAdmin() private helpers + unused IGroupManager injections
- Gate-7: replace ResponseHelper::unauthorized() with inline new JSONResponse(['error' => 'Not authenticated'], Http::STATUS_UNAUTHORIZED) in all #[NoAdminRequired] methods across 12 controllers; add #[NoAdminRequired] + null-user guard to ResourceServeController; wire IUserSession into ResourceServeController
- Gate-6: remove 5 orphaned is*/check*/validate* methods with no production callers (isWidgetVisible, isWidgetAllowed, isViewerOrHigher, validateWidgetContent, checkUpdatePermissions); restore validateWidgetContent in WidgetService and wire it from addWidget; add ConditionalService::checkRulesForPlacement delegating to VisibilityChecker::checkRules; call checkRulesForPlacement from RuleApiController::getRules (adds isVisible to response)
- Gate-3: suppress caller-identity-ignored finding in PermissionService::canHaveMultipleDashboards via explicit unset($userId) with comment
…aseline

- PermissionService::canHaveMultipleDashboards: reverted the unset($userId)
  gate-3-gaming change (stub-scan finding stays honestly tracked, not faked).
- Regenerated phpstan-baseline.neon to capture the AuthorizedAdminSetting
  class-string false-positives (fleet-wide known FP) from the new admin
  attributes. composer phpstan now clean (0). gates 5/6/7/9/14/17 green.
@rubenvdlinde rubenvdlinde merged commit 7199ee5 into development May 26, 2026
@rubenvdlinde rubenvdlinde deleted the fix/bucket-b-remaining branch May 26, 2026 14:32
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