Repository navigation
fix(content-types): save legacy editor changes with the user's permissions - #38270
Conversation
…sions The legacy content type editor (/ext/structure/edit_structure) now saves through the requesting user's ContentTypeAPI, with the same checks as the REST endpoints: EDIT_PERMISSIONS on an existing type, and permission to add children and edit content type permissions on the destination site or folder for a new type or a move. Workflow schemes are saved only after the type itself was saved. When the user may not save the type, nothing is changed, the page shows the insufficient-permissions message, and the refusal is written once to the security log. Making a content type the default one now requires EDIT_PERMISSIONS on it, checked as the save checks it; the legacy editor shows a permissions message when it is refused. StructureFactory.saveStructure(Structure, User) is added for this. The existing saveStructure(Structure), used by jobs, push publishing and upgrade tasks, is unchanged.
|
Claude finished @oidacra's task in 2m 33s —— View job Code ReviewReviewed the diff against Verification notes:
New Issues
No correctness, security, or error-handling issues found in the changed code. |
…the legacy editor ContentTypeAPIImpl.setAsDefault checks EDIT_PERMISSIONS in the permissions stored for the content type, with the API's respectFrontendRoles flag. The legacy content type editor answers a requested type that the user may not read, or that does not exist, the same way: the fixed dont-have-permissions-msg message and a redirect to the referer or the content type list. Only the refusal is written to the security log. A posted inode that matches no type is no longer saved as a new type. When making a type the default one fails for a reason other than permissions, the failure is logged as an error and the page shows an-unexpected-error-occurred. The Javadoc of StructureFactory.saveStructure(Structure, User) now states that every save needs permission to add children and to edit content type permissions on the type's site or folder.
…ditor-saves-as-user # Conflicts: # dotcms-integration/src/test/java/com/dotcms/MainSuite2a.java
…ditor-saves-as-user
…uite2a instead of at the end
swicken
left a comment
There was a problem hiding this comment.
Looks good. The legacy editor now loads, saves and sets the default content type with the logged-in user's permissions, and a type the user can't read gets the same answer as one that doesn't exist. Internal callers keep the no-user saveStructure overload, and EditFieldAction already checks PUBLISH before its save. setAsDefault now needs EDIT_PERMISSIONS rather than READ, which applies to every caller of ContentTypeAPI, not only the legacy editor; that looks intended. Since erick's approval the only changes are merges from main and the MainSuite2a registration move. CI is green.
Summary
The legacy content type editor (
/ext/structure/edit_structure) saves content types with thepermissions of the logged-in user, applying the same checks as the content type REST endpoints.
Making a content type the default one requires EDIT_PERMISSIONS stored for it. A requested content
type the user may not read, or that does not exist, gets the same fixed answer.
Changes
EditStructureAction:StructureFactory.saveStructure(Structure, User), which usesAPILocator.getContentTypeAPI(user):site or folder the type is saved on (the destination one for a new type or a move);
first), nothing is changed, the page shows
message.insufficient.permissions.to.save, andthe refusal is written once to the security log.
the page shows
dont-have-permissions-msgand returns to the referer or the content typelist. Only the refusal is logged. A posted inode that matches no type is no longer saved as a
new type.
cmd=SET_DEFAULT: a refusal showsdont-have-permissions-msgand is logged; any otherfailure is logged as an error and shows
an-unexpected-error-occurred.StructureFactory:saveStructure(Structure, User). It sets the saved inode on the structure and sends thesame save event as
saveStructure(Structure).saveStructure(Structure)is unchanged for its callers (jobs, push publishing, upgrade tasks,the field editor). It shares a private helper with the new method.
ContentTypeAPIImpl.setAsDefault:respectFrontendRolesflag.Tests
EditStructureActionTest(12): the user's permissions are used; no schemes and no cache updateafter a refused save; one message and one security log entry for a refused save, a refused
set-default and a refused load; an unknown type gets the same answer with nothing saved and no
log entry; data errors are not reported as refusals, and a set-default data error shows a
fixed error message.
ContentTypeAPIImplSetAsDefaultTest(4): only the stored permissions count.EditStructureActionSaveTest(12), driven throughprocessActionwith storedpermission rows.
the workflow schemes without EDIT_PERMISSIONS on the type; creating on, or moving to, a site
without add-children; set-default without EDIT_PERMISSIONS stored for the type.
matches no type creates nothing.
with a scheme, set default.
MainSuite2a, the shortest compatible suite. Median job runtime over 5 recentmerged PRs (test(ci): stop the Postman and Karate stacks sleeping 3 s per write #38226, fix(postman): serve by-URL fixtures from WireMock and seed the language Content_Version_Resource needs #38213, fix(ci): tolerate transient network failures in SDKMAN, pnpm and image pulls #38210, fix(ui): restore native Array.from so Stencil attributes reach props on legacy pages (#35291) #38182, fix(docker): drop the compromised emSign ECC Root CA - G3 from the JDK truststore #38176): 2a 23.7 min, 1a 38.2 min, 1b 43.3 min,
2b 44.5 min, 3a 45.7 min.
Risk
Angular editor: add-children plus content type edit-permissions on the type's site or folder for
every save, and EDIT_PERMISSIONS on an existing type.
setAsDefaultrequires EDIT_PERMISSIONS stored for the type.sends such a request.
Fixes dotCMS/private-issues#889