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