-
Notifications
You must be signed in to change notification settings - Fork 310
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
Filtering request using OpenAPI spec #645
base: main
Are you sure you want to change the base?
Conversation
@bollwyvl I created this PoC to filter request at runtime using OpenAPI specification for allowed and blocked routes. For allowed routes, this sounds great. But for blocked routes (blocking only request matching that subset of rules), it may be too complicated. In particular you can not blocked easily any sub path by simply blocking a common root. The other issue I see is that OpenAPI does not support path parameter with slashes. So... should I switch to something more trivial to define routes like Regex and list of methods? |
@@ -96,7 +98,9 @@ def _prepare_templates(self): | |||
self.initialize_templates() | |||
# Add templates to web app settings if extension has templates. | |||
if len(self.template_paths) > 0: |
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.
could just be if self.template_paths
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.
I won't change it as it is not modified by this PR.
Right: it's only convention that sub-routes are even related. Regexen would be a way to do it, but could even be applied as a class of patch. The key thing is still to end up with an actual, accurate OpenAPI at the end, whether created by JSON Patch, JSON-e, python, or otherwise. |
Thanks a lot for reviewing this one @bollwyvl
Ok then let's keep OpenAPI as expected input format and let interested admin/dev design their tool to generate it. But that does not address the issue with path parameter with
|
Codecov Report
@@ Coverage Diff @@
## main #645 +/- ##
==========================================
+ Coverage 77.88% 78.08% +0.19%
==========================================
Files 110 113 +3
Lines 10405 10630 +225
Branches 1400 1429 +29
==========================================
+ Hits 8104 8300 +196
- Misses 1911 1937 +26
- Partials 390 393 +3
Continue to review full report at Codecov.
|
I gladly add some documentation about this feature. Could somebody advice me on the best place to do so? |
Maybe these docs? |
I added to the developers section as it is not configurable. So it probably makes more sense there. |
|
||
class MyExtensionApp(ExtensionApp): | ||
|
||
_allowed_spec = { |
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.
It feels like these should be public attributes if they are meant to be part of the API
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.
Following the idea of jupyterlab/jupyterlab_server#167, the scenario imagined to design this PR is the following:
James wants to create a SmithApp
that inherits from ExtensionApp
. That app can be executed either as an Jupyter server extension or as a standalone application. But in the case of the standalone application, he only wants the new handlers of his extension and the get contents endpoint to be available.
To achieve this, James will overrides the protected class attribute _allowed_spec
in the child class SmithApp
. Users of the SmithApp
will never be able to change the endpoints available in standalone mode*.
*of course because this is Python, this is only a convention that protected attribute should not be modified externally.
pinging @bollwyvl to get his opinion
@fcollonval and @bollwyvl , great stuff here! Do you mind waiting to merge this until after we have our next Jupyter Server meeting (January 6th)? I'm hoping to get more folks to weigh-in on this feature since we've discussed this in the past. For context, we added a way to add/remove whole "services" in Jupyter Server by overriding jupyter_server/jupyter_server/serverapp.py Lines 741 to 757 in 3e78339
This PR goes a few steps further and allows developers to cherry-pick individual routes (i.e. within individual services), which is really slick. |
Following the discussion at yesterday meeting, The authorization layer will definitely have overlap with this proposal as it can be seen as adding authorization policy to all users.
That said I can't formulate the best articulation between this PR and #165. It could make sense to have both simultaneously - although as pointed by @echarles it will likely be confusing. |
There have been discussions around the default behavior in case of absence of
True. This being said, I don't think #165 enforces RBAC approach. I have e.g. given a demo a few months ago during our developer meeting of a Open Policy Agent (OPA) implementation which nicely integrates with the proposed authorization layer. |
👍
Awesome that the current proposal is so flexible. So does that means we could transform this PR as an concrete |
This would be a nice convergence. Maybe have a a look at #165 where the Authorizer is a class that can be extended, or that you can inherit from something that will implement this PR features. Not sure if the the deny by default is implemented in that PR, but it should be possible to make it work like that. |
Fixes jupyterlab/jupyterlab_server#167
This is a PoC to add allowed and blocked request at runtime.