mirror of
https://github.com/jupyter/notebook.git
synced 2025-02-23 12:49:41 +08:00
remove notebook read-only view
it is largely broken, and had problematic security issues.
This commit is contained in:
parent
6fd10471e1
commit
f9dd129e1c
@ -88,33 +88,6 @@ if tornado.version_info <= (2,1,1):
|
||||
websocket.WebSocketHandler._execute = _execute
|
||||
del _execute
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Decorator for disabling read-only handlers
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
@decorator
|
||||
def not_if_readonly(f, self, *args, **kwargs):
|
||||
if self.settings.get('read_only', False):
|
||||
raise web.HTTPError(403, "Notebook server is read-only")
|
||||
else:
|
||||
return f(self, *args, **kwargs)
|
||||
|
||||
@decorator
|
||||
def authenticate_unless_readonly(f, self, *args, **kwargs):
|
||||
"""authenticate this page *unless* readonly view is active.
|
||||
|
||||
In read-only mode, the notebook list and print view should
|
||||
be accessible without authentication.
|
||||
"""
|
||||
|
||||
@web.authenticated
|
||||
def auth_f(self, *args, **kwargs):
|
||||
return f(self, *args, **kwargs)
|
||||
|
||||
if self.settings.get('read_only', False):
|
||||
return f(self, *args, **kwargs)
|
||||
else:
|
||||
return auth_f(self, *args, **kwargs)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Top-level handlers
|
||||
@ -141,7 +114,7 @@ class AuthenticatedHandler(RequestHandler):
|
||||
if user_id is None:
|
||||
# prevent extra Invalid cookie sig warnings:
|
||||
self.clear_login_cookie()
|
||||
if not self.read_only and not self.login_available:
|
||||
if not self.login_available:
|
||||
user_id = 'anonymous'
|
||||
return user_id
|
||||
|
||||
@ -175,13 +148,6 @@ class AuthenticatedHandler(RequestHandler):
|
||||
"""
|
||||
return bool(self.settings.get('password', ''))
|
||||
|
||||
@property
|
||||
def read_only(self):
|
||||
"""Is the notebook read-only?
|
||||
|
||||
"""
|
||||
return self.settings.get('read_only', False)
|
||||
|
||||
|
||||
class IPythonHandler(AuthenticatedHandler):
|
||||
"""IPython-specific extensions to authenticated handling
|
||||
@ -269,7 +235,6 @@ class IPythonHandler(AuthenticatedHandler):
|
||||
return dict(
|
||||
base_project_url=self.base_project_url,
|
||||
base_kernel_url=self.base_kernel_url,
|
||||
read_only=self.read_only,
|
||||
logged_in=self.logged_in,
|
||||
login_available=self.login_available,
|
||||
use_less=self.use_less,
|
||||
@ -278,7 +243,7 @@ class IPythonHandler(AuthenticatedHandler):
|
||||
class AuthenticatedFileHandler(IPythonHandler, web.StaticFileHandler):
|
||||
"""static files should only be accessible when logged in"""
|
||||
|
||||
@authenticate_unless_readonly
|
||||
@web.authenticated
|
||||
def get(self, path):
|
||||
return web.StaticFileHandler.get(self, path)
|
||||
|
||||
|
@ -20,7 +20,7 @@ import os
|
||||
from tornado import web
|
||||
HTTPError = web.HTTPError
|
||||
|
||||
from ..base.handlers import IPythonHandler, authenticate_unless_readonly
|
||||
from ..base.handlers import IPythonHandler
|
||||
from ..utils import url_path_join
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
@ -38,7 +38,7 @@ class NewHandler(IPythonHandler):
|
||||
|
||||
class NamedNotebookHandler(IPythonHandler):
|
||||
|
||||
@authenticate_unless_readonly
|
||||
@web.authenticated
|
||||
def get(self, notebook_id):
|
||||
nbm = self.notebook_manager
|
||||
if not nbm.notebook_exists(notebook_id):
|
||||
@ -54,7 +54,7 @@ class NamedNotebookHandler(IPythonHandler):
|
||||
|
||||
class NotebookRedirectHandler(IPythonHandler):
|
||||
|
||||
@authenticate_unless_readonly
|
||||
@web.authenticated
|
||||
def get(self, notebook_name):
|
||||
# strip trailing .ipynb:
|
||||
notebook_name = os.path.splitext(notebook_name)[0]
|
||||
|
@ -164,7 +164,6 @@ class NotebookWebApplication(web.Application):
|
||||
# authentication
|
||||
cookie_secret=ipython_app.cookie_secret,
|
||||
login_url=url_path_join(base_project_url,'/login'),
|
||||
read_only=ipython_app.read_only,
|
||||
password=ipython_app.password,
|
||||
|
||||
# managers
|
||||
@ -227,18 +226,6 @@ flags['no-mathjax']=(
|
||||
When disabled, equations etc. will appear as their untransformed TeX source.
|
||||
"""
|
||||
)
|
||||
flags['read-only'] = (
|
||||
{'NotebookApp' : {'read_only' : True}},
|
||||
"""Allow read-only access to notebooks.
|
||||
|
||||
When using a password to protect the notebook server, this flag
|
||||
allows unauthenticated clients to view the notebook list, and
|
||||
individual notebooks, but not edit them, start kernels, or run
|
||||
code.
|
||||
|
||||
If no password is set, the server will be entirely read-only.
|
||||
"""
|
||||
)
|
||||
|
||||
# Add notebook manager flags
|
||||
flags.update(boolean_flag('script', 'FileNotebookManager.save_script',
|
||||
@ -248,7 +235,7 @@ flags.update(boolean_flag('script', 'FileNotebookManager.save_script',
|
||||
# the flags that are specific to the frontend
|
||||
# these must be scrubbed before being passed to the kernel,
|
||||
# or it will raise an error on unrecognized flags
|
||||
notebook_flags = ['no-browser', 'no-mathjax', 'read-only', 'script', 'no-script']
|
||||
notebook_flags = ['no-browser', 'no-mathjax', 'script', 'no-script']
|
||||
|
||||
aliases = dict(kernel_aliases)
|
||||
|
||||
@ -369,10 +356,6 @@ class NotebookApp(BaseIPythonApplication):
|
||||
BROWSER environment variable to override it.
|
||||
""")
|
||||
|
||||
read_only = Bool(False, config=True,
|
||||
help="Whether to prevent editing/execution of notebooks."
|
||||
)
|
||||
|
||||
use_less = Bool(False, config=True,
|
||||
help="""Wether to use Browser Side less-css parsing
|
||||
instead of compiled css version in templates that allows
|
||||
@ -554,7 +537,7 @@ class NotebookApp(BaseIPythonApplication):
|
||||
if ssl_options is None:
|
||||
self.log.critical(warning + " and not using encryption. This "
|
||||
"is not recommended.")
|
||||
if not self.password and not self.read_only:
|
||||
if not self.password:
|
||||
self.log.critical(warning + " and not using authentication. "
|
||||
"This is highly insecure and not recommended.")
|
||||
success = None
|
||||
|
@ -22,7 +22,7 @@ from zmq.utils import jsonapi
|
||||
|
||||
from IPython.utils.jsonutil import date_default
|
||||
|
||||
from ...base.handlers import IPythonHandler, authenticate_unless_readonly
|
||||
from ...base.handlers import IPythonHandler
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Notebook web service handlers
|
||||
@ -30,7 +30,7 @@ from ...base.handlers import IPythonHandler, authenticate_unless_readonly
|
||||
|
||||
class NotebookRootHandler(IPythonHandler):
|
||||
|
||||
@authenticate_unless_readonly
|
||||
@web.authenticated
|
||||
def get(self):
|
||||
nbm = self.notebook_manager
|
||||
km = self.kernel_manager
|
||||
@ -57,7 +57,7 @@ class NotebookHandler(IPythonHandler):
|
||||
|
||||
SUPPORTED_METHODS = ('GET', 'PUT', 'DELETE')
|
||||
|
||||
@authenticate_unless_readonly
|
||||
@web.authenticated
|
||||
def get(self, notebook_id):
|
||||
nbm = self.notebook_manager
|
||||
format = self.get_argument('format', default='json')
|
||||
|
@ -148,10 +148,6 @@ var IPython = (function (IPython) {
|
||||
*/
|
||||
CodeCell.prototype.handle_codemirror_keyevent = function (editor, event) {
|
||||
|
||||
if (this.read_only){
|
||||
return false;
|
||||
}
|
||||
|
||||
var that = this;
|
||||
// whatever key is pressed, first, cancel the tooltip request before
|
||||
// they are sent, and remove tooltip if any, except for tab again
|
||||
|
@ -43,7 +43,6 @@ function (marked) {
|
||||
|
||||
IPython.mathjaxutils.init();
|
||||
|
||||
IPython.read_only = $('body').data('readOnly') === 'True';
|
||||
$('#ipython-main-app').addClass('border-box-sizing');
|
||||
$('div#notebook_panel').addClass('border-box-sizing');
|
||||
|
||||
@ -54,7 +53,7 @@ function (marked) {
|
||||
IPython.pager = new IPython.Pager('div#pager', 'div#pager_splitter');
|
||||
IPython.quick_help = new IPython.QuickHelp();
|
||||
IPython.login_widget = new IPython.LoginWidget('span#login_widget',{baseProjectUrl:baseProjectUrl});
|
||||
IPython.notebook = new IPython.Notebook('div#notebook',{baseProjectUrl:baseProjectUrl, read_only:IPython.read_only});
|
||||
IPython.notebook = new IPython.Notebook('div#notebook',{baseProjectUrl:baseProjectUrl});
|
||||
IPython.save_widget = new IPython.SaveWidget('span#save_widget');
|
||||
IPython.menubar = new IPython.MenuBar('#menubar',{baseProjectUrl:baseProjectUrl})
|
||||
IPython.toolbar = new IPython.MainToolBar('#maintoolbar-container')
|
||||
@ -75,15 +74,6 @@ function (marked) {
|
||||
}
|
||||
$('#fonttest').remove();
|
||||
|
||||
if(IPython.read_only){
|
||||
// hide various elements from read-only view
|
||||
$('div#pager').remove();
|
||||
$('div#pager_splitter').remove();
|
||||
|
||||
// set the notebook name field as not modifiable
|
||||
$('#notebook_name').attr('disabled','disabled')
|
||||
}
|
||||
|
||||
IPython.page.show();
|
||||
|
||||
IPython.layout_manager.do_resize();
|
||||
|
@ -25,7 +25,6 @@ var IPython = (function (IPython) {
|
||||
var Notebook = function (selector, options) {
|
||||
var options = options || {};
|
||||
this._baseProjectUrl = options.baseProjectUrl;
|
||||
this.read_only = options.read_only || IPython.read_only;
|
||||
|
||||
this.element = $(selector);
|
||||
this.element.scroll();
|
||||
@ -91,7 +90,6 @@ var IPython = (function (IPython) {
|
||||
this.container = $("<div/>").addClass("container").attr("id", "notebook-container");
|
||||
var end_space = $('<div/>').addClass('end_space');
|
||||
end_space.dblclick(function (e) {
|
||||
if (that.read_only) return;
|
||||
var ncells = that.ncells();
|
||||
that.insert_cell_below('code',ncells-1);
|
||||
});
|
||||
@ -138,8 +136,6 @@ var IPython = (function (IPython) {
|
||||
|
||||
|
||||
$(document).keydown(function (event) {
|
||||
// console.log(event);
|
||||
if (that.read_only) return true;
|
||||
|
||||
// Save (CTRL+S) or (AppleKey+S)
|
||||
//metaKey = applekey on mac
|
||||
@ -366,7 +362,7 @@ var IPython = (function (IPython) {
|
||||
}
|
||||
// if we are autosaving, trigger an autosave on nav-away.
|
||||
// still warn, because if we don't the autosave may fail.
|
||||
if (that.dirty && ! that.read_only) {
|
||||
if (that.dirty) {
|
||||
if ( that.autosave_interval ) {
|
||||
that.save_notebook();
|
||||
return "Autosave in progress, latest changes may be lost.";
|
||||
@ -1777,11 +1773,10 @@ var IPython = (function (IPython) {
|
||||
|
||||
// Create the kernel after the notebook is completely loaded to prevent
|
||||
// code execution upon loading, which is a security risk.
|
||||
if (! this.read_only) {
|
||||
this.start_kernel();
|
||||
// load our checkpoint list
|
||||
IPython.notebook.list_checkpoints();
|
||||
}
|
||||
this.start_kernel();
|
||||
// load our checkpoint list
|
||||
IPython.notebook.list_checkpoints();
|
||||
|
||||
$([IPython.events]).trigger('notebook_loaded.Notebook');
|
||||
};
|
||||
|
||||
|
@ -157,7 +157,6 @@ var IPython = (function (IPython) {
|
||||
* @method edit
|
||||
*/
|
||||
TextCell.prototype.edit = function () {
|
||||
if ( this.read_only ) return;
|
||||
if (this.rendered === true) {
|
||||
var text_cell = this.element;
|
||||
var output = text_cell.find("div.text_cell_render");
|
||||
|
@ -17,7 +17,6 @@ $(document).ready(function () {
|
||||
window.open($('body').data('baseProjectUrl')+'new');
|
||||
});
|
||||
|
||||
IPython.read_only = $('body').data('readOnly') === 'True';
|
||||
IPython.notebook_list = new IPython.NotebookList('#notebook_list');
|
||||
IPython.cluster_list = new IPython.ClusterList('#cluster_list');
|
||||
IPython.login_widget = new IPython.LoginWidget('#login_widget');
|
||||
|
@ -34,9 +34,6 @@ var IPython = (function (IPython) {
|
||||
|
||||
|
||||
NotebookList.prototype.bind_events = function () {
|
||||
if (IPython.read_only){
|
||||
return;
|
||||
}
|
||||
var that = this;
|
||||
$('#refresh_notebook_list').click(function () {
|
||||
that.load_list();
|
||||
@ -129,13 +126,11 @@ var IPython = (function (IPython) {
|
||||
var kernel = data[i].kernel_id;
|
||||
var item = this.new_notebook_item(i);
|
||||
this.add_link(notebook_id, nbname, item);
|
||||
if (!IPython.read_only){
|
||||
// hide delete buttons when readonly
|
||||
if(kernel == null){
|
||||
this.add_delete_button(item);
|
||||
} else {
|
||||
this.add_shutdown_button(item,kernel);
|
||||
}
|
||||
// hide delete buttons when readonly
|
||||
if(kernel == null){
|
||||
this.add_delete_button(item);
|
||||
} else {
|
||||
this.add_shutdown_button(item,kernel);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
@ -20,7 +20,7 @@
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if read_only or not login_available %}
|
||||
{% if not login_available %}
|
||||
Proceed to the <a href="{{base_project_url}}">dashboard</a>.
|
||||
{% else %}
|
||||
Proceed to the <a href="{{base_project_url}}login">login page</a>.
|
||||
|
@ -24,7 +24,6 @@ window.mathjax_url = "{{mathjax_url}}";
|
||||
data-project={{project}}
|
||||
data-base-project-url={{base_project_url}}
|
||||
data-base-kernel-url={{base_kernel_url}}
|
||||
data-read-only={{read_only and not logged_in}}
|
||||
data-notebook-id={{notebook_id}}
|
||||
class="notebook_app"
|
||||
|
||||
|
@ -13,7 +13,6 @@
|
||||
data-project={{project}}
|
||||
data-base-project-url={{base_project_url}}
|
||||
data-base-kernel-url={{base_kernel_url}}
|
||||
data-read-only={{read_only}}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
@ -30,7 +29,7 @@ data-read-only={{read_only}}
|
||||
|
||||
<div class="tab-content">
|
||||
<div id="notebooks" class="tab-pane active">
|
||||
{% if logged_in or not read_only %}
|
||||
{% if logged_in %}
|
||||
<div id="notebook_toolbar">
|
||||
<form id='alternate_upload' class='alternate_upload' >
|
||||
<span id="drag_info" style="position:absolute" >
|
||||
|
@ -16,7 +16,8 @@ Authors:
|
||||
# Imports
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
from ..base.handlers import IPythonHandler, authenticate_unless_readonly
|
||||
from tornado import web
|
||||
from ..base.handlers import IPythonHandler
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Handlers
|
||||
@ -25,7 +26,7 @@ from ..base.handlers import IPythonHandler, authenticate_unless_readonly
|
||||
|
||||
class ProjectDashboardHandler(IPythonHandler):
|
||||
|
||||
@authenticate_unless_readonly
|
||||
@web.authenticated
|
||||
def get(self):
|
||||
self.write(self.render_template('tree.html',
|
||||
project=self.project,
|
||||
|
Loading…
Reference in New Issue
Block a user