зеркало из https://github.com/mozilla/kitsune.git
Merge commit '7aa2483' into development
This commit is contained in:
Коммит
bf9f40a187
|
@ -0,0 +1,50 @@
|
|||
from nose.tools import eq_
|
||||
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.test.client import Client
|
||||
|
||||
|
||||
def test_json_format():
|
||||
"""JSON without callback should return application/json"""
|
||||
c = Client()
|
||||
response = c.get(reverse('search'), {
|
||||
'q': 'bookmarks',
|
||||
'format': 'json',
|
||||
})
|
||||
eq_(response['Content-Type'], 'application/json')
|
||||
|
||||
|
||||
def test_json_callback_validation():
|
||||
"""Various json callbacks -- validation"""
|
||||
c = Client()
|
||||
q = 'bookmarks'
|
||||
format = 'json'
|
||||
|
||||
callbacks = (
|
||||
('callback', 200),
|
||||
('validCallback', 200),
|
||||
('obj.method', 200),
|
||||
('obj.someMethod', 200),
|
||||
('arr[1]', 200),
|
||||
('arr[12]', 200),
|
||||
("alert('xss');foo", 400),
|
||||
("eval('nastycode')", 400),
|
||||
("someFunc()", 400),
|
||||
('x', 200),
|
||||
('x123', 200),
|
||||
('$', 200),
|
||||
('_func', 200),
|
||||
('"></script><script>alert(\'xss\')</script>', 400),
|
||||
('">', 400),
|
||||
('var x=something;foo', 400),
|
||||
('var x=', 400),
|
||||
)
|
||||
|
||||
for callback, status in callbacks:
|
||||
response = c.get(reverse('search'), {
|
||||
'q': q,
|
||||
'format': format,
|
||||
'callback': callback,
|
||||
})
|
||||
eq_(response['Content-Type'], 'application/x-javascript')
|
||||
eq_(response.status_code, status)
|
|
@ -1,10 +1,12 @@
|
|||
# Create your views here.
|
||||
|
||||
import time
|
||||
import re
|
||||
|
||||
from django.utils.datastructures import MultiValueDict
|
||||
from django import forms
|
||||
from django.conf import settings
|
||||
from django.http import HttpResponse
|
||||
|
||||
import jingo
|
||||
from l10n import ugettext as _
|
||||
|
@ -17,6 +19,12 @@ from .utils import crc32
|
|||
import search as constants
|
||||
|
||||
|
||||
def jsonp_is_valid(func):
|
||||
func_regex = re.compile(r'^[a-zA-Z_\$][a-zA-Z0-9_\$]*'
|
||||
+ r'(\[[a-zA-Z0-9_\$]*\])*(\.[a-zA-Z0-9_\$]+(\[[a-zA-Z0-9_\$]*\])*)*$')
|
||||
return func_regex.match(func)
|
||||
|
||||
|
||||
def search(request):
|
||||
"""Performs search or displays the search form"""
|
||||
|
||||
|
@ -218,6 +226,32 @@ def search(request):
|
|||
refine_query = '?a=1&w=' + str(where) + '&' \
|
||||
+ flatten(refine_query, encode=False)
|
||||
|
||||
if request.GET.get('format') == 'json':
|
||||
callback = request.GET.get('callback', '').strip()
|
||||
# check callback is valid
|
||||
if callback and not jsonp_is_valid(callback):
|
||||
return HttpResponse('', mimetype='application/x-javascript',
|
||||
status=400)
|
||||
|
||||
data = {}
|
||||
data['results'] = results
|
||||
data['total'] = len(documents)
|
||||
data['query'] = q
|
||||
if not results:
|
||||
data['message'] = _('No pages matched the search criteria')
|
||||
import json
|
||||
json_data = json.dumps(data)
|
||||
if callback:
|
||||
json_data = callback + '(' + json_data + ');'
|
||||
response = HttpResponse(json_data,
|
||||
mimetype='application/x-javascript')
|
||||
else:
|
||||
response = HttpResponse(json_data,
|
||||
mimetype='application/json')
|
||||
|
||||
return response
|
||||
|
||||
|
||||
return jingo.render(request, 'results.html',
|
||||
{'num_results': len(documents), 'results': results, 'q': q,
|
||||
'locale': request.LANGUAGE_CODE, 'pages': pages,
|
||||
|
|
Загрузка…
Ссылка в новой задаче