Skip to content

#37259: fix(roles): require authenticated backend user with Roles portlet on GET /v1/roles/layouts - #37323

Merged
hassandotcms merged 2 commits into
mainfrom
37259-roles-layouts-auth-gate
Sep 3, 2026
Merged

#37259: fix(roles): require authenticated backend user with Roles portlet on GET /v1/roles/layouts#37323
hassandotcms merged 2 commits into
mainfrom
37259-roles-layouts-auth-gate

Conversation

@hassandotcms

@hassandotcms hassandotcms commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Proposed Changes

  • GET /api/v1/roles/layouts (RoleResource#getAllLayouts) had no authentication gate — the only one of the 16 endpoints on the resource. Anonymous callers got 200 and the full tool-group catalog (layout ids, names, portlet ids, localized portlet titles).
  • Added the same WebResource.InitBuilder block every sibling uses: requiredBackendUser(true), requiredPortlet("roles"), rejectWhenNoUser(true).
  • getPorletTitlesFromLayout now takes the authenticated User from InitDataObject instead of re-resolving it from the request. The old getLoggedInUser(request)LanguageUtil.get(null, key) path silently fell back to the default company user, which is what let the anonymous call succeed. getAllLayouts was the only caller.
  • Swagger description and 401 response state the requirement; openapi.yaml regenerated.
  • 4 integration tests in RoleResourceIntegrationTest (MainSuite3a): anonymous → 401, backend user without roles portlet → 401, non-admin user with roles portlet → 200 (payload shape unchanged), admin → 200.

Checklist

  • Tests

This PR fixes: #37259

This PR fixes: #37259

…1/roles/layouts

`RoleResource#getAllLayouts` was the only endpoint on the resource without a
`WebResource.InitBuilder` gate, so anonymous callers received the full
tool-group catalog (layout ids, names, portlet ids, localized portlet
titles). Public since v23.06 (#24997), where the write twin
`saveRoleLayouts` did get the gate.

- Add the same InitBuilder block every sibling uses: requiredBackendUser,
  requiredPortlet("roles"), rejectWhenNoUser.
- Pass the authenticated user from InitDataObject to
  getPorletTitlesFromLayout instead of re-resolving it from the request;
  the null-user fallback in LanguageUtil is what let the anonymous call
  survive. getAllLayouts was the helper's only caller.
- Swagger: state the requirement in the description and on the 401
  response (the gate emits 401 for every rejection); regenerate
  openapi.yaml.
- ITs: anonymous -> 401, backend user without roles portlet -> 401,
  non-admin roles-portlet user -> 200 with unchanged payload shape,
  admin -> 200.
@github-actions github-actions Bot added the Area : Backend PR changes Java/Maven backend code label Sep 1, 2026
@hassandotcms
hassandotcms marked this pull request as ready for review September 1, 2026 14:10
@hassandotcms
hassandotcms added this pull request to the merge queue Sep 3, 2026
Merged via the queue into main with commit 4a82203 Sep 3, 2026
57 checks passed
@hassandotcms
hassandotcms deleted the 37259-roles-layouts-auth-gate branch September 3, 2026 05:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area : Backend PR changes Java/Maven backend code

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

GET /api/v1/roles/layouts is reachable without authentication

2 participants