##// END OF EJS Templates
Merge branch csp into 3.x...
Min RK -
r21487:7222bd53 merge
parent child Browse files
Show More
@@ -42,16 +42,24 b' sys_info = json.dumps(get_sys_info())'
42 42
43 43 class AuthenticatedHandler(web.RequestHandler):
44 44 """A RequestHandler with an authenticated user."""
45
46 @property
47 def content_security_policy(self):
48 """The default Content-Security-Policy header
49
50 Can be overridden by defining Content-Security-Policy in settings['headers']
51 """
52 return '; '.join([
53 "frame-ancestors 'self'",
54 # Make sure the report-uri is relative to the base_url
55 "report-uri " + url_path_join(self.base_url, csp_report_uri),
56 ])
45 57
46 58 def set_default_headers(self):
47 59 headers = self.settings.get('headers', {})
48 60
49 61 if "Content-Security-Policy" not in headers:
50 headers["Content-Security-Policy"] = (
51 "frame-ancestors 'self'; "
52 # Make sure the report-uri is relative to the base_url
53 "report-uri " + url_path_join(self.base_url, csp_report_uri) + ";"
54 )
62 headers["Content-Security-Policy"] = self.content_security_policy
55 63
56 64 # Allow for overriding headers
57 65 for header_name,value in headers.items() :
@@ -307,7 +315,22 b' class IPythonHandler(AuthenticatedHandler):'
307 315 html = self.render_template('error.html', **ns)
308 316
309 317 self.write(html)
310
318
319
320 class APIHandler(IPythonHandler):
321 """Base class for API handlers"""
322
323 @property
324 def content_security_policy(self):
325 csp = '; '.join([
326 super(APIHandler, self).content_security_policy,
327 "default-src 'none'",
328 ])
329 return csp
330
331 def finish(self, *args, **kwargs):
332 self.set_header('Content-Type', 'application/json')
333 return super(APIHandler, self).finish(*args, **kwargs)
311 334
312 335
313 336 class Template404(IPythonHandler):
@@ -370,6 +393,7 b' def json_errors(method):'
370 393 try:
371 394 result = yield gen.maybe_future(method(self, *args, **kwargs))
372 395 except web.HTTPError as e:
396 self.set_header('Content-Type', 'application/json')
373 397 status = e.status_code
374 398 message = e.log_message
375 399 self.log.warn(message)
@@ -377,6 +401,7 b' def json_errors(method):'
377 401 reply = dict(message=message, reason=e.reason)
378 402 self.finish(json.dumps(reply))
379 403 except Exception:
404 self.set_header('Content-Type', 'application/json')
380 405 self.log.error("Unhandled error in API request", exc_info=True)
381 406 status = 500
382 407 message = "Unknown server error"
@@ -399,7 +424,7 b' def json_errors(method):'
399 424 # to minimize subclass changes:
400 425 HTTPError = web.HTTPError
401 426
402 class FileFindHandler(web.StaticFileHandler):
427 class FileFindHandler(IPythonHandler, web.StaticFileHandler):
403 428 """subclass of StaticFileHandler for serving files from a search path"""
404 429
405 430 # cache search results, don't search for files more than once
@@ -453,7 +478,7 b' class FileFindHandler(web.StaticFileHandler):'
453 478 return super(FileFindHandler, self).validate_absolute_path(root, absolute_path)
454 479
455 480
456 class ApiVersionHandler(IPythonHandler):
481 class APIVersionHandler(APIHandler):
457 482
458 483 @json_errors
459 484 def get(self):
@@ -524,5 +549,5 b' path_regex = r"(?P<path>(?:(?:/[^/]+)+|/?))"'
524 549
525 550 default_handlers = [
526 551 (r".*/", TrailingSlashHandler),
527 (r"api", ApiVersionHandler)
552 (r"api", APIVersionHandler)
528 553 ]
@@ -7,28 +7,28 b' import json'
7 7
8 8 from tornado import web
9 9
10 from ...base.handlers import IPythonHandler
10 from ...base.handlers import APIHandler
11 11
12 12 #-----------------------------------------------------------------------------
13 13 # Cluster handlers
14 14 #-----------------------------------------------------------------------------
15 15
16 16
17 class MainClusterHandler(IPythonHandler):
17 class MainClusterHandler(APIHandler):
18 18
19 19 @web.authenticated
20 20 def get(self):
21 21 self.finish(json.dumps(self.cluster_manager.list_profiles()))
22 22
23 23
24 class ClusterProfileHandler(IPythonHandler):
24 class ClusterProfileHandler(APIHandler):
25 25
26 26 @web.authenticated
27 27 def get(self, profile):
28 28 self.finish(json.dumps(self.cluster_manager.profile_info(profile)))
29 29
30 30
31 class ClusterActionHandler(IPythonHandler):
31 class ClusterActionHandler(APIHandler):
32 32
33 33 @web.authenticated
34 34 def post(self, profile, action):
@@ -9,9 +9,9 b' import errno'
9 9 from tornado import web
10 10
11 11 from IPython.utils.py3compat import PY3
12 from ...base.handlers import IPythonHandler, json_errors
12 from ...base.handlers import APIHandler, json_errors
13 13
14 class ConfigHandler(IPythonHandler):
14 class ConfigHandler(APIHandler):
15 15 SUPPORTED_METHODS = ('GET', 'PUT', 'PATCH')
16 16
17 17 @web.authenticated
@@ -11,7 +11,7 b' from IPython.html.utils import url_path_join, url_escape'
11 11 from IPython.utils.jsonutil import date_default
12 12
13 13 from IPython.html.base.handlers import (
14 IPythonHandler, json_errors, path_regex,
14 IPythonHandler, APIHandler, json_errors, path_regex,
15 15 )
16 16
17 17
@@ -75,7 +75,7 b' def validate_model(model, expect_content):'
75 75 )
76 76
77 77
78 class ContentsHandler(IPythonHandler):
78 class ContentsHandler(APIHandler):
79 79
80 80 SUPPORTED_METHODS = (u'GET', u'PUT', u'PATCH', u'POST', u'DELETE')
81 81
@@ -257,7 +257,7 b' class ContentsHandler(IPythonHandler):'
257 257 self.finish()
258 258
259 259
260 class CheckpointsHandler(IPythonHandler):
260 class CheckpointsHandler(APIHandler):
261 261
262 262 SUPPORTED_METHODS = ('GET', 'POST')
263 263
@@ -286,7 +286,7 b' class CheckpointsHandler(IPythonHandler):'
286 286 self.finish(data)
287 287
288 288
289 class ModifyCheckpointsHandler(IPythonHandler):
289 class ModifyCheckpointsHandler(APIHandler):
290 290
291 291 SUPPORTED_METHODS = ('POST', 'DELETE')
292 292
@@ -13,12 +13,12 b' from IPython.utils.jsonutil import date_default'
13 13 from IPython.utils.py3compat import cast_unicode
14 14 from IPython.html.utils import url_path_join, url_escape
15 15
16 from ...base.handlers import IPythonHandler, json_errors
16 from ...base.handlers import IPythonHandler, APIHandler, json_errors
17 17 from ...base.zmqhandlers import AuthenticatedZMQStreamHandler, deserialize_binary_message
18 18
19 19 from IPython.core.release import kernel_protocol_version
20 20
21 class MainKernelHandler(IPythonHandler):
21 class MainKernelHandler(APIHandler):
22 22
23 23 @web.authenticated
24 24 @json_errors
@@ -46,7 +46,7 b' class MainKernelHandler(IPythonHandler):'
46 46 self.finish(json.dumps(model))
47 47
48 48
49 class KernelHandler(IPythonHandler):
49 class KernelHandler(APIHandler):
50 50
51 51 SUPPORTED_METHODS = ('DELETE', 'GET')
52 52
@@ -67,7 +67,7 b' class KernelHandler(IPythonHandler):'
67 67 self.finish()
68 68
69 69
70 class KernelActionHandler(IPythonHandler):
70 class KernelActionHandler(APIHandler):
71 71
72 72 @web.authenticated
73 73 @json_errors
@@ -67,7 +67,8 b' class KernelAPITest(NotebookTestBase):'
67 67
68 68 self.assertEqual(r.headers['Content-Security-Policy'], (
69 69 "frame-ancestors 'self'; "
70 "report-uri /api/security/csp-report;"
70 "report-uri /api/security/csp-report; "
71 "default-src 'none'"
71 72 ))
72 73
73 74 def test_main_kernel_handler(self):
@@ -80,7 +81,8 b' class KernelAPITest(NotebookTestBase):'
80 81
81 82 self.assertEqual(r.headers['Content-Security-Policy'], (
82 83 "frame-ancestors 'self'; "
83 "report-uri /api/security/csp-report;"
84 "report-uri /api/security/csp-report; "
85 "default-src 'none'"
84 86 ))
85 87
86 88 # GET request
@@ -10,7 +10,7 b' pjoin = os.path.join'
10 10
11 11 from tornado import web
12 12
13 from ...base.handlers import IPythonHandler, json_errors
13 from ...base.handlers import APIHandler, json_errors
14 14 from ...utils import url_path_join
15 15
16 16 def kernelspec_model(handler, name):
@@ -40,7 +40,7 b' def kernelspec_model(handler, name):'
40 40 )
41 41 return d
42 42
43 class MainKernelSpecHandler(IPythonHandler):
43 class MainKernelSpecHandler(APIHandler):
44 44 SUPPORTED_METHODS = ('GET',)
45 45
46 46 @web.authenticated
@@ -62,7 +62,7 b' class MainKernelSpecHandler(IPythonHandler):'
62 62 self.finish(json.dumps(model))
63 63
64 64
65 class KernelSpecHandler(IPythonHandler):
65 class KernelSpecHandler(APIHandler):
66 66 SUPPORTED_METHODS = ('GET',)
67 67
68 68 @web.authenticated
@@ -2,9 +2,9 b' import json'
2 2
3 3 from tornado import web
4 4
5 from ...base.handlers import IPythonHandler, json_errors
5 from ...base.handlers import APIHandler, json_errors
6 6
7 class NbconvertRootHandler(IPythonHandler):
7 class NbconvertRootHandler(APIHandler):
8 8 SUPPORTED_METHODS = ('GET',)
9 9
10 10 @web.authenticated
@@ -5,10 +5,10 b''
5 5
6 6 from tornado import gen, web
7 7
8 from ...base.handlers import IPythonHandler, json_errors
8 from ...base.handlers import APIHandler, json_errors
9 9 from . import csp_report_uri
10 10
11 class CSPReportHandler(IPythonHandler):
11 class CSPReportHandler(APIHandler):
12 12 '''Accepts a content security policy violation report'''
13 13 @web.authenticated
14 14 @json_errors
@@ -7,13 +7,13 b' import json'
7 7
8 8 from tornado import web
9 9
10 from ...base.handlers import IPythonHandler, json_errors
10 from ...base.handlers import APIHandler, json_errors
11 11 from IPython.utils.jsonutil import date_default
12 12 from IPython.html.utils import url_path_join, url_escape
13 13 from IPython.kernel.kernelspec import NoSuchKernel
14 14
15 15
16 class SessionRootHandler(IPythonHandler):
16 class SessionRootHandler(APIHandler):
17 17
18 18 @web.authenticated
19 19 @json_errors
@@ -65,7 +65,7 b' class SessionRootHandler(IPythonHandler):'
65 65 self.set_status(201)
66 66 self.finish(json.dumps(model, default=date_default))
67 67
68 class SessionHandler(IPythonHandler):
68 class SessionHandler(APIHandler):
69 69
70 70 SUPPORTED_METHODS = ('GET', 'PATCH', 'DELETE')
71 71
@@ -1,9 +1,9 b''
1 1 import json
2 2 from tornado import web, gen
3 from ..base.handlers import IPythonHandler, json_errors
3 from ..base.handlers import APIHandler, json_errors
4 4 from ..utils import url_path_join
5 5
6 class TerminalRootHandler(IPythonHandler):
6 class TerminalRootHandler(APIHandler):
7 7 @web.authenticated
8 8 @json_errors
9 9 def get(self):
@@ -19,7 +19,7 b' class TerminalRootHandler(IPythonHandler):'
19 19 self.finish(json.dumps({'name': name}))
20 20
21 21
22 class TerminalHandler(IPythonHandler):
22 class TerminalHandler(APIHandler):
23 23 SUPPORTED_METHODS = ('GET', 'DELETE')
24 24
25 25 @web.authenticated
General Comments 0
You need to be logged in to leave comments. Login now