diff --git a/ciscosma.json b/ciscosma.json index 3d4b819..2607031 100644 --- a/ciscosma.json +++ b/ciscosma.json @@ -294,6 +294,215 @@ ], "versions": "EQ(*)" }, + { + "action": "search tracking messages", + "identifier": "search_tracking_messages", + "description": "Search for messages in message tracking", + "type": "investigate", + "read_only": true, + "parameters": { + "start_date": { + "description": "Start date in ISO format (YYYY-MM-DDThh:mm:ss.000Z)", + "data_type": "string", + "required": true, + "order": 0 + }, + "end_date": { + "description": "End date in ISO format (YYYY-MM-DDThh:mm:ss.000Z)", + "data_type": "string", + "required": true, + "order": 1 + }, + "cisco_host": { + "description": "Specific appliance to search (default: All_Hosts)", + "data_type": "string", + "required": false, + "order": 2 + }, + "offset": { + "description": "Number of records to skip/offset", + "data_type": "numeric", + "required": false, + "order": 3 + }, + "limit": { + "description": "Max number of records to return", + "data_type": "numeric", + "required": false, + "order": 4 + }, + "sender": { + "description": "Filter by sender email address", + "data_type": "string", + "required": false, + "order": 5 + }, + "recipient": { + "description": "Filter by recipient email address", + "data_type": "string", + "required": false, + "order": 6 + }, + "subject": { + "description": "Filter by message subject", + "data_type": "string", + "required": false, + "order": 7 + }, + "message_id": { + "description": "Filter by message ID (mid)", + "data_type": "string", + "required": false, + "order": 8 + }, + "status": { + "description": "Filter by message status", + "data_type": "string", + "required": false, + "order": 9, + "value_list": ["Delivered", "Hard Bounced", "Soft Bounced", "Spam", "Virus Positive", "Quarantined"] + } + }, + "output": [ + { + "data_path": "action_result.status", + "data_type": "string" + }, + { + "data_path": "action_result.parameter.start_date", + "data_type": "string" + }, + { + "data_path": "action_result.parameter.end_date", + "data_type": "string" + }, + { + "data_path": "action_result.parameter.cisco_host", + "data_type": "string" + }, + { + "data_path": "action_result.parameter.offset", + "data_type": "numeric" + }, + { + "data_path": "action_result.parameter.limit", + "data_type": "numeric" + }, + { + "data_path": "action_result.parameter.sender", + "data_type": "string" + }, + { + "data_path": "action_result.parameter.recipient", + "data_type": "string" + }, + { + "data_path": "action_result.parameter.subject", + "data_type": "string" + }, + { + "data_path": "action_result.parameter.message_id", + "data_type": "string" + }, + { + "data_path": "action_result.parameter.status", + "data_type": "string" + }, + { + "data_path": "action_result.data.*.attributes.direction", + "data_type": "string" + }, + { + "data_path": "action_result.data.*.attributes.icid", + "data_type": "numeric" + }, + { + "data_path": "action_result.data.*.attributes.senderGroup", + "data_type": "string" + }, + { + "data_path": "action_result.data.*.attributes.sender", + "data_type": "string", + "contains": ["email"] + }, + { + "data_path": "action_result.data.*.attributes.replyTo", + "data_type": "string" + }, + { + "data_path": "action_result.data.*.attributes.timestamp", + "data_type": "string" + }, + { + "data_path": "action_result.data.*.attributes.hostName", + "data_type": "string" + }, + { + "data_path": "action_result.data.*.attributes.subject", + "data_type": "string" + }, + { + "data_path": "action_result.data.*.attributes.mid", + "data_type": "numeric", + "contains": ["cisco sma message id"] + }, + { + "data_path": "action_result.data.*.attributes.isCompleteData", + "data_type": "boolean" + }, + { + "data_path": "action_result.data.*.attributes.messageStatus", + "data_type": "string" + }, + { + "data_path": "action_result.data.*.attributes.mailPolicy", + "data_type": "string" + }, + { + "data_path": "action_result.data.*.attributes.senderIp", + "data_type": "string", + "contains": ["ip"] + }, + { + "data_path": "action_result.data.*.attributes.verdictChart", + "data_type": "string" + }, + { + "data_path": "action_result.data.*.attributes.senderDomain", + "data_type": "string" + }, + { + "data_path": "action_result.data.*.attributes.recipient", + "data_type": "string", + "contains": ["email"] + }, + { + "data_path": "action_result.data.*.attributes.sbrs", + "data_type": "string" + }, + { + "data_path": "action_result.data.*.attributes.serialNumber", + "data_type": "string" + }, + { + "data_path": "action_result.summary.total_messages", + "data_type": "numeric" + }, + { + "data_path": "action_result.summary.messages_returned", + "data_type": "numeric" + }, + { + "data_path": "action_result.summary.bad_records", + "data_type": "numeric" + }, + { + "data_path": "action_result.message", + "data_type": "string" + } + ], + "versions": "EQ(*)" + }, { "action": "get tracking details", "identifier": "get_message_tracking_details", diff --git a/ciscosma_connector.py b/ciscosma_connector.py index b1a8a71..8083578 100644 --- a/ciscosma_connector.py +++ b/ciscosma_connector.py @@ -27,6 +27,7 @@ CISCOSMA_GET_MESSAGE_TRACKING_DETAILS_ENDPOINT, CISCOSMA_GET_TOKEN_ENDPOINT, CISCOSMA_SEARCH_MESSAGES_ENDPOINT, + CISCOSMA_SEARCH_TRACKING_MESSAGES_ENDPOINT, CISCOSMA_VALID_FILTER_OPERATORS, CISCOSMA_VALID_ORDER_BY, CISCOSMA_VALID_ORDER_DIRECTIONS, @@ -251,6 +252,53 @@ def _handle_get_message_details(self, param): return action_result.set_status(phantom.APP_SUCCESS, "Successfully retrieved message details") + def _handle_search_tracking_messages(self, param): + action_result = self.add_action_result(ActionResult(dict(param))) + + start_date = param.get("start_date") + end_date = param.get("end_date") + if not start_date or not end_date: + return action_result.set_status(phantom.APP_ERROR, "Both 'start_date' and 'end_date' parameters are required") + + params = {"startDate": start_date, "endDate": end_date, "searchOption": "messages"} + + # TODO: Confirm these params (documentation is unclear) + optional_params = { + "cisco_host": "ciscoHost", + "offset": "offset", + "limit": "limit", + "sender": "sender", + "recipient": "recipient", + "subject": "subject", + "message_id": "mid", + "status": "status", + } + + for param_name, api_param in optional_params.items(): + if value := param.get(param_name): + params[api_param] = value + + ret_val, response = self._make_authenticated_request(action_result, CISCOSMA_SEARCH_TRACKING_MESSAGES_ENDPOINT, params=params) + + if phantom.is_fail(ret_val): + return action_result.get_status() + + try: + messages = response.get("data", []) + total_count = response.get("meta", {}).get("totalCount", 0) + bad_records = response.get("meta", {}).get("num_bad_records", 0) + + for message in messages: + action_result.add_data(message) + + summary = {"total_messages": total_count, "messages_returned": len(messages), "bad_records": bad_records} + action_result.update_summary(summary) + + except Exception as e: + return action_result.set_status(phantom.APP_ERROR, f"Error parsing response: {str(e)}") + + return action_result.set_status(phantom.APP_SUCCESS, "Successfully retrieved tracking messages") + def _handle_get_message_tracking_details(self, param): action_result = self.add_action_result(ActionResult(dict(param))) @@ -309,6 +357,7 @@ def handle_action(self, param): "get_message_details": self._handle_get_message_details, "get_message_tracking_details": self._handle_get_message_tracking_details, "search_quarantine_messages": self._handle_search_quarantine_messages, + "search_tracking_messages": self._handle_search_tracking_messages, } action = self.get_action_identifier() diff --git a/ciscosma_consts.py b/ciscosma_consts.py index ee8f24b..f4130df 100644 --- a/ciscosma_consts.py +++ b/ciscosma_consts.py @@ -23,7 +23,7 @@ CISCOSMA_GET_MESSAGE_DETAILS_ENDPOINT = "/sma/api/v2.0/quarantine/messages/details" CISCOSMA_GET_MESSAGE_TRACKING_DETAILS_ENDPOINT = "/sma/api/v2.0/message-tracking/details" CISCOSMA_SEARCH_MESSAGES_ENDPOINT = "/sma/api/v2.0/quarantine/messages" - +CISCOSMA_SEARCH_TRACKING_MESSAGES_ENDPOINT = "/sma/api/v2.0/message-tracking/messages" # Future endpoints # GET /api/v2.0/reporting/report?resource_attribute