diff --git a/IPython/frontend/html/notebook/handlers.py b/IPython/frontend/html/notebook/handlers.py index 7822118..ca92d59 100644 --- a/IPython/frontend/html/notebook/handlers.py +++ b/IPython/frontend/html/notebook/handlers.py @@ -116,7 +116,14 @@ def authenticate_unless_readonly(f, self, *args, **kwargs): # Top-level handlers #----------------------------------------------------------------------------- -class AuthenticatedHandler(web.RequestHandler): +class RequestHandler(web.RequestHandler): + """RequestHandler with default variable setting.""" + + def render(*args, **kwargs): + kwargs.setdefault('message', '') + return web.RequestHandler.render(*args, **kwargs) + +class AuthenticatedHandler(RequestHandler): """A RequestHandler with an authenticated user.""" def get_current_user(self): @@ -167,7 +174,7 @@ class ProjectDashboardHandler(AuthenticatedHandler): class LoginHandler(AuthenticatedHandler): - def _render(self, message=''): + def _render(self, message=None): self.render('login.html', next=self.get_argument('next', default='/'), read_only=self.read_only, @@ -175,7 +182,10 @@ class LoginHandler(AuthenticatedHandler): ) def get(self): - self._render() + if self.current_user: + self.redirect(self.get_argument('next', default='/')) + else: + self._render() def post(self): pwd = self.get_argument('password', default=u'') @@ -183,12 +193,19 @@ class LoginHandler(AuthenticatedHandler): if passwd_check(self.application.password, pwd): self.set_secure_cookie('username', str(uuid.uuid4())) else: - self._render(message='Invalid password') + self._render(message={'error': 'Invalid password'}) return self.redirect(self.get_argument('next', default='/')) +class LogoutHandler(AuthenticatedHandler): + + def get(self): + self.clear_cookie('username') + self.render('logout.html', message={'info': 'Successfully logged out.'}) + + class NewHandler(AuthenticatedHandler): @web.authenticated diff --git a/IPython/frontend/html/notebook/notebookapp.py b/IPython/frontend/html/notebook/notebookapp.py index e507607..bdef5ad 100644 --- a/IPython/frontend/html/notebook/notebookapp.py +++ b/IPython/frontend/html/notebook/notebookapp.py @@ -40,7 +40,7 @@ from tornado import web # Our own libraries from .kernelmanager import MappingKernelManager -from .handlers import (LoginHandler, +from .handlers import (LoginHandler, LogoutHandler, ProjectDashboardHandler, NewHandler, NamedNotebookHandler, MainKernelHandler, KernelHandler, KernelActionHandler, IOPubHandler, ShellHandler, NotebookRootHandler, NotebookHandler, RSTHandler @@ -87,6 +87,7 @@ class NotebookWebApplication(web.Application): handlers = [ (r"/", ProjectDashboardHandler), (r"/login", LoginHandler), + (r"/logout", LogoutHandler), (r"/new", NewHandler), (r"/%s" % _notebook_id_regex, NamedNotebookHandler), (r"/kernels", MainKernelHandler), diff --git a/IPython/frontend/html/notebook/static/css/layout.css b/IPython/frontend/html/notebook/static/css/layout.css index b9e0b08..d8bec47 100644 --- a/IPython/frontend/html/notebook/static/css/layout.css +++ b/IPython/frontend/html/notebook/static/css/layout.css @@ -102,12 +102,27 @@ box-pack: center; } -#message { - border: 1px solid red; - background-color: #FFD3D1; +.message { + border-width: 1px; + border-style: solid; text-align: center; padding: 0.5em; - margin: 0.5em; + margin: 0.5em 0; +} + +.message.error { + background-color: #FFD3D1; + border-color: red; +} + +.message.warning { + background-color: #FFD09E; + border-color: orange; +} + +.message.info { + background-color: #CBFFBA; + border-color: green; } #content_panel { diff --git a/IPython/frontend/html/notebook/static/js/loginwidget.js b/IPython/frontend/html/notebook/static/js/loginwidget.js index 17fcc58..6ba8075 100644 --- a/IPython/frontend/html/notebook/static/js/loginwidget.js +++ b/IPython/frontend/html/notebook/static/js/loginwidget.js @@ -21,12 +21,12 @@ var IPython = (function (IPython) { }; LoginWidget.prototype.style = function () { - this.element.find('button#login').button(); + this.element.find('button#logout').button(); }; LoginWidget.prototype.bind_events = function () { var that = this; - this.element.find("button#login").click(function () { - window.location = "/login?next="+location.pathname; + this.element.find("button#logout").click(function () { + window.location = "/logout"; }); }; diff --git a/IPython/frontend/html/notebook/templates/layout.html b/IPython/frontend/html/notebook/templates/layout.html new file mode 100644 index 0000000..1f24a40 --- /dev/null +++ b/IPython/frontend/html/notebook/templates/layout.html @@ -0,0 +1,77 @@ + + + +
+ + +