Skip to content

Commit

Permalink
Merge branch csp into 3.x
Browse files Browse the repository at this point in the history
Add APIHandler
  • Loading branch information
minrk committed Jun 22, 2015
2 parents dcec5d4 + 3a67913 commit 7222bd5
Show file tree
Hide file tree
Showing 11 changed files with 65 additions and 38 deletions.
43 changes: 34 additions & 9 deletions IPython/html/base/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,24 @@

class AuthenticatedHandler(web.RequestHandler):
"""A RequestHandler with an authenticated user."""

@property
def content_security_policy(self):
"""The default Content-Security-Policy header
Can be overridden by defining Content-Security-Policy in settings['headers']
"""
return '; '.join([
"frame-ancestors 'self'",
# Make sure the report-uri is relative to the base_url
"report-uri " + url_path_join(self.base_url, csp_report_uri),
])

def set_default_headers(self):
headers = self.settings.get('headers', {})

if "Content-Security-Policy" not in headers:
headers["Content-Security-Policy"] = (
"frame-ancestors 'self'; "
# Make sure the report-uri is relative to the base_url
"report-uri " + url_path_join(self.base_url, csp_report_uri) + ";"
)
headers["Content-Security-Policy"] = self.content_security_policy

# Allow for overriding headers
for header_name,value in headers.items() :
Expand Down Expand Up @@ -307,7 +315,22 @@ def write_error(self, status_code, **kwargs):
html = self.render_template('error.html', **ns)

self.write(html)



class APIHandler(IPythonHandler):
"""Base class for API handlers"""

@property
def content_security_policy(self):
csp = '; '.join([
super(APIHandler, self).content_security_policy,
"default-src 'none'",
])
return csp

def finish(self, *args, **kwargs):
self.set_header('Content-Type', 'application/json')
return super(APIHandler, self).finish(*args, **kwargs)


class Template404(IPythonHandler):
Expand Down Expand Up @@ -370,13 +393,15 @@ def wrapper(self, *args, **kwargs):
try:
result = yield gen.maybe_future(method(self, *args, **kwargs))
except web.HTTPError as e:
self.set_header('Content-Type', 'application/json')
status = e.status_code
message = e.log_message
self.log.warn(message)
self.set_status(e.status_code)
reply = dict(message=message, reason=e.reason)
self.finish(json.dumps(reply))
except Exception:
self.set_header('Content-Type', 'application/json')
self.log.error("Unhandled error in API request", exc_info=True)
status = 500
message = "Unknown server error"
Expand All @@ -399,7 +424,7 @@ def wrapper(self, *args, **kwargs):
# to minimize subclass changes:
HTTPError = web.HTTPError

class FileFindHandler(web.StaticFileHandler):
class FileFindHandler(IPythonHandler, web.StaticFileHandler):
"""subclass of StaticFileHandler for serving files from a search path"""

# cache search results, don't search for files more than once
Expand Down Expand Up @@ -453,7 +478,7 @@ def validate_absolute_path(self, root, absolute_path):
return super(FileFindHandler, self).validate_absolute_path(root, absolute_path)


class ApiVersionHandler(IPythonHandler):
class APIVersionHandler(APIHandler):

@json_errors
def get(self):
Expand Down Expand Up @@ -524,5 +549,5 @@ def get(self, path=''):

default_handlers = [
(r".*/", TrailingSlashHandler),
(r"api", ApiVersionHandler)
(r"api", APIVersionHandler)
]
8 changes: 4 additions & 4 deletions IPython/html/services/clusters/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,28 @@

from tornado import web

from ...base.handlers import IPythonHandler
from ...base.handlers import APIHandler

#-----------------------------------------------------------------------------
# Cluster handlers
#-----------------------------------------------------------------------------


class MainClusterHandler(IPythonHandler):
class MainClusterHandler(APIHandler):

@web.authenticated
def get(self):
self.finish(json.dumps(self.cluster_manager.list_profiles()))


class ClusterProfileHandler(IPythonHandler):
class ClusterProfileHandler(APIHandler):

@web.authenticated
def get(self, profile):
self.finish(json.dumps(self.cluster_manager.profile_info(profile)))


class ClusterActionHandler(IPythonHandler):
class ClusterActionHandler(APIHandler):

@web.authenticated
def post(self, profile, action):
Expand Down
4 changes: 2 additions & 2 deletions IPython/html/services/config/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
from tornado import web

from IPython.utils.py3compat import PY3
from ...base.handlers import IPythonHandler, json_errors
from ...base.handlers import APIHandler, json_errors

class ConfigHandler(IPythonHandler):
class ConfigHandler(APIHandler):
SUPPORTED_METHODS = ('GET', 'PUT', 'PATCH')

@web.authenticated
Expand Down
8 changes: 4 additions & 4 deletions IPython/html/services/contents/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from IPython.utils.jsonutil import date_default

from IPython.html.base.handlers import (
IPythonHandler, json_errors, path_regex,
IPythonHandler, APIHandler, json_errors, path_regex,
)


Expand Down Expand Up @@ -75,7 +75,7 @@ def validate_model(model, expect_content):
)


class ContentsHandler(IPythonHandler):
class ContentsHandler(APIHandler):

SUPPORTED_METHODS = (u'GET', u'PUT', u'PATCH', u'POST', u'DELETE')

Expand Down Expand Up @@ -257,7 +257,7 @@ def delete(self, path=''):
self.finish()


class CheckpointsHandler(IPythonHandler):
class CheckpointsHandler(APIHandler):

SUPPORTED_METHODS = ('GET', 'POST')

Expand Down Expand Up @@ -286,7 +286,7 @@ def post(self, path=''):
self.finish(data)


class ModifyCheckpointsHandler(IPythonHandler):
class ModifyCheckpointsHandler(APIHandler):

SUPPORTED_METHODS = ('POST', 'DELETE')

Expand Down
8 changes: 4 additions & 4 deletions IPython/html/services/kernels/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@
from IPython.utils.py3compat import cast_unicode
from IPython.html.utils import url_path_join, url_escape

from ...base.handlers import IPythonHandler, json_errors
from ...base.handlers import IPythonHandler, APIHandler, json_errors
from ...base.zmqhandlers import AuthenticatedZMQStreamHandler, deserialize_binary_message

from IPython.core.release import kernel_protocol_version

class MainKernelHandler(IPythonHandler):
class MainKernelHandler(APIHandler):

@web.authenticated
@json_errors
Expand Down Expand Up @@ -46,7 +46,7 @@ def post(self):
self.finish(json.dumps(model))


class KernelHandler(IPythonHandler):
class KernelHandler(APIHandler):

SUPPORTED_METHODS = ('DELETE', 'GET')

Expand All @@ -67,7 +67,7 @@ def delete(self, kernel_id):
self.finish()


class KernelActionHandler(IPythonHandler):
class KernelActionHandler(APIHandler):

@web.authenticated
@json_errors
Expand Down
6 changes: 4 additions & 2 deletions IPython/html/services/kernels/tests/test_kernels_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ def test_default_kernel(self):

self.assertEqual(r.headers['Content-Security-Policy'], (
"frame-ancestors 'self'; "
"report-uri /api/security/csp-report;"
"report-uri /api/security/csp-report; "
"default-src 'none'"
))

def test_main_kernel_handler(self):
Expand All @@ -80,7 +81,8 @@ def test_main_kernel_handler(self):

self.assertEqual(r.headers['Content-Security-Policy'], (
"frame-ancestors 'self'; "
"report-uri /api/security/csp-report;"
"report-uri /api/security/csp-report; "
"default-src 'none'"
))

# GET request
Expand Down
6 changes: 3 additions & 3 deletions IPython/html/services/kernelspecs/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

from tornado import web

from ...base.handlers import IPythonHandler, json_errors
from ...base.handlers import APIHandler, json_errors
from ...utils import url_path_join

def kernelspec_model(handler, name):
Expand Down Expand Up @@ -40,7 +40,7 @@ def kernelspec_model(handler, name):
)
return d

class MainKernelSpecHandler(IPythonHandler):
class MainKernelSpecHandler(APIHandler):
SUPPORTED_METHODS = ('GET',)

@web.authenticated
Expand All @@ -62,7 +62,7 @@ def get(self):
self.finish(json.dumps(model))


class KernelSpecHandler(IPythonHandler):
class KernelSpecHandler(APIHandler):
SUPPORTED_METHODS = ('GET',)

@web.authenticated
Expand Down
4 changes: 2 additions & 2 deletions IPython/html/services/nbconvert/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

from tornado import web

from ...base.handlers import IPythonHandler, json_errors
from ...base.handlers import APIHandler, json_errors

class NbconvertRootHandler(IPythonHandler):
class NbconvertRootHandler(APIHandler):
SUPPORTED_METHODS = ('GET',)

@web.authenticated
Expand Down
4 changes: 2 additions & 2 deletions IPython/html/services/security/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@

from tornado import gen, web

from ...base.handlers import IPythonHandler, json_errors
from ...base.handlers import APIHandler, json_errors
from . import csp_report_uri

class CSPReportHandler(IPythonHandler):
class CSPReportHandler(APIHandler):
'''Accepts a content security policy violation report'''
@web.authenticated
@json_errors
Expand Down
6 changes: 3 additions & 3 deletions IPython/html/services/sessions/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@

from tornado import web

from ...base.handlers import IPythonHandler, json_errors
from ...base.handlers import APIHandler, json_errors
from IPython.utils.jsonutil import date_default
from IPython.html.utils import url_path_join, url_escape
from IPython.kernel.kernelspec import NoSuchKernel


class SessionRootHandler(IPythonHandler):
class SessionRootHandler(APIHandler):

@web.authenticated
@json_errors
Expand Down Expand Up @@ -65,7 +65,7 @@ def post(self):
self.set_status(201)
self.finish(json.dumps(model, default=date_default))

class SessionHandler(IPythonHandler):
class SessionHandler(APIHandler):

SUPPORTED_METHODS = ('GET', 'PATCH', 'DELETE')

Expand Down
6 changes: 3 additions & 3 deletions IPython/html/terminal/api_handlers.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import json
from tornado import web, gen
from ..base.handlers import IPythonHandler, json_errors
from ..base.handlers import APIHandler, json_errors
from ..utils import url_path_join

class TerminalRootHandler(IPythonHandler):
class TerminalRootHandler(APIHandler):
@web.authenticated
@json_errors
def get(self):
Expand All @@ -19,7 +19,7 @@ def post(self):
self.finish(json.dumps({'name': name}))


class TerminalHandler(IPythonHandler):
class TerminalHandler(APIHandler):
SUPPORTED_METHODS = ('GET', 'DELETE')

@web.authenticated
Expand Down

0 comments on commit 7222bd5

Please sign in to comment.