Skip to content

Commit

Permalink
PAPP-35194 search quaratine messages action
Browse files Browse the repository at this point in the history
  • Loading branch information
grokas-splunk committed Dec 16, 2024
1 parent a1b6fbb commit 3236f70
Show file tree
Hide file tree
Showing 3 changed files with 265 additions and 29 deletions.
164 changes: 164 additions & 0 deletions ciscosma.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,170 @@
"output": [],
"versions": "EQ(*)"
},
{
"action": "search quarantine messages",
"identifier": "search_quarantine_messages",
"description": "Search for messages in the spam quarantine",
"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
},
"order_by": {
"description": "Field to sort results by",
"data_type": "string",
"required": false,
"order": 2,
"value_list": ["from_address", "to_address", "subject"]
},
"order_direction": {
"description": "Sort direction",
"data_type": "string",
"required": false,
"order": 3,
"value_list": ["asc", "desc"]
},
"offset": {
"description": "Number of records to skip/offset",
"data_type": "numeric",
"required": false,
"order": 4
},
"limit": {
"description": "Max number of records to return",
"data_type": "numeric",
"required": false,
"order": 5
},
"envelope_recipient_filter_operator": {
"description": "Operator for envelope recipient filter",
"data_type": "string",
"required": false,
"order": 6,
"value_list": ["contains", "is", "begins_with", "ends_with", "does_not_contain"]
},
"envelope_recipient_filter_value": {
"description": "Value for envelope recipient filter",
"data_type": "string",
"required": false,
"order": 7
},
"filter_operator": {
"description": "Operator for general filter",
"data_type": "string",
"required": false,
"order": 8,
"value_list": ["contains", "is", "begins_with", "ends_with", "does_not_contain"]
},
"filter_value": {
"description": "Value for general filter",
"data_type": "string",
"required": false,
"order": 9
}
},
"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.order_by",
"data_type": "string"
},
{
"data_path": "action_result.parameter.order_direction",
"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.envelope_recipient_filter_operator",
"data_type": "string"
},
{
"data_path": "action_result.parameter.envelope_recipient_filter_value",
"data_type": "string"
},
{
"data_path": "action_result.parameter.filter_operator",
"data_type": "string"
},
{
"data_path": "action_result.parameter.filter_value",
"data_type": "string"
},
{
"data_path": "action_result.data.*.mid",
"data_type": "numeric",
"contains": ["cisco sma message id"]
},
{
"data_path": "action_result.data.*.attributes.subject",
"data_type": "string"
},
{
"data_path": "action_result.data.*.attributes.date",
"data_type": "string"
},
{
"data_path": "action_result.data.*.attributes.fromAddress",
"data_type": "string",
"contains": ["email"]
},
{
"data_path": "action_result.data.*.attributes.toAddress",
"data_type": "string",
"contains": ["email"]
},
{
"data_path": "action_result.data.*.attributes.envelopeRecipient",
"data_type": "string",
"contains": ["email"]
},
{
"data_path": "action_result.data.*.attributes.size",
"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.message",
"data_type": "string"
}
],
"versions": "EQ(*)"
},
{
"action": "get message details",
"identifier": "get_message_details",
Expand Down
125 changes: 96 additions & 29 deletions ciscosma_connector.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,15 @@
from phantom.action_result import ActionResult
from phantom.base_connector import BaseConnector

from ciscosma_consts import CISCOSMA_GET_MESSAGE_DETAILS_ENDPOINT, CISCOSMA_GET_TOKEN_ENDPOINT, CISCOSMA_GET_MESSAGE_TRACKING_DETAILS_ENDPOINT
from ciscosma_consts import (
CISCOSMA_GET_MESSAGE_DETAILS_ENDPOINT,
CISCOSMA_GET_MESSAGE_TRACKING_DETAILS_ENDPOINT,
CISCOSMA_GET_TOKEN_ENDPOINT,
CISCOSMA_SEARCH_MESSAGES_ENDPOINT,
CISCOSMA_VALID_FILTER_OPERATORS,
CISCOSMA_VALID_ORDER_BY,
CISCOSMA_VALID_ORDER_DIRECTIONS,
)


class CiscoSmaConnector(BaseConnector):
Expand Down Expand Up @@ -149,6 +157,74 @@ def _handle_test_connectivity(self, param):
self.save_progress("Test Connectivity Passed")
return action_result.set_status(phantom.APP_SUCCESS)

def _handle_search_quarantine_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, "quarantineType": "spam"}

order_by = param.get("order_by")
order_dir = param.get("order_direction")
offset = param.get("offset")
limit = param.get("limit")
envelope_recipient_operator = param.get("envelope_recipient_filter_operator")
envelope_recipient_value = param.get("envelope_recipient_filter_value")
filter_operator = param.get("filter_operator")
filter_value = param.get("filter_value")

if order_by and order_by not in CISCOSMA_VALID_ORDER_BY:
return action_result.set_status(phantom.APP_ERROR, "Invalid 'order_by' parameter")

if order_dir and order_dir not in CISCOSMA_VALID_ORDER_DIRECTIONS:
return action_result.set_status(phantom.APP_ERROR, "Invalid 'order_direction' parameter")

if envelope_recipient_operator and envelope_recipient_operator not in CISCOSMA_VALID_FILTER_OPERATORS:
return action_result.set_status(phantom.APP_ERROR, "Invalid 'envelope_recipient_filter_operator' parameter")

if filter_operator and filter_operator not in CISCOSMA_VALID_FILTER_OPERATORS:
return action_result.set_status(phantom.APP_ERROR, "Invalid 'filter_operator' parameter")

if offset:
params["offset"] = offset
if limit:
params["limit"] = limit
if order_by:
params["orderBy"] = order_by
if order_dir:
params["orderDir"] = order_dir
if envelope_recipient_operator:
params["envelopeRecipientFilterOperator"] = envelope_recipient_operator
if envelope_recipient_value:
params["envelopeRecipientFilterValue"] = envelope_recipient_value
if filter_operator:
params["filterOperator"] = filter_operator
if filter_value:
params["filterValue"] = filter_value

ret_val, response = self._make_authenticated_request(action_result, CISCOSMA_SEARCH_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)

for message in messages:
action_result.add_data(message)

summary = {"total_messages": total_count, "messages_returned": len(messages)}
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 messages")

def _handle_get_message_details(self, param):
action_result = self.add_action_result(ActionResult(dict(param)))

Expand Down Expand Up @@ -178,54 +254,44 @@ def _handle_get_message_details(self, param):
def _handle_get_message_tracking_details(self, param):
action_result = self.add_action_result(ActionResult(dict(param)))

mid = param.get('mid')
mid = param.get("mid")
if not mid:
return action_result.set_status(phantom.APP_ERROR, "Parameter 'mid' is required")

icid = param.get('icid')
serial_number = param.get('serial_number')
start_date = param.get('start_date')
end_date = param.get('end_date')
icid = param.get("icid")
serial_number = param.get("serial_number")
start_date = param.get("start_date")
end_date = param.get("end_date")

params = {'mid': mid}
params = {"mid": mid}
if icid:
params['icid'] = icid
params["icid"] = icid
if serial_number:
params['serialNumber'] = serial_number
params["serialNumber"] = serial_number
if start_date:
params['startDate'] = start_date
params["startDate"] = start_date
if end_date:
params['endDate'] = end_date
params["endDate"] = end_date

ret_val, response = self._make_authenticated_request(
action_result,
CISCOSMA_GET_MESSAGE_TRACKING_DETAILS_ENDPOINT,
params=params
)
ret_val, response = self._make_authenticated_request(action_result, CISCOSMA_GET_MESSAGE_TRACKING_DETAILS_ENDPOINT, params=params)

if phantom.is_fail(ret_val):
return action_result.get_status()

try:
message_data = response.get('data', {}).get('messages', {})
message_data = response.get("data", {}).get("messages", {})
action_result.add_data(message_data)
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_ERROR, f"Error parsing response: {str(e)}")

summary = {
'subject': message_data.get('subject'),
'status': message_data.get('messageStatus'),
'direction': message_data.get('direction')
"subject": message_data.get("subject"),
"status": message_data.get("messageStatus"),
"direction": message_data.get("direction"),
}
action_result.update_summary(summary)

return action_result.set_status(
phantom.APP_SUCCESS,
"Successfully retrieved message tracking details"
)
return action_result.set_status(phantom.APP_SUCCESS, "Successfully retrieved message tracking details")

def initialize(self):
config = self.get_config()
Expand All @@ -241,7 +307,8 @@ def handle_action(self, param):
action_mapping = {
"test_connectivity": self._handle_test_connectivity,
"get_message_details": self._handle_get_message_details,
"get_message_tracking_details": self._handle_get_message_tracking_details
"get_message_tracking_details": self._handle_get_message_tracking_details,
"search_quarantine_messages": self._handle_search_quarantine_messages,
}

action = self.get_action_identifier()
Expand Down
5 changes: 5 additions & 0 deletions ciscosma_consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,14 @@

# Cisco SMA Constants

CISCOSMA_VALID_ORDER_BY = ["from_address", "to_address", "subject"]
CISCOSMA_VALID_ORDER_DIRECTIONS = ["asc", "desc"]
CISCOSMA_VALID_FILTER_OPERATORS = ["contains", "is", "begins_with", "ends_with", "does_not_contain"]

CISCOSMA_GET_TOKEN_ENDPOINT = "/sma/api/v2.0/login"
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"


# Future endpoints
Expand Down

0 comments on commit 3236f70

Please sign in to comment.