Skip to content

Conversation

@akshayutture-augment
Copy link

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@akshayutture-augment
Copy link
Author

@greptileai

@greptile-apps
Copy link

greptile-apps bot commented Nov 14, 2025

Greptile Overview

Confidence Score: 1/5

  • This PR is unsafe to merge - critical NPE vulnerabilities remain unresolved
  • While the PR correctly identifies and partially fixes a concurrency issue in getSubGroupsCount(), it leaves three identical NPE vulnerabilities in the getSubGroupsStream() methods unpatched. Additionally, the implemented fix violates the interface contract by returning null instead of 0L.
  • GroupAdapter.java requires immediate attention to fix remaining NPE vulnerabilities and interface contract violation

Important Files Changed

File Analysis

Filename Score Overview
model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/GroupAdapter.java 1/5 Added null check for getSubGroupsCount() but three other getSubGroupsStream() methods still have the same NPE vulnerability, and return value violates interface contract
tests/base/src/test/java/org/keycloak/tests/admin/group/GroupTest.java 3/5 Added concurrency test for create/delete/read operations; test has a race condition where reader thread may not start before deletions complete

Sequence Diagram

sequenceDiagram
    participant Reader as Reader Thread
    participant Deleter as Deleter Thread
    participant GA as GroupAdapter
    participant MS as modelSupplier
    participant Cache as CacheSession
    participant DB as Database

    Note over Reader,DB: Concurrent Group Access Scenario

    Deleter->>Cache: groups().group(id).remove()
    Cache->>DB: Delete group from database
    DB-->>Cache: Group deleted
    
    Reader->>GA: getSubGroupsCount()
    GA->>GA: Check isUpdated() = false
    GA->>MS: modelSupplier.get()
    MS->>Cache: getGroupById(realm, id)
    Cache->>DB: Query deleted group
    DB-->>Cache: null (not found)
    Cache-->>MS: null
    MS-->>GA: null
    
    alt Fixed: getSubGroupsCount()
        GA-->>Reader: null or 0L (prevents NPE)
    end
    
    alt Unfixed: getSubGroupsStream() variants
        GA->>GA: model.getSubGroupsStream(...)
        Note right of GA: NPE thrown here!
        GA--xReader: NullPointerException
    end
Loading

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Additional Comments (3)

  1. model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/GroupAdapter.java, line 256 (link)

    logic: NPE can still occur here during concurrent deletion - same issue as getSubGroupsCount(). When modelSupplier.get() returns null (group deleted), this will throw NPE.

  2. model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/GroupAdapter.java, line 262 (link)

    logic: NPE can still occur here during concurrent deletion - same issue as getSubGroupsCount(). When modelSupplier.get() returns null (group deleted), this will throw NPE.

  3. model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/GroupAdapter.java, line 268 (link)

    logic: NPE can still occur here during concurrent deletion - same issue as getSubGroupsCount(). When modelSupplier.get() returns null (group deleted), this will throw NPE.

4 files reviewed, 5 comments

Edit Code Review Agent Settings | Greptile

if (isUpdated()) return updated.getSubGroupsCount();
return getGroupModel().getSubGroupsCount();
GroupModel model = modelSupplier.get();
return model == null ? null : model.getSubGroupsCount();
Copy link

Choose a reason for hiding this comment

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

logic: Violates interface contract - GroupModel.getSubGroupsCount() javadoc states "Never returns {@code null}". Should return 0L instead.

Suggested change
return model == null ? null : model.getSubGroupsCount();
return model == null ? 0L : model.getSubGroupsCount();
Prompt To Fix With AI
This is a comment left during a code review.
Path: model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/GroupAdapter.java
Line: 275:275

Comment:
**logic:** Violates interface contract - `GroupModel.getSubGroupsCount()` javadoc states "Never returns {@code null}". Should return `0L` instead.

```suggestion
        return model == null ? 0L : model.getSubGroupsCount();
```

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +139 to +149
new Thread(() -> {
while (!deletedAll.get()) {
try {
// just loading briefs
managedRealm.admin().groups().groups(null, 0, Integer.MAX_VALUE, true);
} catch (Exception e) {

caughtExceptions.add(e);
}
}
}).start();
Copy link

Choose a reason for hiding this comment

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

logic: Race condition - thread may not start before groups are deleted. Add a small delay or synchronization to ensure the reader thread is actually running before deletion starts.

Prompt To Fix With AI
This is a comment left during a code review.
Path: tests/base/src/test/java/org/keycloak/tests/admin/group/GroupTest.java
Line: 139:149

Comment:
**logic:** Race condition - thread may not start before groups are deleted. Add a small delay or synchronization to ensure the reader thread is actually running before deletion starts.

How can I resolve this? If you propose a fix, please make it concise.

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.

3 participants