# HG changeset patch # User Katia Saurfelt # Date 1354012683 -3600 # Node ID 1a6000ff208045d4905e14a9db3550a3efc06cfe # Parent d74addac92bbe2dd5ea6dd53ede482b6bded48a8 [web] add a ``anonymize-jsonp-queries`` option in file configuration (closes #2465388) This option controls connection anonymizing before executing any query for CSRF / safety reason. diff -r d74addac92bb -r 1a6000ff2080 web/test/unittest_views_json.py --- a/web/test/unittest_views_json.py Tue Nov 27 11:27:49 2012 +0100 +++ b/web/test/unittest_views_json.py Tue Nov 27 11:38:03 2012 +0100 @@ -1,8 +1,34 @@ +# -*- coding: utf-8 -*- +# copyright 2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved. +# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr +# +# This file is part of CubicWeb. +# +# CubicWeb is free software: you can redistribute it and/or modify it under the +# terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 2.1 of the License, or (at your option) +# any later version. +# +# CubicWeb is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License along +# with CubicWeb. If not, see . from cubicweb.devtools.testlib import CubicWebTC from cubicweb.utils import json +from cubicweb.web.application import anonymized_request + class JsonViewsTC(CubicWebTC): + anonymize = True + res_jsonp_data = '[["guests", 1]]' + + def setUp(self): + super(JsonViewsTC, self).setUp() + self.config.global_set_option('anonymize-jsonp-queries', self.anonymize) def test_json_rsetexport(self): req = self.request() @@ -19,7 +45,7 @@ data = self.ctrl_publish(req, ctrl='jsonp') self.assertEqual(req.headers_out.getRawHeaders('content-type'), ['application/javascript']) # because jsonp anonymizes data, only 'guests' group should be found - self.assertEqual(data, 'foo([["guests", 1]])') + self.assertEqual(data, 'foo(%s)' % self.res_jsonp_data) def test_json_rsetexport_with_jsonp_and_bad_vid(self): req = self.request() @@ -30,7 +56,7 @@ data = self.ctrl_publish(req, ctrl='jsonp') self.assertEqual(req.headers_out.getRawHeaders('content-type'), ['application/javascript']) # result should be plain json, not the table view - self.assertEqual(data, 'foo([["guests", 1]])') + self.assertEqual(data, 'foo(%s)' % self.res_jsonp_data) def test_json_ersetexport(self): req = self.request() @@ -41,6 +67,10 @@ self.assertEqual(data[1]['name'], 'managers') +class NotAnonymousJsonViewsTC(JsonViewsTC): + anonymize = False + res_jsonp_data = '[["guests", 1], ["managers", 1]]' + if __name__ == '__main__': from logilab.common.testlib import unittest_main unittest_main() diff -r d74addac92bb -r 1a6000ff2080 web/views/json.py --- a/web/views/json.py Tue Nov 27 11:27:49 2012 +0100 +++ b/web/views/json.py Tue Nov 27 11:38:03 2012 +0100 @@ -1,4 +1,4 @@ -# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved. +# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved. # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr # # This file is part of CubicWeb. @@ -50,14 +50,20 @@ self._cw.form['vid'] = 'jsonexport' else: # if no vid is specified, use jsonexport self._cw.form['vid'] = 'jsonexport' - with anonymized_request(self._cw): - json_data = super(JsonpController, self).publish(rset) - if 'callback' in self._cw.form: # jsonp - json_padding = self._cw.form['callback'] - # use ``application/javascript`` is ``callback`` parameter is - # provided, let ``application/json`` otherwise - self._cw.set_content_type('application/javascript') - json_data = '%s(%s)' % (json_padding, json_data) + if self._cw.vreg.config['anonymize-jsonp-queries']: + with anonymized_request(self._cw): + return self._get_json_data(rset) + else: + return self._get_json_data(rset) + + def _get_json_data(self, rset): + json_data = super(JsonpController, self).publish(rset) + if 'callback' in self._cw.form: # jsonp + json_padding = self._cw.form['callback'] + # use ``application/javascript`` is ``callback`` parameter is + # provided, let ``application/json`` otherwise + self._cw.set_content_type('application/javascript') + json_data = '%s(%s)' % (json_padding, json_data) return json_data diff -r d74addac92bb -r 1a6000ff2080 web/webconfig.py --- a/web/webconfig.py Tue Nov 27 11:27:49 2012 +0100 +++ b/web/webconfig.py Tue Nov 27 11:38:03 2012 +0100 @@ -1,4 +1,4 @@ -# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved. +# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved. # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr # # This file is part of CubicWeb. @@ -219,6 +219,12 @@ 'help': 'use modconcat-like URLS to concat and serve JS / CSS files', 'group': 'web', 'level': 2, }), + ('anonymize-jsonp-queries', + {'type': 'yn', + 'default': True, + 'help': 'anonymize the connection before executing any jsonp query.', + 'group': 'web', 'level': 1 + }), )) def fckeditor_installed(self): @@ -251,7 +257,7 @@ def anonymous_user(self): """return a login and password to use for anonymous users. - + None may be returned for both if anonymous connection is not allowed or if an empty login is used in configuration """