##// END OF EJS Templates
remove notebook read-only view...
MinRK -
Show More
@@ -88,33 +88,6 b' if tornado.version_info <= (2,1,1):'
88 websocket.WebSocketHandler._execute = _execute
88 websocket.WebSocketHandler._execute = _execute
89 del _execute
89 del _execute
90
90
91 #-----------------------------------------------------------------------------
92 # Decorator for disabling read-only handlers
93 #-----------------------------------------------------------------------------
94
95 @decorator
96 def not_if_readonly(f, self, *args, **kwargs):
97 if self.settings.get('read_only', False):
98 raise web.HTTPError(403, "Notebook server is read-only")
99 else:
100 return f(self, *args, **kwargs)
101
102 @decorator
103 def authenticate_unless_readonly(f, self, *args, **kwargs):
104 """authenticate this page *unless* readonly view is active.
105
106 In read-only mode, the notebook list and print view should
107 be accessible without authentication.
108 """
109
110 @web.authenticated
111 def auth_f(self, *args, **kwargs):
112 return f(self, *args, **kwargs)
113
114 if self.settings.get('read_only', False):
115 return f(self, *args, **kwargs)
116 else:
117 return auth_f(self, *args, **kwargs)
118
91
119 #-----------------------------------------------------------------------------
92 #-----------------------------------------------------------------------------
120 # Top-level handlers
93 # Top-level handlers
@@ -141,7 +114,7 b' class AuthenticatedHandler(RequestHandler):'
141 if user_id is None:
114 if user_id is None:
142 # prevent extra Invalid cookie sig warnings:
115 # prevent extra Invalid cookie sig warnings:
143 self.clear_login_cookie()
116 self.clear_login_cookie()
144 if not self.read_only and not self.login_available:
117 if not self.login_available:
145 user_id = 'anonymous'
118 user_id = 'anonymous'
146 return user_id
119 return user_id
147
120
@@ -175,13 +148,6 b' class AuthenticatedHandler(RequestHandler):'
175 """
148 """
176 return bool(self.settings.get('password', ''))
149 return bool(self.settings.get('password', ''))
177
150
178 @property
179 def read_only(self):
180 """Is the notebook read-only?
181
182 """
183 return self.settings.get('read_only', False)
184
185
151
186 class IPythonHandler(AuthenticatedHandler):
152 class IPythonHandler(AuthenticatedHandler):
187 """IPython-specific extensions to authenticated handling
153 """IPython-specific extensions to authenticated handling
@@ -269,7 +235,6 b' class IPythonHandler(AuthenticatedHandler):'
269 return dict(
235 return dict(
270 base_project_url=self.base_project_url,
236 base_project_url=self.base_project_url,
271 base_kernel_url=self.base_kernel_url,
237 base_kernel_url=self.base_kernel_url,
272 read_only=self.read_only,
273 logged_in=self.logged_in,
238 logged_in=self.logged_in,
274 login_available=self.login_available,
239 login_available=self.login_available,
275 use_less=self.use_less,
240 use_less=self.use_less,
@@ -278,7 +243,7 b' class IPythonHandler(AuthenticatedHandler):'
278 class AuthenticatedFileHandler(IPythonHandler, web.StaticFileHandler):
243 class AuthenticatedFileHandler(IPythonHandler, web.StaticFileHandler):
279 """static files should only be accessible when logged in"""
244 """static files should only be accessible when logged in"""
280
245
281 @authenticate_unless_readonly
246 @web.authenticated
282 def get(self, path):
247 def get(self, path):
283 return web.StaticFileHandler.get(self, path)
248 return web.StaticFileHandler.get(self, path)
284
249
@@ -20,7 +20,7 b' import os'
20 from tornado import web
20 from tornado import web
21 HTTPError = web.HTTPError
21 HTTPError = web.HTTPError
22
22
23 from ..base.handlers import IPythonHandler, authenticate_unless_readonly
23 from ..base.handlers import IPythonHandler
24 from ..utils import url_path_join
24 from ..utils import url_path_join
25
25
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
@@ -38,7 +38,7 b' class NewHandler(IPythonHandler):'
38
38
39 class NamedNotebookHandler(IPythonHandler):
39 class NamedNotebookHandler(IPythonHandler):
40
40
41 @authenticate_unless_readonly
41 @web.authenticated
42 def get(self, notebook_id):
42 def get(self, notebook_id):
43 nbm = self.notebook_manager
43 nbm = self.notebook_manager
44 if not nbm.notebook_exists(notebook_id):
44 if not nbm.notebook_exists(notebook_id):
@@ -54,7 +54,7 b' class NamedNotebookHandler(IPythonHandler):'
54
54
55 class NotebookRedirectHandler(IPythonHandler):
55 class NotebookRedirectHandler(IPythonHandler):
56
56
57 @authenticate_unless_readonly
57 @web.authenticated
58 def get(self, notebook_name):
58 def get(self, notebook_name):
59 # strip trailing .ipynb:
59 # strip trailing .ipynb:
60 notebook_name = os.path.splitext(notebook_name)[0]
60 notebook_name = os.path.splitext(notebook_name)[0]
@@ -164,7 +164,6 b' class NotebookWebApplication(web.Application):'
164 # authentication
164 # authentication
165 cookie_secret=ipython_app.cookie_secret,
165 cookie_secret=ipython_app.cookie_secret,
166 login_url=url_path_join(base_project_url,'/login'),
166 login_url=url_path_join(base_project_url,'/login'),
167 read_only=ipython_app.read_only,
168 password=ipython_app.password,
167 password=ipython_app.password,
169
168
170 # managers
169 # managers
@@ -227,18 +226,6 b" flags['no-mathjax']=("
227 When disabled, equations etc. will appear as their untransformed TeX source.
226 When disabled, equations etc. will appear as their untransformed TeX source.
228 """
227 """
229 )
228 )
230 flags['read-only'] = (
231 {'NotebookApp' : {'read_only' : True}},
232 """Allow read-only access to notebooks.
233
234 When using a password to protect the notebook server, this flag
235 allows unauthenticated clients to view the notebook list, and
236 individual notebooks, but not edit them, start kernels, or run
237 code.
238
239 If no password is set, the server will be entirely read-only.
240 """
241 )
242
229
243 # Add notebook manager flags
230 # Add notebook manager flags
244 flags.update(boolean_flag('script', 'FileNotebookManager.save_script',
231 flags.update(boolean_flag('script', 'FileNotebookManager.save_script',
@@ -248,7 +235,7 b" flags.update(boolean_flag('script', 'FileNotebookManager.save_script',"
248 # the flags that are specific to the frontend
235 # the flags that are specific to the frontend
249 # these must be scrubbed before being passed to the kernel,
236 # these must be scrubbed before being passed to the kernel,
250 # or it will raise an error on unrecognized flags
237 # or it will raise an error on unrecognized flags
251 notebook_flags = ['no-browser', 'no-mathjax', 'read-only', 'script', 'no-script']
238 notebook_flags = ['no-browser', 'no-mathjax', 'script', 'no-script']
252
239
253 aliases = dict(kernel_aliases)
240 aliases = dict(kernel_aliases)
254
241
@@ -369,10 +356,6 b' class NotebookApp(BaseIPythonApplication):'
369 BROWSER environment variable to override it.
356 BROWSER environment variable to override it.
370 """)
357 """)
371
358
372 read_only = Bool(False, config=True,
373 help="Whether to prevent editing/execution of notebooks."
374 )
375
376 use_less = Bool(False, config=True,
359 use_less = Bool(False, config=True,
377 help="""Wether to use Browser Side less-css parsing
360 help="""Wether to use Browser Side less-css parsing
378 instead of compiled css version in templates that allows
361 instead of compiled css version in templates that allows
@@ -554,7 +537,7 b' class NotebookApp(BaseIPythonApplication):'
554 if ssl_options is None:
537 if ssl_options is None:
555 self.log.critical(warning + " and not using encryption. This "
538 self.log.critical(warning + " and not using encryption. This "
556 "is not recommended.")
539 "is not recommended.")
557 if not self.password and not self.read_only:
540 if not self.password:
558 self.log.critical(warning + " and not using authentication. "
541 self.log.critical(warning + " and not using authentication. "
559 "This is highly insecure and not recommended.")
542 "This is highly insecure and not recommended.")
560 success = None
543 success = None
@@ -22,7 +22,7 b' from zmq.utils import jsonapi'
22
22
23 from IPython.utils.jsonutil import date_default
23 from IPython.utils.jsonutil import date_default
24
24
25 from ...base.handlers import IPythonHandler, authenticate_unless_readonly
25 from ...base.handlers import IPythonHandler
26
26
27 #-----------------------------------------------------------------------------
27 #-----------------------------------------------------------------------------
28 # Notebook web service handlers
28 # Notebook web service handlers
@@ -30,7 +30,7 b' from ...base.handlers import IPythonHandler, authenticate_unless_readonly'
30
30
31 class NotebookRootHandler(IPythonHandler):
31 class NotebookRootHandler(IPythonHandler):
32
32
33 @authenticate_unless_readonly
33 @web.authenticated
34 def get(self):
34 def get(self):
35 nbm = self.notebook_manager
35 nbm = self.notebook_manager
36 km = self.kernel_manager
36 km = self.kernel_manager
@@ -57,7 +57,7 b' class NotebookHandler(IPythonHandler):'
57
57
58 SUPPORTED_METHODS = ('GET', 'PUT', 'DELETE')
58 SUPPORTED_METHODS = ('GET', 'PUT', 'DELETE')
59
59
60 @authenticate_unless_readonly
60 @web.authenticated
61 def get(self, notebook_id):
61 def get(self, notebook_id):
62 nbm = self.notebook_manager
62 nbm = self.notebook_manager
63 format = self.get_argument('format', default='json')
63 format = self.get_argument('format', default='json')
@@ -148,10 +148,6 b' var IPython = (function (IPython) {'
148 */
148 */
149 CodeCell.prototype.handle_codemirror_keyevent = function (editor, event) {
149 CodeCell.prototype.handle_codemirror_keyevent = function (editor, event) {
150
150
151 if (this.read_only){
152 return false;
153 }
154
155 var that = this;
151 var that = this;
156 // whatever key is pressed, first, cancel the tooltip request before
152 // whatever key is pressed, first, cancel the tooltip request before
157 // they are sent, and remove tooltip if any, except for tab again
153 // they are sent, and remove tooltip if any, except for tab again
@@ -43,7 +43,6 b' function (marked) {'
43
43
44 IPython.mathjaxutils.init();
44 IPython.mathjaxutils.init();
45
45
46 IPython.read_only = $('body').data('readOnly') === 'True';
47 $('#ipython-main-app').addClass('border-box-sizing');
46 $('#ipython-main-app').addClass('border-box-sizing');
48 $('div#notebook_panel').addClass('border-box-sizing');
47 $('div#notebook_panel').addClass('border-box-sizing');
49
48
@@ -54,7 +53,7 b' function (marked) {'
54 IPython.pager = new IPython.Pager('div#pager', 'div#pager_splitter');
53 IPython.pager = new IPython.Pager('div#pager', 'div#pager_splitter');
55 IPython.quick_help = new IPython.QuickHelp();
54 IPython.quick_help = new IPython.QuickHelp();
56 IPython.login_widget = new IPython.LoginWidget('span#login_widget',{baseProjectUrl:baseProjectUrl});
55 IPython.login_widget = new IPython.LoginWidget('span#login_widget',{baseProjectUrl:baseProjectUrl});
57 IPython.notebook = new IPython.Notebook('div#notebook',{baseProjectUrl:baseProjectUrl, read_only:IPython.read_only});
56 IPython.notebook = new IPython.Notebook('div#notebook',{baseProjectUrl:baseProjectUrl});
58 IPython.save_widget = new IPython.SaveWidget('span#save_widget');
57 IPython.save_widget = new IPython.SaveWidget('span#save_widget');
59 IPython.menubar = new IPython.MenuBar('#menubar',{baseProjectUrl:baseProjectUrl})
58 IPython.menubar = new IPython.MenuBar('#menubar',{baseProjectUrl:baseProjectUrl})
60 IPython.toolbar = new IPython.MainToolBar('#maintoolbar-container')
59 IPython.toolbar = new IPython.MainToolBar('#maintoolbar-container')
@@ -75,15 +74,6 b' function (marked) {'
75 }
74 }
76 $('#fonttest').remove();
75 $('#fonttest').remove();
77
76
78 if(IPython.read_only){
79 // hide various elements from read-only view
80 $('div#pager').remove();
81 $('div#pager_splitter').remove();
82
83 // set the notebook name field as not modifiable
84 $('#notebook_name').attr('disabled','disabled')
85 }
86
87 IPython.page.show();
77 IPython.page.show();
88
78
89 IPython.layout_manager.do_resize();
79 IPython.layout_manager.do_resize();
@@ -25,7 +25,6 b' var IPython = (function (IPython) {'
25 var Notebook = function (selector, options) {
25 var Notebook = function (selector, options) {
26 var options = options || {};
26 var options = options || {};
27 this._baseProjectUrl = options.baseProjectUrl;
27 this._baseProjectUrl = options.baseProjectUrl;
28 this.read_only = options.read_only || IPython.read_only;
29
28
30 this.element = $(selector);
29 this.element = $(selector);
31 this.element.scroll();
30 this.element.scroll();
@@ -91,7 +90,6 b' var IPython = (function (IPython) {'
91 this.container = $("<div/>").addClass("container").attr("id", "notebook-container");
90 this.container = $("<div/>").addClass("container").attr("id", "notebook-container");
92 var end_space = $('<div/>').addClass('end_space');
91 var end_space = $('<div/>').addClass('end_space');
93 end_space.dblclick(function (e) {
92 end_space.dblclick(function (e) {
94 if (that.read_only) return;
95 var ncells = that.ncells();
93 var ncells = that.ncells();
96 that.insert_cell_below('code',ncells-1);
94 that.insert_cell_below('code',ncells-1);
97 });
95 });
@@ -138,8 +136,6 b' var IPython = (function (IPython) {'
138
136
139
137
140 $(document).keydown(function (event) {
138 $(document).keydown(function (event) {
141 // console.log(event);
142 if (that.read_only) return true;
143
139
144 // Save (CTRL+S) or (AppleKey+S)
140 // Save (CTRL+S) or (AppleKey+S)
145 //metaKey = applekey on mac
141 //metaKey = applekey on mac
@@ -366,7 +362,7 b' var IPython = (function (IPython) {'
366 }
362 }
367 // if we are autosaving, trigger an autosave on nav-away.
363 // if we are autosaving, trigger an autosave on nav-away.
368 // still warn, because if we don't the autosave may fail.
364 // still warn, because if we don't the autosave may fail.
369 if (that.dirty && ! that.read_only) {
365 if (that.dirty) {
370 if ( that.autosave_interval ) {
366 if ( that.autosave_interval ) {
371 that.save_notebook();
367 that.save_notebook();
372 return "Autosave in progress, latest changes may be lost.";
368 return "Autosave in progress, latest changes may be lost.";
@@ -1777,11 +1773,10 b' var IPython = (function (IPython) {'
1777
1773
1778 // Create the kernel after the notebook is completely loaded to prevent
1774 // Create the kernel after the notebook is completely loaded to prevent
1779 // code execution upon loading, which is a security risk.
1775 // code execution upon loading, which is a security risk.
1780 if (! this.read_only) {
1781 this.start_kernel();
1776 this.start_kernel();
1782 // load our checkpoint list
1777 // load our checkpoint list
1783 IPython.notebook.list_checkpoints();
1778 IPython.notebook.list_checkpoints();
1784 }
1779
1785 $([IPython.events]).trigger('notebook_loaded.Notebook');
1780 $([IPython.events]).trigger('notebook_loaded.Notebook');
1786 };
1781 };
1787
1782
@@ -157,7 +157,6 b' var IPython = (function (IPython) {'
157 * @method edit
157 * @method edit
158 */
158 */
159 TextCell.prototype.edit = function () {
159 TextCell.prototype.edit = function () {
160 if ( this.read_only ) return;
161 if (this.rendered === true) {
160 if (this.rendered === true) {
162 var text_cell = this.element;
161 var text_cell = this.element;
163 var output = text_cell.find("div.text_cell_render");
162 var output = text_cell.find("div.text_cell_render");
@@ -17,7 +17,6 b' $(document).ready(function () {'
17 window.open($('body').data('baseProjectUrl')+'new');
17 window.open($('body').data('baseProjectUrl')+'new');
18 });
18 });
19
19
20 IPython.read_only = $('body').data('readOnly') === 'True';
21 IPython.notebook_list = new IPython.NotebookList('#notebook_list');
20 IPython.notebook_list = new IPython.NotebookList('#notebook_list');
22 IPython.cluster_list = new IPython.ClusterList('#cluster_list');
21 IPython.cluster_list = new IPython.ClusterList('#cluster_list');
23 IPython.login_widget = new IPython.LoginWidget('#login_widget');
22 IPython.login_widget = new IPython.LoginWidget('#login_widget');
@@ -34,9 +34,6 b' var IPython = (function (IPython) {'
34
34
35
35
36 NotebookList.prototype.bind_events = function () {
36 NotebookList.prototype.bind_events = function () {
37 if (IPython.read_only){
38 return;
39 }
40 var that = this;
37 var that = this;
41 $('#refresh_notebook_list').click(function () {
38 $('#refresh_notebook_list').click(function () {
42 that.load_list();
39 that.load_list();
@@ -129,14 +126,12 b' var IPython = (function (IPython) {'
129 var kernel = data[i].kernel_id;
126 var kernel = data[i].kernel_id;
130 var item = this.new_notebook_item(i);
127 var item = this.new_notebook_item(i);
131 this.add_link(notebook_id, nbname, item);
128 this.add_link(notebook_id, nbname, item);
132 if (!IPython.read_only){
133 // hide delete buttons when readonly
129 // hide delete buttons when readonly
134 if(kernel == null){
130 if(kernel == null){
135 this.add_delete_button(item);
131 this.add_delete_button(item);
136 } else {
132 } else {
137 this.add_shutdown_button(item,kernel);
133 this.add_shutdown_button(item,kernel);
138 }
134 }
139 }
140 };
135 };
141 };
136 };
142
137
@@ -20,7 +20,7 b''
20 {% endfor %}
20 {% endfor %}
21 {% endif %}
21 {% endif %}
22
22
23 {% if read_only or not login_available %}
23 {% if not login_available %}
24 Proceed to the <a href="{{base_project_url}}">dashboard</a>.
24 Proceed to the <a href="{{base_project_url}}">dashboard</a>.
25 {% else %}
25 {% else %}
26 Proceed to the <a href="{{base_project_url}}login">login page</a>.
26 Proceed to the <a href="{{base_project_url}}login">login page</a>.
@@ -24,7 +24,6 b' window.mathjax_url = "{{mathjax_url}}";'
24 data-project={{project}}
24 data-project={{project}}
25 data-base-project-url={{base_project_url}}
25 data-base-project-url={{base_project_url}}
26 data-base-kernel-url={{base_kernel_url}}
26 data-base-kernel-url={{base_kernel_url}}
27 data-read-only={{read_only and not logged_in}}
28 data-notebook-id={{notebook_id}}
27 data-notebook-id={{notebook_id}}
29 class="notebook_app"
28 class="notebook_app"
30
29
@@ -13,7 +13,6 b''
13 data-project={{project}}
13 data-project={{project}}
14 data-base-project-url={{base_project_url}}
14 data-base-project-url={{base_project_url}}
15 data-base-kernel-url={{base_kernel_url}}
15 data-base-kernel-url={{base_kernel_url}}
16 data-read-only={{read_only}}
17
16
18 {% endblock %}
17 {% endblock %}
19
18
@@ -30,7 +29,7 b' data-read-only={{read_only}}'
30
29
31 <div class="tab-content">
30 <div class="tab-content">
32 <div id="notebooks" class="tab-pane active">
31 <div id="notebooks" class="tab-pane active">
33 {% if logged_in or not read_only %}
32 {% if logged_in %}
34 <div id="notebook_toolbar">
33 <div id="notebook_toolbar">
35 <form id='alternate_upload' class='alternate_upload' >
34 <form id='alternate_upload' class='alternate_upload' >
36 <span id="drag_info" style="position:absolute" >
35 <span id="drag_info" style="position:absolute" >
@@ -16,7 +16,8 b' Authors:'
16 # Imports
16 # Imports
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 from ..base.handlers import IPythonHandler, authenticate_unless_readonly
19 from tornado import web
20 from ..base.handlers import IPythonHandler
20
21
21 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
22 # Handlers
23 # Handlers
@@ -25,7 +26,7 b' from ..base.handlers import IPythonHandler, authenticate_unless_readonly'
25
26
26 class ProjectDashboardHandler(IPythonHandler):
27 class ProjectDashboardHandler(IPythonHandler):
27
28
28 @authenticate_unless_readonly
29 @web.authenticated
29 def get(self):
30 def get(self):
30 self.write(self.render_template('tree.html',
31 self.write(self.render_template('tree.html',
31 project=self.project,
32 project=self.project,
General Comments 0
You need to be logged in to leave comments. Login now