Skip to content

Commit

Permalink
Add Moderate Retry Mechanism (#29015)
Browse files Browse the repository at this point in the history
* Added relevent code

* updated the code after tests

* pre-commit fixs

* Updated RN

* Bump pack from version MicrosoftGraphMail to 1.5.11.

* Bump pack from version MicrosoftGraphTeams to 1.0.11.

* fixed cr notes

* fixed conflicts

* updated rn

* Bump pack from version MicrosoftExchangeOnline to 1.2.19.

* Bump pack from version MicrosoftDefenderAdvancedThreatProtection to 1.16.5.

* fixed the use of _get_refresh_token_from_auth_code_param

* Bump pack from version MicrosoftGraphSecurity to 2.2.1.

* Bump pack from version AzureDevOps to 1.3.1.

* revert michal changes

* updated rn

* added ut

* fixed conflicts

* Bump pack from version MicrosoftExchangeOnline to 1.2.23.

* update set context function

* Update Packs/ApiModules/Scripts/MicrosoftApiModule/MicrosoftApiModule.py

Co-authored-by: Dan Tavori <38749041+dantavori@users.noreply.github.com>

---------

Co-authored-by: Content Bot <bot@demisto.com>
Co-authored-by: michal-dagan <mdagan@paloaltonetworks.com>
Co-authored-by: Dan Tavori <38749041+dantavori@users.noreply.github.com>
  • Loading branch information
4 people authored and moishce committed Sep 14, 2023
1 parent c7ffb10 commit da2f8de
Show file tree
Hide file tree
Showing 68 changed files with 390 additions and 34 deletions.
55 changes: 55 additions & 0 deletions Packs/ApiModules/Scripts/MicrosoftApiModule/MicrosoftApiModule.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,9 @@ class Resources:
TOKEN_EXPIRED_ERROR_CODES = {50173, 700082, 70008, 54005, 7000222,
} # See: https://login.microsoftonline.com/error?code=

# Moderate Retry Mechanism
MAX_DELAY_REQUEST_COUNTER = 6


class CloudEndpointNotSetException(Exception):
pass
Expand Down Expand Up @@ -981,11 +984,21 @@ def _oproxy_authorize(self, resource: str = '', scope: str | None = None) -> tup
"""
content = self.refresh_token or self.tenant_id
headers = self._add_info_headers()
context = get_integration_context()
next_request_time = context.get("next_request_time", 0.0)
delay_request_counter = min(int(context.get('delay_request_counter', 1)), MAX_DELAY_REQUEST_COUNTER)

should_delay_request(next_request_time)
oproxy_response = self._oproxy_authorize_build_request(headers, content, scope, resource)

if not oproxy_response.ok:
next_request_time = calculate_next_request_time(delay_request_counter=delay_request_counter)
set_retry_mechanism_arguments(next_request_time=next_request_time, delay_request_counter=delay_request_counter,
context=context)
self._raise_authentication_error(oproxy_response)

# In case of success, reset the retry mechanism arguments.
set_retry_mechanism_arguments(context=context)
# Oproxy authentication succeeded
try:
gcloud_function_exec_id = oproxy_response.headers.get('Function-Execution-Id')
Expand Down Expand Up @@ -1404,6 +1417,48 @@ def __init__(self, message):
self.message = message


def calculate_next_request_time(delay_request_counter: int) -> float:
"""
Calculates the next request time based on the delay_request_counter.
This is an implication of the Moderate Retry Mechanism for the Oproxy requests.
"""
# The max delay time should be limited to ~60 sec.
next_request_time = get_current_time() + timedelta(seconds=(2 ** delay_request_counter))
return next_request_time.timestamp()


def set_retry_mechanism_arguments(context: dict, next_request_time: float = 0.0, delay_request_counter: int = 1):
"""
Sets the next_request_time in the integration context.
This is an implication of the Moderate Retry Mechanism for the Oproxy requests.
"""
context = context or {}
next_counter = delay_request_counter + 1

context['next_request_time'] = next_request_time
context['delay_request_counter'] = next_counter
# Should reset the context retry arguments.
if next_request_time == 0.0:
context['delay_request_counter'] = 1
set_integration_context(context)


def should_delay_request(next_request_time: float):
"""
Checks if the request should be delayed based on context variables.
This is an implication of the Moderate Retry Mechanism for the Oproxy requests.
"""
now = get_current_time().timestamp()

# If the next_request_time is 0 or negative, it means that the request should not be delayed because no error has occurred.
if next_request_time <= 0.0:
return
# Checking if the next_request_time has passed.
if now >= next_request_time:
return
raise Exception(f"The request will be delayed until {datetime.fromtimestamp(next_request_time)}")


def get_azure_managed_identities_client_id(params: dict) -> str | None:
"""
Extract the Azure Managed Identities from the demisto params
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@

import freezegun
from requests import Response
from MicrosoftApiModule import *
import demistomock as demisto
Expand All @@ -21,6 +21,7 @@
SCOPE = 'https://graph.microsoft.com/.default'
RESOURCE = 'https://defender.windows.com/shtak'
RESOURCES = ['https://resource1.com', 'https://resource2.com']
FREEZE_STR_DATE = "1970-01-01 00:00:00"


def oproxy_client_tenant():
Expand Down Expand Up @@ -756,3 +757,88 @@ def test_get_azure_cloud(params, expected_resource_manager, expected_active_dire
assert get_azure_cloud(params=params, integration_name='test').endpoints.active_directory == expected_active_directory
assert get_azure_cloud(
params=params, integration_name='test').endpoints.microsoft_graph_resource_id == expected_microsoft_graph_resource_id


@freezegun.freeze_time(FREEZE_STR_DATE)
def test_should_delay_true():
"""
Given:
- Mocked context with later next request time than the current time.
When:
- Calling the function should_delay_request.
Then:
- Ensure the function return the expected value.
"""
from MicrosoftApiModule import should_delay_request
from datetime import datetime

mocked_next_request_time = datetime.strptime(FREEZE_STR_DATE, '%Y-%m-%d %H:%M:%S').timestamp() + 1.0
excepted_error = f"The request will be delayed until {datetime.fromtimestamp(mocked_next_request_time)}"
with pytest.raises(Exception) as e:
should_delay_request(mocked_next_request_time)
assert str(e.value) == excepted_error


@freezegun.freeze_time(FREEZE_STR_DATE)
def test_should_delay_false():
"""
Given:
- Mocked context with next request time equal to the current time.
When:
- Calling the function should_delay_request.
Then:
- Ensure the function return with no error.
"""
from MicrosoftApiModule import should_delay_request
from datetime import datetime

mocked_next_request_time = datetime.strptime(FREEZE_STR_DATE, '%Y-%m-%d %H:%M:%S').timestamp()
should_delay_request(mocked_next_request_time)


@freezegun.freeze_time(FREEZE_STR_DATE)
@pytest.mark.parametrize('mocked_next_request_time,excepted', [(2, 4.0), (3, 8.0), (6, 64.0)])
def test_calculate_next_request_time(mocked_next_request_time, excepted):
"""
Given:
- Mocked context with next request time equal to the current time.
When:
- Calling the function should_delay_request.
Then:
- Ensure the function return with no error.
"""
from MicrosoftApiModule import calculate_next_request_time
assert calculate_next_request_time(mocked_next_request_time) == excepted


@freezegun.freeze_time(FREEZE_STR_DATE)
@pytest.mark.parametrize('mocked_delay_request_counter,excepted',
[({'delay_request_counter': 5}, {'next_request_time': 32.0, 'delay_request_counter': 6}),
({'delay_request_counter': 6}, {'next_request_time': 64.0, 'delay_request_counter': 7}),
({'delay_request_counter': 7}, {'next_request_time': 64.0, 'delay_request_counter': 7})])
def test_oproxy_authorize_retry_mechanism(mocker, capfd, mocked_delay_request_counter, excepted):
"""
Given:
- Mocked context with next request time equal to the current time.
When:
- Calling the _oproxy_authorize function.
Then:
- Ensure the function return with no error and the context has been set with the right values.
"""
from datetime import datetime
# pytest raises a warning when there is error in the stderr, this is a workaround to disable it
with capfd.disabled():
client = oproxy_client_refresh()
error = Response()
error.status_code = 400
error.reason = "Bad Request"
mocked_next_request_time = {'next_request_time': datetime.strptime(FREEZE_STR_DATE, '%Y-%m-%d %H:%M:%S').timestamp()}

mocked_context = mocked_next_request_time | mocked_delay_request_counter
mocker.patch.object(demisto, 'getIntegrationContext', return_value=mocked_context)
mocker.patch.object(client, '_oproxy_authorize_build_request', return_value=error)
res = mocker.patch.object(demisto, 'setIntegrationContext')

with pytest.raises(Exception):
client._oproxy_authorize()
assert res.call_args[0][0] == excepted
6 changes: 6 additions & 0 deletions Packs/AzureActiveDirectory/ReleaseNotes/1_3_19.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

#### Integrations

##### Azure Active Directory Identity Protection (Deprecated)

- Added a moderate retry mechanism for the authorization HTTP request through oproxy.
2 changes: 1 addition & 1 deletion Packs/AzureActiveDirectory/pack_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"description": "Deprecated. Use Microsoft Graph Identity and Access instead.",
"support": "xsoar",
"hidden": true,
"currentVersion": "1.3.18",
"currentVersion": "1.3.19",
"author": "Cortex XSOAR",
"url": "https://www.paloaltonetworks.com/cortex",
"email": "",
Expand Down
6 changes: 6 additions & 0 deletions Packs/AzureCompute/ReleaseNotes/1_2_16.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

#### Integrations

##### Azure Compute v2

- Added a moderate retry mechanism for the authorization HTTP request through oproxy.
2 changes: 1 addition & 1 deletion Packs/AzureCompute/pack_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "Azure Compute",
"description": "Create and Manage Azure Virtual Machines",
"support": "xsoar",
"currentVersion": "1.2.15",
"currentVersion": "1.2.16",
"author": "Cortex XSOAR",
"url": "https://www.paloaltonetworks.com/cortex",
"email": "",
Expand Down
6 changes: 6 additions & 0 deletions Packs/AzureDataExplorer/ReleaseNotes/1_2_28.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

#### Integrations

##### Azure Data Explorer

- Added a moderate retry mechanism for the authorization HTTP request through oproxy.
2 changes: 1 addition & 1 deletion Packs/AzureDataExplorer/pack_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "Azure Data Explorer",
"description": "Use Azure Data Explorer integration to collect and analyze data inside clusters of Azure Data Explorer and manage search queries.",
"support": "xsoar",
"currentVersion": "1.2.27",
"currentVersion": "1.2.28",
"author": "Cortex XSOAR",
"url": "https://www.paloaltonetworks.com/cortex",
"email": "",
Expand Down
6 changes: 6 additions & 0 deletions Packs/AzureDevOps/ReleaseNotes/1_3_3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

#### Integrations

##### AzureDevOps

- Added a moderate retry mechanism for the authorization HTTP request through oproxy.
2 changes: 1 addition & 1 deletion Packs/AzureDevOps/pack_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "AzureDevOps",
"description": "Create and manage Git repositories in Azure DevOps Services.",
"support": "xsoar",
"currentVersion": "1.3.2",
"currentVersion": "1.3.3",
"author": "Cortex XSOAR",
"url": "https://www.paloaltonetworks.com/cortex",
"email": "",
Expand Down
6 changes: 6 additions & 0 deletions Packs/AzureFirewall/ReleaseNotes/1_1_28.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

#### Integrations

##### Azure Firewall

- Added a moderate retry mechanism for the authorization HTTP request through oproxy.
2 changes: 1 addition & 1 deletion Packs/AzureFirewall/pack_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "Azure Firewall",
"description": "Azure Firewall is a cloud-native and intelligent network firewall security service that provides breed threat protection for cloud workloads running in Azure.It's a fully stateful, firewall as a service with built-in high availability and unrestricted cloud scalability.",
"support": "xsoar",
"currentVersion": "1.1.27",
"currentVersion": "1.1.28",
"author": "Cortex XSOAR",
"url": "https://www.paloaltonetworks.com/cortex",
"email": "",
Expand Down
6 changes: 6 additions & 0 deletions Packs/AzureKeyVault/ReleaseNotes/1_1_29.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

#### Integrations

##### Azure Key Vault

- Added a moderate retry mechanism for the authorization HTTP request through oproxy.
2 changes: 1 addition & 1 deletion Packs/AzureKeyVault/pack_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "Azure Key Vault",
"description": "Use Key Vault to safeguard and manage cryptographic keys and secrets used by cloud applications and services.",
"support": "xsoar",
"currentVersion": "1.1.28",
"currentVersion": "1.1.29",
"author": "Cortex XSOAR",
"url": "https://www.paloaltonetworks.com/cortex",
"email": "",
Expand Down
6 changes: 6 additions & 0 deletions Packs/AzureKubernetesServices/ReleaseNotes/1_1_21.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

#### Integrations

##### Azure Kubernetes Services

- Added a moderate retry mechanism for the authorization HTTP request through oproxy.
2 changes: 1 addition & 1 deletion Packs/AzureKubernetesServices/pack_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "Azure Kubernetes Services",
"description": "Deploy and manage containerized applications with a fully managed Kubernetes service.",
"support": "xsoar",
"currentVersion": "1.1.20",
"currentVersion": "1.1.21",
"author": "Cortex XSOAR",
"url": "https://www.paloaltonetworks.com/cortex",
"email": "",
Expand Down
6 changes: 6 additions & 0 deletions Packs/AzureLogAnalytics/ReleaseNotes/1_1_19.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

#### Integrations

##### Azure Log Analytics

- Added a moderate retry mechanism for the authorization HTTP request through oproxy.
2 changes: 1 addition & 1 deletion Packs/AzureLogAnalytics/pack_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "Azure Log Analytics",
"description": "Log Analytics is a service that helps you collect and analyze data generated by resources in your cloud and on-premises environments.",
"support": "xsoar",
"currentVersion": "1.1.18",
"currentVersion": "1.1.19",
"author": "Cortex XSOAR",
"url": "https://www.paloaltonetworks.com/cortex",
"email": "",
Expand Down
6 changes: 6 additions & 0 deletions Packs/AzureNetworkSecurityGroups/ReleaseNotes/1_2_21.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

#### Integrations

##### Azure Network Security Groups

- Added a moderate retry mechanism for the authorization HTTP request through oproxy.
2 changes: 1 addition & 1 deletion Packs/AzureNetworkSecurityGroups/pack_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "Azure Network Security Groups",
"description": "Azure Network Security Groups are used to filter network traffic to and from Azure resources in an Azure virtual network",
"support": "xsoar",
"currentVersion": "1.2.20",
"currentVersion": "1.2.21",
"author": "Cortex XSOAR",
"url": "https://www.paloaltonetworks.com/cortex",
"email": "",
Expand Down
6 changes: 6 additions & 0 deletions Packs/AzureRiskyUsers/ReleaseNotes/1_1_19.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

#### Integrations

##### Azure Risky Users

- Added a moderate retry mechanism for the authorization HTTP request through oproxy.
2 changes: 1 addition & 1 deletion Packs/AzureRiskyUsers/pack_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "Azure Risky Users",
"description": "Azure Risky Users provides access to all at-risk users and risk detections in Azure AD environment.",
"support": "xsoar",
"currentVersion": "1.1.18",
"currentVersion": "1.1.19",
"author": "Cortex XSOAR",
"url": "https://www.paloaltonetworks.com/cortex",
"email": "",
Expand Down
6 changes: 6 additions & 0 deletions Packs/AzureSQLManagement/ReleaseNotes/1_1_30.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

#### Integrations

##### Azure SQL Management

- Added a moderate retry mechanism for the authorization HTTP request through oproxy.
2 changes: 1 addition & 1 deletion Packs/AzureSQLManagement/pack_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "Azure SQL Management",
"description": "Microsoft Azure SQL Database is a managed cloud database provided as part of Microsoft Azure",
"support": "xsoar",
"currentVersion": "1.1.29",
"currentVersion": "1.1.30",
"author": "Cortex XSOAR",
"url": "https://www.paloaltonetworks.com/cortex",
"email": "",
Expand Down
10 changes: 10 additions & 0 deletions Packs/AzureSecurityCenter/ReleaseNotes/2_0_11.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

#### Integrations

##### Microsoft Defender for Cloud Event Collector

- Added a moderate retry mechanism for the authorization HTTP request through oproxy.

##### Microsoft Defender for Cloud

- Added a moderate retry mechanism for the authorization HTTP request through oproxy.
2 changes: 1 addition & 1 deletion Packs/AzureSecurityCenter/pack_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "Microsoft Defender for Cloud",
"description": "Unified security management and advanced threat protection across hybrid cloud workloads.",
"support": "xsoar",
"currentVersion": "2.0.10",
"currentVersion": "2.0.11",
"author": "Cortex XSOAR",
"url": "https://www.paloaltonetworks.com/cortex",
"email": "",
Expand Down
6 changes: 6 additions & 0 deletions Packs/AzureSentinel/ReleaseNotes/1_5_21.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

#### Integrations

##### Microsoft Sentinel

- Added a moderate retry mechanism for the authorization HTTP request through oproxy.
2 changes: 1 addition & 1 deletion Packs/AzureSentinel/pack_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "Microsoft Sentinel",
"description": "Microsoft Sentinel is a cloud-native security information and event manager (SIEM) platform that uses built-in AI to help analyze large volumes of data across an enterprise.",
"support": "xsoar",
"currentVersion": "1.5.20",
"currentVersion": "1.5.21",
"author": "Cortex XSOAR",
"url": "https://www.paloaltonetworks.com/cortex",
"email": "",
Expand Down

0 comments on commit da2f8de

Please sign in to comment.