Skip to content

[NAE-2389] Actor ref resolution does not includes realmId#421

Merged
machacjozef merged 5 commits intorelease/7.0.0-rev10from
NAE-2389
Apr 9, 2026
Merged

[NAE-2389] Actor ref resolution does not includes realmId#421
machacjozef merged 5 commits intorelease/7.0.0-rev10from
NAE-2389

Conversation

@renczesstefan
Copy link
Copy Markdown
Member

@renczesstefan renczesstefan commented Mar 6, 2026

Description

Added realmId inclusion when searching for user at resolving actor permission on cases and tasks.

Fixes NAE-2389

Dependencies

No new dependencies were introduced

Third party dependencies

No new dependencies were introduced

Blocking Pull requests

There are no dependencies on other PR

How Has Been This Tested?

This was tested manually and with unit tests.

Test Configuration

Name Tested on
OS macOS Tahoe 26.3
Runtime Java 21
Dependency Manager Maven 3.9.9n
Framework version Spring Boot 3.4.4
Run parameters
Other configuration

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • My changes have been checked, personally or remotely, with @machacjozef
  • I have commented my code, particularly in hard-to-understand areas
  • I have resolved all conflicts with the target branch of the PR
  • I have updated and synced my code with the target branch
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing tests pass locally with my changes:
    • Lint test
    • Unit tests
    • Integration tests
  • I have checked my contribution with code analysis tools:
  • I have made corresponding changes to the documentation:
    • Developer documentation
    • User Guides
    • Migration Guides

Summary by CodeRabbit

  • Refactor
    • Improved actor existence checks to exclude invalid/blank IDs and to perform realm-aware user and group resolution, resulting in more reliable actor filtering while preserving public behavior.
  • Documentation
    • Minor alignment and formatting tweaks in internal documentation/comments.

Moved the logic for validating actor existence into a dedicated `actorExists` method to improve code readability and reduce duplication. This change was applied to both `WorkflowService` and `TaskService` for consistency.
@renczesstefan renczesstefan self-assigned this Mar 6, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 6, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: a06364fd-6e4d-4299-aeae-d1956b770ab1

📥 Commits

Reviewing files that changed from the base of the PR and between f8f3649 and f8f510e.

📒 Files selected for processing (1)
  • application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java

Walkthrough

Extracted inline actor existence checks into a private helper actorExists(ActorFieldValue) in TaskService and WorkflowService; the helper validates IDs, performs realm-aware userService.findById(actorId, realmId), and falls back to groupService.findById(actorId). getExistingActors() now filters via this helper. No public signatures changed.

Changes

Cohort / File(s) Summary
Actor existence refactor
application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java, application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java
Extracted actor existence logic into private actorExists(ActorFieldValue) (validates actorFieldValue/id/ObjectId format, uses userService.findById(actorId, realmId), falls back to groupService.findById(actorId)); replaced inline stream filters in getExistingActors() with this helper. Minor whitespace/doc alignment in WorkflowService.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly references the main change: adding realmId inclusion to actor ref resolution to ensure realm-scoped user lookup, which aligns with the refactored actorExists method that now uses realm-aware user searches.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Retoocs
Retoocs previously approved these changes Mar 6, 2026
@coderabbitai coderabbitai bot added bugfix A change that fixes a bug Medium Small labels Mar 6, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java`:
- Around line 285-296: The actorExists method should defensively check that
actorFieldValue.getId() is not null or empty before calling userService.findById
or groupService.findById; update the actorExists(ActorFieldValue) implementation
to return false immediately when actorFieldValue.getId() is null/blank, then
proceed to call userService.findById(actorFieldValue.getId(),
actorFieldValue.getRealmId()) and fallback to
groupService.findById(actorFieldValue.getId()) as before (catching
IllegalArgumentException).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: adeab910-3f18-4072-ab2a-2f36a4c2a426

📥 Commits

Reviewing files that changed from the base of the PR and between fe97154 and 267ff2e.

📒 Files selected for processing (2)
  • application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java
  • application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java

tuplle
tuplle previously approved these changes Mar 6, 2026
Added null checks for actorFieldValue and its ID in actorExists methods of WorkflowService and TaskService. This prevents potential NullPointerExceptions and ensures robustness in cases where invalid or null input is provided.
@renczesstefan renczesstefan dismissed stale reviews from tuplle and Retoocs via c68380b March 6, 2026 11:41
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java (1)

285-299: ⚠️ Potential issue | 🟠 Major

Guard malformed actor IDs before the user lookup.

Line 289 still assumes every non-null id is a valid user ObjectId. In nae-user-ce/src/main/java/com/netgrif/application/engine/auth/service/UserServiceImpl.java:339-344, findById(id, realmId) constructs new ObjectId(id), so blank or malformed ids will throw before the group fallback runs. This should stay a soft false during actor filtering, not break case resolution.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java`
around lines 285 - 299, actorExists currently calls userService.findById with
any non-null id which can throw on malformed ObjectId; fix by validating the id
before the user lookup: in actorExists(ActorFieldValue) first check
actorFieldValue.getId() is not blank and ObjectId.isValid(id) (or equivalent
try-new-ObjectId wrapper) and only then call userService.findById; if the id is
not a valid ObjectId, skip the userService call and fall back to the existing
groupService.findById try/catch so malformed or blank ids return false without
throwing.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java`:
- Around line 867-881: actorExists currently calls userService.findById(...)
which can throw IllegalArgumentException for blank/malformed ids and abort
resolution; update actorExists to treat null/blank actorFieldValue.getId() as
missing, wrap the userService.findById(...) call in a try/catch that catches
IllegalArgumentException and treats it like a non-existent user, then only if
the user lookup fails proceed to try groupService.findById(...) (also swallowing
IllegalArgumentException similarly) so a bad actor id is filtered out rather
than causing the whole resolution to fail; refer to the actorExists method and
the userService.findById and groupService.findById calls when making the change.

---

Duplicate comments:
In
`@application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java`:
- Around line 285-299: actorExists currently calls userService.findById with any
non-null id which can throw on malformed ObjectId; fix by validating the id
before the user lookup: in actorExists(ActorFieldValue) first check
actorFieldValue.getId() is not blank and ObjectId.isValid(id) (or equivalent
try-new-ObjectId wrapper) and only then call userService.findById; if the id is
not a valid ObjectId, skip the userService call and fall back to the existing
groupService.findById try/catch so malformed or blank ids return false without
throwing.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 6209912c-9833-4a44-b843-37b9896e3aa3

📥 Commits

Reviewing files that changed from the base of the PR and between 267ff2e and c68380b.

📒 Files selected for processing (2)
  • application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java
  • application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java

Comment on lines +867 to +881
private boolean actorExists(ActorFieldValue actorFieldValue) {
if (actorFieldValue == null || actorFieldValue.getId() == null) {
return false;
}
AbstractUser user = userService.findById(actorFieldValue.getId(), actorFieldValue.getRealmId());
if (user != null) {
return true;
}
try {
groupService.findById(actorFieldValue.getId());
return true;
} catch (IllegalArgumentException ignored) {
return false;
}
}
Copy link
Copy Markdown

@coderabbitai coderabbitai bot Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Catch invalid user IDs here instead of aborting task resolution.

Line 871 can still throw on blank or malformed ids because userService.findById(...) builds an ObjectId internally. That means one bad actor entry can fail the whole resolution path instead of being filtered out. Treat blank ids as missing and swallow IllegalArgumentException from the user lookup before falling back to groups.

Proposed fix
 private boolean actorExists(ActorFieldValue actorFieldValue) {
-    if (actorFieldValue == null || actorFieldValue.getId() == null) {
+    if (actorFieldValue == null || actorFieldValue.getId() == null || actorFieldValue.getId().isBlank()) {
         return false;
     }
-    AbstractUser user = userService.findById(actorFieldValue.getId(), actorFieldValue.getRealmId());
-    if (user != null) {
-        return true;
+    try {
+        AbstractUser user = userService.findById(actorFieldValue.getId(), actorFieldValue.getRealmId());
+        if (user != null) {
+            return true;
+        }
+    } catch (IllegalArgumentException ignored) {
+        // Not a valid user id, continue with group lookup.
     }
     try {
         groupService.findById(actorFieldValue.getId());
         return true;
     } catch (IllegalArgumentException ignored) {
         return false;
     }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java`
around lines 867 - 881, actorExists currently calls userService.findById(...)
which can throw IllegalArgumentException for blank/malformed ids and abort
resolution; update actorExists to treat null/blank actorFieldValue.getId() as
missing, wrap the userService.findById(...) call in a try/catch that catches
IllegalArgumentException and treats it like a non-existent user, then only if
the user lookup fails proceed to try groupService.findById(...) (also swallowing
IllegalArgumentException similarly) so a bad actor id is filtered out rather
than causing the whole resolution to fail; refer to the actorExists method and
the userService.findById and groupService.findById calls when making the change.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added check to the first IF statement to check whether the ID is valid ObjectID, because If it its not valid, both the userService and groupService will throw IllegalArgumentException, so in both cases we should return false.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

Let me check the current state of the actorExists method on the PR branch.


🏁 Script executed:

#!/bin/bash
# Check the current state of the actorExists method in TaskService.java
rg -n "actorExists|isValid|ObjectId" application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java -A 3 -B 1

Length of output: 893


Let me see the full current method.


🏁 Script executed:

#!/bin/bash
# Get the full actorExists method
sed -n '867,890p' application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java

Length of output: 1015


@renczesstefan, that's a clean approach — using ObjectId.isValid(id) as an upfront guard is more concise than wrapping both service calls in separate try-catch blocks. Since ObjectId is already imported at Line 45, it fits naturally here.

The guard would look something like:

if (actorFieldValue == null || actorFieldValue.getId() == null || !ObjectId.isValid(actorFieldValue.getId())) {
    return false;
}

One small note: ObjectId.isValid(null) returns false in the Mongo driver, so the explicit actorFieldValue.getId() == null check is technically redundant when placed before it — but keeping it is fine for readability.

The fix hasn't appeared on the branch yet though — could you push the commit? Once it's up I'll mark this resolved.


🧠 Learnings used
Learnt from: Retoocs
Repo: netgrif/application-engine PR: 397
File: application-engine/src/main/java/com/netgrif/application/engine/workflow/service/CaseSearchService.java:98-104
Timestamp: 2025-12-12T13:40:00.786Z
Learning: In application-engine/src/main/java/com/netgrif/application/engine/workflow/service/CaseSearchService.java, the permission constraint logic in buildQuery() intentionally applies negative actor constraints globally: ((roleConstraint AND NOT negRoleConstraint) OR actorConstraint) AND NOT negActorConstraint. This means users in negativeViewActors are excluded even if they have positive role permissions, which is the intended authorization behavior.

Learnt from: Retoocs
Repo: netgrif/application-engine PR: 400
File: application-engine/src/main/java/com/netgrif/application/engine/workflow/web/AbstractTaskController.java:239-247
Timestamp: 2025-12-19T07:55:13.427Z
Learning: In the netgrif/application-engine project, the `taskService.findOne()` method (from ITaskService) never returns null. When a task is not found, it handles the error through other means (such as throwing an exception) rather than returning null, so null checks after `findOne()` calls are unnecessary.

Learnt from: Retoocs
Repo: netgrif/application-engine PR: 397
File: application-engine/src/test/groovy/com/netgrif/application/engine/impersonation/ImpersonationServiceTest.groovy:18-20
Timestamp: 2025-12-12T12:40:35.354Z
Learning: In the actor refactoring, UserFieldValue is a subclass of ActorFieldValue, and ActorListFieldValue accepts ActorFieldValue instances. Therefore, passing UserFieldValue instances to ActorListFieldValue is valid through polymorphism.

Learnt from: Retoocs
Repo: netgrif/application-engine PR: 397
File: application-engine/src/main/resources/petriNets/engine-processes/org_group.xml:36-39
Timestamp: 2025-12-12T12:36:06.651Z
Learning: In the org_group.xml file (application-engine/src/main/resources/petriNets/engine-processes/org_group.xml), variable names in action blocks like userField and user_selection should be kept as-is even when the field type changes from "user" to "actor".

Learnt from: Retoocs
Repo: netgrif/application-engine PR: 397
File: nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java:15-16
Timestamp: 2026-01-30T10:32:47.754Z
Learning: In the NAE-2285 refactoring (PR `#397`), breaking API changes to field visibility (public to protected) and type changes (String[] to Set<String>) in I18nField.java (nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java) are acceptable and intentional as part of the user-to-actor migration.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please check it once more.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check the current state of actorExists method
rg -n "actorExists|isValid|isBlank" application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java -A 2 -B 1

Length of output: 738


@renczesstefan, the fix is in place. Line 868 now guards with all four conditions:

if (actorFieldValue == null || actorFieldValue.getId() == null || actorFieldValue.getId().isBlank() || !ObjectId.isValid(actorFieldValue.getId())) {
    return false;
}

This correctly short-circuits before either userService.findById(...) or groupService.findById(...) are called for null, blank, or malformed IDs — no IllegalArgumentException can propagate from those lookups due to a bad ID.


🧠 Learnings used
Learnt from: Retoocs
Repo: netgrif/application-engine PR: 397
File: application-engine/src/main/java/com/netgrif/application/engine/workflow/service/CaseSearchService.java:98-104
Timestamp: 2025-12-12T13:40:00.786Z
Learning: In application-engine/src/main/java/com/netgrif/application/engine/workflow/service/CaseSearchService.java, the permission constraint logic in buildQuery() intentionally applies negative actor constraints globally: ((roleConstraint AND NOT negRoleConstraint) OR actorConstraint) AND NOT negActorConstraint. This means users in negativeViewActors are excluded even if they have positive role permissions, which is the intended authorization behavior.

Learnt from: Retoocs
Repo: netgrif/application-engine PR: 400
File: application-engine/src/main/java/com/netgrif/application/engine/workflow/web/AbstractTaskController.java:239-247
Timestamp: 2025-12-19T07:55:13.427Z
Learning: In the netgrif/application-engine project, the `taskService.findOne()` method (from ITaskService) never returns null. When a task is not found, it handles the error through other means (such as throwing an exception) rather than returning null, so null checks after `findOne()` calls are unnecessary.

Learnt from: Retoocs
Repo: netgrif/application-engine PR: 397
File: application-engine/src/test/groovy/com/netgrif/application/engine/impersonation/ImpersonationServiceTest.groovy:18-20
Timestamp: 2025-12-12T12:40:35.354Z
Learning: In the actor refactoring, UserFieldValue is a subclass of ActorFieldValue, and ActorListFieldValue accepts ActorFieldValue instances. Therefore, passing UserFieldValue instances to ActorListFieldValue is valid through polymorphism.

Learnt from: Retoocs
Repo: netgrif/application-engine PR: 397
File: application-engine/src/main/resources/petriNets/engine-processes/org_group.xml:36-39
Timestamp: 2025-12-12T12:36:06.651Z
Learning: In the org_group.xml file (application-engine/src/main/resources/petriNets/engine-processes/org_group.xml), variable names in action blocks like userField and user_selection should be kept as-is even when the field type changes from "user" to "actor".

Learnt from: Retoocs
Repo: netgrif/application-engine PR: 397
File: nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java:15-16
Timestamp: 2026-01-30T10:32:47.754Z
Learning: In the NAE-2285 refactoring (PR `#397`), breaking API changes to field visibility (public to protected) and type changes (String[] to Set<String>) in I18nField.java (nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java) are acceptable and intentional as part of the user-to-actor migration.

If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

coderabbitai[bot]
coderabbitai bot previously approved these changes Apr 8, 2026
machacjozef
machacjozef previously approved these changes Apr 8, 2026
Enhanced the `actorExists` method to check if the actor ID is blank or invalid using `ObjectId.isValid`. This ensures more robust validation and prevents potential errors when processing malformed IDs.
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java`:
- Around line 285-299: TaskService.actorExists currently only checks for null
IDs causing inconsistent behavior vs WorkflowService.actorExists; update
TaskService.actorExists to mirror WorkflowService by returning false if
actorFieldValue is null or actorFieldValue.getId() is null or isBlank() or
ObjectId.isValid(...) is false, then proceed to call
userService.findById(actorFieldValue.getId(), actorFieldValue.getRealmId()) and
return true if non-null, otherwise attempt
groupService.findById(actorFieldValue.getId()) and return true unless it throws
IllegalArgumentException (return false in that case). Ensure you reference the
same validation logic (isBlank and ObjectId.isValid) used in WorkflowService to
keep behavior consistent.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: e9bf8deb-e250-415e-a54a-41701ab10ed2

📥 Commits

Reviewing files that changed from the base of the PR and between c68380b and f8f3649.

📒 Files selected for processing (1)
  • application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java

renczesstefan and others added 2 commits April 8, 2026 13:50
Updated the actorExists method to validate that the actor ID is not blank and adheres to ObjectId format. This prevents invalid or malformed IDs from causing issues during runtime.
@machacjozef machacjozef requested review from Retoocs and tuplle April 9, 2026 10:07
@renczesstefan
Copy link
Copy Markdown
Member Author

@coderabbitai please review the PR and approve if its ok

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 9, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Fetch the PR diff
gh pr diff 421 --repo netgrif/application-engine

Length of output: 5046


🏁 Script executed:

#!/bin/bash
# Find ActorFieldValue class
fd "ActorFieldValue.java" --exec cat {}

# Find userService findById signature
rg -n "findById" --type java -C2 application-engine/src/main/java/com/netgrif/application/engine/auth/service

# Check ObjectId import in TaskService and WorkflowService
rg -n "import.*ObjectId" --type java application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java 2>/dev/null || rg -n "import.*ObjectId" --type java

Length of output: 3626


@renczesstefan I've reviewed PR #421. Here's my assessment:


✅ Review Summary

Core fix is correct. The bug was that userService.findById(actorId, null) was called with a null realm, preventing realm-scoped user resolution. The fix correctly passes actorFieldValue.getRealmId() — confirmed that:

  • ActorFieldValue has a protected String realmId field with Lombok @Getter, so getRealmId() is available ✓
  • userService.findById(String id, String realmId) accepts the realm parameter ✓
  • org.bson.types.ObjectId is already imported in both TaskService.java and WorkflowService.java

Validation improvements are solid:

  • Null guard on the ActorFieldValue object itself
  • Null and blank guards on the actor ID
  • ObjectId.isValid() check prevents malformed IDs from reaching the database

Stream order is correct: .filter(this::actorExists) is applied before .map(ActorFieldValue::getId), so the full ActorFieldValue object is available during filtering.

Group fallback is unchanged (groupService.findById(actorId) without realm) — this appears intentional since groups may not be realm-scoped.


⚠️ Minor Observation (non-blocking)

The actorExists(ActorFieldValue) method is identical in both TaskService and WorkflowService. Consider extracting it to a shared utility class or a common base/service to avoid duplication, but this is not a blocker for merging.


The changes are well-structured, address the reported bug, and add meaningful defensive validation. Approving ✅

[approve]


🧠 Learnings used
Learnt from: Retoocs
Repo: netgrif/application-engine PR: 397
File: nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java:15-16
Timestamp: 2026-01-30T10:32:47.754Z
Learning: In the NAE-2285 refactoring (PR `#397`), breaking API changes to field visibility (public to protected) and type changes (String[] to Set<String>) in I18nField.java (nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java) are acceptable and intentional as part of the user-to-actor migration.

Learnt from: Retoocs
Repo: netgrif/application-engine PR: 397
File: application-engine/src/main/java/com/netgrif/application/engine/workflow/service/CaseSearchService.java:98-104
Timestamp: 2025-12-12T13:40:00.786Z
Learning: In application-engine/src/main/java/com/netgrif/application/engine/workflow/service/CaseSearchService.java, the permission constraint logic in buildQuery() intentionally applies negative actor constraints globally: ((roleConstraint AND NOT negRoleConstraint) OR actorConstraint) AND NOT negActorConstraint. This means users in negativeViewActors are excluded even if they have positive role permissions, which is the intended authorization behavior.

@machacjozef machacjozef merged commit 844d184 into release/7.0.0-rev10 Apr 9, 2026
6 of 7 checks passed
@machacjozef machacjozef deleted the NAE-2389 branch April 9, 2026 11:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix A change that fixes a bug Medium Small

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants