Skip to content

Commit 2e5ab70

Browse files
committed
fix(flask): preserve html content-type for error routes
When we introduces the direct usage of the Response type we purged the content-type and returned text/plain instead. Fix this behavior by explicitly setting the content-type and add asserts for all expected content-types.
1 parent 67f7f72 commit 2e5ab70

File tree

8 files changed

+39
-6
lines changed

8 files changed

+39
-6
lines changed

test/test_admin.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,11 +183,13 @@ def test_edit_requires_admin(db, client):
183183
resp = client.post(url_for('tracker.edit_user', username=USERNAME), follow_redirects=True,
184184
data=dict(username=USERNAME, email=EMAIL, password=PASSWORD))
185185
assert resp.status_code == Forbidden.code
186+
assert 'text/html; charset=utf-8' == resp.content_type
186187

187188

188189
@create_user(username=USERNAME, password=PASSWORD)
189190
@logged_in(role=UserRole.security_team)
190191
def test_list_user(db, client):
191192
resp = client.get(url_for('tracker.list_user'), follow_redirects=True)
192193
assert resp.status_code == 200
194+
assert 'text/html; charset=utf-8' == resp.content_type
193195
assert USERNAME in resp.data.decode()

test/test_advisory.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ def test_edit_advisory(db, client):
208208
resp = client.post(url_for('tracker.edit_advisory', advisory_id=DEFAULT_ADVISORY_ID), follow_redirects=True,
209209
data={'workaround': workaround, 'impact': impact})
210210
assert 200 == resp.status_code
211+
assert 'text/html; charset=utf-8' == resp.content_type
211212
assert_advisory_data(DEFAULT_ADVISORY_ID, workaround=workaround, impact=impact)
212213
assert 1 == advisory_count()
213214

@@ -217,6 +218,7 @@ def test_edit_advisory_not_found(db, client):
217218
resp = client.post(url_for('tracker.edit_advisory', advisory_id=DEFAULT_ADVISORY_ID), follow_redirects=True,
218219
data={'workaround': 'nothing', 'impact': 'nothing'})
219220
assert resp.status_code == NotFound.code
221+
assert 'text/html; charset=utf-8' == resp.content_type
220222

221223

222224
@create_package(name='foo', version='1.2.3-4')
@@ -360,6 +362,7 @@ def test_advisory_atom(db, client):
360362
def test_advisory_json_no_data(db, client):
361363
resp = client.get(url_for('tracker.advisory_json', postfix='/json'), follow_redirects=True)
362364
assert 200 == resp.status_code
365+
assert 'application/json; charset=utf-8' == resp.content_type
363366
data = resp.get_json()
364367
assert data == []
365368

@@ -370,6 +373,7 @@ def test_advisory_json_no_data(db, client):
370373
def test_advisory_json(db, client):
371374
resp = client.get(url_for('tracker.advisory_json', postfix='/json'), follow_redirects=True)
372375
assert 200 == resp.status_code
376+
assert 'application/json; charset=utf-8' == resp.content_type
373377
data = resp.get_json()
374378
assert len(data) == 1
375379
assert data[0]['name'] == DEFAULT_ADVISORY_ID
@@ -400,6 +404,7 @@ def test_advisory_format_issue_listing_raw(db, client):
400404
advisory_id=DEFAULT_ADVISORY_ID),
401405
follow_redirects=True)
402406
assert 200 == resp.status_code
407+
assert 'text/plain; charset=utf-8' == resp.content_type
403408
data = resp.data.decode()
404409
assert 'CVE-ID : CVE-1111-1234 CVE-1111-12345 CVE-1234-11111 CVE-1234-11112\n' + \
405410
' CVE-1234-12345 CVE-1234-123456\n' in data
@@ -466,6 +471,7 @@ def test_advisory_publish_advisory(db, client, patch_get):
466471
def test_advisory_raw(db, client):
467472
resp = client.get(url_for('tracker.show_advisory_raw', advisory_id=DEFAULT_ADVISORY_ID), follow_redirects=True)
468473
assert 200 == resp.status_code
474+
assert 'text/plain; charset=utf-8' == resp.content_type
469475
data = resp.data.decode()
470476
assert 'Arch Linux Security Advisory {}'.format(DEFAULT_ADVISORY_ID) in data
471477

test/test_cve.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,13 +236,15 @@ def test_copy_needs_login(db, client):
236236
def test_show_issue(db, client):
237237
resp = client.get(url_for('tracker.show_cve', cve=DEFAULT_ISSUE_ID, path=''))
238238
assert 200 == resp.status_code
239+
assert 'text/html; charset=utf-8' == resp.content_type
239240
assert DEFAULT_ISSUE_ID in resp.data.decode()
240241

241242

242243
@logged_in
243244
def test_show_issue_not_found(db, client):
244245
resp = client.get(url_for('tracker.show_cve', cve='CVE-2011-0000', path=''), follow_redirects=True)
245246
assert resp.status_code == NotFound.code
247+
assert 'text/html; charset=utf-8' == resp.content_type
246248

247249

248250
@create_issue
@@ -278,6 +280,7 @@ def test_delete_issue_not_found(db, client):
278280
def test_issue_json(db, client):
279281
resp = client.get(url_for('tracker.show_cve_json', cve=DEFAULT_ISSUE_ID, path='', suffix='.json'), follow_redirects=True)
280282
assert 200 == resp.status_code
283+
assert 'application/json; charset=utf-8' == resp.content_type
281284

282285
data = resp.get_json()
283286
assert DEFAULT_ISSUE_ID == data['name']
@@ -286,6 +289,7 @@ def test_issue_json(db, client):
286289
def test_issue_json_not_found(db, client):
287290
resp = client.get(url_for('tracker.show_cve_json', cve=DEFAULT_ISSUE_ID, path='', suffix='.json'), follow_redirects=True)
288291
assert resp.status_code == NotFound.code
292+
assert 'application/json; charset=utf-8' == resp.content_type
289293

290294

291295
@create_issue
@@ -426,6 +430,7 @@ def test_edit_issue_as_reporter_with_referenced_advisory_fails(db, client):
426430
resp = client.post(url_for('tracker.edit_cve', cve=DEFAULT_ISSUE_ID), follow_redirects=True,
427431
data=default_issue_dict(dict(description='changed')))
428432
assert Forbidden.code == resp.status_code
433+
assert 'text/html; charset=utf-8' == resp.content_type
429434

430435
data = resp.data.decode()
431436
assert f'Edited {DEFAULT_ISSUE_ID}' not in data

test/test_group.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ def test_copy_needs_login(db, client):
143143
def test_show_group_not_found(db, client):
144144
resp = client.get(url_for('tracker.show_group', avg='AVG-42'), follow_redirects=True)
145145
assert resp.status_code == NotFound.code
146+
assert 'text/html; charset=utf-8' == resp.content_type
146147

147148

148149
@logged_in
@@ -329,11 +330,20 @@ def test_show_group_sort_cve_entries(db, client):
329330
'CVE-1111-12345',
330331
'CVE-1111-1234'] == cves
331332

333+
@create_group(id=DEFAULT_GROUP_ID, packages=['foo'], affected='1.2.3-3', fixed='1.2.3-4')
334+
@create_advisory(id=DEFAULT_ADVISORY_ID, group_package_id=DEFAULT_GROUP_ID, advisory_type=issue_types[1])
335+
def test_show_group(db, client):
336+
resp = client.get(url_for('tracker.show_group', avg=DEFAULT_GROUP_NAME), follow_redirects=True)
337+
assert 200 == resp.status_code
338+
assert 'text/html; charset=utf-8' == resp.content_type
339+
assert DEFAULT_GROUP_NAME in resp.data.decode()
340+
332341
@create_group(id=DEFAULT_GROUP_ID, packages=['foo'], affected='1.2.3-3', fixed='1.2.3-4')
333342
@create_advisory(id=DEFAULT_ADVISORY_ID, group_package_id=DEFAULT_GROUP_ID, advisory_type=issue_types[1])
334343
def test_show_group_json(db, client):
335344
resp = client.get(url_for('tracker.show_group_json', avg=DEFAULT_GROUP_NAME, postfix='/json'), follow_redirects=True)
336345
assert 200 == resp.status_code
346+
assert 'application/json; charset=utf-8' == resp.content_type
337347
data = resp.get_json()
338348
assert data['name'] == DEFAULT_GROUP_NAME
339349
assert data['issues'] == [DEFAULT_ISSUE_ID]
@@ -344,6 +354,7 @@ def test_show_group_json(db, client):
344354
def test_show_group_json_not_found(db, client):
345355
resp = client.get(url_for('tracker.show_group_json', avg=DEFAULT_GROUP_NAME, postfix='/json'), follow_redirects=True)
346356
assert NotFound.code == resp.status_code
357+
assert 'application/json; charset=utf-8' == resp.content_type
347358

348359
@create_package(name='foo', version='1.2.3-4')
349360
@create_group(id=DEFAULT_GROUP_ID, packages=['foo'], affected='1.2.3-3', fixed='1.2.3-4')

test/test_index.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
from flask import url_for
2-
from werkzeug.exceptions import NotFound
32

43
from .conftest import DEFAULT_GROUP_ID
54
from .conftest import DEFAULT_GROUP_NAME
@@ -12,6 +11,7 @@
1211
def test_index(db, client):
1312
resp = client.get(url_for('tracker.index'), follow_redirects=True)
1413
assert 200 == resp.status_code
14+
assert 'text/html; charset=utf-8' == resp.content_type
1515
assert DEFAULT_GROUP_NAME not in resp.data.decode()
1616

1717

@@ -37,6 +37,7 @@ def test_index_json(db, client):
3737
resp = client.get(url_for('tracker.index_json', only_vulernable=False, path='all.json'), follow_redirects=True)
3838
assert 200 == resp.status_code
3939
data = resp.get_json()
40+
assert 'application/json; charset=utf-8' == resp.content_type
4041
assert len(data) == 1
4142
assert data[0]['name'] == DEFAULT_GROUP_NAME
4243

test/test_login.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
def test_login_view(db, client):
1717
resp = client.get(url_for('tracker.login'))
1818
assert 200 == resp.status_code
19+
assert 'text/html; charset=utf-8' == resp.content_type
1920

2021

2122
@create_user
@@ -31,6 +32,7 @@ def test_login_invalid_credentials(db, client):
3132
resp = client.post(url_for('tracker.login'), data={'username': DEFAULT_USERNAME,
3233
'password': 'N' * TRACKER_PASSWORD_LENGTH_MIN})
3334
assert_not_logged_in(resp, status_code=Unauthorized.code)
35+
assert 'text/html; charset=utf-8' == resp.content_type
3436
assert ERROR_INVALID_USERNAME_PASSWORD in resp.data.decode()
3537

3638

test/test_package.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
def test_show_package_json(db, client):
1919
resp = client.get(url_for('tracker.show_package_json', pkgname='foo', suffix='/json'), follow_redirects=True)
2020
assert 200 == resp.status_code
21+
assert 'application/json; charset=utf-8' == resp.content_type
2122
data = resp.get_json()
2223
assert len(data['groups']) == 1
2324
assert len(data['versions']) == 1
@@ -29,10 +30,14 @@ def test_show_package_json(db, client):
2930
def test_show_package_json_not_found(db, client):
3031
resp = client.get(url_for('tracker.show_package_json', pkgname='foo', suffix='/json'), follow_redirects=True)
3132
assert NotFound.code == resp.status_code
33+
assert 'application/json; charset=utf-8' == resp.content_type
34+
3235

3336
def test_show_package_not_found(db, client):
3437
resp = client.get(url_for('tracker.show_package', pkgname='foo'), follow_redirects=True)
3538
assert NotFound.code == resp.status_code
39+
assert 'text/html; charset=utf-8' == resp.content_type
40+
3641

3742
@create_package(name='foo', version='1.2.3-4')
3843
@create_group(id=DEFAULT_GROUP_ID, packages=['foo'], affected='1.2.3-3', fixed='1.2.3-4')
@@ -42,4 +47,5 @@ def test_show_package(db, client):
4247
html = AssertionHTMLParser()
4348
html.feed(resp.data.decode())
4449
assert 200 == resp.status_code
50+
assert 'text/html; charset=utf-8' == resp.content_type
4551
assert 'foo' in resp.data.decode()

tracker/view/error.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
from os import urandom
55
from random import randint
66

7+
from flask import make_response
78
from flask import render_template
8-
from werkzeug import Response
99
from werkzeug.exceptions import BadRequest
1010
from werkzeug.exceptions import Forbidden
1111
from werkzeug.exceptions import Gone
@@ -34,10 +34,10 @@ def wrapped(*args, **kwargs):
3434
def handle_error(e, code, json=False):
3535
if json:
3636
return {'message': e}, code
37-
return Response(render_template('error.html',
38-
smiley=smileys_sad[randint(0, len(smileys_sad) - 1)],
39-
text=e,
40-
title='{}'.format(code)), code)
37+
return make_response(render_template('error.html',
38+
smiley=smileys_sad[randint(0, len(smileys_sad) - 1)],
39+
text=e,
40+
title='{}'.format(code)), code)
4141

4242

4343
@errorhandler(NotFound.code)

0 commit comments

Comments
 (0)