Skip to content

Commit 680f4ad

Browse files
committed
Support for password protected Notebook servers
1 parent d1b5f21 commit 680f4ad

4 files changed

Lines changed: 44 additions & 25 deletions

File tree

Python2.tmLanguage

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2886,4 +2886,4 @@
28862886
<key>uuid</key>
28872887
<string>F23DB5B2-7D08-11D9-A709-220D93B6E43C</string>
28882888
</dict>
2889-
</plist>
2889+
</plist>

ipy_connection.py

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -29,31 +29,36 @@
2929
from .external import nbformat3 as nbformat
3030
from .external.websocket import websocket3 as websocket
3131
from .external.websocket.websocket3 import *
32-
from urllib.request import urlopen, Request, ProxyHandler, build_opener, install_opener
33-
from urllib.parse import urlparse
34-
35-
36-
32+
from urllib.request import urlopen, Request, ProxyHandler, build_opener, install_opener, HTTPCookieProcessor
33+
from urllib.parse import urlparse, urlencode
34+
from http.cookiejar import CookieJar
3735

3836
def install_proxy_opener():
37+
cookies=CookieJar()
3938
proxy = ProxyHandler({})
40-
opener = build_opener(proxy)
39+
opener = build_opener(proxy, HTTPCookieProcessor(cookies))
4140
install_opener(opener)
41+
return cookies
4242

43-
install_proxy_opener()
43+
cookies=install_proxy_opener()
4444

4545
def create_uid():
4646
return str(uuid.uuid4())
4747

48-
def get_notebooks(baseurl):
49-
target_url = "http://%s/notebooks" % baseurl
48+
def get_notebooks(baseurl, psswd=None):
5049
try:
50+
if psswd!=None:
51+
target_url=baseurl+'''/login?next=%2F'''
52+
urlopen(target_url, data=urlencode({'password': psswd}).encode('utf8'))
53+
target_url = baseurl +"/notebooks"
5154
req = urlopen(target_url)
5255
try:
5356
encoding = req.headers.get_content_charset()
5457
body = req.readall().decode(encoding)
5558
except AttributeError:
5659
body = req.read()
60+
if '<input type="password" name="password" id="password_input">' in body:
61+
return 'psswd'
5762
data = json.loads(body)
5863
return data
5964
except Exception as e:
@@ -63,7 +68,7 @@ def get_notebooks(baseurl):
6368

6469
def create_new_notebook(baseurl):
6570
try:
66-
req = urlopen("http://" + baseurl + "/new")
71+
req = urlopen(baseurl + "/new")
6772
try:
6873
encoding = req.headers.get_content_charset()
6974
body = req.readall().decode(encoding)
@@ -285,20 +290,20 @@ def get_kernel_id(self):
285290
raise Exception("notebook_id not found")
286291

287292
def start_kernel(self):
288-
url = "http://" + self.baseurl + "/kernels?notebook=" + self.notebook_id
293+
url = self.baseurl + "/kernels?notebook=" + self.notebook_id
289294
req = urlopen(url, data=b"") # data="" makes it POST request
290295
req.read()
291296
self.create_websockets()
292297

293298
def restart_kernel(self):
294-
url = "http://" + self.baseurl + "/kernels/" + self.kernel_id + "/restart"
299+
url = self.baseurl + "/kernels/" + self.kernel_id + "/restart"
295300
req = urlopen(url, data=b"")
296301
req.read()
297302
self.create_websockets()
298303
self.status_callback("idle")
299304

300305
def interrupt_kernel(self):
301-
url = "http://" + self.baseurl + "/kernels/" + self.kernel_id + "/interrupt"
306+
url = self.baseurl + "/kernels/" + self.kernel_id + "/interrupt"
302307
req = urlopen(url, data=bytearray(b""))
303308
req.read()
304309

@@ -311,7 +316,7 @@ def get_notebook(self):
311316

312317
@property
313318
def notebook_url(self):
314-
return "http://" + self.baseurl + "/notebooks/" + self.notebook_id
319+
return self.baseurl + "/notebooks/" + self.notebook_id
315320

316321
def save_notebook(self, notebook):
317322
request = Request(self.notebook_url, str(notebook).encode(self.encoding))
@@ -400,15 +405,17 @@ def create_websockets(self):
400405
if self.iopub is not None:
401406
self.iopub.close()
402407

403-
url = "ws://" + self.baseurl + "/kernels/" + self.kernel_id + "/"
408+
url = self.baseurl.replace('http', 'ws') + "/kernels/" + self.kernel_id + "/"
409+
auth=''.join([c.name+'='+c.value for c in cookies])
404410
self.shell = websocket.WebSocketApp(url=url + "shell",
405411
on_message=lambda ws, msg: self.on_shell_msg(msg),
406-
on_open=lambda ws: ws.send(""),
412+
on_open=lambda ws: ws.send(auth),
407413
on_error=lambda ws, err: print(err))
408414
self.iopub = websocket.WebSocketApp(url=url + "iopub",
409415
on_message=lambda ws, msg: self.on_iopub_msg(msg),
410-
on_open=lambda ws: ws.send(""),
411-
on_error=lambda ws, err: print(err))
416+
on_open=lambda ws: ws.send(auth),
417+
on_error=lambda ws, err: print(err)
418+
)
412419

413420
_thread.start_new_thread(self.shell.run_forever, ())
414421
_thread.start_new_thread(self.iopub.run_forever, ())

ipy_view.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ def get_input_content(self):
9797
return self.view.substr(input_region)
9898
else:
9999
return ""
100-
100+
101101
def check_R(self):
102102
pass
103103

@@ -288,7 +288,7 @@ def __init__(self, view, notebook_id, baseurl):
288288
self.baseurl = baseurl
289289
view.set_scratch(True)
290290
#view.set_syntax_file("Packages/Python/Python.tmLanguage")
291-
view.set_syntax_file("Packages/IPython Notebook/SublimeIPythonNotebook.tmLanguage")
291+
view.set_syntax_file("Packages/SublimeIPythonNotebook/SublimeIPythonNotebook.tmLanguage")
292292
view.settings().set("ipython_notebook", True)
293293
self.cells = []
294294
self.notebook_id = notebook_id

subl_ipy_notebook.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def on_close(self, view):
3131

3232
def get_last_used_address():
3333
settings = sublime.load_settings("SublimeIPythonNotebook.sublime-settings")
34-
return settings.get("default_address", "127.0.0.1:8888")
34+
return settings.get("default_address", "http://127.0.0.1:8888")
3535

3636

3737
def set_last_used_address(value):
@@ -45,13 +45,25 @@ def run(self):
4545
self.on_done, None, None)
4646

4747
def on_done(self, line):
48-
self.window.run_command("inb_list_notebooks", {"baseurl": line})
48+
self.window.run_command("inb_list_notebooks", {"baseurl": line, "psswd": None})
49+
50+
class InbPromptPasswordCommand(sublime_plugin.WindowCommand):
51+
def run(self, baseurl):
52+
self.baseurl=baseurl
53+
self.window.show_input_panel("Password: ", '',
54+
self.on_done, None, None)
55+
56+
def on_done(self, line):
57+
self.window.run_command("inb_list_notebooks", {"baseurl": self.baseurl, 'psswd': line})
4958

5059

5160
class InbListNotebooksCommand(sublime_plugin.WindowCommand):
52-
def run(self, baseurl):
61+
def run(self, baseurl, psswd):
5362
self.baseurl = baseurl
54-
nbs = ipy_connection.get_notebooks(baseurl)
63+
nbs = ipy_connection.get_notebooks(baseurl, psswd)
64+
if nbs=='psswd':
65+
self.window.run_command("inb_prompt_password", {"baseurl": baseurl})
66+
return
5567
if nbs is None:
5668
print("Cannot get a list of notebooks")
5769
return

0 commit comments

Comments
 (0)