Skip to content

Commit 64a5e15

Browse files
committed
add auth to the websocket
1 parent 2c3920a commit 64a5e15

File tree

1 file changed

+37
-4
lines changed

1 file changed

+37
-4
lines changed

jupyter_server/services/events/handlers.py

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
1+
"""A Websocket Handler for emitting Jupyter server events.
2+
3+
.. versionadded:: 2.0
4+
"""
15
import logging
26

3-
import tornado.web
4-
import tornado.websocket
57
from jupyter_telemetry.eventlog import _skip_message
68
from pythonjsonlogger import jsonlogger
9+
from tornado import web, websocket
710

811
from jupyter_server.base.handlers import JupyterHandler
912

13+
AUTH_RESOURCE = "events"
14+
1015

1116
class TornadoWebSocketLoggingHandler(logging.Handler):
12-
"""Logging handler that routes records to a Tornado websocket."""
17+
"""Python logging handler that routes records to a Tornado websocket."""
1318

1419
def __init__(self, websocket):
1520
super().__init__()
@@ -22,13 +27,41 @@ def emit(self, record):
2227

2328
class SubscribeWebsocket(
2429
JupyterHandler,
25-
tornado.websocket.WebSocketHandler,
30+
websocket.WebSocketHandler,
2631
):
32+
"""Websocket Handler for listening to eve"""
33+
34+
auth_resource = AUTH_RESOURCE
35+
36+
def pre_get(self):
37+
"""Handles authentication/authorization when
38+
attempting to subscribe to events emitted by
39+
Jupyter Server's eventbus.
40+
"""
41+
# authenticate the request before opening the websocket
42+
user = self.current_user
43+
if user is None:
44+
self.log.warning("Couldn't authenticate WebSocket connection")
45+
raise web.HTTPError(403)
46+
47+
# authorize the user.
48+
if not self.authorizer.is_authorized(self, user, "execute", "events"):
49+
raise web.HTTPError(403)
50+
51+
async def get(self, *args, **kwargs):
52+
self.pre_get()
53+
res = super().get(*args, **kwargs)
54+
await res
55+
2756
@property
2857
def event_bus(self):
58+
"""Jupyter Server's event bus that emits structured event data."""
2959
return self.settings["event_bus"]
3060

3161
def open(self):
62+
"""Routes events that are emitted by Jupyter Server's
63+
EventBus to a WebSocket client in the browser.
64+
"""
3265
self.logging_handler = TornadoWebSocketLoggingHandler(self)
3366
# Add a JSON formatter to the handler.
3467
formatter = jsonlogger.JsonFormatter(json_serializer=_skip_message)

0 commit comments

Comments
 (0)