diff --git a/Packs/CommonScripts/ReleaseNotes/1_11_81.md b/Packs/CommonScripts/ReleaseNotes/1_11_81.md new file mode 100644 index 000000000000..0205b3b0741d --- /dev/null +++ b/Packs/CommonScripts/ReleaseNotes/1_11_81.md @@ -0,0 +1,6 @@ + +#### Scripts + +##### New: DisplayHTMLWithImages + +- Script for dynamic-section to display HTML with embedded images. (Available from Cortex XSOAR 6.5.0). diff --git a/Packs/CommonScripts/Scripts/DisplayHTMLWithImages/DisplayHTMLWithImages.py b/Packs/CommonScripts/Scripts/DisplayHTMLWithImages/DisplayHTMLWithImages.py new file mode 100644 index 000000000000..906a8c9515dd --- /dev/null +++ b/Packs/CommonScripts/Scripts/DisplayHTMLWithImages/DisplayHTMLWithImages.py @@ -0,0 +1,73 @@ +import re +import demistomock as demisto # noqa: F401 +from CommonServerPython import * # noqa: F401 + + +def create_html_with_images(email_html='', entry_id_list=None): + if not entry_id_list: + return email_html + + account_name = get_tenant_account_name() + + for entry_id in entry_id_list: + # Handling inline attachments from Gmail mailboxes + if re.search(f'src="[^>]+"(?=[^>]+alt="{entry_id[0]}")', email_html): + email_html = re.sub(f'src="[^>]+"(?=[^>]+alt="{entry_id[0]}")', + f'src={account_name}/entry/download/{entry_id[1]}', + email_html + ) + # Handling inline attachments from Outlook mailboxes + # Note: when tested, entry id list and inline attachments were in the same order, so there was no need in + # special validation that the right src was being replaced. + else: + email_html = re.sub('(src="cid(.*?"))', + f'src={account_name}/entry/download/{entry_id[1]}', + email_html, count=1, + ) + return email_html + + +def get_entry_id_list(attachments, files): + """Get the email attachments and create entry id list. + Args: + attachments (list): The attachments of the email. + files (list): The uploaded files in the context. + Returns: + list. Attachments entries ids list. + """ + if not (attachments and files): + return [] + + entry_id_list = [] + files = [files] if not isinstance(files, list) else files + for attachment in attachments: + attachment_name = attachment.get('name', '') + for file in files: + if attachment_name == file.get('Name'): + entry_id_list.append((attachment_name, file.get('EntryID'))) + demisto.info(f'\n\n idlist \n\n{entry_id_list}') + return entry_id_list + + +def main(args): + incident = demisto.incident() + custom_fields = incident.get('CustomFields', {}) + html_body = custom_fields.get('renderedhtml', '') or \ + custom_fields.get('emailhtml', '') or \ + custom_fields.get('emailbody', '') + attachments = incident.get('attachment', {}) + files = demisto.context().get('File', []) + + if 'src="cid' in html_body: + entry_id_list = get_entry_id_list(attachments, files) + html_body = create_html_with_images(html_body, entry_id_list) + + return_results({ + 'ContentsFormat': formats['html'], + 'Type': entryTypes['note'], + 'Contents': html_body, + }) + + +if __name__ in ('__builtin__', 'builtins', '__main__'): + main(demisto.args()) diff --git a/Packs/CommonScripts/Scripts/DisplayHTMLWithImages/DisplayHTMLWithImages.yml b/Packs/CommonScripts/Scripts/DisplayHTMLWithImages/DisplayHTMLWithImages.yml new file mode 100644 index 000000000000..c03a4a64afdc --- /dev/null +++ b/Packs/CommonScripts/Scripts/DisplayHTMLWithImages/DisplayHTMLWithImages.yml @@ -0,0 +1,17 @@ +commonfields: + id: DisplayHTMLWithImages + version: -1 +name: DisplayHTMLWithImages +script: '' +type: python +subtype: python3 +comment: Display HTML with embedded images. +tags: +- dynamic-section +system: true +scripttarget: 0 +runonce: false +fromversion: 6.5.0 +dockerimage: demisto/python3:3.10.11.61265 +tests: +- No tests (auto formatted) diff --git a/Packs/CommonScripts/Scripts/DisplayHTMLWithImages/DisplayHTMLWithImages_test.py b/Packs/CommonScripts/Scripts/DisplayHTMLWithImages/DisplayHTMLWithImages_test.py new file mode 100644 index 000000000000..f084cd2b1ab1 --- /dev/null +++ b/Packs/CommonScripts/Scripts/DisplayHTMLWithImages/DisplayHTMLWithImages_test.py @@ -0,0 +1,120 @@ +import demistomock as demisto +import pytest + +EMAIL_HTML = """ +
image 1: +
image_1.png
image 2: +
image_2.png

+
On Thu, Oct 22, 2020 at 1:56 AM Some Person < +some.person@demistodev.onmicrosoft.com> wrote:
+
+

please add multiple inline images

""" + +EMAIL_HTML_NO_ALT = """ + + + +
+ +
+ +
+""" + +EXPECTED_RESULT_1 = """ +
image 1: +
image_1.png
image 2: +
image_2.png

+
On Thu, Oct 22, 2020 at 1:56 AM Some Person < +some.person@demistodev.onmicrosoft.com> wrote:
+
+

please add multiple inline images

""" + +EXPECTED_RESULT_2 = """ +
image 1: +
image_1.png
\ +
image 2: +
image_2.png
\ +

+
On Thu, Oct 22, 2020 at 1:56 AM Some Person < +some.person@demistodev.onmicrosoft.com> wrote:
+
+

please add multiple inline images

""" + +EXPECTED_RESULT_NO_ALT = """ + + + +
+ +
+ +
+""" + + +@pytest.mark.parametrize( + "email_html,expected", + [ + (EMAIL_HTML, EXPECTED_RESULT_2), + (EMAIL_HTML_NO_ALT, EXPECTED_RESULT_NO_ALT) + ] +) +def test_main_mt(mocker, email_html, expected): + """ + Given + - Html contained images src + When + - All images were uploaded to the server + Then + - The images' src attribute would be replaced as expected with account tenant name + """ + import DisplayHTMLWithImages + from DisplayHTMLWithImages import main + + mocked_incident = { + 'CustomFields': { + 'emailbody': email_html + }, + 'attachment': [ + {'name': 'image_1.png'}, + {'name': 'image_2.png'} + ] + } + mocked_files = [ + {'Name': 'image_1.png', 'EntryID': '37@119'}, + {'Name': 'image_2.png', 'EntryID': '38@120'} + ] + + mocker.patch.object(demisto, 'demistoUrls', return_value={'server': 'https://localhost:8443:/acc_test_tenant'}) + mocker.patch.object(demisto, 'incident', return_value=mocked_incident) + mocker.patch.object(demisto, 'context', return_value={'File': mocked_files}) + mocker.patch.object(DisplayHTMLWithImages, 'return_results') + + main({}) + + assert expected in DisplayHTMLWithImages.return_results.call_args[0][0]['Contents'] diff --git a/Packs/CommonScripts/Scripts/DisplayHTMLWithImages/README.md b/Packs/CommonScripts/Scripts/DisplayHTMLWithImages/README.md new file mode 100644 index 000000000000..59995f5c1c07 --- /dev/null +++ b/Packs/CommonScripts/Scripts/DisplayHTMLWithImages/README.md @@ -0,0 +1,17 @@ +Display HTML with embedded images. + +## Script Data +--- + +| **Name** | **Description** | +| --- | --- | +| Script Type | python3 | +| Tags | dynamic-section | + +## Inputs +--- +There are no inputs for this script. + +## Outputs +--- +There are no outputs for this script. diff --git a/Packs/CommonScripts/pack_metadata.json b/Packs/CommonScripts/pack_metadata.json index dc5a3145b0f4..96efadc4c10e 100644 --- a/Packs/CommonScripts/pack_metadata.json +++ b/Packs/CommonScripts/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Common Scripts", "description": "Frequently used scripts pack.", "support": "xsoar", - "currentVersion": "1.11.80", + "currentVersion": "1.11.81", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "",