Skip to content

Add onQueryResult script hook to filter managed object query results#139

Open
Copilot wants to merge 5 commits intomasterfrom
copilot/add-on-query-result-script-hook
Open

Add onQueryResult script hook to filter managed object query results#139
Copilot wants to merge 5 commits intomasterfrom
copilot/add-on-query-result-script-hook

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 26, 2026

  • ManagedObjectSetTest.java — already had Portions copyright 2026 3A Systems, LLC.
  • ManagedObjectSet.java — added Portions copyright 2026 3A Systems, LLC.
  • appendix-objects.adoc — updated to Portions Copyright 2024, 2026 3A Systems LLC.
  • appendix-scripting.adoc — updated to Portions Copyright 2024-2026 3A Systems LLC.
  • managed-user-on-query-result.json — new JSON file, no comment syntax possible
Original prompt

Context

Discussion #131 requests the ability to filter individual objects returned from a query on managed objects, similar to how validSource / validTarget work in sync.json mappings. Currently, there is no way to include/exclude specific objects from query results based on custom scripted logic (e.g., access control based on the requester's attributes).

What needs to be implemented

Add a new onQueryResult script hook to the ManagedObjectSet class in openidm-core/src/main/java/org/forgerock/openidm/managed/ManagedObjectSet.java.

Behaviour

  • The new hook should be called once per object returned from a query in the queryCollection() method (lines ~1275–1309).
  • The script receives the current query result object (as object) plus standard bindings: context, request, resourceName.
  • If the script returns false (or a falsy value), the object is excluded from the result set and NOT passed to handler.handleResource(...).
  • If the script returns true (or a truthy value, or null — i.e., when no hook is configured), the object is included as normal.
  • If the script throws an exception, it should be treated as an error and propagate correctly (set ex[0] and return false from handleResource).

Changes required

1. ManagedObjectSet.java

File: openidm-core/src/main/java/org/forgerock/openidm/managed/ManagedObjectSet.java

  1. Add onQueryResult to the ScriptHook enum (after onRetrieve, line ~150):
/** Script to execute for each object returned from a query; return false to exclude the object. */
onQueryResult,
  1. In queryCollection(), inside the QueryResourceHandler.handleResource() anonymous class, after the onRetrieve block and before/after relationship population, invoke the new hook and skip the object if the result is Boolean.FALSE:
// Execute the onQueryResult script if configured; skip object if it returns false
Object queryResultScriptResult = null;
try {
    queryResultScriptResult = execScriptHook(managedContext, ScriptHook.onQueryResult,
            resource.getContent(),
            prepareScriptBindings(managedContext, request, resource.getId(),
                    new JsonValue(null), new JsonValue(null)));
} catch (ResourceException e) {
    ex[0] = e;
    return false;
}
if (Boolean.FALSE.equals(queryResultScriptResult)) {
    // Object excluded by onQueryResult script
    return true; // continue iteration but skip this object
}

This block should be inserted after the onRetrieve block and before the relationship population and handler.handleResource(...) call.

2. Documentation update

File: openidm-doc/src/main/asciidoc/integrators-guide/appendix-objects.adoc

Add documentation for the new onQueryResult hook in the managed objects script hooks section, similar to how onRetrieve is documented.

File: openidm-doc/src/main/asciidoc/integrators-guide/appendix-scripting.adoc

Add onQueryResult to the script triggers table for managed.json (the table that lists onCreate, onUpdate, onRetrieve, etc. with their available variables).

Example configuration (managed.json)

After this change, users will be able to configure the hook like this:

{
  "name": "user",
  "onQueryResult": {
    "type": "text/javascript",
    "source": "var requester = context.security.authenticationId; object.owner === requester || requester === 'admin';"
  }
}

The script has access to:

  • object — the managed object being evaluated
  • context — the current security/request context
  • request — the query request

Return true to include the object in results, false to exclude it.

Files to change

  • openidm-core/src/main/java/org/forgerock/openidm/managed/ManagedObjectSet.java
  • openidm-doc/src/main/asciidoc/integrators-guide/appendix-objects.adoc
  • openidm-doc/src/main/asciidoc/integrators-guide/appendix-scripting.adoc

The following is the prior conversation context from the user's chat exploration (may be truncated):

User: подготовь ответ и согласуй со мной

Assistant: Вот подготовленный ответ на дискуссию #131. Пожалуйста, проверьте и согласуйте:


Предлагаемый ответ на дискуссию:


Thank you for the suggestion! This is a valid use case — filtering query results per-requester based on access control logic, similar to how validSource/validTarget work in sync mappings.

Current workaround options:

  1. onRetrieve script hook — already available in managed.json, it runs for every object returned from a query (when executeOnRetrieve=true is passed). You can use it to modify the returned object (e.g., strip sensitive fields), but it cannot currently exclude an object from the result set — throwing an exception there would fail the entire query.

  2. Router filter (router.json) — you can intercept query responses via onResponse hook in conf/router.json and post-process the result list, filtering out objec...

This pull request was created from Copilot chat.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI changed the title [WIP] Add onQueryResult script hook to ManagedObjectSet for filtering Add onQueryResult script hook to filter managed object query results Mar 26, 2026
Copilot AI requested a review from vharseko March 26, 2026 19:01
@vharseko vharseko requested a review from maximthomas March 26, 2026 19:01
@vharseko vharseko marked this pull request as ready for review March 27, 2026 05:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants