misc: add option for file received via webservice action to be hidden (#62727) #1404

Merged
fpeters merged 1 commits from wip/62727-webservice-file-no-history into main 2024-04-15 16:52:43 +02:00
2 changed files with 70 additions and 25 deletions

View File

@ -488,6 +488,26 @@ def test_webservice_call(http_requests, pub):
assert isinstance(attachment, AttachmentEvolutionPart)
assert attachment.base_filename == 'xxx.xml'
assert attachment.content_type == 'text/xml'
assert attachment.display_in_history is True
attachment.fp.seek(0)
assert attachment.fp.read(5) == b'<?xml'
formdata.workflow_data = None
# check storing response as attachment, not displayed in history
item = WebserviceCallStatusItem()
item.url = 'http://remote.example.net/xml'
item.varname = 'xxx'
item.response_type = 'attachment'
item.record_errors = True
item.attach_file_to_history = False
item.perform(formdata)
assert formdata.workflow_data.get('xxx_status') == 200
assert formdata.workflow_data.get('xxx_content_type') == 'text/xml'
attachment = formdata.evolution[-1].parts[-1]
assert isinstance(attachment, AttachmentEvolutionPart)
assert attachment.base_filename == 'xxx.xml'
assert attachment.content_type == 'text/xml'
assert attachment.display_in_history is False
attachment.fp.seek(0)
assert attachment.fp.read(5) == b'<?xml'
formdata.workflow_data = None

View File

@ -126,6 +126,7 @@ class WebserviceCallStatusItem(WorkflowStatusItem):
_method = None
response_type = 'json'
backoffice_filefield_id = None
attach_file_to_history = True # legacy behaviour
action_on_app_error = ':pass'
action_on_4xx = ':stop'
@ -179,6 +180,7 @@ class WebserviceCallStatusItem(WorkflowStatusItem):
'response_type',
'varname',
'request_signature_key',
'attach_file_to_history',
'backoffice_filefield_id',
'action_on_app_error',
'action_on_4xx',
@ -197,8 +199,11 @@ class WebserviceCallStatusItem(WorkflowStatusItem):
if self.method not in ('POST', 'PUT', 'PATCH', 'DELETE'):
parameters.remove('post')
parameters.remove('post_data')
if self.response_type != 'attachment' and 'backoffice_filefield_id' in parameters:
parameters.remove('backoffice_filefield_id')
if self.response_type != 'attachment':
if 'backoffice_filefield_id' in parameters:
parameters.remove('backoffice_filefield_id')
if 'attach_file_to_history' in parameters:
parameters.remove('attach_file_to_history')
if self.response_type != 'json':
parameters.remove('action_on_bad_data')
return parameters
@ -321,6 +326,21 @@ class WebserviceCallStatusItem(WorkflowStatusItem):
value=self.varname,
hint=_('This is used as prefix for webservice result variable names.'),
)
if 'attach_file_to_history' in parameters:
form.add(
CheckboxWidget,
'%sattach_file_to_history' % prefix,
title=_('Include in form history'),
value=self.attach_file_to_history,
attrs={
'data-dynamic-display-child-of': '%sresponse_type' % prefix,
'data-dynamic-display-value': response_types.get('attachment'),
},
default_value=self.__class__.attach_file_to_history,
tab=('response', _('Response')),
)
if 'backoffice_filefield_id' in parameters:
options = self.get_backoffice_filefield_options()
if options:
@ -494,26 +514,23 @@ class WebserviceCallStatusItem(WorkflowStatusItem):
)
if app_error_code_header:
workflow_data['%s_app_error_header' % self.varname] = app_error_code_header
if status in (204, 205):
pass # not returning any content
elif (status // 100) == 2 and app_error_code == 0:
self.store_response(formdata, response, data, workflow_data)
else: # on error, record data if it is JSON
try:
d = json.loads(force_str(data))
except (ValueError, TypeError):
pass
else:
workflow_data['%s_error_response' % self.varname] = d
formdata.update_workflow_data(workflow_data)
formdata.store()
if self.backoffice_filefield_id:
if (status // 100) == 2 and app_error_code == 0 and status not in (204, 205):
filename, content_type = self.get_attachment_data(response)
self.store_in_backoffice_filefield(
formdata, self.backoffice_filefield_id, filename, content_type, data
)
if status in (204, 205):
pass # not returning any content
elif (status // 100) == 2 and app_error_code == 0:
self.store_response(formdata, response, data, workflow_data)
elif self.varname: # on error, record data if it is JSON
try:
d = json.loads(force_str(data))
except (ValueError, TypeError):
pass
else:
workflow_data['%s_error_response' % self.varname] = d
if workflow_data:
formdata.update_workflow_data(workflow_data)
formdata.store()
recorded_error = False
if app_error_code != 0:
@ -543,7 +560,7 @@ class WebserviceCallStatusItem(WorkflowStatusItem):
return filename, content_type
def store_response(self, formdata, response, data, workflow_data):
if self.response_type == 'json':
if self.response_type == 'json' and self.varname:
try:
d = json.loads(force_str(data))
except (ValueError, TypeError) as e:
@ -562,16 +579,24 @@ class WebserviceCallStatusItem(WorkflowStatusItem):
formdata.id_display = d.get('data', {}).get('display_id')
elif d.get('display_id'):
formdata.id_display = d.get('display_id')
else: # store result as attachment
elif self.response_type == 'attachment':
# store result as attachment
filename, content_type = self.get_attachment_data(response)
workflow_data['%s_content_type' % self.varname] = content_type
workflow_data['%s_length' % self.varname] = len(data)
if self.varname:
workflow_data['%s_content_type' % self.varname] = content_type
workflow_data['%s_length' % self.varname] = len(data)
fp_content = io.BytesIO(data)
attachment = AttachmentEvolutionPart(
filename, fp_content, content_type=content_type, varname=self.varname
)
attachment.display_in_history = self.attach_file_to_history
formdata.evolution[-1].add_part(attachment)
if self.backoffice_filefield_id:
self.store_in_backoffice_filefield(
formdata, self.backoffice_filefield_id, filename, content_type, data
)
def action_on_error(
self, action, formdata, response=None, data=None, exception=None, recorded_error=False
):