misc: do not decorate uploaded HTML files (#87331)
gitea/wcs/pipeline/head This commit looks good
Details
gitea/wcs/pipeline/head This commit looks good
Details
This commit is contained in:
parent
8a7c779d91
commit
b48214feac
|
@ -238,6 +238,42 @@ def test_form_file_field_image_submit(pub):
|
||||||
assert '<img alt="" src="tempfile?' not in resp.text
|
assert '<img alt="" src="tempfile?' not in resp.text
|
||||||
|
|
||||||
|
|
||||||
|
def test_form_file_field_html_submit(pub):
|
||||||
|
FormDef.wipe()
|
||||||
|
formdef = FormDef()
|
||||||
|
formdef.name = 'test'
|
||||||
|
formdef.fields = [fields.FileField(id='0', label='file')]
|
||||||
|
formdef.store()
|
||||||
|
formdef.data_class().wipe()
|
||||||
|
|
||||||
|
html_content = b'<html><body>hello</body></html>'
|
||||||
|
upload = Upload('test.html', html_content, 'text/html')
|
||||||
|
|
||||||
|
app = get_app(pub)
|
||||||
|
resp = app.get('/test/')
|
||||||
|
resp.forms[0]['f0$file'] = upload
|
||||||
|
resp = resp.forms[0].submit('submit')
|
||||||
|
assert 'Check values then click submit.' in resp.text
|
||||||
|
tempfile_id = resp.pyquery('.fileinfo .filename a').attr.href.split('=')[1]
|
||||||
|
|
||||||
|
resp_tempfile = app.get('/test/tempfile?t=%s' % tempfile_id)
|
||||||
|
assert resp_tempfile.body == html_content
|
||||||
|
|
||||||
|
resp = resp.form.submit('submit').follow()
|
||||||
|
assert resp.click('test.html').follow().content_type == 'text/html'
|
||||||
|
assert resp.click('test.html').follow().body == html_content
|
||||||
|
|
||||||
|
# check it's also served raw from backoffice
|
||||||
|
user = create_user(pub)
|
||||||
|
user.is_admin = True
|
||||||
|
user.store()
|
||||||
|
app = get_app(pub)
|
||||||
|
login(app, username='foo', password='foo')
|
||||||
|
resp = app.get(formdef.data_class().select()[0].get_backoffice_url())
|
||||||
|
assert resp.click('test.html').follow().content_type == 'text/html'
|
||||||
|
assert resp.click('test.html').follow().body == html_content
|
||||||
|
|
||||||
|
|
||||||
def test_form_file_field_submit_document_type(pub):
|
def test_form_file_field_submit_document_type(pub):
|
||||||
FormDef.wipe()
|
FormDef.wipe()
|
||||||
formdef = FormDef()
|
formdef = FormDef()
|
||||||
|
|
|
@ -388,7 +388,7 @@ class NamedDataSourcePage(Directory):
|
||||||
def preview_block(self):
|
def preview_block(self):
|
||||||
get_request().disable_error_notifications = True
|
get_request().disable_error_notifications = True
|
||||||
get_request().ignore_session = True
|
get_request().ignore_session = True
|
||||||
get_response().filter = {'raw': True}
|
get_response().raw = True
|
||||||
data_source = self.datasource.extended_data_source
|
data_source = self.datasource.extended_data_source
|
||||||
try:
|
try:
|
||||||
items = get_structured_items(data_source)
|
items = get_structured_items(data_source)
|
||||||
|
|
|
@ -401,7 +401,7 @@ class UsersDirectory(Directory):
|
||||||
r += htmltext('</div>')
|
r += htmltext('</div>')
|
||||||
|
|
||||||
if get_request().form.get('ajax') == 'true':
|
if get_request().form.get('ajax') == 'true':
|
||||||
get_response().filter = {'raw': True}
|
get_response().raw = True
|
||||||
return r.getvalue()
|
return r.getvalue()
|
||||||
|
|
||||||
ident_methods = get_cfg('identification', {}).get('methods', [])
|
ident_methods = get_cfg('identification', {}).get('methods', [])
|
||||||
|
|
|
@ -161,7 +161,7 @@ class NamedWsCallPage(Directory):
|
||||||
def usage(self):
|
def usage(self):
|
||||||
get_request().disable_error_notifications = True
|
get_request().disable_error_notifications = True
|
||||||
get_request().ignore_session = True
|
get_request().ignore_session = True
|
||||||
get_response().filter = {'raw': True}
|
get_response().raw = True
|
||||||
|
|
||||||
usage = {}
|
usage = {}
|
||||||
|
|
||||||
|
|
|
@ -717,7 +717,7 @@ class ManagementDirectory(Directory):
|
||||||
|
|
||||||
if get_request().form.get('ajax') == 'true':
|
if get_request().form.get('ajax') == 'true':
|
||||||
get_request().ignore_session = True
|
get_request().ignore_session = True
|
||||||
get_response().filter = {'raw': True}
|
get_response().raw = True
|
||||||
return r.getvalue()
|
return r.getvalue()
|
||||||
|
|
||||||
get_response().filter['sidebar'] = self.get_global_listing_sidebar(
|
get_response().filter['sidebar'] = self.get_global_listing_sidebar(
|
||||||
|
@ -2442,7 +2442,7 @@ class FormPage(Directory, TempfileDirectoryMixin):
|
||||||
|
|
||||||
if get_request().form.get('ajax') == 'true':
|
if get_request().form.get('ajax') == 'true':
|
||||||
get_request().ignore_session = True
|
get_request().ignore_session = True
|
||||||
get_response().filter = {'raw': True}
|
get_response().raw = True
|
||||||
r = TemplateIO(html=True)
|
r = TemplateIO(html=True)
|
||||||
r += multi_form.render()
|
r += multi_form.render()
|
||||||
r += get_session().display_message()
|
r += get_session().display_message()
|
||||||
|
@ -3129,7 +3129,7 @@ class FormPage(Directory, TempfileDirectoryMixin):
|
||||||
|
|
||||||
if get_request().form.get('ajax') == 'true':
|
if get_request().form.get('ajax') == 'true':
|
||||||
get_request().ignore_session = True
|
get_request().ignore_session = True
|
||||||
get_response().filter = {'raw': True}
|
get_response().raw = True
|
||||||
return r.getvalue()
|
return r.getvalue()
|
||||||
|
|
||||||
page = TemplateIO(html=True)
|
page = TemplateIO(html=True)
|
||||||
|
@ -3368,13 +3368,13 @@ class FormBackOfficeStatusPage(FormStatusPage):
|
||||||
|
|
||||||
def lateral_block(self):
|
def lateral_block(self):
|
||||||
self.check_receiver()
|
self.check_receiver()
|
||||||
get_response().filter = {'raw': True}
|
get_response().raw = True
|
||||||
response = self.get_lateral_block()
|
response = self.get_lateral_block()
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def user_pending_forms(self):
|
def user_pending_forms(self):
|
||||||
self.check_receiver()
|
self.check_receiver()
|
||||||
get_response().filter = {'raw': True}
|
get_response().raw = True
|
||||||
response = self.get_user_pending_forms()
|
response = self.get_user_pending_forms()
|
||||||
|
|
||||||
# preemptive locking of forms
|
# preemptive locking of forms
|
||||||
|
@ -4159,7 +4159,7 @@ class FormBackOfficeStatusPage(FormStatusPage):
|
||||||
or get_publisher().get_backoffice_root().is_accessible('workflows')
|
or get_publisher().get_backoffice_root().is_accessible('workflows')
|
||||||
):
|
):
|
||||||
raise errors.AccessForbiddenError()
|
raise errors.AccessForbiddenError()
|
||||||
get_response().filter = {'raw': True}
|
get_response().raw = True
|
||||||
return self.test_tool_result()
|
return self.test_tool_result()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -175,7 +175,7 @@ class FormFillPage(PublicFormFillPage):
|
||||||
return super()._q_index(*args, **kwargs)
|
return super()._q_index(*args, **kwargs)
|
||||||
|
|
||||||
def lateral_block(self):
|
def lateral_block(self):
|
||||||
get_response().filter = {'raw': True}
|
get_response().raw = True
|
||||||
response = self.get_lateral_block()
|
response = self.get_lateral_block()
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,7 @@ class TemplateWithFallbackView(TemplateView):
|
||||||
response.reason_phrase = self.quixote_response.reason_phrase
|
response.reason_phrase = self.quixote_response.reason_phrase
|
||||||
elif request.headers.get('X-Popup') == 'true':
|
elif request.headers.get('X-Popup') == 'true':
|
||||||
response = HttpResponse('<div><div class="popup-content">%s</div></div>' % context['body'])
|
response = HttpResponse('<div><div class="popup-content">%s</div></div>' % context['body'])
|
||||||
elif 'raw' in (getattr(self.quixote_response, 'filter') or {}):
|
elif self.quixote_response.raw:
|
||||||
# used for raw HTML snippets (for example in the test tool
|
# used for raw HTML snippets (for example in the test tool
|
||||||
# results in inspect page).
|
# results in inspect page).
|
||||||
response = HttpResponse(context['body'])
|
response = HttpResponse(context['body'])
|
||||||
|
@ -161,7 +161,7 @@ class CompatWcsPublisher(WcsPublisher):
|
||||||
if response.status_code == 304:
|
if response.status_code == 304:
|
||||||
# clients don't like to receive content with a 304
|
# clients don't like to receive content with a 304
|
||||||
return ''
|
return ''
|
||||||
if response.content_type != 'text/html':
|
if response.content_type != 'text/html' or response.raw:
|
||||||
return output
|
return output
|
||||||
if not hasattr(response, 'filter') or not response.filter:
|
if not hasattr(response, 'filter') or not response.filter:
|
||||||
return output
|
return output
|
||||||
|
|
|
@ -112,7 +112,7 @@ class FileDirectory(Directory):
|
||||||
|
|
||||||
# force potential HTML upload to be used as-is (not decorated with theme)
|
# force potential HTML upload to be used as-is (not decorated with theme)
|
||||||
# and with minimal permissions
|
# and with minimal permissions
|
||||||
response.filter = {}
|
response.raw = True
|
||||||
response.set_header(
|
response.set_header(
|
||||||
'Content-Security-Policy',
|
'Content-Security-Policy',
|
||||||
'default-src \'none\'; img-src %s;' % get_request().build_absolute_uri(),
|
'default-src \'none\'; img-src %s;' % get_request().build_absolute_uri(),
|
||||||
|
@ -1074,7 +1074,7 @@ class TempfileDirectoryMixin:
|
||||||
|
|
||||||
# force potential HTML upload to be used as-is (not decorated with theme)
|
# force potential HTML upload to be used as-is (not decorated with theme)
|
||||||
# and with minimal permissions
|
# and with minimal permissions
|
||||||
response.filter = {}
|
response.raw = True
|
||||||
response.set_header(
|
response.set_header(
|
||||||
'Content-Security-Policy',
|
'Content-Security-Policy',
|
||||||
'default-src \'none\'; img-src %s;' % get_request().build_absolute_uri(),
|
'default-src \'none\'; img-src %s;' % get_request().build_absolute_uri(),
|
||||||
|
|
|
@ -28,6 +28,7 @@ class HTTPResponse(quixote.http_response.HTTPResponse):
|
||||||
javascript_code_parts = None
|
javascript_code_parts = None
|
||||||
css_includes = None
|
css_includes = None
|
||||||
after_jobs = None
|
after_jobs = None
|
||||||
|
raw = False # in case of html content, send result as is (True) or embedded in page template (False)
|
||||||
|
|
||||||
def __init__(self, charset=None, **kwargs):
|
def __init__(self, charset=None, **kwargs):
|
||||||
quixote.http_response.HTTPResponse.__init__(self, charset=charset, **kwargs)
|
quixote.http_response.HTTPResponse.__init__(self, charset=charset, **kwargs)
|
||||||
|
|
|
@ -78,7 +78,7 @@ def error_page(error_message, error_title=None, location_hint=None):
|
||||||
def get_decorate_vars(body, response, generate_breadcrumb=True, **kwargs):
|
def get_decorate_vars(body, response, generate_breadcrumb=True, **kwargs):
|
||||||
from .publisher import get_cfg
|
from .publisher import get_cfg
|
||||||
|
|
||||||
if response.content_type != 'text/html':
|
if response.content_type != 'text/html' or response.raw:
|
||||||
return {'body': body}
|
return {'body': body}
|
||||||
|
|
||||||
if get_request().get_header('x-popup') == 'true':
|
if get_request().get_header('x-popup') == 'true':
|
||||||
|
|
Loading…
Reference in New Issue