Skip to content

Commit

Permalink
PAPP-35194 edit quanrantine list entry action
Browse files Browse the repository at this point in the history
  • Loading branch information
grokas-splunk committed Dec 17, 2024
1 parent 6915434 commit dfa5b24
Show file tree
Hide file tree
Showing 3 changed files with 224 additions and 67 deletions.
116 changes: 116 additions & 0 deletions ciscosma.json
Original file line number Diff line number Diff line change
Expand Up @@ -1021,6 +1021,122 @@
}
],
"versions": "EQ(*)"
},
{
"action": "edit list entry",
"identifier": "edit_list_entry",
"description": "Edit an entry in the spam quarantine safelist or blocklist",
"type": "generic",
"read_only": false,
"parameters": {
"list_type": {
"description": "Type of list to edit entry in",
"data_type": "string",
"required": false,
"order": 0,
"value_list": ["safelist", "blocklist"],
"default": "safelist"
},
"view_by": {
"description": "Edit entry by sender or recipient",
"data_type": "string",
"required": false,
"order": 1,
"value_list": ["sender", "recipient"],
"default": "recipient"
},
"recipient_addresses": {
"description": "Recipient email addresses (comma-separated if multiple) - Required with view_by=recipient",
"data_type": "string",
"required": false,
"order": 2
},
"sender_list": {
"description": "Sender addresses or domains (comma-separated if multiple) - Required with view_by=recipient",
"data_type": "string",
"required": false,
"order": 3
},
"sender_addresses": {
"description": "Sender addresses or domains (comma-separated if multiple) - Required with view_by=sender",
"data_type": "string",
"required": false,
"order": 4
},
"recipient_list": {
"description": "Recipient email addresses (comma-separated if multiple) - Required with view_by=sender",
"data_type": "string",
"required": false,
"order": 5
}
},
"output": [
{
"data_path": "action_result.status",
"data_type": "string"
},
{
"data_path": "action_result.parameter.list_type",
"data_type": "string"
},
{
"data_path": "action_result.parameter.view_by",
"data_type": "string"
},
{
"data_path": "action_result.parameter.recipient_addresses",
"data_type": "string"
},
{
"data_path": "action_result.parameter.sender_list",
"data_type": "string"
},
{
"data_path": "action_result.parameter.sender_addresses",
"data_type": "string"
},
{
"data_path": "action_result.parameter.recipient_list",
"data_type": "string"
},
{
"data_path": "action_result.data.*.action",
"data_type": "string"
},
{
"data_path": "action_result.data.*.recipientAddresses",
"data_type": "string"
},
{
"data_path": "action_result.data.*.senderList",
"data_type": "string"
},
{
"data_path": "action_result.data.*.senderAddresses",
"data_type": "string"
},
{
"data_path": "action_result.data.*.recipientList",
"data_type": "string"
},
{
"data_path": "action_result.summary.list_type",
"data_type": "string"
},
{
"data_path": "action_result.summary.view_by",
"data_type": "string"
},
{
"data_path": "action_result.summary.status",
"data_type": "string"
},
{
"data_path": "action_result.message",
"data_type": "string"
}
],
"versions": "EQ(*)"
}
]
}
169 changes: 106 additions & 63 deletions ciscosma_connector.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@
from phantom.base_connector import BaseConnector

from ciscosma_consts import (
CISCOSMA_BLOCKLIST_ENDPOINT,
CISCOSMA_DEFAULT_LIST_LIMIT,
CISCOSMA_DEFAULT_LIST_OFFSET,
CISCOSMA_DELETE_MESSAGES_ENDPOINT,
CISCOSMA_GET_MESSAGE_DETAILS_ENDPOINT,
CISCOSMA_GET_MESSAGE_TRACKING_DETAILS_ENDPOINT,
CISCOSMA_GET_TOKEN_ENDPOINT,
CISCOSMA_RELEASE_MESSAGES_ENDPOINT,
CISCOSMA_SEARCH_BLOCKLIST_ENDPOINT,
CISCOSMA_SAFELIST_ENDPOINT,
CISCOSMA_SEARCH_MESSAGES_ENDPOINT,
CISCOSMA_SEARCH_SAFELIST_ENDPOINT,
CISCOSMA_SEARCH_TRACKING_MESSAGES_ENDPOINT,
CISCOSMA_VALID_FILTER_OPERATORS,
CISCOSMA_VALID_LIST_ORDER_BY,
Expand Down Expand Up @@ -137,6 +137,14 @@ def _make_authenticated_request(self, action_result, endpoint, headers=None, par
return phantom.APP_SUCCESS, resp_json

def _get_jwt_token(self, action_result):
"""Helper to get JWT token for authentication.
Args:
action_result (ActionResult): The action result object
Returns:
tuple: (action_result, jwt_token) or (action_result, None) on error
"""
payload = {
"data": {
"userName": base64.b64encode(self._username.encode()).decode(),
Expand All @@ -154,6 +162,74 @@ def _get_jwt_token(self, action_result):

return phantom.APP_SUCCESS, jwt_token

def _list_entry_operation_setup(self, param, action):
"""Helper for safelist and blocklist entry operations.
Args:
param (dict): Parameters for action
action (str): Action type ('add', 'edit')
Returns:
tuple: (action_result, payload, endpoint)
"""
action_result = self.add_action_result(ActionResult(dict(param)))

list_type = param.get("list_type", "safelist").lower()
if list_type not in CISCOSMA_VALID_LIST_TYPES:
action_result.set_status(phantom.APP_ERROR, "Invalid parameter 'list_type'")
return action_result, None, None

view_by = param.get("view_by", "recipient")
if view_by not in CISCOSMA_VALID_LIST_VIEW_BY:
action_result.set_status(phantom.APP_ERROR, "Invalid parameter 'view_by'")
return action_result, None, None

payload = {"action": action, "quarantineType": "spam", "viewBy": view_by}

if view_by == "recipient":
recipient_addresses = param.get("recipient_addresses")
if not recipient_addresses:
action_result.set_status(phantom.APP_ERROR, "Parameter 'recipient_addresses' is required when view_by is 'recipient'")
return action_result, None, None

sender_list = param.get("sender_list")
if not sender_list:
action_result.set_status(phantom.APP_ERROR, "Parameter 'sender_list' is required when view_by is 'recipient'")
return action_result, None, None

# Convert to list
if isinstance(recipient_addresses, str):
recipient_addresses = [addr.strip() for addr in recipient_addresses.split(",")]
if isinstance(sender_list, str):
sender_list = [sender.strip() for sender in sender_list.split(",")]

payload["recipientAddresses"] = recipient_addresses
payload["senderList"] = sender_list

else: # sender
sender_addresses = param.get("sender_addresses")
if not sender_addresses:
action_result.set_status(phantom.APP_ERROR, "Parameter 'sender_addresses' is required when view_by is 'sender'")
return action_result, None, None

recipient_list = param.get("recipient_list")
if not recipient_list:
action_result.set_status(phantom.APP_ERROR, "Parameter 'recipient_list' is required when view_by is 'sender'")
return action_result, None, None

# Convert to list
if isinstance(sender_addresses, str):
sender_addresses = [addr.strip() for addr in sender_addresses.split(",")]
if isinstance(recipient_list, str):
recipient_list = [recip.strip() for recip in recipient_list.split(",")]

payload["senderAddresses"] = sender_addresses
payload["recipientList"] = recipient_list

endpoint = CISCOSMA_SAFELIST_ENDPOINT if list_type == "safelist" else CISCOSMA_BLOCKLIST_ENDPOINT

return action_result, payload, endpoint

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

Expand Down Expand Up @@ -423,7 +499,7 @@ def _handle_search_list(self, param):
if list_type not in CISCOSMA_VALID_LIST_TYPES:
return action_result.set_status(phantom.APP_ERROR, "Invalid parameter 'list_type'")

endpoint = CISCOSMA_SEARCH_SAFELIST_ENDPOINT if list_type == "safelist" else CISCOSMA_SEARCH_BLOCKLIST_ENDPOINT
endpoint = CISCOSMA_SAFELIST_ENDPOINT if list_type == "safelist" else CISCOSMA_BLOCKLIST_ENDPOINT

params = {"action": "view", "quarantineType": "spam"}

Expand Down Expand Up @@ -475,67 +551,36 @@ def _handle_search_list(self, param):
return action_result.set_status(phantom.APP_SUCCESS, f"Successfully retrieved {list_type} entries")

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

list_type = param.get("list_type", "safelist").lower()
if list_type not in CISCOSMA_VALID_LIST_TYPES:
return action_result.set_status(phantom.APP_ERROR, "Invalid parameter 'list_type'")

view_by = param.get("view_by", "recipient")
if view_by not in CISCOSMA_VALID_LIST_VIEW_BY:
return action_result.set_status(phantom.APP_ERROR, "Invalid parameter 'view_by'")

payload = {
"action": "add",
"quarantineType": "spam",
"viewBy": view_by
}

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

sender_list = param.get("sender_list")
if not sender_list:
return action_result.set_status(phantom.APP_ERROR, "Parameter 'sender_list' is required when view_by is 'recipient'")
action_result, payload, endpoint = self._list_entry_operation_setup(param, "add")
if payload is None:
return action_result.get_status()

# Convert to list
if isinstance(recipient_addresses, str):
recipient_addresses = [addr.strip() for addr in recipient_addresses.split(",")]
if isinstance(sender_list, str):
sender_list = [sender.strip() for sender in sender_list.split(",")]
ret_val, response = self._make_authenticated_request(action_result, endpoint, json_data=payload, method="post")

payload["recipientAddresses"] = recipient_addresses
payload["senderList"] = sender_list
if phantom.is_fail(ret_val):
return action_result.get_status()

else:
# sender
sender_addresses = param.get("sender_addresses")
if not sender_addresses:
return action_result.set_status(phantom.APP_ERROR, "Parameter 'sender_addresses' is required when view_by is 'sender'")
try:
action_result.add_data(response.get("data", {}))

recipient_list = param.get("recipient_list")
if not recipient_list:
return action_result.set_status(phantom.APP_ERROR, "Parameter 'recipient_list' is required when view_by is 'sender'")
summary = {
"list_type": "safelist" if CISCOSMA_SAFELIST_ENDPOINT in endpoint else "blocklist",
"view_by": payload["viewBy"],
"status": "success",
}
action_result.update_summary(summary)

# Convert to list
if isinstance(sender_addresses, str):
sender_addresses = [addr.strip() for addr in sender_addresses.split(",")]
if isinstance(recipient_list, str):
recipient_list = [recip.strip() for recip in recipient_list.split(",")]
except Exception as e:
return action_result.set_status(phantom.APP_ERROR, f"Error parsing response: {str(e)}")

payload["senderAddresses"] = sender_addresses
payload["recipientList"] = recipient_list
return action_result.set_status(phantom.APP_SUCCESS, f"Successfully added entry in {summary['list_type']}")

endpoint = CISCOSMA_ADD_SAFELIST_ENDPOINT if list_type == "safelist" else CISCOSMA_ADD_BLOCKLIST_ENDPOINT
def _handle_edit_list_entry(self, param):
action_result, payload, endpoint = self._list_entry_operation_setup(param, "edit")
if payload is None:
return action_result.get_status()

ret_val, response = self._make_authenticated_request(
action_result,
endpoint,
json_data=payload,
method="post"
)
ret_val, response = self._make_authenticated_request(action_result, endpoint, json_data=payload, method="post")

if phantom.is_fail(ret_val):
return action_result.get_status()
Expand All @@ -544,19 +589,16 @@ def _handle_add_list_entry(self, param):
action_result.add_data(response.get("data", {}))

summary = {
"list_type": list_type,
"view_by": view_by,
"status": "success"
"list_type": "safelist" if CISCOSMA_SAFELIST_ENDPOINT in endpoint else "blocklist",
"view_by": payload["viewBy"],
"status": "success",
}
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,
f"Successfully added entry to {list_type}"
)
return action_result.set_status(phantom.APP_SUCCESS, f"Successfully edited entry in {summary['list_type']}")

def initialize(self):
config = self.get_config()
Expand All @@ -579,6 +621,7 @@ def handle_action(self, param):
"delete_email": self._handle_delete_email,
"search_list": self._handle_search_list,
"add_list_entry": self._handle_add_list_entry,
"edit_list_entry": self._handle_edit_list_entry,
}

action = self.get_action_identifier()
Expand Down
6 changes: 2 additions & 4 deletions ciscosma_consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,8 @@
CISCOSMA_SEARCH_TRACKING_MESSAGES_ENDPOINT = "/sma/api/v2.0/message-tracking/messages"
CISCOSMA_RELEASE_MESSAGES_ENDPOINT = "/sma/api/v2.0/quarantine/messages"
CISCOSMA_DELETE_MESSAGES_ENDPOINT = "/sma/api/v2.0/quarantine/messages"
CISCOSMA_SEARCH_SAFELIST_ENDPOINT = "/sma/api/v2.0/quarantine/safelist"
CISCOSMA_SEARCH_BLOCKLIST_ENDPOINT = "/sma/api/v2.0/quarantine/blocklist"
CISCOSMA_ADD_SAFELIST_ENDPOINT = "/sma/api/v2.0/quarantine/safelist"
CISCOSMA_ADD_BLOCKLIST_ENDPOINT = "/sma/api/v2.0/quarantine/blocklist"
CISCOSMA_SAFELIST_ENDPOINT = "/sma/api/v2.0/quarantine/safelist"
CISCOSMA_BLOCKLIST_ENDPOINT = "/sma/api/v2.0/quarantine/blocklist"

# Future endpoints
# GET /api/v2.0/reporting/report?resource_attribute
Expand Down

0 comments on commit dfa5b24

Please sign in to comment.