|
1 | 1 | """
|
2 | 2 | Password generation for the Notebook.
|
3 | 3 | """
|
| 4 | + |
| 5 | +from contextlib import contextmanager |
4 | 6 | import getpass
|
5 | 7 | import hashlib
|
| 8 | +import io |
| 9 | +import json |
| 10 | +import os |
6 | 11 | import random
|
| 12 | +import traceback |
| 13 | +import warnings |
7 | 14 |
|
8 |
| -from ipython_genutils.py3compat import cast_bytes, str_to_bytes |
| 15 | +from ipython_genutils.py3compat import cast_bytes, str_to_bytes, cast_unicode |
| 16 | +from traitlets.config import Config, ConfigFileNotFound, JSONFileConfigLoader |
| 17 | +from jupyter_core.paths import jupyter_config_dir |
9 | 18 |
|
10 | 19 | # Length of the salt in nr of hex chars, which implies salt_len * 4
|
11 | 20 | # bits of randomness.
|
@@ -99,3 +108,41 @@ def passwd_check(hashed_passphrase, passphrase):
|
99 | 108 | h.update(cast_bytes(passphrase, 'utf-8') + cast_bytes(salt, 'ascii'))
|
100 | 109 |
|
101 | 110 | return h.hexdigest() == pw_digest
|
| 111 | + |
| 112 | +@contextmanager |
| 113 | +def persist_config(config_file=None, mode=0o600): |
| 114 | + """Context manager that can be used to modify a config object |
| 115 | +
|
| 116 | + On exit of the context manager, the config will be written back to disk, |
| 117 | + by default with user-only (600) permissions. |
| 118 | + """ |
| 119 | + |
| 120 | + if config_file is None: |
| 121 | + config_file = os.path.join(jupyter_config_dir(), 'jupyter_notebook_config.json') |
| 122 | + |
| 123 | + loader = JSONFileConfigLoader(os.path.basename(config_file), os.path.dirname(config_file)) |
| 124 | + try: |
| 125 | + config = loader.load_config() |
| 126 | + except ConfigFileNotFound: |
| 127 | + config = Config() |
| 128 | + |
| 129 | + yield config |
| 130 | + |
| 131 | + with io.open(config_file, 'w', encoding='utf8') as f: |
| 132 | + f.write(cast_unicode(json.dumps(config, indent=2))) |
| 133 | + |
| 134 | + try: |
| 135 | + os.chmod(config_file, mode) |
| 136 | + except Exception as e: |
| 137 | + tb = traceback.format_exc() |
| 138 | + warnings.warn("Failed to set permissions on %s:\n%s" % (config_file, tb), |
| 139 | + RuntimeWarning) |
| 140 | + |
| 141 | + |
| 142 | +def set_password(password=None, config_file=None): |
| 143 | + """Ask user for password, store it in notebook json configuration file""" |
| 144 | + |
| 145 | + hashed_password = passwd(password) |
| 146 | + |
| 147 | + with persist_config(config_file) as config: |
| 148 | + config.NotebookApp.password = hashed_password |
0 commit comments