misc: directly serve cards file fields when url is signed (#55374)
This commit is contained in:
parent
07bc7d4b6f
commit
d2496c3973
|
@ -355,6 +355,35 @@ def test_cards_http_auth_access(pub, local_user):
|
|||
assert resp.json['err_desc'] == 'unsufficient roles'
|
||||
|
||||
|
||||
def test_card_get_file(pub):
|
||||
pub.role_class.wipe()
|
||||
|
||||
CardDef.wipe()
|
||||
carddef = CardDef()
|
||||
carddef.name = 'test'
|
||||
carddef.fields = [
|
||||
fields.StringField(id='0', label='foobar', varname='foobar'),
|
||||
fields.FileField(id='3', label='foobar4', varname='file'),
|
||||
]
|
||||
carddef.store()
|
||||
|
||||
upload = PicklableUpload('test.txt', 'text/plain', 'ascii')
|
||||
upload.receive([b'file content'])
|
||||
|
||||
carddef.data_class().wipe()
|
||||
formdata = carddef.data_class()()
|
||||
formdata.data = {'0': 'blah', '3': upload}
|
||||
formdata.just_created()
|
||||
formdata.store()
|
||||
|
||||
resp = get_app(pub).get(sign_uri('/api/cards/test/%s/' % formdata.id))
|
||||
file_url = resp.json['fields']['file']['url']
|
||||
assert get_app(pub).get(file_url, status=403)
|
||||
|
||||
resp = get_app(pub).get(sign_uri(file_url), status=200)
|
||||
assert resp.text == 'file content'
|
||||
|
||||
|
||||
def test_post_invalid_json(pub, local_user):
|
||||
resp = get_app(pub).post(
|
||||
'/api/cards/test/submit', params='not a json payload', content_type='application/json', status=400
|
||||
|
|
|
@ -51,6 +51,9 @@ class CardData(FormData):
|
|||
def get_author_qualification(self):
|
||||
return None
|
||||
|
||||
def get_file_base_url(self):
|
||||
return '%sdownload' % self.get_api_url()
|
||||
|
||||
def just_created(self):
|
||||
super().just_created()
|
||||
if self.submission_agent_id:
|
||||
|
|
|
@ -1438,7 +1438,7 @@ class FileField(WidgetField):
|
|||
return t.getvalue()
|
||||
|
||||
def get_download_url(self, formdata, **kwargs):
|
||||
return '%sdownload?%s' % (formdata.get_url(), self.get_download_query_string(**kwargs))
|
||||
return '%s?%s' % (formdata.get_file_base_url(), self.get_download_query_string(**kwargs))
|
||||
|
||||
def get_opendocument_node_value(self, value, formdata=None, **kwargs):
|
||||
show_link = True
|
||||
|
|
|
@ -70,8 +70,8 @@ def get_dict_with_varnames(fields, data, formdata=None, varnames_only=False):
|
|||
if value and hasattr(value, 'base_filename'):
|
||||
new_data['var_%s' % field.varname] = value.base_filename
|
||||
if formdata is not None:
|
||||
new_data['var_%s_url' % field.varname] = '%sdownload?f=%s' % (
|
||||
formdata.get_url(),
|
||||
new_data['var_%s_url' % field.varname] = '%s?f=%s' % (
|
||||
formdata.get_file_base_url(),
|
||||
field.id,
|
||||
)
|
||||
elif raw_value is not None:
|
||||
|
@ -698,6 +698,9 @@ class FormData(StorableObject):
|
|||
def get_api_url(self):
|
||||
return '%s%s/' % (self.formdef.get_api_url(), self.id)
|
||||
|
||||
def get_file_base_url(self):
|
||||
return '%sdownload' % self.get_url()
|
||||
|
||||
def get_display_id(self):
|
||||
return str(self.id_display or self.id)
|
||||
|
||||
|
|
|
@ -36,11 +36,11 @@ from ..qommon import _, errors, get_logger, misc, template
|
|||
class FileDirectory(Directory):
|
||||
_q_exports = []
|
||||
_lookup_methods = ['lookup_file_field']
|
||||
thumbnails = False
|
||||
|
||||
def __init__(self, formdata, reference):
|
||||
def __init__(self, formdata, reference, thumbnails=False):
|
||||
self.formdata = formdata
|
||||
self.reference = reference
|
||||
self.thumbnails = thumbnails
|
||||
|
||||
def lookup_file_field(self, filename):
|
||||
try:
|
||||
|
@ -674,7 +674,8 @@ class FormStatusPage(Directory, FormTemplateMixin):
|
|||
return get_publisher().get_root_url()
|
||||
|
||||
def download(self):
|
||||
self.check_receiver()
|
||||
if not is_url_signed():
|
||||
self.check_receiver()
|
||||
try:
|
||||
fn = get_request().form['f']
|
||||
if '$' in fn:
|
||||
|
@ -704,8 +705,18 @@ class FormStatusPage(Directory, FormTemplateMixin):
|
|||
else:
|
||||
raise errors.TraversalError()
|
||||
|
||||
if is_url_signed():
|
||||
# serve file directly, no redirect to URL with path ending with filename
|
||||
file_directory = FileDirectory(
|
||||
self.filled,
|
||||
reference=fn,
|
||||
thumbnails=bool(get_request().form.get('thumbnail') and file.can_thumbnail()),
|
||||
)
|
||||
return file_directory._q_lookup(component=None)
|
||||
|
||||
if getattr(file, 'base_filename'):
|
||||
file_url += urllib.parse.quote(file.base_filename)
|
||||
|
||||
return redirect(file_url)
|
||||
|
||||
@classmethod
|
||||
|
|
Loading…
Reference in New Issue