Skip to content

Commit

Permalink
[Slack v3] - add support for file-mirroring from xsoar to slack (#32611)
Browse files Browse the repository at this point in the history
* logs

* mirror files from xsoar to slack

* start implementing mirror from slack to xsoar

* mirror from slack to xsoar - in progress

* use http-request for mirroring slack files to xsoar

* revert enable_dm param

* revert csp changes

* handle ssl errors

* add context

* revert mirror from slack to xsoar

* add test

* bump rn

* type ignore

* add comment handling and fix test

* update param location

* bump docker

* rn

* update docs

* fix test

* update rn

* update disclaimer

* Bump pack from version Slack to 3.4.6.

---------

Co-authored-by: Content Bot <[email protected]>
  • Loading branch information
2 people authored and maimorag committed Feb 28, 2024
1 parent 04dab35 commit 2d4f56a
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 33 deletions.
47 changes: 24 additions & 23 deletions Packs/Slack/Integrations/SlackV3/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,30 +15,31 @@ to learn about configuring SlackV3 using the app manifest.
2. Search for SlackV3.
3. Click **Add instance** to create and configure a new integration instance.

| **Parameter** | **Description** | **Required** |
|---|---|---|
| `bot_token` | Slack API bot token. | False |
| `user_token` | Slack API user token. | False |
| `app_token` | Slack API app token. | False |
| `incidentNotificationChannel` | Dedicated Slack channel to receive notifications. | False |
| `min_severity` | Minimum incident severity by which to send messages to Slack. | False |
| `incidentType` | Type of incidents created in Slack. | False |
| `allow_incidents` | Allow external users to create incidents via direct messages. | False |
| `proxy` | Use system proxy settings. | False |
| `unsecure` | Trust any certificate (not secure). Make sure to mark this parameter if you want the SlackBlockBuilder script to send a response back to the incident context. | False |
| `longRunning` | Long running instance. Required for investigation mirroring and direct messages. | False |
| `bot_name` | Bot display name in Slack (Cortex XSOAR by default). | False |
| `bot_icon` | Bot icon in Slack - Image URL (Cortex XSOAR icon by default). | False |
| `max_limit_time` | Maximum time to wait for a rate limiting call in seconds. | False |
| `paginated_count` | Number of objects to return in each paginated call. | False |
| `proxy_url` | Proxy URL to use in Slack API calls. | False |
| `filtered_tags` | Comma-separated list of tags by which to filter the messages sent from Cortex XSOAR. Only supported in Cortex XSOAR V6.1 and above. | False |
| `permitted_notifications` | Types of notifications to send (to individual users and to the dedicated Slack channel, if specified). | False |
| `common_channels` | For workspaces where a handful of channels are consistently being used, you may add them as a CSV in the format ChannelName:ChannelID. | False |
| **Parameter** | **Description** | **Required** |
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---|
| `bot_token` | Slack API bot token. | False |
| `user_token` | Slack API user token. | False |
| `app_token` | Slack API app token. | False |
| `incidentNotificationChannel` | Dedicated Slack channel to receive notifications. | False |
| `min_severity` | Minimum incident severity by which to send messages to Slack. | False |
| `incidentType` | Type of incidents created in Slack. | False |
| `allow_incidents` | Allow external users to create incidents via direct messages. | False |
| `proxy` | Use system proxy settings. | False |
| `unsecure` | Trust any certificate (not secure). Make sure to mark this parameter if you want the SlackBlockBuilder script to send a response back to the incident context. | False |
| `longRunning` | Long running instance. Required for investigation mirroring and direct messages. | False |
| `bot_name` | Bot display name in Slack (Cortex XSOAR by default). | False |
| `bot_icon` | Bot icon in Slack - Image URL (Cortex XSOAR icon by default). | False |
| `max_limit_time` | Maximum time to wait for a rate limiting call in seconds. | False |
| `paginated_count` | Number of objects to return in each paginated call. | False |
| `proxy_url` | Proxy URL to use in Slack API calls. | False |
| `filtered_tags` | Comma-separated list of tags by which to filter the messages sent from Cortex XSOAR. Only supported in Cortex XSOAR V6.1 and above. | False |
| `permitted_notifications` | Types of notifications to send (to individual users and to the dedicated Slack channel, if specified). | False |
| `common_channels` | For workspaces where a handful of channels are consistently being used, you may add them as a CSV in the format ChannelName:ChannelID. | False |
| `disable_caching` | When configured, Disable Caching will prevent the integration from paginating to search for Users or Conversations. Additionally, it will prevent excess data from being stored to the integration context. If this parameter is disabled, the instance may create high memory usage. | False |
| `mirroring` | Enable Incident Mirroring. | False |
| `ignore_event_retries` | In some cases, events may not be processed fast enough. If you wish to attempt to retry the event, select `false`. Note that this can result in some responses being double-posted. Default is `True`. | False |
| `extensive_logging` | Extensive Logging. This parameter will write additional data to the logs and should only be used when you are directed to by XSOAR support. | False |
| `mirroring` | Enable Incident Mirroring. | False |
| `enable_outbound_file_mirroring` | Enable Outbound File Mirroring. Whether to enable mirroring from xsoar to slack, mark it file mirroring is required in investigations. | False |
| `ignore_event_retries` | In some cases, events may not be processed fast enough. If you wish to attempt to retry the event, select `false`. Note that this can result in some responses being double-posted. Default is `True`. | False |
| `extensive_logging` | Extensive Logging. This parameter will write additional data to the logs and should only be used when you are directed to by XSOAR support. | False |

5. Click **Test** to validate the URLs, token, and connection.

Expand Down
51 changes: 44 additions & 7 deletions Packs/Slack/Integrations/SlackV3/SlackV3.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
CACHED_INTEGRATION_CONTEXT: dict
CACHE_EXPIRY: float
MIRRORING_ENABLED: bool
FILE_MIRRORING_ENABLED: bool
LONG_RUNNING_ENABLED: bool
DEMISTO_API_KEY: str
DEMISTO_URL: str
Expand Down Expand Up @@ -1767,6 +1768,31 @@ def get_conversation_by_name(conversation_name: str) -> dict:
return conversation


def send_mirrored_file_to_slack(entry: str, message: str, original_channel: str, channel_id: str, comment: Optional[str] = None):
"""
Sends a file from xsoar investigation to a mirrored slack channel
Args:
entry: the entry ID of the file
message: the message from the war-room when uploading file
original_channel: the channel name to upload the file
channel_id: the channel ID to upload the file
comment: a comment that was added when uploading the file
"""
file_name = demisto.getFilePath(entry)["name"]
if FILE_MIRRORING_ENABLED:
demisto.debug(
f'file {file_name} has been uploaded to a mirrored incident, '
f'uploading the file to slack channel {original_channel}'
)
if comment:
# if a comment was added when uploading the file, add it to the message
message = f'{message}\nComment: {comment}'
slack_send_file(original_channel, channel_id, entry, message)
else:
demisto.debug(f'file {file_name} will not be mirrored because file mirroring is not enabled')


def slack_send():
"""
Sends a message to slack
Expand Down Expand Up @@ -1807,6 +1833,16 @@ def slack_send():
if tags and not any(elem in entry_tags for elem in tags):
return

if entry:
send_mirrored_file_to_slack(
entry,
message=message,
original_channel=original_channel,
channel_id=channel_id,
comment=entry_object.get("contents")
)
return

if (to and group) or (to and original_channel) or (to and original_channel and group):
return_error('Only one destination can be provided.')

Expand Down Expand Up @@ -1910,17 +1946,17 @@ def save_entitlement(entitlement, thread, reply, expiry, default_response):
set_to_integration_context_with_retries({'questions': questions}, OBJECTS_TO_KEYS, SYNC_CONTEXT)


def slack_send_file():
def slack_send_file(_channel: str | None = None, _channel_id: str = '', _entry_id: str | None = None, _comment: str = ""):
"""
Sends a file to slack
"""
to = demisto.args().get('to')
channel = demisto.args().get('channel')
channel_id = demisto.args().get('channel_id', '')
channel = _channel or demisto.args().get('channel')
channel_id = _channel_id or demisto.args().get('channel_id', '')
group = demisto.args().get('group')
entry_id = demisto.args().get('file')
entry_id = _entry_id or demisto.args().get('file')
thread_id = demisto.args().get('threadID')
comment = demisto.args().get('comment', '')
comment = _comment or demisto.args().get('comment', '')

if not (to or channel or group):
mirror = find_mirror_by_investigation()
Expand Down Expand Up @@ -2747,7 +2783,7 @@ def init_globals(command_name: str = ''):
"""

global BOT_TOKEN, PROXY_URL, PROXIES, DEDICATED_CHANNEL, CLIENT, USER_CLIENT, \
CACHED_INTEGRATION_CONTEXT, MIRRORING_ENABLED, USER_TOKEN
CACHED_INTEGRATION_CONTEXT, MIRRORING_ENABLED, FILE_MIRRORING_ENABLED, USER_TOKEN
global SEVERITY_THRESHOLD, ALLOW_INCIDENTS, INCIDENT_TYPE, VERIFY_CERT, ENABLE_DM, BOT_ID, CACHE_EXPIRY
global BOT_NAME, BOT_ICON_URL, MAX_LIMIT_TIME, PAGINATED_COUNT, SSL_CONTEXT, APP_TOKEN, ASYNC_CLIENT
global DEFAULT_PERMITTED_NOTIFICATION_TYPES, CUSTOM_PERMITTED_NOTIFICATION_TYPES, PERMITTED_NOTIFICATION_TYPES
Expand Down Expand Up @@ -2784,6 +2820,7 @@ def init_globals(command_name: str = ''):
CUSTOM_PERMITTED_NOTIFICATION_TYPES = demisto.params().get('permitted_notifications', [])
PERMITTED_NOTIFICATION_TYPES = DEFAULT_PERMITTED_NOTIFICATION_TYPES + CUSTOM_PERMITTED_NOTIFICATION_TYPES
MIRRORING_ENABLED = demisto.params().get('mirroring', True)
FILE_MIRRORING_ENABLED = demisto.params().get('enable_outbound_file_mirroring', False)
LONG_RUNNING_ENABLED = demisto.params().get('longRunning', True)
DEMISTO_API_KEY = demisto.params().get('demisto_api_key', {}).get('password', '')
demisto_urls = demisto.demistoUrls()
Expand Down Expand Up @@ -2949,7 +2986,7 @@ def main() -> None:
if EXTENSIVE_LOGGING:
os.environ['PYTHONASYNCIODEBUG'] = "1"
support_multithreading()
command_func()
command_func() # type: ignore
except Exception as e:
demisto.debug(e)
return_error(str(e))
Expand Down
10 changes: 8 additions & 2 deletions Packs/Slack/Integrations/SlackV3/SlackV3.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,14 @@ configuration:
display: Enable Incident Mirroring
name: mirroring
type: 8
section: Collect
section: Connect
required: false
- display: Enable Outbound File Mirroring
name: enable_outbound_file_mirroring
type: 8
section: Connect
required: false
additionalinfo: Whether to enable mirroring only from xsoar to slack, mark it if file mirroring is required in investigations.
- defaultvalue: 'true'
display: Long running instance. Required for investigation mirroring and direct messages.
name: longRunning
Expand Down Expand Up @@ -492,7 +498,7 @@ script:
description: Set this argument to specify how many results to return.
description: Retrieves replies to specific messages, regardless of whether it's from a public or private channel, direct message, or otherwise.
name: slack-get-conversation-replies
dockerimage: demisto/slackv3:1.0.0.86601
dockerimage: demisto/slackv3:1.0.0.87650
longRunning: true
runonce: false
script: '-'
Expand Down
38 changes: 38 additions & 0 deletions Packs/Slack/Integrations/SlackV3/SlackV3_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2835,6 +2835,44 @@ def api_call(method: str, http_verb: str = 'POST', file: str = None, params=None
assert demisto.getIntegrationContext()['questions'] == js.dumps(questions)


def test_slack_send_with_mirrored_file(mocker):
"""
Given:
- mirror entry which is basically a file
When:
- running send-notification triggered from mirroring
Then:
- Validate that the file is sent successfully
"""
import SlackV3

mocker.patch.object(demisto, 'params', return_value={'enable_outbound_file_mirroring': True})

SlackV3.init_globals()

mocker.patch.object(
demisto,
'args',
return_value={
"message": "test",
"channel_id": "1234",
"channel": "channel",
"entry": "1234",
"messageType": SlackV3.MIRROR_TYPE,
"entryObject": {}
}
)
slack_send_request = mocker.patch.object(SlackV3, 'slack_send_request', return_value='file-sent')
demisto_results = mocker.patch.object(demisto, 'results')

SlackV3.slack_send()
assert slack_send_request.call_args_list[0].kwargs["file_dict"]
assert slack_send_request.call_args_list[0].kwargs["channel_id"] == "1234"
assert demisto_results.call_args_list[0][0][0] == 'File sent to Slack successfully.'


def test_send_request_with_entitlement_blocks(mocker):
import SlackV3

Expand Down
8 changes: 8 additions & 0 deletions Packs/Slack/ReleaseNotes/3_4_6.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

#### Integrations

##### Slack v3

- Added support for mirroring files from xsoar to slack.
- Added the **Enable Outbound File Mirroring** integration parameter to allow file mirroring from xsoar to slack. The parameter is unchecked by default, disabling file mirroring.
- Updated the Docker image to: *demisto/slackv3:1.0.0.87650*.
2 changes: 1 addition & 1 deletion Packs/Slack/pack_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "Slack",
"description": "Interact with Slack API - collect logs, send messages and notifications to your Slack team.",
"support": "xsoar",
"currentVersion": "3.4.5",
"currentVersion": "3.4.6",
"author": "Cortex XSOAR",
"url": "https://www.paloaltonetworks.com/cortex",
"email": "",
Expand Down

0 comments on commit 2d4f56a

Please sign in to comment.