fix: value resolver 403, CamundaTask modify action, and register the freemarker plugins (v12) - #906
Open
Klaas-Ritense wants to merge 4 commits into
Open
fix: value resolver 403, CamundaTask modify action, and register the freemarker plugins (v12)#906Klaas-Ritense wants to merge 4 commits into
Klaas-Ritense wants to merge 4 commits into
Conversation
GET /api/management/v1/value-resolver and the document-definition key endpoints returned 403 for a ROLE_ADMIN token, leaving the *Value resolver* input mode without options. The key endpoints resolve through JsonSchemaDocumentDefinitionService.findLatestByName / findByNameAndVersion, which require the VIEW permission on JsonSchemaDocumentDefinition, so entity-level authorization applied on top of the administrator check that already guards all five endpoints in ValueResolverHttpSecurityConfigurer. They are now annotated with @RunWithoutAuthorization. Access remains restricted to administrators. The authorization module is declared compileOnly rather than implementation: only the annotation symbol is needed here, the aspect that acts on it lives in :backend:authorization and is present in every application, and an annotation whose class is absent at runtime is skipped by the JVM. An implementation dependency would put AuthorizationAutoConfiguration on the runtime classpath of every value-resolver consumer — it needs a UserManagementService, a ChangelogService and the authorization tables, none of which the module's own integration test context provides, so the context would fail to load. Verified with ./gradlew :backend:value-resolver:integrationTestingPostgresql — green, including all nine ValueResolverResourceIT tests.
CamundaTaskService.setDueDate and removeDueDate both call requirePermission(task, MODIFY), but CamundaTaskActionProvider did not list MODIFY among its available actions, so the action was not discoverable through AuthorizationService.getAvailableActionsForResource when granting permissions on the CamundaTask resource type.
Contributor
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Klaas-Ritense
force-pushed
the
bugfix/v12-plugin-di-and-config-fixes
branch
from
August 13, 2026 13:08
f5f14ee to
79cdbfc
Compare
Picks up the latest v12 release of the plugin, for both the backend artifact (com.ritense.valtimoplugins:freemarker) and the frontend package (@valtimo-plugins/freemarker) that release builds pin.
Klaas-Ritense
force-pushed
the
bugfix/v12-plugin-di-and-config-fixes
branch
from
August 13, 2026 13:46
79cdbfc to
1b8df3c
Compare
No released v12 frontend registered the external plugins. The hook for them existed only in apps/valtimo (app-plugins.ts / app-plugins.prod.ts) and angular.json had no app-plugins.ts -> app-plugins.prod.ts fileReplacement for any app, so every build compiled the empty stub and the @valtimo-plugins/* packages CI installed from release-plugins.json were never imported by anything. Meanwhile the backend freemarker plugin ships in the dev, gzac and evenementenvergunning apps but not in valtimo, so the one app carrying the frontend hook had no backend counterpart. The gzac app now imports the plugin modules and specifications directly: SmtpMailPluginModule, MailTemplatePluginModule, TextTemplatePluginModule and DocumentGeneratorPluginModule. The packages are plain package.json dependencies, pinned there instead of in release-plugins.json. No app-plugins split is needed on this branch. That indirection exists on next-minor because its package.json declares @valtimo/* as npm workspaces pointing at uncompiled projects/valtimo/* source, which breaks Vite's pre-bundling of the plugin packages' transitive @valtimo/* imports — hence keeping them out of package.json and swapping the module list at build time. v12 has no workspaces at all: all 37 @valtimo/* are already declared as file:dist/valtimo/*, so node resolution lands on the compiled libraries locally exactly as it does in CI, and the builder is webpack rather than esbuild/Vite. node_modules/@valtimo/plugin is a symlink to ../../dist/valtimo/plugin either way. Consequently release-plugins.json and the workflow step that applied its pins are removed, as are the now-unused apps/valtimo stubs. Dropping the stub from apps/valtimo/app.module.ts changes nothing there: it spread two empty arrays. Verified: `npm run build:gzac` and `npm run build:valtimo` both succeed, and `npx ng build gzac` without the production configuration succeeds too — the case the split was meant to protect. The gzac bundle contains the plugin config InjectionToken exactly once and carries the freemarker and smtpmail code; the valtimo bundle contains neither, as before. Against a running stack the plugin picker offers all 17 plugins, including Document generator, Mail sjablonen, Text sjablonen and SMTP Mail, and a process link on the Genereer Mailinhoud action rendered a mail into a process variable.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Ports the applicable fixes from #903 to v12 on top of
rc/12.43.0, and fixes the reason no v12 image could show thefreemarker plugin screens at all. What from #903 does not apply here is listed at the bottom.
Value resolver management endpoints returned 403 for administrators
GET /api/management/v1/value-resolverand the document-definition key endpoints returned 403 for aROLE_ADMINtoken, leaving the Value resolver input mode without options. The key endpoints resolve through
JsonSchemaDocumentDefinitionService.findLatestByName/findByNameAndVersion, which require theVIEWpermission onJsonSchemaDocumentDefinition, so entity-level authorization applied on top of the administrator check that alreadyguards all five endpoints in
ValueResolverHttpSecurityConfigurer. They are now annotated@RunWithoutAuthorization.Access remains restricted to administrators.
:backend:authorizationis declaredcompileOnlyrather thanimplementation. Only the annotation symbol isneeded here; the aspect that acts on it lives in the authorization module,
corealready exposes that module to everyapp as an
apidependency, and a@Retention(RUNTIME)annotation whose class is absent is simply skipped by the JVM.An
implementationdependency would instead putAuthorizationAutoConfigurationon the runtime classpath of everyvalue-resolver consumer — it needs a
UserManagementService, aChangelogServiceand the authorization tables, none ofwhich the module's own integration test context provides (
liquibase.enabled: false,ddl-auto: none), so the contextfails to load. That is the
DefaultCacheAwareContextLoaderDelegatefailureValueResolverResourceIThit on #903; thesame one-word change fixes it there.
modifyaction for CamundaTaskCamundaTaskService.setDueDateandremoveDueDateboth callrequirePermission(task, MODIFY), butCamundaTaskActionProviderdid not listMODIFY, so the action was not discoverable throughAuthorizationService.getAvailableActionsForResourcewhen granting permissions on theCamundaTaskresource type.No released v12 frontend registered the external plugins
The hook for them existed only in
apps/valtimo(app-plugins.ts/app-plugins.prod.ts) andangular.jsonhad noapp-plugins.ts -> app-plugins.prod.tsfileReplacement for any app, so every build compiled the empty stub and the@valtimo-plugins/*packages CI installed fromrelease-plugins.jsonwere never imported by anything. Meanwhile thebackend freemarker plugin ships in the
dev,gzacandevenementenvergunningapps but not invaltimo— the one appcarrying the frontend hook had no backend counterpart.
The gzac app now imports the plugin modules and specifications directly:
SmtpMailPluginModule,MailTemplatePluginModule,TextTemplatePluginModuleandDocumentGeneratorPluginModule. The packages are plainpackage.jsondependencies, pinned there instead of inrelease-plugins.json.No
app-pluginssplit is needed on this branch. That indirection exists onnext-minorbecause itspackage.jsondeclares
@valtimo/*as npm workspaces pointing at uncompiledprojects/valtimo/*source, which breaks Vite'spre-bundling of the plugin packages' transitive
@valtimo/*imports — hence keeping them out ofpackage.jsonandswapping the module list at build time. v12 has no workspaces at all: all 37
@valtimo/*are already declared asfile:dist/valtimo/*, so node resolution lands on the compiled libraries locally exactly as it does in CI, and thebuilder is webpack rather than esbuild/Vite.
node_modules/@valtimo/pluginis a symlink to../../dist/valtimo/plugineither way.
Consequently
release-plugins.jsonand the workflow step that applied its pins are removed, as are the now-unusedapps/valtimostubs. Dropping the stub fromapps/valtimo/app.module.tschanges nothing there: it spread two emptyarrays.
Freemarker plugin -> 8.5.3-V12
Latest v12 release, for the backend artifact (
com.ritense.valtimoplugins:freemarker,gradle.properties) and thefrontend packages (now
frontend/package.json).Not ported from #903
tsconfig.app.prod.json+angular.jsonproductiontsConfig. The duplicate-library DI defect does not exist onv12, for the same reason the
app-pluginssplit is unnecessary: both resolution routes land ondist/valtimo/*.Confirmed on a v12
gzac-frontendbuilt from this branch — the bundle contains the plugin configInjectionTokenexactly once.
Stamp frontend versionchange infrontend_build_push_docker_image.yml. Not needed on v12. The step onlypatches
projects/valtimo'sversions.ts, which this branch's app does not bundle — but the libraries workflowalready stamps
versions.tsand rebuilds@valtimo/configbefore uploading thedistartifact this job consumes, andskips its content-keyed lib cache whenever an explicit
project_versionis given.ritense/gzac-frontend:12.42.0does report
12.42.0. The stamp step is a harmless no-op here, so its logic is left untouched.BuildingBlockValueResolverResource. Nobuilding-blockmodule on v12.GlobalPermissionImporter/GlobalRoleImporterand noconfig/globalsupport. Adding theCamundaTaskmodifygrant under a bumped changeset was considered and rejected: the app does not set
valtimo.changelog.pbac.clear-tables, andPermissionDeployer.deployonly callssaveAllwith freshly builtentities, so a new changeset would duplicate all 41 existing rows. The file is untouched, which also means v12 keeps
the non-reconciling behaviour — a permission removed from the file stays active.
Verification
Backend:
./gradlew :backend:value-resolver:integrationTestingPostgresql— green, including all nineValueResolverResourceITtests, which is what confirms the
compileOnlychoice../gradlew :backend:value-resolver:test :backend:core:test :backend:exact-plugin:test— green (exact-pluginis theonly module depending on
value-resolver)../gradlew :backend:apps:gzac:bootJar— green, and:backend:authorizationstill resolves on theruntimeClasspathof all four apps through
core'sapidependency.Frontend:
npm run build:gzacandnpm run build:valtimo— both succeed.npx ng build gzacwithout the productionconfiguration also succeeds, which is the case the
app-pluginssplit was meant to protect.contains neither, unchanged from before.
Against a running stack — released
ritense/gzac-backend:12.42.0and agzacimage built from this branch, side byside on the same database, with the gzac app's own roles (it ships no permission file, so
ROLE_ADMINholds no entitypermissions):
GET /api/management/v1/value-resolverPOST /api/management/v1/value-resolver/document-definition/mail-test/keysPOST /api/management/v2/value-resolver/document-definition/mail-test/keysThe
GETnever returned 403 on v12 — it resolves no entity — so the annotation there is preventive rather than a fix.End-to-end through the UI of the
gzac-frontendimage built from this branch: the plugin picker offers all 17 pluginsincluding Document generator, Mail sjablonen, Text sjablonen and SMTP Mail; a Mail sjablonen plugin
configuration and a plugin process link on the Genereer Mailinhoud action were created without a single console error
(no
NullInjectorErroron either the plugin configuration or the action configuration step); every request returned 200,including the
POST /api/management/v2/value-resolver/document-definition/mail-test/keysthat the Value-resolver veldinput mode issues. Running the process rendered the mail into the
mailContentprocess variable:Known, pre-existing
The published
-V12plugin packages declare@angular/core: ^19.2.8peers while this branch is on17.3.12— true for8.5.1-V12as well.frontend/.npmrcsetslegacy-peer-deps=true, so installs are unaffected and both apps build, butthe peer range is wrong in the plugin repo.