remove notebook read-only view

it is largely broken, and had problematic security issues.
This commit is contained in:
MinRK 2013-07-23 13:03:03 -07:00
parent 6fd10471e1
commit f9dd129e1c
14 changed files with 26 additions and 105 deletions

View File

@ -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)

View File

@ -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]

View File

@ -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

View File

@ -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')

View File

@ -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

View File

@ -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();

View File

@ -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');
};

View File

@ -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");

View File

@ -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');

View File

@ -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);
}
};
};

View File

@ -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>.

View File

@ -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"

View File

@ -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" >

View File

@ -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,