dotCMS / dotCMS/core

[Task] Tools: `PortletID.TOOLS`, tools catalog endpoints and custom-tool gate on `/v1/portlet`

Open
#37,574 1 comment 0 reactions 1 assignee View on GitHub

@hassandotcms is already working on this.

Since Sep 16, 2026.

dotCMS : Admin Tools Team : Modernization Type : Task
Dominant language
Java
Stars
970
Forks
486
Avg merge
3d 33m
Merged PRs (30d)
170

Description

Context

The Tools portlet's Available Tools panel lists every tool that can be placed in a navigation section and offers New Tool, Edit and Delete for custom content tools. Today the list of placeable tools is available only through the Dojo remoting layer behind the Roles & Tools screen, which the Angular portlet cannot call. Custom content tools can already be created, updated and deleted over REST, but only by users who hold the Roles portlet, there is no way to read one back in the shape the Edit dialog needs, and the delete does not check that its target is a custom tool. There is no tools portlet id to gate any of this on.

This task delivers the portlet-side backend for that panel. The section endpoints under /v1/layouts are #37353, which depends on the portlet id added here.

Requirements

Tools catalog

  1. The system exposes a catalog of every tool that can be placed in a navigation section. It applies the same inclusion rules as the legacy Roles & Tools picker: tools the product marks as not placeable are excluded, and the legacy Languages tool is excluded while the configuration that hides it is on.
  2. Each catalog entry carries the tool's id, its title localized to the caller's language, and an isCustom flag. Entries are unique and sorted by title, ignoring letter case.
  3. isCustom is true only for tools created at runtime as custom content tools. It is determined by how the tool was registered, not by the spelling of its id; the c_ prefix is a convention, not a contract.
  4. When a title has no translation for the caller's language, the entry shows the name the tool was given at creation (custom tools only), and failing that its id. It never shows a raw translation key.
  5. A tool created, updated or deleted through any operation below appears, changes or disappears in the next catalog read.

Custom content tool read

  1. The system exposes a read of one custom content tool by id returning its id, name, base types and content types as lists, and its data view mode as stored (list or card, lowercase). An unknown id, or the id of a tool that is not a custom content tool, is answered with not found.

Tools portlet id

  1. The product's portlet id registry contains an entry resolving to tools, so this task and #37353 have an id to gate on and #37356 has an id to promote to.

Access

  1. The catalog and the single-tool read require an authenticated backend user who holds a granted section containing tools or tools-beta, or is a CMS Administrator. Both ids are required because access is exact membership of the id in the user's sections and the portlet admins add during Beta is tools-beta. Any other caller is rejected with 401, the response every portlet-gated endpoint gives today.
  2. Custom-tool create, update and delete accept a caller who holds roles, tools or tools-beta, or is a CMS Administrator, so Roles admins keep working and Tools-only admins can create custom tools. Their request and response contracts do not change. The gate moves to tools alone in #37356, once the Dojo tab that creates tools from the Roles screen is retired.
  3. The custom-tool delete refuses, with not found and without changing any data, any id that is not a custom content tool. Today it removes whatever id it is given, shipped or custom, from every section on the instance.
  4. The operation that adds a tool to a section the caller holds keeps its Roles-only gate. It accepts any placeable tool, so widening it would let a Tools holder add the Roles or Users tool to their own section. The Tools portlet does not use it.

Documentation

  1. Every endpoint added or changed is described in the generated API documentation with response schemas that match what is returned.

Must keep working

  • The Dojo Roles & Tools screen, which creates and deletes custom tools through the same REST operations and fetches the catalog through remoting.
  • The Angular Add to menu dialog on the Content Types listing, which creates a custom tool and adds it to a section. It sends the data view mode in lowercase.
  • The PortletResource Postman collection.

The frontend PR #37481 currently sends the data view mode as List / Card and maps its delete to the role-scoped remove; both change when it wires the real endpoints.

Out of scope

  • Section create, update, delete, reorder and tool assignment (#37353).
  • The Dojo JSPs and RoleAjax remoting methods.
  • The role-scoped removes DELETE /v1/portlet/portletId/{id} and .../roleId/{roleId}.
  • A licence check; no sibling admin endpoint has one.
  • The equivalent roles-beta versus roles gate gap.

Acceptance criteria

  • The catalog returns only placeable tools, sorted by title, with isCustom true only for custom tools, and omits the legacy Languages tool when the hide flag is on.
  • The single-tool read returns name, id, base types, content types and data view mode; not found for an unknown or non-custom id.
  • Catalog and single read reject an unauthenticated caller and a backend user with neither tools nor tools-beta with 401; a non-admin with only tools-beta passes.
  • A non-admin with only tools-beta can create, update and delete a custom tool; one with only roles still can; one with only tools-beta is still rejected when adding a tool to a section.
  • Deleting roles through the custom-tool delete returns not found and roles remains in every section that had it; deleting a custom id works as before.
  • The Dojo screen and the Add to menu dialog still create, add and delete custom tools for a Roles holder.
  • The Postman collection stays green.
  • Response schemas match; the regenerated openapi.yaml is committed.

Definition of Done

  • New: GET /v1/portlet (catalog) and GET /v1/portlet/custom/{portletId} (single custom tool), gated on tools / tools-beta.
  • Modified: POST / PUT /v1/portlet/custom and DELETE /v1/portlet/custom/{portletId} accept roles or tools / tools-beta; the delete refuses non-custom ids. Contracts otherwise unchanged.
  • TOOLS added to the portlet id registry.
  • Every endpoint annotated for the API documentation; openapi.yaml regenerated and committed.
  • Integration tests for catalog filtering and isCustom, the single-tool read, the delete guard and every access combination above, registered in a MainSuite so CI runs them.
  • Dojo screen, remoting methods and Add to menu unchanged in behaviour.

Refs #37353

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.