2013-07-30 01:19:04 +08:00
|
|
|
from __future__ import unicode_literals
|
2011-10-14 05:34:56 +08:00
|
|
|
|
2014-02-15 01:28:51 +08:00
|
|
|
import datetime
|
|
|
|
import decimal
|
2013-09-16 05:51:24 +08:00
|
|
|
import os
|
2009-04-01 01:10:06 +08:00
|
|
|
import sys
|
|
|
|
|
2013-08-04 17:01:01 +08:00
|
|
|
from django.core.exceptions import PermissionDenied, SuspiciousOperation
|
2010-12-22 01:18:41 +08:00
|
|
|
from django.core.urlresolvers import get_resolver
|
2014-06-16 15:39:18 +08:00
|
|
|
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse, Http404
|
2010-12-22 01:18:41 +08:00
|
|
|
from django.shortcuts import render_to_response, render
|
2011-01-21 06:33:58 +08:00
|
|
|
from django.template import Context, RequestContext, TemplateDoesNotExist
|
2011-06-09 06:18:46 +08:00
|
|
|
from django.views.debug import technical_500_response, SafeExceptionReporterFilter
|
|
|
|
from django.views.decorators.debug import (sensitive_post_parameters,
|
|
|
|
sensitive_variables)
|
2013-09-16 05:51:24 +08:00
|
|
|
from django.utils._os import upath
|
2011-06-09 06:18:46 +08:00
|
|
|
from django.utils.log import getLogger
|
2008-07-19 03:45:00 +08:00
|
|
|
|
2014-06-16 15:39:18 +08:00
|
|
|
from django.views.generic import View
|
|
|
|
|
2011-10-14 05:34:56 +08:00
|
|
|
from . import BrokenException, except_args
|
2012-06-04 08:33:09 +08:00
|
|
|
|
2013-09-16 05:51:24 +08:00
|
|
|
dirs = (os.path.join(os.path.dirname(upath(__file__)), 'other_templates'),)
|
2008-07-19 03:45:00 +08:00
|
|
|
|
2007-09-17 22:48:33 +08:00
|
|
|
|
|
|
|
def index_page(request):
|
2007-09-19 21:26:56 +08:00
|
|
|
"""Dummy index page"""
|
2007-09-17 22:48:33 +08:00
|
|
|
return HttpResponse('<html><body>Dummy page</body></html>')
|
2008-07-19 03:45:00 +08:00
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2009-04-01 01:10:06 +08:00
|
|
|
def raises(request):
|
2011-01-13 21:47:03 +08:00
|
|
|
# Make sure that a callable that raises an exception in the stack frame's
|
|
|
|
# local vars won't hijack the technical 500 response. See:
|
|
|
|
# http://code.djangoproject.com/ticket/15025
|
|
|
|
def callable():
|
|
|
|
raise Exception
|
2009-04-01 01:10:06 +08:00
|
|
|
try:
|
|
|
|
raise Exception
|
|
|
|
except Exception:
|
|
|
|
return technical_500_response(request, *sys.exc_info())
|
2009-04-12 11:50:47 +08:00
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2012-10-20 20:50:44 +08:00
|
|
|
def raises500(request):
|
|
|
|
# We need to inspect the HTML generated by the fancy 500 debug view but
|
|
|
|
# the test client ignores it, so we send it explicitly.
|
|
|
|
try:
|
|
|
|
raise Exception
|
|
|
|
except Exception:
|
|
|
|
return technical_500_response(request, *sys.exc_info())
|
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2013-08-04 17:01:01 +08:00
|
|
|
def raises400(request):
|
|
|
|
raise SuspiciousOperation
|
2010-03-08 23:20:29 +08:00
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2011-08-12 22:15:31 +08:00
|
|
|
def raises403(request):
|
|
|
|
raise PermissionDenied
|
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2013-08-04 17:01:01 +08:00
|
|
|
def raises404(request):
|
|
|
|
resolver = get_resolver(None)
|
2014-02-15 21:41:01 +08:00
|
|
|
resolver.resolve('/not-in-urls')
|
2013-08-04 17:01:01 +08:00
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2014-06-16 15:39:18 +08:00
|
|
|
def technical404(request):
|
|
|
|
raise Http404("Testing technical 404.")
|
|
|
|
|
|
|
|
|
|
|
|
class Http404View(View):
|
|
|
|
def get(self, request):
|
|
|
|
raise Http404("Testing class-based technical 404.")
|
|
|
|
|
|
|
|
|
2009-04-12 11:50:47 +08:00
|
|
|
def redirect(request):
|
|
|
|
"""
|
|
|
|
Forces an HTTP redirect.
|
|
|
|
"""
|
|
|
|
return HttpResponseRedirect("target/")
|
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2010-03-08 23:20:29 +08:00
|
|
|
def view_exception(request, n):
|
|
|
|
raise BrokenException(except_args[int(n)])
|
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2010-03-09 01:01:21 +08:00
|
|
|
def template_exception(request, n):
|
|
|
|
return render_to_response('debug/template_exception.html',
|
|
|
|
{'arg': except_args[int(n)]})
|
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2012-11-17 22:37:30 +08:00
|
|
|
def jsi18n(request):
|
|
|
|
return render_to_response('jsi18n.html')
|
|
|
|
|
2010-12-22 01:18:41 +08:00
|
|
|
# Some views to exercise the shortcuts
|
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2010-12-22 01:18:41 +08:00
|
|
|
def render_to_response_view(request):
|
|
|
|
return render_to_response('debug/render_test.html', {
|
|
|
|
'foo': 'FOO',
|
|
|
|
'bar': 'BAR',
|
|
|
|
})
|
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2010-12-22 01:18:41 +08:00
|
|
|
def render_to_response_view_with_request_context(request):
|
|
|
|
return render_to_response('debug/render_test.html', {
|
|
|
|
'foo': 'FOO',
|
|
|
|
'bar': 'BAR',
|
|
|
|
}, context_instance=RequestContext(request))
|
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2013-01-31 20:39:29 +08:00
|
|
|
def render_to_response_view_with_content_type(request):
|
2010-12-22 01:18:41 +08:00
|
|
|
return render_to_response('debug/render_test.html', {
|
|
|
|
'foo': 'FOO',
|
|
|
|
'bar': 'BAR',
|
2013-01-31 20:39:29 +08:00
|
|
|
}, content_type='application/x-rendertest')
|
2010-12-22 01:18:41 +08:00
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2013-09-16 05:51:24 +08:00
|
|
|
def render_to_response_view_with_dirs(request):
|
|
|
|
return render_to_response('render_dirs_test.html', dirs=dirs)
|
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2010-12-22 01:18:41 +08:00
|
|
|
def render_view(request):
|
|
|
|
return render(request, 'debug/render_test.html', {
|
|
|
|
'foo': 'FOO',
|
|
|
|
'bar': 'BAR',
|
|
|
|
})
|
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2010-12-22 01:18:41 +08:00
|
|
|
def render_view_with_base_context(request):
|
|
|
|
return render(request, 'debug/render_test.html', {
|
|
|
|
'foo': 'FOO',
|
|
|
|
'bar': 'BAR',
|
|
|
|
}, context_instance=Context())
|
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2010-12-22 12:54:10 +08:00
|
|
|
def render_view_with_content_type(request):
|
2010-12-22 01:18:41 +08:00
|
|
|
return render(request, 'debug/render_test.html', {
|
|
|
|
'foo': 'FOO',
|
|
|
|
'bar': 'BAR',
|
2010-12-22 12:54:10 +08:00
|
|
|
}, content_type='application/x-rendertest')
|
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2010-12-22 12:54:10 +08:00
|
|
|
def render_view_with_status(request):
|
|
|
|
return render(request, 'debug/render_test.html', {
|
|
|
|
'foo': 'FOO',
|
|
|
|
'bar': 'BAR',
|
|
|
|
}, status=403)
|
2011-01-06 06:41:43 +08:00
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2011-01-06 06:41:43 +08:00
|
|
|
def render_view_with_current_app(request):
|
|
|
|
return render(request, 'debug/render_test.html', {
|
|
|
|
'foo': 'FOO',
|
|
|
|
'bar': 'BAR',
|
|
|
|
}, current_app="foobar_app")
|
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2011-01-06 06:41:43 +08:00
|
|
|
def render_view_with_current_app_conflict(request):
|
|
|
|
# This should fail because we don't passing both a current_app and
|
|
|
|
# context_instance:
|
|
|
|
return render(request, 'debug/render_test.html', {
|
|
|
|
'foo': 'FOO',
|
|
|
|
'bar': 'BAR',
|
|
|
|
}, current_app="foobar_app", context_instance=RequestContext(request))
|
2011-01-21 06:33:58 +08:00
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2013-09-16 05:51:24 +08:00
|
|
|
def render_with_dirs(request):
|
|
|
|
return render(request, 'render_dirs_test.html', dirs=dirs)
|
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2013-02-24 23:41:10 +08:00
|
|
|
def raises_template_does_not_exist(request, path='i_dont_exist.html'):
|
2011-01-21 06:33:58 +08:00
|
|
|
# We need to inspect the HTML generated by the fancy 500 debug view but
|
|
|
|
# the test client ignores it, so we send it explicitly.
|
|
|
|
try:
|
2013-02-24 23:41:10 +08:00
|
|
|
return render_to_response(path)
|
2011-01-21 06:33:58 +08:00
|
|
|
except TemplateDoesNotExist:
|
|
|
|
return technical_500_response(request, *sys.exc_info())
|
2011-06-09 06:18:46 +08:00
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2013-09-07 04:50:18 +08:00
|
|
|
def render_no_template(request):
|
|
|
|
# If we do not specify a template, we need to make sure the debug
|
|
|
|
# view doesn't blow up.
|
|
|
|
return render(request, [], {})
|
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2011-06-09 06:18:46 +08:00
|
|
|
def send_log(request, exc_info):
|
|
|
|
logger = getLogger('django.request')
|
2011-06-22 14:01:44 +08:00
|
|
|
# The default logging config has a logging filter to ensure admin emails are
|
|
|
|
# only sent with DEBUG=False, but since someone might choose to remove that
|
|
|
|
# filter, we still want to be able to test the behavior of error emails
|
|
|
|
# with DEBUG=True. So we need to remove the filter temporarily.
|
|
|
|
admin_email_handler = [
|
|
|
|
h for h in logger.handlers
|
|
|
|
if h.__class__.__name__ == "AdminEmailHandler"
|
2013-10-18 17:02:43 +08:00
|
|
|
][0]
|
2011-06-22 14:01:44 +08:00
|
|
|
orig_filters = admin_email_handler.filters
|
|
|
|
admin_email_handler.filters = []
|
2013-01-01 01:34:08 +08:00
|
|
|
admin_email_handler.include_html = True
|
2012-02-10 02:58:36 +08:00
|
|
|
logger.error('Internal Server Error: %s', request.path,
|
2011-06-09 06:18:46 +08:00
|
|
|
exc_info=exc_info,
|
|
|
|
extra={
|
|
|
|
'status_code': 500,
|
|
|
|
'request': request
|
|
|
|
}
|
|
|
|
)
|
2011-06-22 14:01:44 +08:00
|
|
|
admin_email_handler.filters = orig_filters
|
2011-06-09 06:18:46 +08:00
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2011-06-09 06:18:46 +08:00
|
|
|
def non_sensitive_view(request):
|
|
|
|
# Do not just use plain strings for the variables' values in the code
|
|
|
|
# so that the tests don't return false positives when the function's source
|
|
|
|
# is displayed in the exception report.
|
2013-10-19 20:31:38 +08:00
|
|
|
cooked_eggs = ''.join(['s', 'c', 'r', 'a', 'm', 'b', 'l', 'e', 'd']) # NOQA
|
|
|
|
sauce = ''.join(['w', 'o', 'r', 'c', 'e', 's', 't', 'e', 'r', 's', 'h', 'i', 'r', 'e']) # NOQA
|
2011-06-09 06:18:46 +08:00
|
|
|
try:
|
|
|
|
raise Exception
|
|
|
|
except Exception:
|
|
|
|
exc_info = sys.exc_info()
|
|
|
|
send_log(request, exc_info)
|
|
|
|
return technical_500_response(request, *exc_info)
|
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2011-06-09 06:18:46 +08:00
|
|
|
@sensitive_variables('sauce')
|
|
|
|
@sensitive_post_parameters('bacon-key', 'sausage-key')
|
|
|
|
def sensitive_view(request):
|
|
|
|
# Do not just use plain strings for the variables' values in the code
|
|
|
|
# so that the tests don't return false positives when the function's source
|
|
|
|
# is displayed in the exception report.
|
2013-10-19 20:31:38 +08:00
|
|
|
cooked_eggs = ''.join(['s', 'c', 'r', 'a', 'm', 'b', 'l', 'e', 'd']) # NOQA
|
|
|
|
sauce = ''.join(['w', 'o', 'r', 'c', 'e', 's', 't', 'e', 'r', 's', 'h', 'i', 'r', 'e']) # NOQA
|
2011-06-09 06:18:46 +08:00
|
|
|
try:
|
|
|
|
raise Exception
|
|
|
|
except Exception:
|
|
|
|
exc_info = sys.exc_info()
|
|
|
|
send_log(request, exc_info)
|
|
|
|
return technical_500_response(request, *exc_info)
|
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2011-06-09 06:18:46 +08:00
|
|
|
@sensitive_variables()
|
|
|
|
@sensitive_post_parameters()
|
|
|
|
def paranoid_view(request):
|
|
|
|
# Do not just use plain strings for the variables' values in the code
|
|
|
|
# so that the tests don't return false positives when the function's source
|
|
|
|
# is displayed in the exception report.
|
2013-10-19 20:31:38 +08:00
|
|
|
cooked_eggs = ''.join(['s', 'c', 'r', 'a', 'm', 'b', 'l', 'e', 'd']) # NOQA
|
|
|
|
sauce = ''.join(['w', 'o', 'r', 'c', 'e', 's', 't', 'e', 'r', 's', 'h', 'i', 'r', 'e']) # NOQA
|
2011-06-09 06:18:46 +08:00
|
|
|
try:
|
|
|
|
raise Exception
|
|
|
|
except Exception:
|
|
|
|
exc_info = sys.exc_info()
|
|
|
|
send_log(request, exc_info)
|
|
|
|
return technical_500_response(request, *exc_info)
|
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2013-01-01 01:34:08 +08:00
|
|
|
def sensitive_args_function_caller(request):
|
|
|
|
try:
|
|
|
|
sensitive_args_function(''.join(['w', 'o', 'r', 'c', 'e', 's', 't', 'e', 'r', 's', 'h', 'i', 'r', 'e']))
|
|
|
|
except Exception:
|
|
|
|
exc_info = sys.exc_info()
|
|
|
|
send_log(request, exc_info)
|
|
|
|
return technical_500_response(request, *exc_info)
|
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2013-01-01 01:34:08 +08:00
|
|
|
@sensitive_variables('sauce')
|
|
|
|
def sensitive_args_function(sauce):
|
|
|
|
# Do not just use plain strings for the variables' values in the code
|
|
|
|
# so that the tests don't return false positives when the function's source
|
|
|
|
# is displayed in the exception report.
|
2013-10-19 20:31:38 +08:00
|
|
|
cooked_eggs = ''.join(['s', 'c', 'r', 'a', 'm', 'b', 'l', 'e', 'd']) # NOQA
|
2013-01-01 01:34:08 +08:00
|
|
|
raise Exception
|
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2013-01-01 01:34:08 +08:00
|
|
|
def sensitive_kwargs_function_caller(request):
|
|
|
|
try:
|
|
|
|
sensitive_kwargs_function(''.join(['w', 'o', 'r', 'c', 'e', 's', 't', 'e', 'r', 's', 'h', 'i', 'r', 'e']))
|
|
|
|
except Exception:
|
|
|
|
exc_info = sys.exc_info()
|
|
|
|
send_log(request, exc_info)
|
|
|
|
return technical_500_response(request, *exc_info)
|
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2013-01-01 01:34:08 +08:00
|
|
|
@sensitive_variables('sauce')
|
|
|
|
def sensitive_kwargs_function(sauce=None):
|
|
|
|
# Do not just use plain strings for the variables' values in the code
|
|
|
|
# so that the tests don't return false positives when the function's source
|
|
|
|
# is displayed in the exception report.
|
2013-10-19 20:31:38 +08:00
|
|
|
cooked_eggs = ''.join(['s', 'c', 'r', 'a', 'm', 'b', 'l', 'e', 'd']) # NOQA
|
2013-01-01 01:34:08 +08:00
|
|
|
raise Exception
|
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2011-06-09 06:18:46 +08:00
|
|
|
class UnsafeExceptionReporterFilter(SafeExceptionReporterFilter):
|
|
|
|
"""
|
|
|
|
Ignores all the filtering done by its parent class.
|
|
|
|
"""
|
|
|
|
|
|
|
|
def get_post_parameters(self, request):
|
|
|
|
return request.POST
|
|
|
|
|
|
|
|
def get_traceback_frame_variables(self, request, tb_frame):
|
|
|
|
return tb_frame.f_locals.items()
|
|
|
|
|
|
|
|
|
|
|
|
@sensitive_variables()
|
|
|
|
@sensitive_post_parameters()
|
|
|
|
def custom_exception_reporter_filter_view(request):
|
|
|
|
# Do not just use plain strings for the variables' values in the code
|
|
|
|
# so that the tests don't return false positives when the function's source
|
|
|
|
# is displayed in the exception report.
|
2013-10-19 20:31:38 +08:00
|
|
|
cooked_eggs = ''.join(['s', 'c', 'r', 'a', 'm', 'b', 'l', 'e', 'd']) # NOQA
|
|
|
|
sauce = ''.join(['w', 'o', 'r', 'c', 'e', 's', 't', 'e', 'r', 's', 'h', 'i', 'r', 'e']) # NOQA
|
2011-06-09 06:18:46 +08:00
|
|
|
request.exception_reporter_filter = UnsafeExceptionReporterFilter()
|
|
|
|
try:
|
|
|
|
raise Exception
|
|
|
|
except Exception:
|
|
|
|
exc_info = sys.exc_info()
|
|
|
|
send_log(request, exc_info)
|
|
|
|
return technical_500_response(request, *exc_info)
|
2012-06-04 08:33:09 +08:00
|
|
|
|
|
|
|
|
|
|
|
class Klass(object):
|
|
|
|
|
|
|
|
@sensitive_variables('sauce')
|
|
|
|
def method(self, request):
|
|
|
|
# Do not just use plain strings for the variables' values in the code
|
|
|
|
# so that the tests don't return false positives when the function's
|
|
|
|
# source is displayed in the exception report.
|
2013-10-19 20:31:38 +08:00
|
|
|
cooked_eggs = ''.join(['s', 'c', 'r', 'a', 'm', 'b', 'l', 'e', 'd']) # NOQA
|
|
|
|
sauce = ''.join(['w', 'o', 'r', 'c', 'e', 's', 't', 'e', 'r', 's', 'h', 'i', 'r', 'e']) # NOQA
|
2012-06-04 08:33:09 +08:00
|
|
|
try:
|
|
|
|
raise Exception
|
|
|
|
except Exception:
|
|
|
|
exc_info = sys.exc_info()
|
|
|
|
send_log(request, exc_info)
|
|
|
|
return technical_500_response(request, *exc_info)
|
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2012-06-04 08:33:09 +08:00
|
|
|
def sensitive_method_view(request):
|
2013-01-31 20:39:29 +08:00
|
|
|
return Klass().method(request)
|
2013-09-17 19:46:38 +08:00
|
|
|
|
|
|
|
|
|
|
|
@sensitive_variables('sauce')
|
|
|
|
@sensitive_post_parameters('bacon-key', 'sausage-key')
|
|
|
|
def multivalue_dict_key_error(request):
|
2013-10-19 20:31:38 +08:00
|
|
|
cooked_eggs = ''.join(['s', 'c', 'r', 'a', 'm', 'b', 'l', 'e', 'd']) # NOQA
|
|
|
|
sauce = ''.join(['w', 'o', 'r', 'c', 'e', 's', 't', 'e', 'r', 's', 'h', 'i', 'r', 'e']) # NOQA
|
2013-09-17 19:46:38 +08:00
|
|
|
try:
|
|
|
|
request.POST['bar']
|
|
|
|
except Exception:
|
|
|
|
exc_info = sys.exc_info()
|
|
|
|
send_log(request, exc_info)
|
|
|
|
return technical_500_response(request, *exc_info)
|
2014-02-15 01:28:51 +08:00
|
|
|
|
|
|
|
|
|
|
|
def json_response_view(request):
|
|
|
|
return JsonResponse({
|
|
|
|
'a': [1, 2, 3],
|
|
|
|
'foo': {'bar': 'baz'},
|
|
|
|
# Make sure datetime and Decimal objects would be serialized properly
|
|
|
|
'timestamp': datetime.datetime(2013, 5, 19, 20),
|
|
|
|
'value': decimal.Decimal('3.14'),
|
|
|
|
})
|