Skip to content

Commit

Permalink
[SOAR-17735] Zoom - error handling (#2802)
Browse files Browse the repository at this point in the history
* Init

* Unit tests | Update error raised

* Lint | Update SDK

* Version update
  • Loading branch information
ablakley-r7 committed Sep 19, 2024
1 parent b8bf522 commit 409b877
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 10 deletions.
6 changes: 3 additions & 3 deletions plugins/zoom/.CHECKSUM
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"spec": "6c7bceeedb5860a3d416365d84ca4816",
"manifest": "a0c9eeed724903476f406ef15764f302",
"setup": "2631fd5c3ecee7cc33a9549c8b49d491",
"spec": "614b806a5eabac0a801df2df451a16c0",
"manifest": "cd25ebcb44fd0a245b0699be299475b8",
"setup": "851527db87c7d4d49370e3e6d91a2a69",
"schemas": [
{
"identifier": "create_user/schema.py",
Expand Down
2 changes: 1 addition & 1 deletion plugins/zoom/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM --platform=linux/amd64 rapid7/insightconnect-python-3-plugin:6.1.0
FROM --platform=linux/amd64 rapid7/insightconnect-python-3-plugin:6.1.2

LABEL organization=rapid7
LABEL sdk=python
Expand Down
2 changes: 1 addition & 1 deletion plugins/zoom/bin/icon_zoom
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ from sys import argv

Name = "Zoom"
Vendor = "rapid7"
Version = "4.1.15"
Version = "4.1.16"
Description = "[Zoom](https://zoom.us) is a cloud platform for video and audio conferencing, chat, and webinars. The Zoom plugin allows you to add and remove users as part of of workflow, while also providing the ability to trigger workflows on new user sign-in and sign-out activity events. This plugin uses the [Zoom API](https://marketplace.zoom.us/docs/api-reference/introduction) and requires a Pro, Business, or Enterprise plan"


Expand Down
1 change: 1 addition & 0 deletions plugins/zoom/help.md
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ Example output:

# Version History

* 4.1.16 - Update SDK | Update error handling
* 4.1.15 - Error Handling Updated | SDK Bump to 6.1.0
* 4.1.14 - SDK Bumped to 6.0.1 | Task connection test added
* 4.1.13 - Fix defect where Event objects failed to create on a missing attribute | Update insight-plugin-runtime to version 5.5.5
Expand Down
25 changes: 23 additions & 2 deletions plugins/zoom/icon_zoom/tasks/monitor_sign_in_out_activity/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,9 @@ def handle_request_exception(self, exception: Exception, now: str) -> TaskOutput
data=exception.data,
),
)
elif hasattr(exception, "data") and "No permission." in exception.data:
elif hasattr(exception, "data") and (
"No permission." in exception.data or "Only available for" in exception.data
):
self.logger.error(self.PERMISSIONS_ERROR_MESSAGE_USER)
return TaskOutput(
output=[],
Expand All @@ -440,8 +442,27 @@ def handle_request_exception(self, exception: Exception, now: str) -> TaskOutput
data=exception.data,
),
)
else:
return TaskOutput(
output=[],
state={
self.LAST_REQUEST_TIMESTAMP: now,
},
has_more_pages=False,
status_code=500,
error=exception,
)
else:
raise exception
plugin_exception = PluginException(preset=PluginException.Preset.UNKNOWN, data=exception)
return TaskOutput(
output=[],
state={
self.LAST_REQUEST_TIMESTAMP: now,
},
has_more_pages=False,
status_code=500,
error=plugin_exception,
)

@staticmethod
def _dedupe_events(all_events: [Event], latest_event_timestamp: Optional[str] = None) -> [Event]:
Expand Down
5 changes: 3 additions & 2 deletions plugins/zoom/plugin.spec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ requirements:
- "API credentials for OAuth 2.0:
\n\t* Requires account ID as well as client ID and secret from a Server-to-Server OAuth app in the Zoom Marketplace.
\n\t* Server-to-Server OAuth app has the `report:read:admin` scope enabled."
version: 4.1.15
version: 4.1.16
connection_version: 4
vendor: rapid7
support: rapid7
Expand All @@ -22,7 +22,7 @@ cloud_ready: true
tags: [zoom, chat]
sdk:
type: full
version: 6.1.0
version: 6.1.2
user: nobody
hub_tags:
use_cases: [alerting_and_notifications, application_management, threat_detection_and_response, user_management]
Expand All @@ -35,6 +35,7 @@ resources:
enable_cache: false

version_history:
- "4.1.16 - Update SDK | Update error handling"
- "4.1.15 - Error Handling Updated | SDK Bump to 6.1.0"
- "4.1.14 - SDK Bumped to 6.0.1 | Task connection test added"
- "4.1.13 - Fix defect where Event objects failed to create on a missing attribute | Update insight-plugin-runtime to version 5.5.5"
Expand Down
2 changes: 1 addition & 1 deletion plugins/zoom/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@


setup(name="zoom-rapid7-plugin",
version="4.1.15",
version="4.1.16",
description="[Zoom](https://zoom.us) is a cloud platform for video and audio conferencing, chat, and webinars. The Zoom plugin allows you to add and remove users as part of of workflow, while also providing the ability to trigger workflows on new user sign-in and sign-out activity events. This plugin uses the [Zoom API](https://marketplace.zoom.us/docs/api-reference/introduction) and requires a Pro, Business, or Enterprise plan",
author="rapid7",
author_email="",
Expand Down
57 changes: 57 additions & 0 deletions plugins/zoom/unit_test/test_monitor_sign_in_out_activity.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import sys
from typing import Any, Dict, List

import icon_zoom.tasks.monitor_sign_in_out_activity.task

sys.path.append("../")

import datetime
Expand Down Expand Up @@ -210,6 +212,61 @@ def test_broken_pagination_token_run(
validate(output, MonitorSignInOutActivityOutput.schema)
validate(state, MonitorSignInOutActivityState.schema)

@patch(GET_DATETIME_LAST_X_HOURS_PATH, side_effect=[STUB_DATETIME_LAST_24_HOURS])
@patch(GET_DATETIME_NOW_PATH, side_effect=[STUB_DATETIME_NOW + datetime.timedelta(minutes=DEFAULT_TIMEDELTA)])
@patch(
GET_USER_ACTIVITY_EVENTS_PATH,
side_effect=PluginException(
preset=PluginException.Preset.SERVER_ERROR,
data={"code": 200, "message": "Only available for Paid or ZMP account: ABCDEFGHIJKLMNOP"},
),
)
def test_permissions_error_response(
self, mock_call: MagicMock, mock_datetime_now: MagicMock, mock_datetime_last_24: MagicMock
) -> None:
expected_state = {"last_request_timestamp": "2023-02-23T22:05:00Z"}
output, state, has_more_pages, status_code, error = self.task.run(state=STUB_EXPECTED_PAGINATION_ERROR_STATE)
expected_error_cause = PluginException.causes.get(PluginException.Preset.UNAUTHORIZED, "")
expected_error_assistance = MonitorSignInOutActivity.PERMISSIONS_ERROR_MESSAGE_USER

expected_output, expected_has_more_pages, expected_status_code = [], False, 403
self.assertListEqual(output, expected_output)
self.assertDictEqual(state, expected_state)
self.assertFalse(output, expected_has_more_pages)
self.assertEqual(status_code, expected_status_code)
self.assertEqual(error.cause, expected_error_cause)
self.assertEqual(error.assistance, expected_error_assistance)

validate(output, MonitorSignInOutActivityOutput.schema)
validate(state, MonitorSignInOutActivityState.schema)

@patch(GET_DATETIME_LAST_X_HOURS_PATH, side_effect=[STUB_DATETIME_LAST_24_HOURS])
@patch(GET_DATETIME_NOW_PATH, side_effect=[STUB_DATETIME_NOW + datetime.timedelta(minutes=DEFAULT_TIMEDELTA)])
@patch(
GET_USER_ACTIVITY_EVENTS_PATH,
side_effect=Exception("Something went wrong"),
)
def test_runtime_exception(
self, mock_call: MagicMock, mock_datetime_now: MagicMock, mock_datetime_last_24: MagicMock
) -> None:
expected_state = {"last_request_timestamp": "2023-02-23T22:05:00Z"}
output, state, has_more_pages, status_code, error = self.task.run(state=STUB_EXPECTED_PAGINATION_ERROR_STATE)
expected_error_cause = PluginException.causes.get(PluginException.Preset.UNKNOWN, "")
expected_error_assistance = PluginException.assistances.get(PluginException.Preset.UNKNOWN, "")
expected_error_data = "Something went wrong"

expected_output, expected_has_more_pages, expected_status_code = [], False, 500
self.assertListEqual(output, expected_output)
self.assertDictEqual(state, expected_state)
self.assertFalse(output, expected_has_more_pages)
self.assertEqual(status_code, expected_status_code)
self.assertEqual(error.cause, expected_error_cause)
self.assertEqual(error.assistance, expected_error_assistance)
self.assertEqual(error.data, expected_error_data)

validate(output, MonitorSignInOutActivityOutput.schema)
validate(state, MonitorSignInOutActivityState.schema)

@patch(GET_DATETIME_LAST_X_HOURS_PATH, side_effect=[STUB_DATETIME_LAST_24_HOURS])
@patch(GET_DATETIME_NOW_PATH, side_effect=[STUB_DATETIME_NOW])
@patch(GET_USER_ACTIVITY_EVENTS_PATH)
Expand Down

0 comments on commit 409b877

Please sign in to comment.