Conversation
There was a problem hiding this comment.
Pull request overview
This PR implements user caching in the BearerTokenMiddleware to improve performance by avoiding repeated database queries for Keycloak-authenticated users. The cache stores Django User objects keyed by Keycloak user ID with a configurable TTL (default 60 seconds).
Changes:
- Added Django cache imports and configuration for user caching
- Implemented cache lookup early in the middleware flow to return cached users immediately
- Added cache population at the end of successful authentication flows
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| request.user = cached_user | ||
| request._cached_user = cached_user | ||
| return self.get_response(request) |
There was a problem hiding this comment.
The cached_user retrieved from cache bypasses all the safety checks that ensure a user has a valid Member relationship. The _get_user function and subsequent code have extensive safety guarantees to never assign a user without a Member, but cached users skip these verifications. This could lead to AttributeError exceptions when code tries to access user.member. Consider adding a safety check to verify the cached user still has a valid Member relationship before using it, similar to the checks at lines 146-156.
| request.user = cached_user | |
| request._cached_user = cached_user | |
| return self.get_response(request) | |
| # SAFETY CHECK: Ensure cached user still has a valid Member with matching kc_id | |
| try: | |
| member = cached_user.member | |
| except Member.DoesNotExist: | |
| log.error( | |
| "Cached user %s has no Member; ignoring cache and falling back to _get_user.", | |
| getattr(cached_user, "id", None), | |
| ) | |
| else: | |
| if member and getattr(member, "kc_id", None) == kc_user_id: | |
| request.user = cached_user | |
| request._cached_user = cached_user | |
| return self.get_response(request) |
Closes CH-242
Implemented solution
Added cache in the middleware right after keycloak token check
How to test this PR
...
Sanity checks:
Breaking changes (select one):
breaking-changeand the migration procedure is well described abovePossible deployment updates issues (select one):
alert:deploymentTest coverage (select one):
Documentation (select one):
Nice to have (if relevant):