ozimakov opened a new pull request, #1443:
URL: https://github.com/apache/syncope/pull/1443

   [SYNCOPE-1978](https://issues.apache.org/jira/browse/SYNCOPE-1978)
   
   ### What
   Restores the ability to search audit events by the **username of the entity 
whose payload was logged**, complementing the existing `entityKey` (UUID) 
match. A new repeatable `username` query parameter on `AuditQuery` matches the 
token `"username":"<value>"` embedded in the serialized audit payload 
(`before`, `inputs`, `output`, `throwable`):
   
   - single — `?username=jdoe`
   - multiple, OR-ed — `?username=jdoe&username=asmith`
   
   It is an **exact** match (no wildcards) and composes (AND) with the existing 
audit search filters (`entityKey`, `who`, `type`, `category`, `op`, `outcome`, 
`before`/`after`).
   
   ### Why
   Today an audit search can be pinned to a specific user only via `entityKey`, 
which requires the user's UUID. That UUID is unavailable once the user has been 
deleted, so there is no way to retrieve a deleted user's audit trail. The 
username, however, is preserved inside the `before` snapshot of the relevant 
audit events, so matching by username makes that trail searchable — and saves a 
resolve-then-query round-trip for live users.
   
   Syncope 3.0 allowed an approximation by abusing `entityKey=<username>` (an 
imprecise `LIKE '%key%<value>%'`); the 4.0 audit refactor correctly tightened 
`entityKey` to match only the UUID, which removed that side effect. This change 
reintroduces the capability deliberately and precisely, as a dedicated filter 
rather than re-loosening `entityKey`.
   
   ### Implementation
   The filter is threaded through `AuditServiceImpl` → `AuditLogic` → the 
`AuditEventDAO` interface and all of its implementations:
   
   - **JPA**: per value, `(beforeValue/inputs/output/throwable LIKE ? ESCAPE 
'#')` matching `%"username":"<value>"%`, OR-ed; the value is **bound as a 
parameter** and its `LIKE` metacharacters are escaped (so `%`/`_` in a username 
match literally);
   - **Neo4j**: `ANY(u IN $usernames WHERE n.before CONTAINS u OR ...)` — a 
literal `CONTAINS` with a bound list parameter (no regex);
   - **Elasticsearch / OpenSearch**: a `multi_match` phrase query of 
`"username":"<value>"` over the payload fields, OR-ed via `bool`/`should`.
   
   All values are bound as query parameters (SQL/Cypher) or passed as 
structured phrase queries (Elasticsearch/OpenSearch), so there is no injection 
surface; the pre-existing `entityKey` predicate is intentionally left unchanged.
   
   ### Tests
   Integration tests in `AuditITCase` cover exact match (asserting the matched 
event's payload truly carries the username), multiple values (OR), non-match 
exclusion, exact-not-prefix matching, and the **deleted-user** case (a user is 
created then deleted, and is still found by username via the delete event's 
`before` snapshot). Verified end-to-end against embedded PostgreSQL, Neo4j and 
Elasticsearch.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to