Skip to content

[Task] Roles API: add PUT /v1/roles/{roleId} for role update + reparent #36936

Description

@hmoreras

Context

The Angular Roles and Tools portlet (FE task #36930) needs to update existing roles — including changing the parent (drag-to-reparent in the roles tree, and the Parent field in the Edit Role dialog). The current REST surface only offers POST /v1/roles for creating roles. The only path to update an existing role today is DWR RoleAjax#updateRole (dotCMS/src/main/java/com/dotmarketing/business/ajax/RoleAjax.java, ~line 411), which the Angular portlet is dropping.

Add a PUT /v1/roles/{roleId} endpoint that mirrors the existing POST /v1/roles body shape (RoleForm), so the Angular Edit Role dialog and drag-to-reparent can go through v1 REST end-to-end.

Endpoint Spec

Field Value
HTTP PUT
Path /v1/roles/{roleId}
Class#method com.dotcms.rest.api.v1.system.role.RoleResource#updateRole (new)
Path param roleId — existing role ID
Request body RoleFormroleName*, roleKey, parentRoleId, canEditUsers, canEditPermissions, canEditLayouts, description
Response RoleResponseEntityView (role.toMap()) — same shape POST already returns
Auth gates requiredBackendUser=true, requiredPortlet("roles"), admin check via roleAPI.doesUserHaveRole(user, cmsAdminRole)
OpenAPI @Operation annotation required; swagger-maven-plugin regenerated openapi.yaml committed

Behavior

  • Load the role by roleId; 404 if not found
  • Update fields from the form
  • Handle parentRoleId:
    • Non-null → validate parent exists (roleAPI.loadRoleById(parentRoleId)), reject with 400 if parent is a descendant of the role being edited (would create a cycle), then role.setParent(parentRole.getId())
    • Null → role.setParent(role.getId()) (root)
  • Persist via roleAPI.save(role)
  • Surface these existing exceptions as structured errors:
    • DuplicateRoleKeyException → 409 with field-level error on roleKey
    • DuplicateRoleException / RoleNameException → 409 with field-level error on roleName
  • Do not touch system or locked flags — system roles rejected with 403

Acceptance Criteria

  • PUT /v1/roles/{roleId} implemented with the spec above
  • @Operation OpenAPI doc added on the new method
  • swagger-maven-plugin regenerated dotCMS/src/main/webapp/WEB-INF/openapi/openapi.yaml committed
  • Integration test in dotcms-integration/src/test/.../RoleResourceIntegrationTest.java (or nearest existing) covering: happy-path update, reparent to a different parent, reparent to root (null), attempt to create a cycle (→ 400), attempt to edit a system role (→ 403), duplicate key (→ 409), duplicate name (→ 409), missing role (→ 404), non-admin caller (→ 403), missing portlet gate (→ 403)
  • License + role gating preserved
  • Existing POST /v1/roles and DWR updateRole remain functional (no breaking changes)

References

Metadata

Metadata

Assignees

Type

Projects

Status
In Progress

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions