New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
12167 Removed n+1 queries retrieving users with brief representation #12168
12167 Removed n+1 queries retrieving users with brief representation #12168
Conversation
The basic idea to remove the n+1 query on the user attributes is to make the Infinispan caching layer aware of the fact that different user attributes might be stored in different places so it can make a decision how to request a certain attribute instead of always requesting all attributes. I am not 100% sure this change is sound, but it is the only way I found to actually make this distinction. |
The basic idea to remove the n+1 query on the user credentials is to not always load credentials when the user is put into the cache but only when the password is actually requested. The change I introduced might also fix a potential bug as I found no code that actually updates cached values down the road after the password was cached when the user was loaded initially. |
6732156
to
e466f8b
Compare
The basic idea to remove the n+1 query loading group memberships of a user is to only check for fine-grained permissions via groups if fine-grained permissions are actually enabled. However, this does not remove the n+1 query when they are enabled. As discussed in the linked issue, it would be possible to add a parameter to the request so returning access information can be made optional or suppressible. |
I don't think the failing QuickStart test is due to my changes. |
@hmlnarik can you or someone from the store team take a look at this one? |
Thank you for the PR. Could you please extract the changes in services/src/main/java/org/keycloak/services/resources/admin/permissions/UserPermissions.java into a separate PR? That one seems viable to me. #7080 moved the first/last name, username and email from properties into attributes. The changes in Changes in |
@hmlnarik Thanks for your feedback!
Will do. What do you think about my suggestion to make returning access information optional or suppressible?
I'll try that.
Honestly, I do not understand this part. Where exactly am I introducing a dependency that was not there before? Is it this part? |
At this moment, the dependency is there. However it collides with #10279. The aim of #10279 is to provide a clear border between services which should have no knowledge of storage internals, and storage layer, so that the storage can then be switched to a new implementation without disrupting services.
The separation has started in #11933 PR, and this initial part is close to completion. While it does not contain moving the Hope this helps. |
@hmlnarik Thanks for the explanation. Then I would leave this part out for now and revisit it once the storage is separated. |
Thank you
This I believe relates to the following comment:
Let me check - did you mean when they are disabled? If so, I believe this is exactly where the services should be able to let the store know the preference of obtaining the details of a particular user, e.g. based on whether fine-grained permissions are enabled, and that sounds like a good idea - as long as it is done in a store-independent way.
I would be interested in the details here. Maybe I'm misinterpreting the suggestion as it sounds that the client (application) would then drive whether the groups are fetched and evaluated, and that would mean a potential for a vulnerability. Perhaps you meant a specific endpoint and a specific use case. |
e466f8b
to
d1fcbc0
Compare
@hmlnarik I finally managed to strip this one here down to the changes for reading the user attribute. You suggested to keep the The only way to kind of keep this logic would be to have CachedUser not return a |
@hmlnarik So I experimented a bit more with this and it is possible to have the eager loaded attributes attributes in a collection. This would look somewhat like this in the constructor when initializing the keycloak/model/map/src/main/java/org/keycloak/models/map/user/MapUserAdapter.java Line 92 in 5248815
Also the keycloak/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserAdapter.java Line 78 in ae7c01b
so I don't know why the WDYT? |
I like this since it treats the special fields consistently. In the
It precisely to make the handling the special attributes consistent in the
Let's put aside map store adapters as those are not relevant in the context of legacy store and are under scrutiny (#10004), specifically see #10004 (comment) for more details.
Me neither 😃 These should be consistent - and that's what the code using the |
…owing explicit eager caching of user attributese
d1fcbc0
to
c444f74
Compare
@hmlnarik So I implemented the minimum changes to make this work. I think checking for |
@hmlnarik Any feedback? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sschu , apologies for late response. Yes, now it is good to go. Thanks for the PR!
Implements #12167