feat: allow chatbot to access user data on server by user token#3152
Open
feat: allow chatbot to access user data on server by user token#3152
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a header-based authentication path intended for chatbot/server-to-server calls by decrypting an encrypted session/user token and attaching the resolved Django user to otherwise-anonymous requests.
Changes:
- Added
SessionIDAuthMiddlewareto authenticate anonymous requests using an encryptedX-Session-ID-style header. - Added token decryption + user-id extraction utilities in
sefaria/utils/chatbot.pyand updated token payload to includeuser_id. - Added tests for the new middleware and wired the middleware + header setting into global Django settings.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
sefaria/utils/chatbot.py |
Adds decryption + expiration validation and get_user_id_from_chatbot_user_token; updates token payload to include user_id. |
sefaria/system/middleware.py |
Introduces SessionIDAuthMiddleware that reads a header token, resolves a user, and sets request.user. |
sefaria/settings.py |
Adds SESSION_ID_AUTH_HEADER setting and registers the new middleware in MIDDLEWARE. |
sefaria/system/tests/test_middleware.py |
Adds a new test class covering basic valid/invalid/expired and precedence scenarios for the middleware. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+314
to
+320
| authenticated user from the session, this middleware leaves it untouched. | ||
| """ | ||
|
|
||
| def process_request(self, request): | ||
| if getattr(request, "user", None) and request.user.is_authenticated: | ||
| return | ||
|
|
Comment on lines
121
to
+125
| 'django.middleware.csrf.CsrfViewMiddleware', | ||
| 'django.middleware.locale.LocaleMiddleware', | ||
| 'django.middleware.common.CommonMiddleware', | ||
| 'django.contrib.auth.middleware.AuthenticationMiddleware', | ||
| 'sefaria.system.middleware.SessionIDAuthMiddleware', |
| # Make this unique, and don't share it with anybody. | ||
| SECRET_KEY = '' | ||
| CHATBOT_USER_ID_SECRET = 'secret' | ||
| SESSION_ID_AUTH_HEADER = 'HTTP_X_SESSION_ID' |
Comment on lines
+537
to
+541
| def test_invalid_header_leaves_request_anonymous(self): | ||
| request = self.factory.get("/", HTTP_X_SESSION_ID="not-a-valid-token") | ||
| request.user = AnonymousUser() | ||
|
|
||
| with override_settings(CHATBOT_USER_ID_SECRET=self.secret): |
🧪 CI InsightsHere's what we observed from your CI run for 86fd18d. ✅ Passed Jobs With Interesting Signals
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This pull request introduces a new authentication mechanism that allows requests to be authenticated via an encrypted session ID header, supplementing Django's standard session authentication. The main change is the addition of a middleware that handles this authentication, along with corresponding updates to settings, utility functions, and tests.
Authentication enhancements:
SessionIDAuthMiddlewareto authenticate requests with anX-Session-IDheader, using a secure token to identify users, and integrated it into the Django middleware stack (sefaria/system/middleware.py,sefaria/settings.py). [1] [2]SESSION_ID_AUTH_HEADERsetting to specify the header name for session ID authentication (sefaria/settings.py).Token handling improvements:
get_user_id_from_chatbot_user_tokenand improved token decryption logic, including expiration checks and error handling, to securely extract user IDs from session tokens (sefaria/utils/chatbot.py). [1] [2]Testing:
SessionIDAuthMiddleware, covering valid, invalid, expired, and precedence scenarios for session ID authentication (sefaria/system/tests/test_middleware.py).sefaria/system/tests/test_middleware.py).Dependency and utility updates:
sefaria/system/middleware.py,sefaria/utils/chatbot.py). [1] [2]This pull request introduces a new authentication mechanism that allows anonymous requests to be authenticated via an encrypted session ID header. The main change is the addition of theSessionIDAuthMiddleware, which supplements Django's session authentication by checking for a validX-Session-IDheader and associating the request with the corresponding user if present. The pull request also includes comprehensive tests to ensure the correctness of this middleware, and utility functions for securely encoding and decoding user tokens.New authentication mechanism:
SessionIDAuthMiddlewareto authenticate anonymous requests using an encryptedX-Session-IDheader, supplementing Django's default session authentication. (sefaria/system/middleware.py)sefaria/settings.py) [1] [2]Token encoding/decoding utilities:
_decrypt_chatbot_user_tokenandget_user_id_from_chatbot_user_tokento securely decode and validate encrypted tokens, checking expiration and extracting user ID. (sefaria/utils/chatbot.py) [1] [2]build_chatbot_user_tokento includeuser_idin the payload for easier extraction during authentication. (sefaria/utils/chatbot.py)Testing:
SessionIDAuthMiddlewarecovering valid, invalid, expired, and precedence scenarios to ensure robust behavior. (sefaria/system/tests/test_middleware.py)sefaria/system/tests/test_middleware.py,sefaria/system/middleware.py) [1] [2]