diff --git a/notebook/services/contents/handlers.py b/notebook/services/contents/handlers.py index 2b9cacd1a..a063aec40 100644 --- a/notebook/services/contents/handlers.py +++ b/notebook/services/contents/handlers.py @@ -307,6 +307,17 @@ class NotebooksRedirectHandler(IPythonHandler): put = patch = post = delete = get +class TrustNotebooksHandler(IPythonHandler): + """ Handles trust/signing of notebooks """ + + @json_errors + @web.authenticated + @gen.coroutine + def post(self,path=''): + cm = self.contents_manager + yield gen.maybe_future(cm.trust_notebook(path)) + self.set_status(201) + self.finish() #----------------------------------------------------------------------------- # URL to handler mappings #----------------------------------------------------------------------------- @@ -318,6 +329,7 @@ default_handlers = [ (r"/api/contents%s/checkpoints" % path_regex, CheckpointsHandler), (r"/api/contents%s/checkpoints/%s" % (path_regex, _checkpoint_id_regex), ModifyCheckpointsHandler), + (r"/api/contents%s/trust" % path_regex, TrustNotebooksHandler), (r"/api/contents%s" % path_regex, ContentsHandler), (r"/api/notebooks/?(.*)", NotebooksRedirectHandler), ] diff --git a/notebook/services/contents/manager.py b/notebook/services/contents/manager.py index 09a00e911..19e697ede 100644 --- a/notebook/services/contents/manager.py +++ b/notebook/services/contents/manager.py @@ -426,7 +426,7 @@ class ContentsManager(LoggingConfigurable): nb = model['content'] self.log.warning("Trusting notebook %s", path) self.notary.mark_cells(nb, True) - self.save(model, path) + self.check_and_sign(nb, path) def check_and_sign(self, nb, path=''): """Check for trusted cells, and sign the notebook. @@ -443,7 +443,7 @@ class ContentsManager(LoggingConfigurable): if self.notary.check_cells(nb): self.notary.sign(nb) else: - self.log.warning("Saving untrusted notebook %s", path) + self.log.warning("Notebook %s is not trusted", path) def mark_trusted_cells(self, nb, path=''): """Mark cells as trusted if the notebook signature matches. diff --git a/notebook/static/notebook/js/notebook.js b/notebook/static/notebook/js/notebook.js index 6a3a2d966..468f120d8 100644 --- a/notebook/static/notebook/js/notebook.js +++ b/notebook/static/notebook/js/notebook.js @@ -2876,10 +2876,24 @@ define([ cell.output_area.trusted = true; } } - nb.events.on('notebook_saved.Notebook', function () { - window.location.reload(); + // If its write only and dirty, save before + // trusting + var pr; + if(nb.writable && nb.dirty) { + pr = nb.save_notebook(); + } + else { + pr = Promise.resolve(); + } + return pr.then(function() { + nb.contents.trust(nb.notebook_path) + .then(function(res) { + nb.events.trigger("trust_changed.Notebook", true); + window.location.reload(); + }, function(err) { + console.log(err); + }); }); - nb.save_notebook(); } } } diff --git a/notebook/static/services/contents.js b/notebook/static/services/contents.js index cffc9d236..867ddd470 100644 --- a/notebook/static/services/contents.js +++ b/notebook/static/services/contents.js @@ -161,6 +161,16 @@ define(function(require) { return utils.promising_ajax(url, settings); }; + Contents.prototype.trust = function(path) { + var settings = { + processData : false, + type : "POST", + contentType: 'application/json', + }; + var url = this.api_url(path, "trust"); + return utils.promising_ajax(url, settings); + } + Contents.prototype.save = function(path, model) { /** * We do the call with settings so we can set cache to false.