Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
loop.add_callback(loop.stop)
class RootAPIHandler(APIHandler):
def get(self):
"""GET /api/ returns info about the Hub and its API.
It is not an authenticated endpoint.
For now, it just returns the version of JupyterHub itself.
"""
data = {'version': __version__}
self.finish(json.dumps(data))
class InfoAPIHandler(APIHandler):
@admin_only
def get(self):
"""GET /api/info returns detailed info about the Hub and its API.
It is not an authenticated endpoint.
For now, it just returns the version of JupyterHub itself.
"""
def _class_info(typ):
"""info about a class (Spawner or Authenticator)"""
info = {
'class': '{mod}.{name}'.format(mod=typ.__module__, name=typ.__name__)
}
pkg = typ.__module__.split('.')[0]
try:
"""API handlers for administering the Hub itself"""
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
import json
import sys
from tornado import web
from tornado.ioloop import IOLoop
from .._version import __version__
from ..utils import admin_only
from .base import APIHandler
class ShutdownAPIHandler(APIHandler):
@admin_only
def post(self):
"""POST /api/shutdown triggers a clean shutdown
POST (JSON) parameters:
- servers: specify whether single-user servers should be terminated
- proxy: specify whether the proxy should be terminated
"""
from ..app import JupyterHub
app = JupyterHub.instance()
data = self.get_json_body()
if data:
if 'proxy' in data:
self.log.warning(
"Deprecated in JupyterHub 0.8."
" Admin access API is not needed now that we use OAuth."
)
current = self.current_user
self.log.warning(
"Admin user %s has requested access to %s's server", current.name, name
)
if not self.settings.get('admin_access', False):
raise web.HTTPError(403, "admin access to user servers disabled")
user = self.find_user(name)
if user is None:
raise web.HTTPError(404)
class SpawnProgressAPIHandler(APIHandler):
"""EventStream handler for pending spawns"""
keepalive_interval = 8
def get_content_type(self):
return 'text/event-stream'
async def send_event(self, event):
try:
self.write('data: {}\n\n'.format(json.dumps(event)))
await self.flush()
except StreamClosedError:
self.log.warning("Stream closed while handling %s", self.request.uri)
# raise Finish to halt the handler
raise web.Finish()
if dt.tzinfo:
# strip timezone info to naïve UTC datetime
dt = dt.astimezone(timezone.utc).replace(tzinfo=None)
now = datetime.utcnow()
if (dt - now) > timedelta(minutes=59):
raise web.HTTPError(
400,
"Rejecting activity from more than an hour in the future: {}".format(
isoformat(dt)
),
)
return dt
class ActivityAPIHandler(APIHandler):
def _validate_servers(self, user, servers):
"""Validate servers dict argument
- types are correct
- each server exists
- last_activity fields are parsed into datetime objects
"""
msg = "servers must be a dict of the form {server_name: {last_activity: timestamp}}"
if not isinstance(servers, dict):
raise web.HTTPError(400, msg)
spawners = user.orm_spawners
for server_name, server_info in servers.items():
if server_name not in spawners:
raise web.HTTPError(
400,
"""Group handlers"""
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
import json
from tornado import gen
from tornado import web
from .. import orm
from ..utils import admin_only
from .base import APIHandler
class _GroupAPIHandler(APIHandler):
def _usernames_to_users(self, usernames):
"""Turn a list of usernames into user objects"""
users = []
for username in usernames:
username = self.authenticator.normalize_username(username)
user = self.find_user(username)
if user is None:
raise web.HTTPError(400, "No such user: %s" % username)
users.append(user.orm_user)
return users
def find_group(self, name):
"""Find and return a group by name.
Raise 404 if not found.
"""
from async_generator import aclosing
from dateutil.parser import parse as parse_date
from tornado import web
from tornado.iostream import StreamClosedError
from .. import orm
from ..user import User
from ..utils import admin_only
from ..utils import isoformat
from ..utils import iterate_until
from ..utils import maybe_future
from ..utils import url_path_join
from .base import APIHandler
class SelfAPIHandler(APIHandler):
"""Return the authenticated user's model
Based on the authentication info. Acts as a 'whoami' for auth tokens.
"""
async def get(self):
user = self.current_user
if user is None:
# whoami can be accessed via oauth token
user = self.get_current_user_oauth_token()
if user is None:
raise web.HTTPError(403)
self.write(json.dumps(self.user_model(user)))
class UserListAPIHandler(APIHandler):
)
def _check_group_model(self, model):
"""Check a request-provided group model from a REST API"""
self._check_model(model, self._group_model_types, 'group')
for groupname in model.get('groups', []):
if not isinstance(groupname, str):
raise web.HTTPError(
400, ("group names must be str, not %r", type(groupname))
)
def options(self, *args, **kwargs):
self.finish()
class API404(APIHandler):
"""404 for API requests
Ensures JSON 404 errors for malformed URLs
"""
async def prepare(self):
await super().prepare()
raise web.HTTPError(404)
self.log.info(
"%s %s requested API token for %s",
kind.title(),
requester.name,
user.name,
)
else:
user_kind = 'user' if isinstance(user, User) else 'service'
self.log.info("%s %s requested new API token", user_kind.title(), user.name)
# retrieve the model
token_model = self.token_model(orm.APIToken.find(self.db, api_token))
token_model['token'] = api_token
self.write(json.dumps(token_model))
class UserTokenAPIHandler(APIHandler):
"""API endpoint for retrieving/deleting individual tokens"""
def find_token_by_id(self, user, token_id):
"""Find a token object by token-id key
Raises 404 if not found for any reason
(e.g. wrong owner, invalid key format, etc.)
"""
not_found = "No such token %s for user %s" % (token_id, user.name)
prefix, id = token_id[0], token_id[1:]
if prefix == 'a':
Token = orm.APIToken
elif prefix == 'o':
Token = orm.OAuthAccessToken
else:
raise web.HTTPError(404, not_found)
"""Proxy handlers"""
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
import json
from urllib.parse import urlparse
from tornado import gen
from tornado import web
from .. import orm
from ..utils import admin_only
from .base import APIHandler
class ProxyAPIHandler(APIHandler):
@admin_only
async def get(self):
"""GET /api/proxy fetches the routing table
This is the same as fetching the routing table directly from the proxy,
but without clients needing to maintain separate
"""
routes = await self.proxy.get_all_routes()
self.write(json.dumps(routes))
@admin_only
async def post(self):
"""POST checks the proxy to ensure that it's up to date.
Can be used to jumpstart a newly launched proxy
without waiting for the check_routes interval.
def service_model(service):
"""Produce the model for a service"""
return {
'name': service.name,
'admin': service.admin,
'url': service.url,
'prefix': service.server.base_url if service.server else '',
'command': service.command,
'pid': service.proc.pid if service.proc else 0,
'info': service.info,
}
class ServiceListAPIHandler(APIHandler):
@admin_only
def get(self):
data = {name: service_model(service) for name, service in self.services.items()}
self.write(json.dumps(data))
def admin_or_self(method):
"""Decorator for restricting access to either the target service or admin"""
def decorated_method(self, name):
current = self.current_user
if current is None:
raise web.HTTPError(403)
if not current.admin:
# not admin, maybe self
if not isinstance(current, orm.Service):