mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-09 11:03:00 +00:00
Generate REST API scope descriptions from source code
This commit is contained in:
@@ -17,40 +17,53 @@ securityDefinitions:
|
||||
flow: accessCode
|
||||
authorizationUrl: "/hub/api/oauth2/authorize" # what are the absolute URIs here? is oauth2 correct here or shall we use just authorizations?
|
||||
tokenUrl: "/hub/api/oauth2/token"
|
||||
scopes: # Todo: Generate based on scope table
|
||||
(noscope): Allows only to identify the requesting entity
|
||||
self: Metascope, grants access to user's own resources; resolves to (no scope) for services.
|
||||
all: Metascope, valid for tokens only. Grants access to all resources of the token-owning entity.
|
||||
admin:users: Grants read, write, create and delete access to users and their authentication state but not their servers or tokens.
|
||||
admin:auth_state: Grants access to users' authentication state only.
|
||||
users: Grants read and write permissions to users' models apart from servers, tokens and authentication state.
|
||||
users:activity: Grants access to read and post users' activity only.
|
||||
users:activity!user=username: Update a single user's activity (example horizontal filter).
|
||||
read:users: Read-only access to users' models apart from servers, tokens and authentication state.
|
||||
read:users!user=username: As above limited to a specific user (example horizontal filter).
|
||||
read:users:name: Read-only access to user names.
|
||||
read:roles:users: Read-only access to user role assignments.
|
||||
read:users:groups: Read-only access to a list of users' group names.
|
||||
read:users:activity: Read-only access to users' activity.
|
||||
read:users:activity!group=groupname: Read-only access to specific group's users' activity (example horizontal filter).
|
||||
admin:servers: Grants read, start/stop, create and delete permissions to users' servers and their state.
|
||||
admin:server_state: Grants access to servers' state only.
|
||||
servers: Allows for starting/stopping users' servers in addition to read access to their models. Does not include the server state.
|
||||
servers!server=servername: Limits the above to a specific server (example horizontal filter).
|
||||
read:servers: Read-only access to users' server models. Does not include the server state.
|
||||
tokens: Grants read, write, create and delete permissions to users' tokens.
|
||||
read:tokens: Read-only access to users' tokens.
|
||||
admin:groups: Grants read, write, create and delete access to groups.
|
||||
groups: Grants read and write permissions to groups, including adding/removing users to/from groups.
|
||||
read:roles:groups: Read-only access to group roles assignments
|
||||
groups!group=groupname: As above limited to a specific group only (example horizontal filter)
|
||||
read:groups: Read-only access to groups.
|
||||
read:services: Read-only access to service models.
|
||||
read:services:name: Read-only access to service names.
|
||||
read:roles:services: Read-only access to a list of service roles names.
|
||||
read:hub: Read-only access to detailed information about JupyterHub.
|
||||
proxy: Allows for obtaining information about the proxy's routing table, for syncing the Hub with proxy and notifying the Hub about a new proxy.
|
||||
shutdown: Grants access to shutdown the Hub.
|
||||
scopes: # Generated based on scope table in jupyterhub/scopes.py
|
||||
(no_scope): Identify the owner of the requesting entity.
|
||||
self:
|
||||
The user’s own resources _(metascope for users, resolves to (no_scope)
|
||||
for services)_
|
||||
all: Everything that the token-owning entity can access _(metascope for tokens)_
|
||||
admin:users:
|
||||
Read, write, create and delete users and their authentication state,
|
||||
not including their servers or tokens.
|
||||
admin:auth_state: Read a user’s authentication state.
|
||||
users:
|
||||
Read and write permissions to user models (excluding servers, tokens
|
||||
and authentication state).
|
||||
read:users:
|
||||
Read user models (excluding including servers, tokens and authentication
|
||||
state).
|
||||
read:users:name: Read names of users.
|
||||
read:users:groups: Read users’ group membership.
|
||||
read:users:activity: Read time of last user activity.
|
||||
read:roles: Read role assignments.
|
||||
read:roles:users: Read user role assignments.
|
||||
read:roles:services: Read service role assignments.
|
||||
read:roles:groups: Read group role assignments.
|
||||
users:activity: Update time of last user activity.
|
||||
admin:servers: Read, start, stop, create and delete user servers and their state.
|
||||
admin:server_state: Read and write users’ server state.
|
||||
servers: Start and stop user servers.
|
||||
read:servers:
|
||||
Read users’ names and their server models (excluding the server
|
||||
state).
|
||||
tokens: Read, write, create and delete user tokens.
|
||||
read:tokens: Read user tokens.
|
||||
admin:groups: Read and write group information, create and delete groups.
|
||||
groups:
|
||||
Read and write group information, including adding/removing users to/from
|
||||
groups.
|
||||
read:groups: Read group models.
|
||||
read:groups:name: Read group names.
|
||||
read:services: Read service models.
|
||||
read:services:name: Read service names.
|
||||
read:hub: Read detailed information about the Hub.
|
||||
access:servers: Access user servers via API or browser.
|
||||
access:services: Access services via API or browser.
|
||||
proxy:
|
||||
Read information about the proxy’s routing table, sync the Hub with the
|
||||
proxy and notify the Hub about a new proxy.
|
||||
shutdown: Shutdown the hub.
|
||||
security: # global security, do we want to keep only the apiKey (token: []), change to only oauth2 (with scope self) or have both (either can be used)?
|
||||
- token: []
|
||||
- oauth2:
|
||||
@@ -106,7 +119,9 @@ paths:
|
||||
properties:
|
||||
class:
|
||||
type: string
|
||||
description: The Python class currently active for JupyterHub Authentication
|
||||
description:
|
||||
The Python class currently active for JupyterHub
|
||||
Authentication
|
||||
version:
|
||||
type: string
|
||||
description: The version of the currently active Authenticator
|
||||
@@ -115,7 +130,9 @@ paths:
|
||||
properties:
|
||||
class:
|
||||
type: string
|
||||
description: The Python class currently active for spawning single-user notebook servers
|
||||
description:
|
||||
The Python class currently active for spawning single-user
|
||||
notebook servers
|
||||
version:
|
||||
type: string
|
||||
description: The version of the currently active Spawner
|
||||
@@ -253,16 +270,22 @@ paths:
|
||||
- name: body
|
||||
in: body
|
||||
required: true
|
||||
description: Updated user info. At least one key to be updated (name or admin) is required.
|
||||
description:
|
||||
Updated user info. At least one key to be updated (name or admin)
|
||||
is required.
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: the new name (optional, if another key is updated i.e. admin)
|
||||
description:
|
||||
the new name (optional, if another key is updated i.e.
|
||||
admin)
|
||||
admin:
|
||||
type: boolean
|
||||
description: update admin (optional, if another key is updated i.e. name)
|
||||
description:
|
||||
update admin (optional, if another key is updated i.e.
|
||||
name)
|
||||
responses:
|
||||
"200":
|
||||
description: The updated user info
|
||||
@@ -285,9 +308,9 @@ paths:
|
||||
/users/{name}/activity:
|
||||
post:
|
||||
summary: Notify Hub of activity for a given user.
|
||||
description: Notify the Hub of activity by the user,
|
||||
e.g. accessing a service or (more likely)
|
||||
actively using a server.
|
||||
description:
|
||||
Notify the Hub of activity by the user, e.g. accessing a service
|
||||
or (more likely) actively using a server.
|
||||
security:
|
||||
- oauth2:
|
||||
- users:activity
|
||||
@@ -369,7 +392,9 @@ paths:
|
||||
"201":
|
||||
description: The user's notebook server has started
|
||||
"202":
|
||||
description: The user's notebook server has not yet started, but has been requested
|
||||
description:
|
||||
The user's notebook server has not yet started, but has been
|
||||
requested
|
||||
delete:
|
||||
summary: Stop a user's server
|
||||
security:
|
||||
@@ -385,7 +410,9 @@ paths:
|
||||
"204":
|
||||
description: The user's notebook server has stopped
|
||||
"202":
|
||||
description: The user's notebook server has not yet stopped as it is taking a while to stop
|
||||
description:
|
||||
The user's notebook server has not yet stopped as it is taking
|
||||
a while to stop
|
||||
/users/{name}/servers/{server_name}:
|
||||
post:
|
||||
summary: Start a user's single-user named-server notebook server
|
||||
@@ -420,7 +447,9 @@ paths:
|
||||
"201":
|
||||
description: The user's notebook named-server has started
|
||||
"202":
|
||||
description: The user's notebook named-server has not yet started, but has been requested
|
||||
description:
|
||||
The user's notebook named-server has not yet started, but has
|
||||
been requested
|
||||
delete:
|
||||
summary: Stop a user's named-server
|
||||
security:
|
||||
@@ -453,7 +482,9 @@ paths:
|
||||
"204":
|
||||
description: The user's notebook named-server has stopped
|
||||
"202":
|
||||
description: The user's notebook named-server has not yet stopped as it is taking a while to stop
|
||||
description:
|
||||
The user's notebook named-server has not yet stopped as it
|
||||
is taking a while to stop
|
||||
/users/{name}/tokens:
|
||||
parameters:
|
||||
- name: name
|
||||
@@ -491,7 +522,9 @@ paths:
|
||||
properties:
|
||||
expires_in:
|
||||
type: number
|
||||
description: lifetime (in seconds) after which the requested token will expire.
|
||||
description:
|
||||
lifetime (in seconds) after which the requested token will
|
||||
expire.
|
||||
note:
|
||||
type: string
|
||||
description: A note attached to the token for future bookkeeping
|
||||
@@ -712,9 +745,7 @@ paths:
|
||||
summary: Get a service by name
|
||||
security:
|
||||
- oauth2:
|
||||
- read:services
|
||||
- read:services:name
|
||||
- read:roles:services
|
||||
- read:services - read:services:name - read:roles:services
|
||||
parameters:
|
||||
- name: name
|
||||
description: service name
|
||||
@@ -729,7 +760,9 @@ paths:
|
||||
/proxy:
|
||||
get:
|
||||
summary: Get the proxy's routing table
|
||||
description: A convenience alias for getting the routing table directly from the proxy
|
||||
description:
|
||||
A convenience alias for getting the routing table directly from
|
||||
the proxy
|
||||
security:
|
||||
- oauth2:
|
||||
- proxy
|
||||
@@ -755,7 +788,9 @@ paths:
|
||||
description: Routing table
|
||||
schema:
|
||||
type: object
|
||||
description: configurable-http-proxy routing table (see configurable-http-proxy docs for details)
|
||||
description:
|
||||
configurable-http-proxy routing table (see configurable-http-proxy
|
||||
docs for details)
|
||||
post:
|
||||
summary: Force the Hub to sync with the proxy
|
||||
security:
|
||||
@@ -774,7 +809,9 @@ paths:
|
||||
- name: body
|
||||
in: body
|
||||
required: true
|
||||
description: Any values that have changed for the new proxy. All keys are optional.
|
||||
description:
|
||||
Any values that have changed for the new proxy. All keys are
|
||||
optional.
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
@@ -845,7 +882,9 @@ paths:
|
||||
/authorizations/cookie/{cookie_name}/{cookie_value}:
|
||||
get:
|
||||
summary: Identify a user from a cookie
|
||||
description: Used by single-user notebook servers to hand off cookie authentication to the Hub
|
||||
description:
|
||||
Used by single-user notebook servers to hand off cookie authentication
|
||||
to the Hub
|
||||
parameters:
|
||||
- name: cookie_name
|
||||
in: path
|
||||
@@ -955,10 +994,14 @@ paths:
|
||||
properties:
|
||||
proxy:
|
||||
type: boolean
|
||||
description: Whether the proxy should be shutdown as well (default from Hub config)
|
||||
description:
|
||||
Whether the proxy should be shutdown as well (default from
|
||||
Hub config)
|
||||
servers:
|
||||
type: boolean
|
||||
description: Whether users' notebook servers should be shutdown as well (default from Hub config)
|
||||
description:
|
||||
Whether users' notebook servers should be shutdown as well
|
||||
(default from Hub config)
|
||||
responses:
|
||||
"202":
|
||||
description: Shutdown successful
|
||||
@@ -1009,13 +1052,17 @@ definitions:
|
||||
auth_state:
|
||||
type: string
|
||||
#TODO: will there be predefined states? Should it rather be object instead of string?
|
||||
description: Authentication state of the user. Only available with admin:users:auth_state scope. None otherwise.
|
||||
description:
|
||||
Authentication state of the user. Only available with admin:users:auth_state
|
||||
scope. None otherwise.
|
||||
Server:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: The server's name. The user's default server has an empty name ('')
|
||||
description:
|
||||
The server's name. The user's default server has an empty name
|
||||
('')
|
||||
ready:
|
||||
type: boolean
|
||||
description: |
|
||||
@@ -1046,10 +1093,15 @@ definitions:
|
||||
description: UTC timestamp last-seen activity on this server.
|
||||
state:
|
||||
type: object
|
||||
description: Arbitrary internal state from this server's spawner. Only available on the hub's users list or get-user-by-name method, and only with admin:users:server_state scope. None otherwise.
|
||||
description:
|
||||
Arbitrary internal state from this server's spawner. Only available
|
||||
on the hub's users list or get-user-by-name method, and only with admin:users:server_state
|
||||
scope. None otherwise.
|
||||
user_options:
|
||||
type: object
|
||||
description: User specified options for the user's spawned instance of a single-user server.
|
||||
description:
|
||||
User specified options for the user's spawned instance of a single-user
|
||||
server.
|
||||
Group:
|
||||
type: object
|
||||
properties:
|
||||
@@ -1104,7 +1156,9 @@ definitions:
|
||||
properties:
|
||||
token:
|
||||
type: string
|
||||
description: The token itself. Only present in responses to requests for a new token.
|
||||
description:
|
||||
The token itself. Only present in responses to requests for a
|
||||
new token.
|
||||
id:
|
||||
type: string
|
||||
description: The id of the API token. Used for modifying or deleting the token.
|
||||
@@ -1121,7 +1175,9 @@ definitions:
|
||||
type: string
|
||||
note:
|
||||
type: string
|
||||
description: A note about the token, typically describing what it was created for.
|
||||
description:
|
||||
A note about the token, typically describing what it was created
|
||||
for.
|
||||
created:
|
||||
type: string
|
||||
format: date-time
|
||||
|
@@ -1,11 +1,14 @@
|
||||
import os
|
||||
from collections import defaultdict
|
||||
from pathlib import Path
|
||||
|
||||
from pytablewriter import MarkdownTableWriter
|
||||
from ruamel.yaml import YAML
|
||||
|
||||
from jupyterhub.scopes import scope_definitions
|
||||
|
||||
HERE = os.path.abspath(os.path.dirname(__file__))
|
||||
PARENT = Path(HERE).parent.parent.absolute()
|
||||
|
||||
|
||||
class ScopeTableGenerator:
|
||||
@@ -64,7 +67,7 @@ class ScopeTableGenerator:
|
||||
doc_description = self.scopes[scopename].get('doc_description', '')
|
||||
if doc_description:
|
||||
description = doc_description
|
||||
table_row = [f"{md_indent*depth}`{scopename}`", description]
|
||||
table_row = [f"{md_indent * depth}`{scopename}`", description]
|
||||
table_rows.append(table_row)
|
||||
for subscope in scope_pairs[scopename]:
|
||||
if subscope:
|
||||
@@ -76,7 +79,7 @@ class ScopeTableGenerator:
|
||||
return table_rows
|
||||
|
||||
def write_table(self):
|
||||
"""Generates the scope table in markdown format and writes it into scope-table.md file"""
|
||||
"""Generates the scope table in markdown format and writes it into `scope-table.md`"""
|
||||
filename = f"{HERE}/scope-table.md"
|
||||
table_name = ""
|
||||
headers = ["Scope", "Grants permission to:"]
|
||||
@@ -92,10 +95,30 @@ class ScopeTableGenerator:
|
||||
"Run 'make clean' before 'make html' to ensure the built scopes.html contains latest scope table changes."
|
||||
)
|
||||
|
||||
def write_api(self):
|
||||
"""Generates the API description in markdown format and writes it into `rest-api.yml`"""
|
||||
filename = f"{PARENT}/rest-api.yml"
|
||||
yaml = YAML(typ='rt')
|
||||
yaml.preserve_quotes = True
|
||||
scope_dict = {}
|
||||
with open(filename, 'r+') as f:
|
||||
content = yaml.load(f.read())
|
||||
f.seek(0)
|
||||
for scope in self.scopes:
|
||||
description = self.scopes[scope]['description']
|
||||
doc_description = self.scopes[scope].get('doc_description', '')
|
||||
if doc_description:
|
||||
description = doc_description
|
||||
scope_dict[scope] = description
|
||||
content['securityDefinitions']['oauth2']['scopes'] = scope_dict
|
||||
yaml.dump(content, f)
|
||||
f.truncate()
|
||||
|
||||
|
||||
def main():
|
||||
table_generator = ScopeTableGenerator()
|
||||
table_generator.write_table()
|
||||
table_generator.write_api()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@@ -22,6 +22,8 @@ from tornado.log import app_log
|
||||
from . import orm
|
||||
from . import roles
|
||||
|
||||
"""when modifying the scope definitions, make sure that `docs/source/rbac/generate-scope-table.py` is run
|
||||
so that changes are reflected in the documentation and REST API description."""
|
||||
scope_definitions = {
|
||||
'(no_scope)': {'description': 'Identify the owner of the requesting entity.'},
|
||||
'self': {
|
||||
|
Reference in New Issue
Block a user