Show More
@@ -214,7 +214,7 b' class FileNotebookManager(NotebookManager):' | |||
|
214 | 214 | except Exception as e: |
|
215 | 215 | raise web.HTTPError(400, u"Unreadable Notebook: %s %s" % (os_path, e)) |
|
216 | 216 | model['content'] = nb |
|
217 | sign.mark_trusted_cells(nb, self.secret) | |
|
217 | sign.mark_trusted_cells(nb, self.notary.secret) | |
|
218 | 218 | return model |
|
219 | 219 | |
|
220 | 220 | def save_notebook_model(self, model, name='', path=''): |
@@ -239,7 +239,7 b' class FileNotebookManager(NotebookManager):' | |||
|
239 | 239 | nb = current.to_notebook_json(model['content']) |
|
240 | 240 | |
|
241 | 241 | if sign.check_trusted_cells(nb): |
|
242 | sign.trust_notebook(nb, self.secret, self.signature_scheme) | |
|
242 | sign.trust_notebook(nb, self.notary.secret, self.notary.signature_scheme) | |
|
243 | 243 | |
|
244 | 244 | if 'name' in nb['metadata']: |
|
245 | 245 | nb['metadata']['name'] = u'' |
@@ -17,16 +17,12 b' Authors:' | |||
|
17 | 17 | # Imports |
|
18 | 18 | #----------------------------------------------------------------------------- |
|
19 | 19 | |
|
20 | import base64 | |
|
21 | import hashlib | |
|
22 | import io | |
|
23 | 20 | import os |
|
24 | 21 | |
|
25 | 22 | from IPython.config.configurable import LoggingConfigurable |
|
26 | from IPython.core.application import BaseIPythonApplication | |
|
27 | from IPython.nbformat import current | |
|
23 | from IPython.nbformat import current, sign | |
|
28 | 24 | from IPython.utils import py3compat |
|
29 |
from IPython.utils.traitlets import Unicode, TraitError |
|
|
25 | from IPython.utils.traitlets import Instance, Unicode, TraitError | |
|
30 | 26 | |
|
31 | 27 | #----------------------------------------------------------------------------- |
|
32 | 28 | # Classes |
@@ -46,34 +42,9 b' class NotebookManager(LoggingConfigurable):' | |||
|
46 | 42 | |
|
47 | 43 | filename_ext = Unicode(u'.ipynb') |
|
48 | 44 | |
|
49 | signature_scheme = Enum(hashlib.algorithms, default_value='sha256', config=True, | |
|
50 | help="""The signature scheme used to sign notebooks.""" | |
|
51 | ) | |
|
52 | ||
|
53 | secret = Bytes(config=True, | |
|
54 | help="""The secret key with which notebooks are signed.""" | |
|
55 | ) | |
|
56 | def _secret_default(self): | |
|
57 | # note : this assumes an Application is running | |
|
58 | profile_dir = BaseIPythonApplication.instance().profile_dir | |
|
59 | secret_file = os.path.join(profile_dir.security_dir, 'notebook_secret') | |
|
60 | if os.path.exists(secret_file): | |
|
61 | with io.open(secret_file, 'rb') as f: | |
|
62 | return f.read() | |
|
63 | else: | |
|
64 | secret = base64.encodestring(os.urandom(1024)) | |
|
65 | self.log.info("Writing output secret to %s", secret_file) | |
|
66 | with io.open(secret_file, 'wb') as f: | |
|
67 | f.write(secret) | |
|
68 | try: | |
|
69 | os.chmod(secret_file, 0o600) | |
|
70 | except OSError: | |
|
71 | self.log.warn( | |
|
72 | "Could not set permissions on %s", | |
|
73 | secret_file | |
|
74 | ) | |
|
75 | return secret | |
|
76 | ||
|
45 | notary = Instance(sign.NotebookNotary) | |
|
46 | def _notary_default(self): | |
|
47 | return sign.NotebookNotary(parent=self) | |
|
77 | 48 | |
|
78 | 49 | def path_exists(self, path): |
|
79 | 50 | """Does the API-style path (directory) actually exist? |
@@ -10,11 +10,16 b'' | |||
|
10 | 10 | # Imports |
|
11 | 11 | #----------------------------------------------------------------------------- |
|
12 | 12 | |
|
13 | import base64 | |
|
13 | 14 | from contextlib import contextmanager |
|
14 | 15 | import hashlib |
|
15 | 16 | from hmac import HMAC |
|
17 | import io | |
|
18 | import os | |
|
16 | 19 | |
|
17 | 20 | from IPython.utils.py3compat import string_types, unicode_type, cast_bytes |
|
21 | from IPython.config import LoggingConfigurable | |
|
22 | from IPython.utils.traitlets import Instance, Bytes, Enum | |
|
18 | 23 | |
|
19 | 24 | #----------------------------------------------------------------------------- |
|
20 | 25 | # Code |
@@ -138,4 +143,51 b' def check_trusted_cells(nb):' | |||
|
138 | 143 | return False |
|
139 | 144 | return True |
|
140 | 145 | |
|
141 | No newline at end of file | |
|
146 | ||
|
147 | class NotebookNotary(LoggingConfigurable): | |
|
148 | """A class for configuring notebook signatures | |
|
149 | ||
|
150 | It stores the secret with which to sign notebooks, | |
|
151 | and the hashing scheme to use for notebook signatures. | |
|
152 | """ | |
|
153 | ||
|
154 | signature_scheme = Enum(hashlib.algorithms, default_value='sha256', config=True, | |
|
155 | help="""The signature scheme used to sign notebooks.""" | |
|
156 | ) | |
|
157 | ||
|
158 | profile_dir = Instance("IPython.core.profiledir.ProfileDir") | |
|
159 | def _profile_dir_default(self): | |
|
160 | from IPython.core.application import BaseIPythonApplication | |
|
161 | if BaseIPythonApplication.initialized(): | |
|
162 | app = BaseIPythonApplication.instance() | |
|
163 | else: | |
|
164 | # create an app, without the global instance | |
|
165 | app = BaseIPythonApplication() | |
|
166 | app.initialize() | |
|
167 | return app.profile_dir | |
|
168 | ||
|
169 | secret = Bytes(config=True, | |
|
170 | help="""The secret key with which notebooks are signed.""" | |
|
171 | ) | |
|
172 | def _secret_default(self): | |
|
173 | # note : this assumes an Application is running | |
|
174 | profile_dir = self.profile_dir | |
|
175 | secret_file = os.path.join(profile_dir.security_dir, 'notebook_secret') | |
|
176 | if os.path.exists(secret_file): | |
|
177 | with io.open(secret_file, 'rb') as f: | |
|
178 | return f.read() | |
|
179 | else: | |
|
180 | secret = base64.encodestring(os.urandom(1024)) | |
|
181 | self.log.info("Writing output secret to %s", secret_file) | |
|
182 | with io.open(secret_file, 'wb') as f: | |
|
183 | f.write(secret) | |
|
184 | try: | |
|
185 | os.chmod(secret_file, 0o600) | |
|
186 | except OSError: | |
|
187 | self.log.warn( | |
|
188 | "Could not set permissions on %s", | |
|
189 | secret_file | |
|
190 | ) | |
|
191 | return secret | |
|
192 | ||
|
193 | No newline at end of file |
General Comments 0
You need to be logged in to leave comments.
Login now