diff --git a/Packs/Armorblox/.pack-ignore b/Packs/Armorblox/.pack-ignore index 4079f094496f..e57b613e07f8 100644 --- a/Packs/Armorblox/.pack-ignore +++ b/Packs/Armorblox/.pack-ignore @@ -2,4 +2,9 @@ ignore=IM111 [file:classifier-Armorblox_-_Classifier.json] -ignore=BA101 \ No newline at end of file +ignore=BA101 + +[known_words] +Armorblox +armorblox-sdk +Classifiers diff --git a/Packs/Armorblox/Classifiers/classifier-Armorblox_-_Classifier.json b/Packs/Armorblox/Classifiers/classifier-Armorblox_-_Classifier.json index d535a38ae2ff..d6899277e540 100644 --- a/Packs/Armorblox/Classifiers/classifier-Armorblox_-_Classifier.json +++ b/Packs/Armorblox/Classifiers/classifier-Armorblox_-_Classifier.json @@ -4,44 +4,21 @@ "feed": false, "id": "e8ded555-9409-4d33-842c-45d29b6ab31c", "keyTypeMap": { - "Abuse Report": "Armorblox Abuse Mailbox Report", - "Extortion": "Armorblox Inbound Threat", - "Graymail": "Armorblox Inbound Threat", - "Impersonation: Employee": "Armorblox Inbound Threat", - "Impersonation: VIP": "Armorblox Inbound Threat", - "Impersonation: VIP (Requesting Gift Card)": "Armorblox Inbound Threat", - "Impersonation:Employee": "Armorblox Inbound Threat", - "Impersonation:VIP": "Armorblox Inbound Threat", - "PCI Bank Account Number": "Armorblox Outbound Threat", - "PCI Credit Card Number": "Armorblox Outbound Threat", - "PCI IBAN": "Armorblox Outbound Threat", - "PCI Routing Number": "Armorblox Outbound Threat", - "PII Passport": "Armorblox Outbound Threat", - "PII Social Security Number": "Armorblox Outbound Threat", - "PII Tax Number": "Armorblox Outbound Threat", - "Passwords": "Armorblox Outbound Threat", - "Payment Fraud (External)": "Armorblox Inbound Threat", - "Payment Fraud (Internal)": "Armorblox Inbound Threat", - "Payroll Fraud": "Armorblox Inbound Threat", - "Phish URL (Attachment)": "Armorblox Inbound Threat", - "Phish URL (Mail Body)": "Armorblox Inbound Threat", - "Potential Account Compromise": "Armorblox Inbound Threat", - "Ransomware": "Armorblox Inbound Threat", - "Social Engineering": "Armorblox Inbound Threat" + "ABUSE_INCIDENT_TYPE": "Armorblox Abuse Mailbox Report", + "DLP_INCIDENT_TYPE": "Armorblox Outbound Threat", + "THREAT_INCIDENT_TYPE": "Armorblox Inbound Threat" }, "name": "Armorblox - Classifier", "transformer": { "complex": { - "accessor": "", + "accessor": "incident_type", "filters": [], - "root": "policy_names", + "root": "incidents", "transformers": [ { "args": { "descending": { - "isContext": false, "value": { - "complex": null, "simple": "false" } } @@ -49,12 +26,10 @@ "operator": "sort" }, { - "args": {}, "operator": "FirstArrayElement" } ] - }, - "simple": "" + } }, "type": "classification", "version": -1, diff --git a/Packs/Armorblox/Integrations/Armorblox/Armorblox.py b/Packs/Armorblox/Integrations/Armorblox/Armorblox.py old mode 100644 new mode 100755 index 8eaffef022e6..79aa5e7c5b3d --- a/Packs/Armorblox/Integrations/Armorblox/Armorblox.py +++ b/Packs/Armorblox/Integrations/Armorblox/Armorblox.py @@ -1,4 +1,7 @@ +from typing import Any + import demistomock as demisto # noqa: F401 +from armorblox.client import Client as AbxBaseClient from CommonServerPython import * # noqa: F401 import dateparser import requests @@ -17,53 +20,38 @@ API_KEY = demisto.params().get('apikey') verify_certificate = not demisto.params().get('insecure', False) proxy = demisto.params().get('proxy', False) -BASE_URL = f"https://{TENANT_NAME}.armorblox.io/api/v1beta1/organizations/{TENANT_NAME}" - -payload: Dict = {} -headers = { - 'x-ab-authorization': f'{API_KEY}' -} -class Client(BaseClient): +class Client(AbxBaseClient): """Client class to interact with the service API This Client implements API calls, and does not contain any Demisto logic. Should only do requests and return data. - It inherits from BaseClient defined in CommonServer Python. - Most calls use _http_request() that handles proxy, SSL verification, etc. """ - def get_incidents(self, orderBy="ASC", pageSize=None, pageToken=None, first_fetch=None) -> List[Dict[str, Any]]: - request_params: Dict[str, Any] = {} + def get_incidents(self, orderBy='ASC', pageSize=None, pageToken=None, first_fetch=None): + request_params = {'orderBy': orderBy} - request_params['orderBy'] = orderBy if pageToken == -1 and first_fetch: request_params['timeFilter'] = first_fetch elif pageToken and first_fetch: request_params['timeFilter'] = first_fetch request_params['pageToken'] = pageToken + if pageSize: request_params['pageSize'] = pageSize - return self._http_request( - method='GET', - url_suffix='/incidents', - params=request_params - ) + + response_json, next_page_token, total_count = self.incidents.list(params=request_params) + return response_json, next_page_token def get_incident_details(self, incident_id): - request_params: Dict[str, Any] = {} - return self._http_request( - method='GET', - url_suffix='/incidents/{}'.format(incident_id), - params=request_params - ) + return self.incidents.get(incident_id) def makehash(): return collections.defaultdict(makehash) -def test_module(client: Client) -> str: +def test_module(client: Client) -> str: # pragma: no coverage """Tests API connectivity and authentication' Returning 'ok' indicates that the integration works like it is supposed to. Connection to the service is successful. @@ -86,27 +74,16 @@ def test_module(client: Client) -> str: return 'ok' -def get_page_token(client, pageToken=None): - response = client.get_incidents(pageSize=MAX_INCIDENTS_TO_FETCH, pageToken=pageToken, first_fetch=FIRST_FETCH) - if 'next_page_token' in response.keys(): - return response['next_page_token'] - else: - return None - - def get_incidents_list(client, pageToken, first_fetch): """ Hits the Armorblox API and returns the list of fetched incidents. """ - response = client.get_incidents(pageSize=MAX_INCIDENTS_TO_FETCH, pageToken=pageToken, first_fetch=first_fetch) - results = [] - if 'incidents' in response.keys(): - results = response['incidents'] - + results, next_page_token = client.get_incidents(pageSize=MAX_INCIDENTS_TO_FETCH, pageToken=pageToken, + first_fetch=first_fetch) # For each incident, get the details and extract the message_id for result in results: result['message_ids'] = get_incident_message_ids(client, result["id"]) - return results + return results, next_page_token def get_incident_message_ids(client, incident_id): @@ -152,17 +129,17 @@ def fetch_incidents_command(client): start_time: Any # pageToken fetched from demisto lastRun pageToken = int() - response = {} incidents = [] if 'start_time' not in last_run.keys(): pageToken = -1 - response = client.get_incidents(pageSize=1, pageToken=pageToken, first_fetch=FIRST_FETCH) - if 'incidents' in response.keys(): - start_time = response['incidents'][0]['date'] + response, next_page_token = client.get_incidents(pageSize=1, pageToken=pageToken, first_fetch=FIRST_FETCH) + if response: + response = response[0] + start_time = response.get('date') start_time = dateparser.parse(start_time) - message_ids = get_incident_message_ids(client, response['incidents'][0]['id']) - response['incidents'][0]['message_ids'] = message_ids - curr_incident = {'rawJSON': json.dumps(response['incidents'][0]), 'details': json.dumps(response['incidents'][0])} + message_ids = get_incident_message_ids(client, response.get('id')) + response['message_ids'] = message_ids + curr_incident = {'rawJSON': json.dumps(response), 'details': json.dumps(response)} incidents.append(curr_incident) if last_run and 'pageToken' in last_run.keys(): @@ -172,18 +149,16 @@ def fetch_incidents_command(client): start_time = dateparser.parse(last_run.get('start_time')) start_time = start_time.timestamp() - incidents_data = get_incidents_list(client, pageToken=pageToken, first_fetch=FIRST_FETCH) - pageToken = get_page_token(client, pageToken=pageToken) + incidents_data, pageToken = get_incidents_list(client, pageToken=pageToken, first_fetch=FIRST_FETCH) last_time = start_time for incident in incidents_data: - dt = incident['date'] + dt = incident.get('date') parsed_date = dateparser.parse(dt) assert parsed_date is not None, f'failed parsing {dt}' - dt = parsed_date.timestamp() + dt = int(parsed_date.timestamp()) # Update last run and add incident if the incident is newer than last fetch - if dt > start_time: - + if dt > int(start_time): curr_incident = {'rawJSON': json.dumps(incident), 'details': json.dumps(incident)} last_time = dt incidents.append(curr_incident) @@ -192,17 +167,15 @@ def fetch_incidents_command(client): return incidents -def main(): +def main(): # pragma: no coverage ''' EXECUTION ''' - LOG('command is %s' % (demisto.command(), )) + demisto.info(f'Command being called is {demisto.command()}') try: client = Client( - base_url=BASE_URL, - verify=verify_certificate, - headers=headers, - proxy=proxy) - + api_key=API_KEY, + instance_name=TENANT_NAME + ) if demisto.command() == "fetch-incidents": incident_results = fetch_incidents_command(client) demisto.incidents(incident_results) diff --git a/Packs/Armorblox/Integrations/Armorblox/Armorblox.yml b/Packs/Armorblox/Integrations/Armorblox/Armorblox.yml index 3d061d11fa15..fa3924c4f887 100644 --- a/Packs/Armorblox/Integrations/Armorblox/Armorblox.yml +++ b/Packs/Armorblox/Integrations/Armorblox/Armorblox.yml @@ -73,7 +73,7 @@ script: - contextPath: Armorblox.Threat.remediation_actions description: Should be the remediation action name for the incident under inspection type: string - dockerimage: demisto/python3:3.10.5.31928 + dockerimage: demisto/armorblox:1.0.0.33173 isfetch: true runonce: false script: '' diff --git a/Packs/Armorblox/Integrations/Armorblox/Armorblox_test.py b/Packs/Armorblox/Integrations/Armorblox/Armorblox_test.py old mode 100644 new mode 100755 index ad1fd28401e1..68abac379ab5 --- a/Packs/Armorblox/Integrations/Armorblox/Armorblox_test.py +++ b/Packs/Armorblox/Integrations/Armorblox/Armorblox_test.py @@ -1,167 +1,115 @@ -# import demistomock as demisto -# from CommonServerPython import * -# from CommonServerUserPython import * -"""Base Integration for Cortex XSOAR - Unit Tests file - -Pytest Unit Tests: all function names must start with "test_" - -More details: https://xsoar.pan.dev/docs/integrations/unit-testing - -You must add at least a Unit Test function for every XSOAR command -you are implementing with your integration -""" -from CommonServerPython import * -from Armorblox import Client, get_incident_message_ids, get_remediation_action, get_incidents_list, get_page_token, \ - fetch_incidents_command -import io -import json -BASE_URL = "https://test.com" -API_KEY = "" -payload: Dict = {} -headers = {'Authorization': f"Bearer {API_KEY}"} - - -class MockResponse: - def __init__(self, data, status_code): - self.data = data - self.text = str(data) - self.status_code = status_code - - -def util_load_json(path): - with io.open(path, mode='r', encoding='utf-8') as f: - return json.loads(f.read()) - - -def util_load_response(path): - with io.open(path, mode='r', encoding='utf-8') as f: - return MockResponse(f.read(), 200) - - -def mock_client(mocker, http_request_result=None, throw_error=False): - mocker.patch.object(demisto, 'getIntegrationContext', return_value={'current_refresh_token': 'refresh_token'}) - client = Client( - base_url=BASE_URL, - verify=False, - proxy=False, - auth=None, - headers=headers - ) - if http_request_result: - mocker.patch.object(client, '_http_request', return_value=http_request_result) - - if throw_error: - err_msg = "Error in API call [400] - BAD REQUEST" - mocker.patch.object(client, '_http_request', side_effect=DemistoException(err_msg, res={})) - - return client - - -def test_get_incident_message_ids(requests_mock): - """Tests get_incident_message_ids function. - Configures requests_mock instance to generate the appropriate start_scan - API response when the correct start_scan API request is performed. Checks - the output of the function with the expected output. - """ - mock_response = util_load_json("test_data/test_get_incident_message_ids.json") - requests_mock.get('https://test.com/api/v1/incidents/3875', json=mock_response) - - client = Client( - base_url='https://test.com/api/v1', - verify=False, - headers={ - 'Authentication': 'Bearer some_api_key' - } - ) - response = get_incident_message_ids(client, '3875') - assert response == ["n9orMIXBQF6wKtRYpwb0Dg@geopod-ismtpd-4-0"] - - -def test_get_remediation_action(requests_mock): - """Tests the armorblox-check-remediation-action command function. - Configures requests_mock instance to generate the appropriate - get_alert API response, loaded from a local JSON file. Checks - the output of the command function with the expected output. - """ - - mock_response = util_load_json("test_data/test_get_remediation_action.json") - requests_mock.get('https://test.com/api/v1/incidents/3875', json=mock_response) - - client = Client( - base_url='https://test.com/api/v1', - verify=False, - headers={ - 'Authentication': 'Bearer some_api_key' - } - ) - response = get_remediation_action(client, "3875") - assert response.outputs['remediation_actions'] == 'ALERT' - - -def test_get_incidents_list(requests_mock): - """Tests the fetch_incidents_command command function. - Configures requests_mock instance to generate the appropriate - get_alert API response, loaded from a local JSON file. Checks - the output of the command function with the expected output. - """ - - mock_response = util_load_json("test_data/test_get_incidents_list.json") - requests_mock.get('https://test.com/api/v1/incidents?orderBy=ASC&pageToken=51&timeFilter=lastDay', json=mock_response) - # response for the incident id, to populate message ids - mock_response_for_incident_id = util_load_json("test_data/test_response_for_6484.json") - requests_mock.get('https://test.com/api/v1/incidents/6484', json=mock_response_for_incident_id) - client = Client( - base_url='https://test.com/api/v1', - verify=False, - headers={ - 'Authentication': 'Bearer some_api_key' - } - ) - response = get_incidents_list(client, pageToken=51, first_fetch="lastDay") - assert response == util_load_json("test_data/test_response_for_get_incidents_list.json")['incidents'] - - -def test_get_page_token(requests_mock): - """Tests the get_page_token command function. - Configures requests_mock instance to generate the appropriate - get_alert API response, loaded from a local JSON file. Checks - the output of the command function with the expected output. - """ - - mock_response = util_load_json("test_data/test_get_incidents_list.json") - requests_mock.get('https://test.com/api/v1/incidents?orderBy=ASC', json=mock_response) - - client = Client( - base_url='https://test.com/api/v1', - verify=False, - headers={ - 'Authentication': 'Bearer some_api_key' - } - ) - response = get_page_token(client) - assert response == "1" - - -def test_fetch_incidents_command(requests_mock): - """Tests the fetch_incidents_command command function. - Configures requests_mock instance to generate the appropriate - get_alert API response, loaded from a local JSON file. Checks - the output of the command function with the expected output. - """ - # get incidents function - incidents_response = util_load_json("test_data/test_get_incidents_list.json") - requests_mock.get('https://test.com/api/v1/incidents?orderBy=ASC&pageSize=1', json=incidents_response) - requests_mock.get('https://test.com/api/v1/incidents?orderBy=ASC', json=incidents_response) - # get message ids function - mock_response_for_incident_id = util_load_json("test_data/test_response_for_6484.json") - requests_mock.get('https://test.com/api/v1/incidents/6484', json=mock_response_for_incident_id) - client = Client( - base_url='https://test.com/api/v1', - verify=False, - headers={ - 'Authentication': 'Bearer some_api_key' - } - ) - response = fetch_incidents_command(client) - assert ('rawJSON' in response[0].keys()) is True - assert ('details' in response[0].keys()) is True +# import demistomock as demisto +# from CommonServerPython import * +# from CommonServerUserPython import * +"""Base Integration for Cortex XSOAR - Unit Tests file + +Pytest Unit Tests: all function names must start with "test_" + +More details: https://xsoar.pan.dev/docs/integrations/unit-testing + +You must add at least a Unit Test function for every XSOAR command +you are implementing with your integration +""" +from CommonServerPython import * +from Armorblox import Client, get_incident_message_ids, get_remediation_action, get_incidents_list, \ + fetch_incidents_command +import io +import json + +API_KEY = 'any-api-key' +TENANT_NAME = 'TestIntegration' +ARMORBLOX_INCIDENT_API_PATH = "api/v1beta1/organizations/{}/incidents" +url = "https://{}.armorblox.io/{}".format(TENANT_NAME, ARMORBLOX_INCIDENT_API_PATH.format(TENANT_NAME)) + + +class MockResponse: + def __init__(self, data, status_code): + self.data = data + self.text = str(data) + self.status_code = status_code + + +def util_load_json(path): + with io.open(path, mode='r', encoding='utf-8') as f: + return json.loads(f.read()) + + +def util_load_response(path): + with io.open(path, mode='r', encoding='utf-8') as f: + return MockResponse(f.read(), 200) + + +def mock_client(mocker, http_request_result=None, throw_error=False): + mocker.patch.object(demisto, 'getIntegrationContext', return_value={'current_refresh_token': 'refresh_token'}) + client = Client(api_key=API_KEY, instance_name=TENANT_NAME) + if http_request_result: + mocker.patch.object(client, '_http_request', return_value=http_request_result) + + if throw_error: + err_msg = "Error in API call [400] - BAD REQUEST" + mocker.patch.object(client, '_http_request', side_effect=DemistoException(err_msg, res={})) + + return client + + +def test_get_incident_message_ids(requests_mock): + """Tests get_incident_message_ids function. + Configures requests_mock instance to generate the appropriate start_scan + API response when the correct start_scan API request is performed. Checks + the output of the function with the expected output. + """ + mock_response = util_load_json("test_data/test_get_incident_message_ids.json") + requests_mock.get(url + '/3875', json=mock_response) + client = Client(api_key=API_KEY, instance_name=TENANT_NAME) + response = get_incident_message_ids(client, '3875') + assert response == ["n9orMIXBQF6wKtRYpwb0Dg@geopod-ismtpd-4-0"] + + +def test_get_remediation_action(requests_mock): + """Tests the armorblox-check-remediation-action command function. + Configures requests_mock instance to generate the appropriate + get_alert API response, loaded from a local JSON file. Checks + the output of the command function with the expected output. + """ + + mock_response = util_load_json("test_data/test_get_remediation_action.json") + requests_mock.get(url + '/3875', json=mock_response) + client = Client(api_key=API_KEY, instance_name=TENANT_NAME) + response = get_remediation_action(client, "3875") + assert response.outputs['remediation_actions'] == 'ALERT' + + +def test_get_incidents_list(requests_mock): + """Tests the get_incidents_list command function. + Configures requests_mock instance to generate the appropriate + get_alert API response, loaded from a local JSON file. Checks + the output of the command function with the expected output. + """ + + mock_response = util_load_json("test_data/test_get_incidents_list.json") + requests_mock.get(url + '?orderBy=ASC&pageToken=51&timeFilter=lastDay', json=mock_response) + # response for the incident id, to populate message ids + mock_response_for_incident_id = util_load_json("test_data/test_response_for_6484.json") + requests_mock.get(url + '/6484', json=mock_response_for_incident_id) + client = Client(api_key=API_KEY, instance_name=TENANT_NAME) + response, pageToken = get_incidents_list(client, pageToken=51, first_fetch="lastDay") + assert response == util_load_json("test_data/test_response_for_get_incidents_list.json")['incidents'] + + +def test_fetch_incidents_command(requests_mock): + """Tests the fetch_incidents_command command function. + Configures requests_mock instance to generate the appropriate + get_alert API response, loaded from a local JSON file. Checks + the output of the command function with the expected output. + """ + # get incidents function + incidents_response = util_load_json("test_data/test_get_incidents_list.json") + requests_mock.get(url + '?orderBy=ASC&pageSize=1', json=incidents_response) + requests_mock.get(url + '?orderBy=ASC', json=incidents_response) + # get message ids function + mock_response_for_incident_id = util_load_json("test_data/test_response_for_6484.json") + requests_mock.get(url + '/6484', json=mock_response_for_incident_id) + client = Client(api_key=API_KEY, instance_name=TENANT_NAME) + response = fetch_incidents_command(client) + assert ('rawJSON' in response[0].keys()) is True + assert ('details' in response[0].keys()) is True diff --git a/Packs/Armorblox/Playbooks/Armorblox_Needs_Review.yml b/Packs/Armorblox/Playbooks/Armorblox_Needs_Review.yml index be37e03d99dc..71bd4b983691 100644 --- a/Packs/Armorblox/Playbooks/Armorblox_Needs_Review.yml +++ b/Packs/Armorblox/Playbooks/Armorblox_Needs_Review.yml @@ -1,5 +1,4 @@ -description: This playbook sends email alerts to admins for Armorblox incidents that - need review. +description: This playbook sends email alerts to admins for Armorblox incidents that need review. id: Armorblox Needs Review inputs: - description: Receiver's mailing address. @@ -12,28 +11,28 @@ outputs: - contextPath: Armorblox.Threat.remediation_actions description: Remediation Action for the incident under inspection. type: string -starttaskid: "0" +starttaskid: '0' tasks: - "0": - id: "0" + '0': + id: '0' ignoreworker: false isautoswitchedtoquietmode: false isoversize: false nexttasks: '#none#': - - "1" + - '1' note: false quietmode: 0 separatecontext: false skipunavailable: false task: - brand: "" - id: cecebc00-e9a7-4238-8ee3-254fe6f9a58d + brand: '' + id: 6f38882d-c3f9-4739-8aae-3226975468fd iscommand: false - name: "" + name: '' version: -1 description: '' - taskid: cecebc00-e9a7-4238-8ee3-254fe6f9a58d + taskid: 6f38882d-c3f9-4739-8aae-3226975468fd timertriggers: [] type: start view: |- @@ -43,14 +42,14 @@ tasks: "y": 50 } } - "1": - id: "1" + '1': + id: '1' ignoreworker: false isautoswitchedtoquietmode: false isoversize: false nexttasks: '#none#': - - "3" + - '3' note: false quietmode: 0 scriptarguments: @@ -61,13 +60,13 @@ tasks: task: brand: Armorblox description: 'Check the recommended remediation action for any incident ' - id: 4f2885fc-4161-48e6-8b9d-f0ff38dd208b + id: 81858c3d-9ba7-4b81-8d22-d38593093271 iscommand: true name: Get Remediation Action script: Armorblox|||armorblox-check-remediation-action type: regular version: -1 - taskid: 4f2885fc-4161-48e6-8b9d-f0ff38dd208b + taskid: 81858c3d-9ba7-4b81-8d22-d38593093271 timertriggers: [] type: regular view: |- @@ -77,36 +76,35 @@ tasks: "y": 190 } } - "2": - id: "2" + '2': + id: '2' ignoreworker: false isautoswitchedtoquietmode: false isoversize: false nexttasks: '#none#': - - "5" + - '5' note: false quietmode: 0 scriptarguments: htmlBody: - simple: Hello,

Armorblox Incident Id - ${incident.armorbloxincidentid} - Needs Review

Thank you. + simple: Hello,

Armorblox Incident Id - ${incident.armorbloxincidentid}
Remediation Action - ${Armorblox.Threat.remediation_actions}

Thank you. subject: - simple: NEEDS REVIEW + simple: ${incident.armorbloxincidentid} - ${Armorblox.Threat.remediation_actions} to: simple: ${inputs.recipient_mail_address} separatecontext: false skipunavailable: false task: - brand: "" + brand: '' description: Send an email - id: a999be99-a0f7-45fb-8644-59e868f8c437 + id: 1b55a08e-bf26-44ee-8cb3-e42c90bcd7d9 iscommand: true name: Send Email script: '|||send-mail' type: regular version: -1 - taskid: a999be99-a0f7-45fb-8644-59e868f8c437 + taskid: 1b55a08e-bf26-44ee-8cb3-e42c90bcd7d9 timertriggers: [] type: regular view: |- @@ -116,7 +114,7 @@ tasks: "y": 570 } } - "3": + '3': conditions: - condition: - - left: @@ -127,29 +125,37 @@ tasks: right: value: simple: NEEDS REVIEW - label: "YES" - id: "3" + - operator: isEqualString + left: + value: + simple: Armorblox.Threat.remediation_actions + iscontext: true + right: + value: + simple: WILL_AUTO_REMEDIATE + label: YES + id: '3' ignoreworker: false isautoswitchedtoquietmode: false isoversize: false nexttasks: '#default#': - - "4" - "YES": - - "2" + - '4' + YES: + - '2' note: false quietmode: 0 separatecontext: false skipunavailable: false task: - brand: "" + brand: '' description: Check whether a review is needed - id: 1b7e1042-8e54-4f9b-8d16-7b923311f95e + id: b81094a7-a36f-4cd8-8791-c5a2c27846ce iscommand: false name: Is Review Needed? type: condition version: -1 - taskid: 1b7e1042-8e54-4f9b-8d16-7b923311f95e + taskid: b81094a7-a36f-4cd8-8791-c5a2c27846ce timertriggers: [] type: condition view: |- @@ -159,8 +165,8 @@ tasks: "y": 370 } } - "4": - id: "4" + '4': + id: '4' ignoreworker: false isautoswitchedtoquietmode: false isoversize: false @@ -169,14 +175,14 @@ tasks: separatecontext: false skipunavailable: false task: - brand: "" + brand: '' description: Prints text to war room (Markdown supported) - id: 4c254bec-e5ef-4d22-81c5-f7b24be3afe7 + id: 5aa4df92-e0bb-4585-8369-8df289b54b3a iscommand: false name: Done type: title version: -1 - taskid: 4c254bec-e5ef-4d22-81c5-f7b24be3afe7 + taskid: 5aa4df92-e0bb-4585-8369-8df289b54b3a timertriggers: [] type: title view: |- @@ -186,14 +192,14 @@ tasks: "y": 960 } } - "5": - id: "5" + '5': + id: '5' ignoreworker: false isautoswitchedtoquietmode: false isoversize: false nexttasks: '#none#': - - "4" + - '4' note: false quietmode: 0 scriptarguments: @@ -202,15 +208,15 @@ tasks: separatecontext: false skipunavailable: false task: - brand: "" + brand: '' description: Prints text to war room (Markdown supported) - id: 57a8db76-266f-4556-84d2-0c651bbc17bf + id: 5ed7008c-bfe0-4d52-8b9b-d8c42faf308b iscommand: false name: Mail Sent Successful - script: Print type: regular version: -1 - taskid: 57a8db76-266f-4556-84d2-0c651bbc17bf + scriptName: Print + taskid: 5ed7008c-bfe0-4d52-8b9b-d8c42faf308b timertriggers: [] type: regular view: |- diff --git a/Packs/Armorblox/ReleaseNotes/1_0_4.md b/Packs/Armorblox/ReleaseNotes/1_0_4.md new file mode 100644 index 000000000000..636837ecaf27 --- /dev/null +++ b/Packs/Armorblox/ReleaseNotes/1_0_4.md @@ -0,0 +1,13 @@ + +#### Classifiers +##### Armorblox - Classifier +- Modified the existing condition to send email notification. This playbook now sends an email if the remediation action is **ALERT** or **WILL_AUTO_REMEDIATE**. + +#### Integrations +##### Armorblox +- Modified code to leverage the **armorblox-sdk** package. +- Updated the Docker image to: *demisto/armorblox:1.0.0.33173*. + +#### Playbooks +##### Armorblox Needs Review +- Changed the deciding variable from **policy_names** to **incident_type**. diff --git a/Packs/Armorblox/pack_metadata.json b/Packs/Armorblox/pack_metadata.json index 5405ca60aca2..b93e8ae61e8a 100644 --- a/Packs/Armorblox/pack_metadata.json +++ b/Packs/Armorblox/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Armorblox", "description": "Armorblox is an API-based platform that stops targeted email attacks, protects sensitive data, and automates incident response.", "support": "partner", - "currentVersion": "1.0.3", + "currentVersion": "1.0.4", "author": "Armorblox", "url": "https://www.armorblox.com/", "email": "support@armorblox.com",