From 5495366b9164b11cb60630ac3c01f36f42fb8345 Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Sat, 11 Nov 2017 09:32:54 -0800 Subject: [PATCH] Add option disabled changing password at login. Document the changing of password. --- docs/source/public_server.rst | 42 +++++++++++++++++++++++++++++------ notebook/auth/login.py | 2 +- notebook/base/handlers.py | 1 + notebook/notebookapp.py | 13 +++++++++++ notebook/templates/login.html | 34 +++++++++++++++------------- 5 files changed, 68 insertions(+), 24 deletions(-) diff --git a/docs/source/public_server.rst b/docs/source/public_server.rst index e22e43cb613..004ca142181 100644 --- a/docs/source/public_server.rst +++ b/docs/source/public_server.rst @@ -63,15 +63,28 @@ using the following command:: $ jupyter notebook --generate-config -.. _hashed-pw: -Preparing a hashed password -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Automatic Password setup +~~~~~~~~~~~~~~~~~~~~~~~~ + +As of notebook 5.3, the first time you log-in using a token, the notebook server +should give you the opportunity to setup a password from the user interface. + +You will be presented with a form asking for the current _token_, as well as +your _new_ _password_ ; enter both and click on ``Login and setup new password``. + +Next time you need to log in you'll be able to use the new password instead of +the login token, otherwise follow the procedure to set a password from the +command line. + +The ability to change the password at first login time may be disabled by +integrations by setting the ``--NotebookApp.allow_password_change=True`` + -As of notebook version 5.0, you can enter and store a password for your -notebook server with a single command. -:command:`jupyter notebook password` will prompt you for your password -and record the hashed password in your :file:`jupyter_notebook_config.json`. +Starting at notebook version 5.0, you can enter and store a password for your +notebook server with a single command. :command:`jupyter notebook password` will +prompt you for your password and record the hashed password in your +:file:`jupyter_notebook_config.json`. .. code-block:: bash @@ -80,6 +93,15 @@ and record the hashed password in your :file:`jupyter_notebook_config.json`. Verify password: **** [NotebookPasswordApp] Wrote hashed password to /Users/you/.jupyter/jupyter_notebook_config.json +This can be used to reset a lost password; or if you believe your credentials +have been leaked and desire to change your password. Changing your password will +invalidate all logged-in sessions after a server restart. + +.. _hashed-pw: + +Preparing a hashed password +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + You can prepare a hashed password manually, using the function :func:`notebook.auth.security.passwd`: @@ -109,6 +131,12 @@ directory, ``~/.jupyter``, e.g.:: c.NotebookApp.password = u'sha1:67c9e60bb8b6:9ffede0825894254b2e042ea597d771089e11aed' +Automatic password setup will store the hash in ``jupyter_notebook_config.json`` +while this method store in in ``jupyter_notebook_config.py``. The ``.json`` +configuration options take precedence over the ``.py`` one, thus the manual +password may not take effect if the Json file as a password set. + + Using SSL for encrypted communication ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When using a password, it is a good idea to also use SSL with a web diff --git a/notebook/auth/login.py b/notebook/auth/login.py index 2478fc96a65..9404b8947cf 100644 --- a/notebook/auth/login.py +++ b/notebook/auth/login.py @@ -82,7 +82,7 @@ def post(self): self.set_login_cookie(self, uuid.uuid4().hex) elif self.token and self.token == typed_password: self.set_login_cookie(self, uuid.uuid4().hex) - if self.new_password: + if self.new_password and self.settings.get('allow_password_change'): config_dir = self.settings.get('config_dir') config_file = os.path.join(config_dir, 'jupyter_notebook_config.json') set_password(new_password, config_file=config_file) diff --git a/notebook/base/handlers.py b/notebook/base/handlers.py index 798456caecc..c57082fd49a 100755 --- a/notebook/base/handlers.py +++ b/notebook/base/handlers.py @@ -400,6 +400,7 @@ def template_namespace(self): default_url=self.default_url, ws_url=self.ws_url, logged_in=self.logged_in, + allow_password_change=self.settings.get('allow_password_change'), login_available=self.login_available, token_available=bool(self.token or self.one_time_token), static_url=self.static_url, diff --git a/notebook/notebookapp.py b/notebook/notebookapp.py index 1fff75e5140..83c22db62f9 100755 --- a/notebook/notebookapp.py +++ b/notebook/notebookapp.py @@ -267,6 +267,7 @@ def init_settings(self, jupyter_app, kernel_manager, contents_manager, mathjax_config=jupyter_app.mathjax_config, config=jupyter_app.config, config_dir=jupyter_app.config_dir, + allow_password_change=jupyter_app.allow_password_change, server_root_dir=root_dir, jinja2_env=env, terminals_available=False, # Set later if terminals are available @@ -750,6 +751,18 @@ def _token_changed(self, change): """ ) + allow_password_change = Bool(True, config=True, + help="""Allow password to be changed at login for the notebook server. + + While login-in with a token, the notebook server UI will give the opportunity to + the user to enter a new password at the same time that will replace + the token login mechanism. + + This can be set to false to prevent changing password from the UI/API. + """ + ) + + disable_check_xsrf = Bool(False, config=True, help="""Disable cross-site-request-forgery protection diff --git a/notebook/templates/login.html b/notebook/templates/login.html index c30af5acf08..08e5bd1db03 100644 --- a/notebook/templates/login.html +++ b/notebook/templates/login.html @@ -85,22 +85,24 @@

Cookies are required for authenticated access to notebooks.

-

{% trans %}Setup a Password{% endtrans %}

-

You can setup a password by entering your token and a new password - on the fields below:

-
- {{ xsrf_form_html() | safe }} -
- -
-
- -
-
- -
-
+ {% if allow_password_change %} +

{% trans %}Setup a Password{% endtrans %}

+

You can also setup a password by entering your token and a new password + on the fields below:

+
+ {{ xsrf_form_html() | safe }} +
+ +
+
+ +
+
+ +
+
+ {% endif %} {% endblock token_message %}