-
Notifications
You must be signed in to change notification settings - Fork 350
Allow user to update identity values #1518
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
Merged
minrk
merged 7 commits into
jupyter-server:main
from
brichet:allow_user_to_update_fields
Jun 19, 2025
Merged
Changes from 4 commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
588b831
Add an API to patch user fields
brichet 98b817a
Add test on API handler
brichet 407f3c0
Fix mypy
brichet c2d83db
Fix lint
brichet 93385a9
Split the update_user method to 3 methods (check, update, persist)
brichet 93b6cce
Merge branch 'main' into allow_user_to_update_fields
brichet 9d1060d
Add the updatable fields to the permissions instead of adding a new f…
brichet File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,13 +4,14 @@ | |
# Distributed under the terms of the Modified BSD License. | ||
import json | ||
import os | ||
from typing import Any | ||
from typing import Any, cast | ||
|
||
from jupyter_core.utils import ensure_async | ||
from tornado import web | ||
|
||
from jupyter_server._tz import isoformat, utcfromtimestamp | ||
from jupyter_server.auth.decorator import authorized | ||
from jupyter_server.auth.identity import IdentityProvider, UpdatableField | ||
|
||
from ...base.handlers import APIHandler, JupyterHandler | ||
|
||
|
@@ -70,7 +71,7 @@ async def get(self): | |
|
||
|
||
class IdentityHandler(APIHandler): | ||
"""Get the current user's identity model""" | ||
"""Get or patch the current user's identity model""" | ||
|
||
@web.authenticated | ||
async def get(self): | ||
|
@@ -110,9 +111,30 @@ async def get(self): | |
model = { | ||
"identity": identity, | ||
"permissions": permissions, | ||
"updatable_fields": self.identity_provider.updatable_fields, | ||
} | ||
self.write(json.dumps(model)) | ||
|
||
@web.authenticated | ||
async def patch(self): | ||
"""Update user information.""" | ||
user_data = cast(dict[UpdatableField, str], self.get_json_body()) | ||
if not user_data: | ||
raise web.HTTPError(400, "Invalid or missing JSON body") | ||
|
||
# Update user information | ||
identity_provider = self.settings["identity_provider"] | ||
if not isinstance(identity_provider, IdentityProvider): | ||
raise web.HTTPError(500, "Identity provider not configured properly") | ||
|
||
try: | ||
updated_user = identity_provider.update_user(self, user_data) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would probably pass |
||
self.write( | ||
{"status": "success", "identity": identity_provider.identity_model(updated_user)} | ||
) | ||
except ValueError as e: | ||
raise web.HTTPError(400, str(e)) from e | ||
|
||
|
||
default_handlers = [ | ||
(r"/api/spec.yaml", APISpecHandler), | ||
|
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
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.
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.
This implementation assumes that
get_user
is not overridden, which is the main thing IdentityProvider subclasses (e.g. JupyterHub) will do.The result of this change as-is for JupyterHub will be that:
/api/me
is not actually changedProbably the right thing to happen for JupyterHub which overrides
get_user
but not this method (yet) is to hit a NotImplementedError. I see two ways to go about that:set_login_cookie
step to apersist_user_model
method, so the field validation and user model persistence don't have to be overridden at the same timeThis method really does 3 things:
update_user
)update_user
)I think keeping it as a single method is okay, but that means the base class shouldn't have an implementation of it by default (It can still have it as a method, so subclasses can opt-in to default behavior). But if you want to slice it up so e.g. the key validation happens outside the typically overridden field, e.g.
that would reduce the duplication required by subclasses. If you want,
validate_update_user
could also be an overridable method.