0001-opendatasoft-do-not-escape-on-template-rendering-526.patch
passerelle/apps/opendatasoft/models.py | ||
---|---|---|
11 | 11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | 12 |
# GNU Affero General Public License for more details. |
13 | 13 |
# |
14 | 14 |
# You should have received a copy of the GNU Affero General Public License |
15 | 15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 | 17 |
from django.db import models |
18 | 18 |
from django.shortcuts import get_object_or_404 |
19 |
from django.template import Context, Template |
|
20 | 19 |
from django.urls import reverse |
21 |
from django.utils.encoding import force_text |
|
22 | 20 |
from django.utils.six.moves.urllib import parse as urlparse |
23 | 21 |
from django.utils.translation import ugettext_lazy as _ |
24 | 22 | |
25 |
from passerelle.utils.templates import validate_template |
|
23 |
from passerelle.utils.templates import render_to_string, validate_template
|
|
26 | 24 |
from passerelle.base.models import BaseResource, BaseQuery |
27 | 25 |
from passerelle.utils.api import endpoint |
28 | 26 | |
29 | 27 | |
30 | 28 |
class OpenDataSoft(BaseResource): |
31 | 29 |
service_url = models.CharField( |
32 | 30 |
_('Site URL'), |
33 | 31 |
max_length=256, |
... | ... | |
100 | 98 |
return {'err': 1, 'err_desc': err_desc} |
101 | 99 | |
102 | 100 |
result = [] |
103 | 101 |
for record in result_response.json().get('records'): |
104 | 102 |
data = {} |
105 | 103 |
for key, value in record.get('fields').items(): |
106 | 104 |
data[key] = value |
107 | 105 |
data['id'] = record.get('recordid') |
108 |
template = Template(text_template) |
|
109 |
data['text'] = template.render(Context(data)).strip() |
|
106 |
data['text'] = render_to_string(text_template, data).strip() |
|
110 | 107 |
result.append(data) |
111 | 108 | |
112 | 109 |
return {'data': result} |
113 | 110 | |
114 | 111 |
@endpoint( |
115 | 112 |
name='q', |
116 | 113 |
description=_('Query'), |
117 | 114 |
pattern=r'^(?P<query_slug>[\w:_-]+)/$', |
tests/test_opendatasoft.py | ||
---|---|---|
139 | 139 |
@pytest.fixture |
140 | 140 |
def query(connector): |
141 | 141 |
return Query.objects.create( |
142 | 142 |
resource=connector, |
143 | 143 |
name='Référenciel adresses de test', |
144 | 144 |
slug='my_query', |
145 | 145 |
description='Rechercher une adresse', |
146 | 146 |
dataset='referentiel-adresse-test', |
147 |
text_template='{{numero}} {{nom_rue|safe}} {{nom_commun}}',
|
|
147 |
text_template='{{numero}} {{nom_rue}} {{nom_commun}}', |
|
148 | 148 |
) |
149 | 149 | |
150 | 150 | |
151 | 151 |
def test_views(db, admin_user, app, connector): |
152 | 152 |
app = login(app) |
153 | 153 |
resp = app.get('/opendatasoft/my_connector/', status=200) |
154 | 154 |
resp = resp.click('New Query') |
155 | 155 |
resp.form['name'] = 'my query' |
... | ... | |
186 | 186 | |
187 | 187 | |
188 | 188 |
@mock.patch('passerelle.utils.Request.get') |
189 | 189 |
def test_search_using_q(mocked_get, app, connector): |
190 | 190 |
endpoint = utils.generic_endpoint_url('opendatasoft', 'search', slug=connector.slug) |
191 | 191 |
assert endpoint == '/opendatasoft/my_connector/search' |
192 | 192 |
params = { |
193 | 193 |
'dataset': 'referentiel-adresse-test', |
194 |
'text_template': '{{numero}} {{nom_rue|safe}} {{nom_commun}}',
|
|
194 |
'text_template': '{{numero}} {{nom_rue}} {{nom_commun}}', |
|
195 | 195 |
'q': "rue de l'aubepine", |
196 | 196 |
'rows': 3, |
197 | 197 |
} |
198 | 198 |
mocked_get.return_value = utils.FakedResponse(content=FAKED_CONTENT_Q_SEARCH, status_code=200) |
199 | 199 |
resp = app.get(endpoint, params=params, status=200) |
200 | 200 |
assert not resp.json['err'] |
201 | 201 |
assert len(resp.json['data']) == 3 |
202 | 202 |
# check order is kept |
... | ... | |
216 | 216 | |
217 | 217 | |
218 | 218 |
@mock.patch('passerelle.utils.Request.get') |
219 | 219 |
def test_search_using_id(mocked_get, app, connector): |
220 | 220 |
endpoint = utils.generic_endpoint_url('opendatasoft', 'search', slug=connector.slug) |
221 | 221 |
assert endpoint == '/opendatasoft/my_connector/search' |
222 | 222 |
params = { |
223 | 223 |
'dataset': 'referentiel-adresse-test', |
224 |
'text_template': '{{numero}} {{nom_rue|safe}} {{nom_commun}}',
|
|
224 |
'text_template': '{{numero}} {{nom_rue}} {{nom_commun}}', |
|
225 | 225 |
'id': '7cafcd5c692773e8b863587b2d38d6be82e023d8', |
226 | 226 |
} |
227 | 227 |
mocked_get.return_value = utils.FakedResponse(content=FAKED_CONTENT_ID_SEARCH, status_code=200) |
228 | 228 |
resp = app.get(endpoint, params=params, status=200) |
229 | 229 |
assert len(resp.json['data']) == 1 |
230 | 230 |
assert resp.json['data'][0]['text'] == "19 RUE DE L'AUBEPINE Lipsheim" |
231 | 231 | |
232 | 232 | |
233 |
- |