From 8781eed4ef748ca3cee914c19780dccbc47ea48d Mon Sep 17 00:00:00 2001 From: Yael Shamai <111040837+YaelShamai@users.noreply.github.com> Date: Mon, 17 Aug 2026 14:22:33 +0300 Subject: [PATCH 001/419] CyberArk EPM add authentication method and update get-events command (#45363) * start, no testing yet * refresh token ans set_name argument update * more fixes * more * fix * revert * validation fixes * ai and docs review fixes * more cr fixes * improve testing * improve integration description --- .../CyberArkEPMEventCollector.py | 281 +++++++- .../CyberArkEPMEventCollector.yml | 94 ++- .../CyberArkEPMEventCollector_description.md | 59 +- .../CyberArkEPMEventCollector_test.py | 612 +++++++++++++++++- .../CyberArkEPMEventCollector/README.md | 12 +- Packs/CyberArkEPM/ReleaseNotes/1_3_0.md | 7 + Packs/CyberArkEPM/pack_metadata.json | 3 +- 7 files changed, 1032 insertions(+), 36 deletions(-) create mode 100644 Packs/CyberArkEPM/ReleaseNotes/1_3_0.md diff --git a/Packs/CyberArkEPM/Integrations/CyberArkEPMEventCollector/CyberArkEPMEventCollector.py b/Packs/CyberArkEPM/Integrations/CyberArkEPMEventCollector/CyberArkEPMEventCollector.py index 65b0b160427f..9066102c97ce 100644 --- a/Packs/CyberArkEPM/Integrations/CyberArkEPMEventCollector/CyberArkEPMEventCollector.py +++ b/Packs/CyberArkEPM/Integrations/CyberArkEPMEventCollector/CyberArkEPMEventCollector.py @@ -1,3 +1,4 @@ +import time from collections.abc import Callable from itertools import chain @@ -16,12 +17,42 @@ MAX_FETCH = 5000 VENDOR = "CyberArk" PRODUCT = "EPM" + XSIAM_EVENT_TYPE = { "policy_audits": "policy audit raw event details", "admin_audits": "set admin audit data", "detailed_events": "detailed raw", } + +class Config: + """Global static configuration for authentication, OAuth and command outputs.""" + + # Authentication methods + AUTH_METHOD_OAUTH = "Idira OAuth" + AUTH_METHOD_EPM = "EPM" + AUTH_METHOD_SAML = "SAML" + + # OAuth (CyberArk Identity / Idira ISPSS) constants + GRANT_TYPE_CLIENT_CREDENTIALS = "client_credentials" + ACCESS_TOKEN = "access_token" + EXPIRES_IN = "expires_in" + VALID_UNTIL = "valid_until" + DEFAULT_TOKEN_TTL_SECONDS = 6 * 60 * 60 + CACHE_BUFFER_SECONDS = 60 + # EPM SET API version segment used in the OAuth data-call paths, e.g. + # https:///EPM/API//Sets. Only applies to the Idira OAuth flow. + EPM_API_VERSION = "26.7.0" + + # Context outputs prefix per event type. The *-get-events commands expose the parsed/normalized + # events under these prefixes so operators can verify the normalization while debugging. + OUTPUTS_PREFIX = { + "policy_audits": "CyberArkEPM.PolicyAudit", + "admin_audits": "CyberArkEPM.AdminAudit", + "detailed_events": "CyberArkEPM.Event", + } + + """ CLIENT CLASS """ @@ -38,6 +69,10 @@ def __init__( proxy=False, policy_audits_event_type=None, raw_events_event_type=None, + auth_method=None, + identity_url=None, + web_app_id=None, + server_url=None, ): super().__init__(base_url, verify=verify, proxy=proxy) self._headers = { @@ -49,13 +84,156 @@ def __init__( self.application_id = application_id self.authentication_url = authentication_url self.application_url = application_url - if self.authentication_url and self.application_url: + self.identity_url = identity_url + self.web_app_id = web_app_id + # `server_url` is the EPM server address used only for the Idira OAuth method (e.g. + # https://example.epm.cyberark.com/). For the EPM/SAML methods the base URL is resolved + # from the login response within the code. + self.server_url = server_url + # Resolve the authentication method. When `auth_method` is not provided (e.g. instances + # created before the parameter existed), fall back to the legacy behavior: SAML when both + # SAML URLs are set, otherwise EPM. This keeps existing instances backward compatible. + if not auth_method: + auth_method = ( + Config.AUTH_METHOD_SAML if (self.authentication_url and self.application_url) else Config.AUTH_METHOD_EPM + ) + self.auth_method = auth_method + + if self.auth_method == Config.AUTH_METHOD_OAUTH: + self.oauth_auth_to_cyber_ark() + elif self.auth_method == Config.AUTH_METHOD_SAML: self.saml_auth_to_cyber_ark() else: self.epm_auth_to_cyber_ark() self.policy_audits_event_type = policy_audits_event_type self.raw_events_event_type = raw_events_event_type + def _get_access_token(self, force_refresh: bool = False) -> str: + """Get or refresh the OAuth2 access token, with caching in the integration context. + + Args: + force_refresh: When True, ignore any cached token and always request a fresh one. + Used to reactively recover from a server-side 401 (e.g. the token was revoked, + rotated, or expired earlier than our computed `valid_until` due to clock skew). + """ + current_timestamp = int(time.time()) + cached_context = get_integration_context() or {} + cached_token = cached_context.get(Config.ACCESS_TOKEN) + cached_valid_until = cached_context.get(Config.VALID_UNTIL) + + # Return the cached token if it is still valid (unless a forced refresh was requested). + if not force_refresh and cached_token and cached_valid_until: + try: + valid_until_timestamp = int(float(cached_valid_until)) + if current_timestamp < valid_until_timestamp: + demisto.debug("[Token Cache] Hit! Token is still valid.") + return cached_token + demisto.debug("[Token Cache] Miss. Token expired.") + except (ValueError, TypeError): + demisto.debug("[Token Cache] Error parsing cache. Ignoring.") + + if not self.identity_url or not self.web_app_id: + raise DemistoException("Identity URL and Web App ID are required for OAuth authentication.") + token_url = f"{self.identity_url.rstrip('/')}/oauth2/token/{self.web_app_id}" + demisto.debug(f"[Token Request] Requesting new token from {token_url}") + + token_data = {"grant_type": Config.GRANT_TYPE_CLIENT_CREDENTIALS} + headers = {"Content-Type": "application/x-www-form-urlencoded"} + + try: + # Use `super()._http_request` (not `self._http_request`) so the token request itself + # never enters the OAuth 401 retry logic. A 401 here means bad credentials, and it + # should surface directly as an auth failure rather than triggering a refresh-and-retry. + token_response = super()._http_request( + method="POST", + full_url=token_url, + data=token_data, + headers=headers, + auth=(self.username, self.password), + resp_type="json", + ) + except DemistoException as error: + error_msg = str(error) + demisto.debug(f"[Token Request] Traceback: {traceback.format_exc()}") + demisto.error(f"[Token Request] Failed: {error_msg}") + raise DemistoException(f"Failed to obtain access token: {error_msg}") + + access_token = token_response.get(Config.ACCESS_TOKEN) + if not access_token: + raise DemistoException("Failed to obtain access token. Response missing access_token.") + + token_expires_in = arg_to_number(token_response.get(Config.EXPIRES_IN)) or Config.DEFAULT_TOKEN_TTL_SECONDS + token_valid_until = current_timestamp + token_expires_in - Config.CACHE_BUFFER_SECONDS + demisto.debug(f"[Token Request] Success. Expires in {token_expires_in}s.") + + cached_context[Config.ACCESS_TOKEN] = access_token + cached_context[Config.VALID_UNTIL] = str(token_valid_until) + set_integration_context(cached_context) + + return access_token + + def oauth_auth_to_cyber_ark(self, force_refresh: bool = False) -> None: + # Reference: CyberArk Identity (Idira ISPSS) OAuth2 client_credentials flow. + # For the Idira OAuth method the EPM server address is provided directly via the + # `server_url` parameter, so there is no need to discover the tenant URL at runtime. + if not self.server_url: + raise DemistoException("Server URL is required for Idira OAuth authentication.") + access_token = self._get_access_token(force_refresh=force_refresh) + self._base_url = f"{self.server_url.rstrip('/')}/EPM/API/{Config.EPM_API_VERSION}/" + self._headers["Authorization"] = f"Bearer {access_token}" + + def _refresh_oauth_token(self) -> None: + """Force a new OAuth token and update the Authorization header. + + Clears the cached token/validity so `_get_access_token(force_refresh=True)` cannot + return the stale (now-rejected) token, then re-authenticates. Called reactively when + the server returns 401 for a token our cache still considered valid (early revocation, + rotation, clock skew, or a shorter-than-reported lifetime). + """ + demisto.debug("[Token Refresh] Server rejected the token (401). Forcing a new token.") + cached_context = get_integration_context() or {} + cached_context.pop(Config.ACCESS_TOKEN, None) + cached_context.pop(Config.VALID_UNTIL, None) + set_integration_context(cached_context) + # Re-authenticating issues its own HTTP request (the token request). Guard against + # that request re-entering the 401 retry logic (which would recurse infinitely if the + # token endpoint itself returns 401, e.g. bad credentials). + self._is_authenticating = True + try: + self.oauth_auth_to_cyber_ark(force_refresh=True) + finally: + self._is_authenticating = False + + def _http_request(self, *args, **kwargs): + """Wrap BaseClient._http_request to transparently recover from an expired OAuth token. + + For the OAuth auth method, if a data request fails with 401 Unauthorized, force a token + refresh once and retry the request a single time. This complements the proactive + time-based refresh (the `CACHE_BUFFER_SECONDS` buffer) by covering cases where the token + becomes invalid before its computed expiry. Other auth methods keep the default behavior. + """ + # Only apply the retry logic for OAuth data requests, and never while we are in the + # middle of (re)authenticating, to avoid recursive refresh attempts. + if self.auth_method != Config.AUTH_METHOD_OAUTH or getattr(self, "_is_authenticating", False): + return super()._http_request(*args, **kwargs) + try: + return super()._http_request(*args, **kwargs) + except DemistoException as error: + if not self._is_unauthorized_error(error): + raise + demisto.debug("[Token Refresh] Received 401 on a data request. Refreshing token and retrying once.") + self._refresh_oauth_token() + return super()._http_request(*args, **kwargs) + + @staticmethod + def _is_unauthorized_error(error: DemistoException) -> bool: + """Return True if the given DemistoException represents an HTTP 401 Unauthorized.""" + response = getattr(error, "res", None) + if response is not None and getattr(response, "status_code", None) == 401: + return True + # Fallback for cases where the response object is not attached to the exception. + return re.search(r"\b401\b", str(error)) is not None + def epm_auth_to_cyber_ark(self): # pragma: no cover data = { "Username": self.username, @@ -284,7 +462,8 @@ def get_set_ids_by_set_names(client: Client, set_names: list) -> list[str]: (dict) A dict of {set_id: events (list events associated with a list of set names)}. """ demisto.debug(f"[get_set_ids_by_set_names] Requested set_names from config: {set_names}") - context_set_items = get_integration_context().get("set_items", {}) + integration_context = get_integration_context() or {} + context_set_items = integration_context.get("set_items", {}) demisto.debug(f"[get_set_ids_by_set_names] Cached set_items in context: {context_set_items}") if context_set_items.keys() != set(set_names): @@ -311,7 +490,11 @@ def get_set_ids_by_set_names(client: Client, set_names: list) -> list[str]: f"{unresolved_set_names}. These sets will not be fetched." ) - set_integration_context({"set_items": context_set_items}) + # Merge into the existing context instead of overwriting it, so we don't clobber + # other cached keys (e.g. the OAuth `access_token`/`valid_until` written by + # `_get_access_token`). + integration_context["set_items"] = context_set_items + set_integration_context(integration_context) else: demisto.debug("[get_set_ids_by_set_names] Using cached set_items from integration context") @@ -417,7 +600,14 @@ def get_events_command(client: Client, event_type: str, last_run: dict, limit: i human_readable = tableToMarkdown(string_to_table_header(event_type), events_list) - return events_list, CommandResults(readable_output=human_readable, raw_response=events_list) + # Expose the parsed/normalized events in `outputs` so operators can verify the normalization + # while debugging (in addition to the raw response). + return events_list, CommandResults( + readable_output=human_readable, + outputs_prefix=Config.OUTPUTS_PREFIX[event_type], + outputs=events_list, + raw_response=events_list, + ) def fetch_events( @@ -501,6 +691,48 @@ def test_module(client: Client, last_run: dict) -> str: """ MAIN FUNCTION """ +def validate_params( + auth_method: str, + base_url: str | None, + authentication_url: str | None, + application_url: str | None, + identity_url: str | None, + web_app_id: str | None, + server_url: str | None, +) -> None: + """Validate the authentication-related parameters based on the selected authentication method. + + Args: + auth_method: The selected authentication method (one of Config.AUTH_METHOD_OAUTH, + Config.AUTH_METHOD_SAML, Config.AUTH_METHOD_EPM). + base_url: The SAML/EPM Logon URL. + authentication_url: The SAML Authentication URL. + application_url: The SAML Application URL. + identity_url: The Idira OAuth Identity URL. + web_app_id: The Idira OAuth Web App ID. + server_url: The Idira OAuth Server URL. + + Raises: + SystemExit: Via `return_error` when the required parameters for the selected method are missing or invalid. + """ + demisto.info(f"Authentication method is: {auth_method}") + + if auth_method == Config.AUTH_METHOD_OAUTH: + if not server_url or not identity_url or not web_app_id: + return_error("Server URL, Identity URL, and Web App ID are required for Idira OAuth authentication.") + if "/oauth2/token" in (identity_url or ""): + return_error( + "Identity URL must be the bare FQDN (e.g. https://.id.cyberark.cloud) " + "without a '/oauth2/token' suffix." + ) + elif auth_method == Config.AUTH_METHOD_SAML: + if not base_url or not authentication_url or not application_url: + return_error("SAML/EPM Logon URL, Authentication URL, and Application URL are required for SAML authentication.") + else: # AUTH_METHOD_EPM + if not base_url: + return_error("SAML/EPM Logon URL is required for EPM authentication.") + + def main(): # pragma: no cover args = demisto.args() params = demisto.params() @@ -511,8 +743,23 @@ def main(): # pragma: no cover application_id = params.get("application_id") authentication_url = params.get("authentication_url") application_url = params.get("application_url") + auth_method = params.get("authentication_method") or Config.AUTH_METHOD_EPM + identity_url = params.get("identity_url") + web_app_id = params.get("web_app_id") + server_url = params.get("server_url") username = params.get("credentials").get("identifier") password = params.get("credentials").get("password") + + validate_params( + auth_method=auth_method, + base_url=base_url, + authentication_url=authentication_url, + application_url=application_url, + identity_url=identity_url, + web_app_id=web_app_id, + server_url=server_url, + ) + set_names = argToList(params.get("set_name")) enable_admin_audits = argToBoolean(params.get("enable_admin_audits", False)) policy_audits_event_type = argToList(params.get("policy_audits_event_type")) @@ -545,13 +792,16 @@ def main(): # pragma: no cover application_url=application_url, policy_audits_event_type=policy_audits_event_type, raw_events_event_type=raw_events_event_type, + auth_method=auth_method, + identity_url=identity_url, + web_app_id=web_app_id, + server_url=server_url, ) set_ids = get_set_ids_by_set_names(client, set_names) demisto.debug(f"[main] Resolved {len(set_ids)} set ID(s) from {len(set_names)} configured set name(s)") demisto.debug(f"[main] resolved {set_ids=}") - # Validate we got set IDs if not set_ids: raise DemistoException( f"No set IDs were resolved from configured set names: {set_names}. " @@ -602,14 +852,23 @@ def main(): # pragma: no cover demisto.debug( f"[main] executing cyberarkepm-get-events with limit={max_limit}, " f"from_date={args.get('from_date')}, " - f"raw_events_event_type={raw_events_event_type}, " + f"raw_events_event_type={raw_events_event_type}, {enable_admin_audits=}, " f"should_push_events={argToBoolean(args.get('should_push_events', False))}" ) events, command_result = get_events_command(client, "detailed_events", last_run, max_limit) # type: ignore + command_results = [command_result] + # When admin audits are enabled in the instance configuration, also fetch and include + # them in this command's results (in addition to the detailed events). Keep the admin + # audits as their own CommandResults so their normalized `outputs` are preserved. + if enable_admin_audits: + admin_events, admin_command_result = get_events_command(client, "admin_audits", last_run, max_limit) # type: ignore + demisto.debug(f"[cyberarkepm-get-events] admin audits enabled, fetched {len(admin_events)} admin audit(s)") + events = events + admin_events + command_results.append(admin_command_result) if argToBoolean(args.get("should_push_events", False)): send_events_to_xsiam(events, vendor=VENDOR, product=PRODUCT) demisto.debug(f"[cyberarkepm-get-events] send_events_to_xsiam: {len(events)} events, {events=}") - return_results(command_result) + return_results(command_results) elif command in "fetch-events": events, next_run = fetch_events(client, last_run, max_fetch, enable_admin_audits) # type: ignore @@ -617,8 +876,12 @@ def main(): # pragma: no cover demisto.debug(f"[fetch-events] send_events_to_xsiam: {len(events)} events, {events=}") demisto.setLastRun(next_run) - except Exception as e: - return_error(f"Failed to execute {command} command.\nError:\n{e!s}") + except Exception as error: + error_msg = f"Failed to execute {command}. Error: {error!s}" + demisto.error(f"{error_msg}\n{traceback.format_exc()}") + return_error(error_msg) + + demisto.debug("CyberArkEPMEventCollector integration finished") if __name__ in ("__main__", "__builtin__", "builtins"): diff --git a/Packs/CyberArkEPM/Integrations/CyberArkEPMEventCollector/CyberArkEPMEventCollector.yml b/Packs/CyberArkEPM/Integrations/CyberArkEPMEventCollector/CyberArkEPMEventCollector.yml index decae59a0cba..e645bde81fde 100644 --- a/Packs/CyberArkEPM/Integrations/CyberArkEPMEventCollector/CyberArkEPMEventCollector.yml +++ b/Packs/CyberArkEPM/Integrations/CyberArkEPMEventCollector/CyberArkEPMEventCollector.yml @@ -1,3 +1,5 @@ +display: CyberArk EPM Event Collector +name: CyberArkEPMEventCollector category: Analytics & SIEM provider: CyberArk sectionorder: @@ -7,10 +9,39 @@ commonfields: id: CyberArkEPMEventCollector version: -1 configuration: -- additionalinfo: 'SAML example: https://login.epm.cyberark.com/SAML/Logon.' +- display: Authentication Method + name: authentication_method + additionalinfo: The authentication method to use when connecting to CyberArk EPM. + required: true + defaultvalue: EPM + type: 15 + options: + - Idira OAuth + - EPM + - SAML + section: Connect +- additionalinfo: 'The Server URL. Required for OAuth 2.0 only. For example: https://example.epm.cyberark.com/.' + display: Server URL (only for Idira Oauth) + name: server_url + required: false + type: 0 + section: Connect +- additionalinfo: 'The SAML/EPM Logon URL. Required for EPM and SAML authentication methods only. SAML example: https://login.epm.cyberark.com/SAML/Logon.' display: SAML/EPM Logon URL name: url - required: true + required: false + type: 0 + section: Connect +- additionalinfo: 'The CyberArk Identity FQDN, e.g. https://.id.cyberark.cloud. Required for Idira OAuth authentication only. Used only to obtain the OAuth token; must not include a /oauth2/token suffix.' + display: Identity URL + name: identity_url + required: false + type: 0 + section: Connect +- additionalinfo: 'The registered OAuth2 web-app identifier in CyberArk Identity Administration, used as a URL path segment on the token endpoint (/oauth2/token/). Required for Idira OAuth authentication only.' + display: Web App ID + name: web_app_id + required: false type: 0 section: Connect - display: Username @@ -19,7 +50,7 @@ configuration: type: 9 section: Connect - display: Set name - additionalinfo: A comma-separated list of set names. + additionalinfo: A comma-separated list of set names to collect events from. Required for all authentication methods (EPM, SAML, and Idira OAuth). name: set_name required: true type: 0 @@ -114,9 +145,21 @@ configuration: - Access - Skipped section: Collect -description: CyberArk EPM Event Collector fetches events. -display: CyberArk EPM Event Collector -name: CyberArkEPMEventCollector +- defaultvalue: 'false' + display: Fetch events + name: isFetchEvents + additionalinfo: Whether to fetch events. + type: 8 + required: false + section: Collect +- defaultvalue: '1' + display: Events Fetch Interval + name: eventFetchInterval + type: 19 + required: false + advanced: true + section: Collect +description: Collects policy audits, admin audits, and detailed (raw) events from CyberArk Endpoint Privilege Manager (EPM). script: commands: - arguments: @@ -168,7 +211,7 @@ script: name: limit - description: Date to return results from. (in ISO format '01-01-24T00:00:00.123Z'). name: from_date - description: Gets events from Cyber Ark EPM. + description: Gets events from Cyber Ark EPM. Use this command for development and debugging only, as it may produce duplicate events, exceed API rate limits, or disrupt the fetch mechanism. execution: false name: cyberarkepm-get-events dockerimage: demisto/btfl-soup:1.0.1.10120494 @@ -182,6 +225,43 @@ marketplaces: - marketplacev2 - platform fromversion: 8.2.0 +triggers: +- conditions: + - name: authentication_method + operator: equal + value: Idira OAuth + effects: + - name: identity_url + action: + required: true + - name: web_app_id + action: + required: true + - name: server_url + action: + required: true +- conditions: + - name: authentication_method + operator: equal + value: EPM + effects: + - name: url + action: + required: true +- conditions: + - name: authentication_method + operator: equal + value: SAML + effects: + - name: url + action: + required: true + - name: authentication_url + action: + required: true + - name: application_url + action: + required: true tests: - No tests (auto formatted) supportedModules: diff --git a/Packs/CyberArkEPM/Integrations/CyberArkEPMEventCollector/CyberArkEPMEventCollector_description.md b/Packs/CyberArkEPM/Integrations/CyberArkEPMEventCollector/CyberArkEPMEventCollector_description.md index fddce5230491..d2da5cc66fd3 100644 --- a/Packs/CyberArkEPM/Integrations/CyberArkEPMEventCollector/CyberArkEPMEventCollector_description.md +++ b/Packs/CyberArkEPM/Integrations/CyberArkEPMEventCollector/CyberArkEPMEventCollector_description.md @@ -1,24 +1,55 @@ ## CyberArk EPM Help ### Authentication -There are two methods to authenticate EPM and SAML (currently only via Okta). +There are three methods to authenticate: EPM, SAML (currently only via Okta), and Idira OAuth (CyberArk Identity / ISPSS). Every method needs different parameters as show in the following: * EPM authentication - - url: `https://` (for example: https://login.epm.cyberark.com/login) - - username - - password - - [application ID](https://docs.cyberark.com/Idaptive/Latest/en/Content/Applications/AppsOvw/SpecifyAppID.htm#%23SpecifytheApplicationID) - - set name (comma separated value) + - **url**: `https://` (for example: https://login.epm.cyberark.com/login) + - **username** + - **password** + - [**application ID**](https://docs.cyberark.com/Idaptive/Latest/en/Content/Applications/AppsOvw/SpecifyAppID.htm#%23SpecifytheApplicationID) + - **set name** (comma separated value) * SAML authentication (advanced settings) currently supported only via Okta. - - url: `https://login.epm.cyberark.com/SAML/Logon` - - username - - password - - authentication URL [Okta example](https://developer.okta.com/docs/reference/api/authn/#authentication-operations): `https://[COMPANY_NAME].okta.com/api/v1/authn` - - application URL: `https://[COMPANY_NAME].okta.com/home/[APP_NAME]/[APP_ID]` - - set name (comma separated value) + - **url**: `https://login.epm.cyberark.com/SAML/Logon` + - **username** + - **password** + - **authentication URL** [Okta example](https://developer.okta.com/docs/reference/api/authn/#authentication-operations): `https://[COMPANY_NAME].okta.com/api/v1/authn` + - **Application URL**: `https://[COMPANY_NAME].okta.com/home/[APP_NAME]/[APP_ID]` + - **Set name** (comma separated value) + + +* Idira OAuth authentication (CyberArk Identity / ISPSS). + - **Server URL**: the EPM server address, for example: `https://example.epm.cyberark.com/` + - **Identity URL**: The CyberArk Identity FQDN, for example: `https://.id.cyberark.cloud` (used only to obtain the OAuth token) + - **Web App ID**: The web app's application ID / alias (see the vendor-side setup below) + - **Username** (the service-user login, used as the Client ID) + - **Password** (the service-user password, used as the Client Secret) + - **Set name** (comma separated value) + +#### Vendor-side setup for the Idira OAuth (CyberArk Identity / ISPSS) method + +1. **Create a service user for API requests** — In Identity Administration go to **Core Services > Users > Add User**. Set a **Login name**, **Display name**, and **Password**. Select **Is OAuth confidential client**, **Is Service User**, and **Password never expires**. Click **Create User**. + > The service-user login becomes the Client ID; its password becomes the Client Secret. + +2. **Create the custom permission group (EPM Management Console)** — Log in to the EPM Management Console as an Account Administrator. In the navigation pane, under **Administration**, select **Permission groups**, then click **Create custom permission group**. Enter a name (e.g. `API_Audit_Viewer`) and an optional description. From the **Based on** dropdown, select **View Only Set Admin** as the starting point. In the permissions matrix, fine-tune access so the API user can query the needed endpoints: + - **Sets**: Ensure **Set visibility** is enabled. + - **Policy Audit**: Ensure **View Audit** (or the top-level Policy Audit permission) is enabled. + - Turn off any other permissions the API service user does not need. Click **Create**. + +3. **Create an EPM role using the custom group (EPM Management Console)** — Permission groups cannot be assigned to users directly; they must be bundled with specific Sets into a Role. Still in the EPM Management Console, go to **Administration > Roles** and click **Create role**. Enter a name (e.g. `API_Set_Auditor_Role`), select the custom permission group you just created (`API_Audit_Viewer`), select the specific Set(s) the API is allowed to query, and click **Create**. + +4. **Assign the role to your API service user (Identity Administration)** — Once created in EPM, the role automatically syncs to CyberArk Identity Administration with an `EPM_` prefix. Switch to the Identity Administration console, go to **Core Services > Roles**, and search for the role using the `EPM_` prefix (e.g. `EPM_API_Set_Auditor_Role`). Open the role, go to the **Members** tab, click **Add**, search for your OAuth API service user, select it, and click **Add**. + > Sync between EPM and Identity Administration can take a few moments. If the new `EPM_` role does not appear in Identity Administration immediately, wait a minute or two and refresh. + +5. **Create a custom EPM API web app** — In **Apps & Widgets > Web Apps > Add Web Apps**, search for `EPM`, add **Idira EPM API Client**, confirm, and save the required Settings. + > The web app's application ID / alias becomes the **Web App ID**. + +6. **Configure token expiration and bind the service user** — In the web app's **Tokens** tab, set the token expiration period and save. In the **Permissions** tab, add the service user and save. The web app status should become **Deployed**. + +7. **Identify the Identity URL** — The CyberArk Identity FQDN, e.g. `https://.id.cyberark.cloud` (used only to obtain the OAuth token). ### Fetch Information @@ -27,5 +58,5 @@ Every method needs different parameters as show in the following: * Admin audits. * Events. -* The `set name` parameter contains a list of names to which the events are related. -* The `max fetch` parameter is for every event type and for every name in the `set name` parameter which means that for `max fetch` that equals 1000 the actually max events fetched will be 3000 * sum of names in the `set name` parameter. +* The **set name** parameter contains a list of names to which the events are related. +* The **max fetch** parameter is for every event type and for every name in the **set name** parameter which means that for **max fetch** that equals 1000 the actually max events fetched will be 3000 * sum of names in the **set name** parameter. diff --git a/Packs/CyberArkEPM/Integrations/CyberArkEPMEventCollector/CyberArkEPMEventCollector_test.py b/Packs/CyberArkEPM/Integrations/CyberArkEPMEventCollector/CyberArkEPMEventCollector_test.py index 294054e21c31..ca9637017900 100644 --- a/Packs/CyberArkEPM/Integrations/CyberArkEPMEventCollector/CyberArkEPMEventCollector_test.py +++ b/Packs/CyberArkEPM/Integrations/CyberArkEPMEventCollector/CyberArkEPMEventCollector_test.py @@ -280,6 +280,43 @@ def test_get_set_ids_by_set_names(mocker, requests_mock): assert get_set_ids_by_set_names(client, set_names) == ["id1", "id2"] +def test_get_set_ids_by_set_names_preserves_token_in_context(mocker, requests_mock): + """ + Given: + - An integration context that already holds a cached OAuth token + (access_token / valid_until) alongside no cached set_items. + + When: + - get_set_ids_by_set_names resolves and persists set_items to the context. + + Then: + - The cached token keys are preserved (not clobbered) and set_items is added, + proving the set-name write and the token write can coexist in the context. + """ + from CyberArkEPMEventCollector import get_set_ids_by_set_names + + # Stateful fake integration context shared by the get/set mocks. + fake_context = {"access_token": "cached-token", "valid_until": "9999999999"} + + mocker.patch( + "CyberArkEPMEventCollector.get_integration_context", + side_effect=lambda: dict(fake_context), + ) + mocker.patch( + "CyberArkEPMEventCollector.set_integration_context", + side_effect=lambda ctx: fake_context.update(ctx), + ) + + set_names = ["set_name1", "set_name2"] + client = mocked_client(requests_mock) + + assert get_set_ids_by_set_names(client, set_names) == ["id1", "id2"] + # Token keys must survive the set_items write. + assert fake_context["access_token"] == "cached-token" + assert fake_context["valid_until"] == "9999999999" + assert fake_context["set_items"] == {"set_name1": "id1", "set_name2": "id2"} + + """ TEST COMMAND FUNCTION """ @@ -298,7 +335,7 @@ def test_get_events_command(requests_mock, event_type): Then: - Validates that the function works as expected. """ - from CyberArkEPMEventCollector import create_last_run, get_events_command + from CyberArkEPMEventCollector import Config, create_last_run, get_events_command from CommonServerPython import string_to_table_header @@ -309,6 +346,8 @@ def test_get_events_command(requests_mock, event_type): assert len(events) == 6 assert string_to_table_header(event_type) in command_results.readable_output + assert command_results.outputs == events + assert command_results.outputs_prefix == Config.OUTPUTS_PREFIX[event_type] def test_fetch_events(requests_mock): @@ -378,3 +417,574 @@ def test_prepare_next_run_with_zero_events(event_type, last_fetch, expected_next assert last_run["set123"][event_type]["next_cursor"] == expected_next_cursor assert last_run["set123"][event_type]["from_date"] == expected_from_date + + +""" TEST OAUTH (IDIRA) AUTHENTICATION """ + + +def test_oauth_uses_server_url_as_base_url(mocker, requests_mock): + """ + Given: + - An Idira OAuth configuration with a Server URL, Identity URL, and Web App ID. + + When: + - Building the Client (which performs the OAuth authentication flow). + + Then: + - The token is requested from the Identity URL token endpoint. + - No tenant-URL discovery call is made; the Server URL is used directly. + - The base URL is built from the Server URL with the versioned EPM SET API path, + and the Bearer header is set from the token response. + """ + from CyberArkEPMEventCollector import Client + + mocker.patch("CyberArkEPMEventCollector.get_integration_context", return_value={}) + mocker.patch("CyberArkEPMEventCollector.set_integration_context") + + identity_url = "https://tenant.id.cyberark.cloud" + server_url = "https://example.epm.cyberark.com" + + token_matcher = requests_mock.post( + f"{identity_url}/oauth2/token/web-app-1", json={"access_token": "TOKEN123", "expires_in": 900} + ) + + client = Client( + base_url="", + username="user", + password="pass", + application_id="1", + auth_method="Idira OAuth", + identity_url=identity_url, + web_app_id="web-app-1", + server_url=server_url, + ) + + assert token_matcher.called + # Only the token endpoint should have been called (no tenant-URL discovery). + assert requests_mock.call_count == 1 + assert client._headers["Authorization"] == "Bearer TOKEN123" + # Data calls must use the uppercase, versioned EPM SET API path (matches CyberArk Postman). + assert client._base_url == f"{server_url}/EPM/API/26.7.0/" + + +def test_oauth_missing_server_url_raises(mocker, requests_mock): + """ + Given: + - An Idira OAuth configuration WITHOUT a Server URL. + + When: + - Building the Client (which performs the OAuth authentication flow). + + Then: + - A DemistoException is raised indicating the Server URL is required. + """ + from CyberArkEPMEventCollector import Client + from CommonServerPython import DemistoException + + mocker.patch("CyberArkEPMEventCollector.get_integration_context", return_value={}) + mocker.patch("CyberArkEPMEventCollector.set_integration_context") + + identity_url = "https://tenant.id.cyberark.cloud" + token_matcher = requests_mock.post( + f"{identity_url}/oauth2/token/web-app-1", json={"access_token": "TOKEN123", "expires_in": 900} + ) + + with pytest.raises(DemistoException, match="Server URL is required"): + Client( + base_url="", + username="user", + password="pass", + application_id="1", + auth_method="Idira OAuth", + identity_url=identity_url, + web_app_id="web-app-1", + server_url="", + ) + + # The Server URL guard runs before any token request, so the token endpoint must never be hit. + assert token_matcher.call_count == 0 + + +def _build_oauth_client(requests_mock, identity_url, server_url): + """Helper: build an Idira OAuth Client with the token endpoint mocked. + + Returns a tuple of (client, token_matcher) so callers can assert on the token + endpoint call count using the same matcher that actually served the requests. + """ + from CyberArkEPMEventCollector import Client + + token_matcher = requests_mock.post( + f"{identity_url}/oauth2/token/web-app-1", + json={"access_token": "TOKEN123", "expires_in": 900}, + ) + client = Client( + base_url="", + username="user", + password="pass", + application_id="1", + auth_method="Idira OAuth", + identity_url=identity_url, + web_app_id="web-app-1", + server_url=server_url, + ) + return client, token_matcher + + +def test_oauth_token_endpoint_401_raises_without_retry(mocker, requests_mock): + """ + Given: + - An Idira OAuth configuration whose token endpoint returns 401 (bad credentials). + + When: + - Building the Client (which performs the initial OAuth token request). + + Then: + - The failure surfaces as a clean "Failed to obtain access token" error. + - The token endpoint is called exactly once (the token request must NOT enter the + 401 refresh-and-retry logic). + """ + from CyberArkEPMEventCollector import Client + from CommonServerPython import DemistoException + + mocker.patch("CyberArkEPMEventCollector.get_integration_context", return_value={}) + mocker.patch("CyberArkEPMEventCollector.set_integration_context") + # Avoid writing to stdout (the XSOAR test harness fails tests that leave stdout output). + mocker.patch("CyberArkEPMEventCollector.demisto.error") + mocker.patch("CyberArkEPMEventCollector.demisto.debug") + + identity_url = "https://tenant.id.cyberark.cloud" + token_matcher = requests_mock.post(f"{identity_url}/oauth2/token/web-app-1", status_code=401, json={"error": "unauthorized"}) + + with pytest.raises(DemistoException, match="Failed to obtain access token"): + Client( + base_url="", + username="user", + password="pass", + application_id="1", + auth_method="Idira OAuth", + identity_url=identity_url, + web_app_id="web-app-1", + server_url="https://example.epm.cyberark.com", + ) + + # Exactly one token call: no refresh-and-retry for the token request itself. + assert token_matcher.call_count == 1 + + +def test_oauth_data_call_401_refreshes_and_retries_once(mocker, requests_mock): + """ + Given: + - A valid Idira OAuth Client. + - A data endpoint that returns 401 on the first call and 200 on the second. + + When: + - A data request is made through the overridden `_http_request`. + + Then: + - The client refreshes the token once and retries the data request exactly once, + ultimately returning the successful response. + - The token endpoint is called twice (initial auth + reactive refresh). + """ + mocker.patch("CyberArkEPMEventCollector.get_integration_context", return_value={}) + mocker.patch("CyberArkEPMEventCollector.set_integration_context") + # Avoid writing to stdout (the XSOAR test harness fails tests that leave stdout output). + mocker.patch("CyberArkEPMEventCollector.demisto.error") + mocker.patch("CyberArkEPMEventCollector.demisto.debug") + + identity_url = "https://tenant.id.cyberark.cloud" + server_url = "https://example.epm.cyberark.com" + + client, token_matcher = _build_oauth_client(requests_mock, identity_url, server_url) + + data_matcher = requests_mock.get( + f"{server_url}/EPM/API/26.7.0/Sets", + [ + {"status_code": 401, "json": {"error": "unauthorized"}}, + {"status_code": 200, "json": {"Sets": [{"Id": "id1", "Name": "set_name1"}]}}, + ], + ) + + result = client._http_request("GET", url_suffix="Sets") + + assert result == {"Sets": [{"Id": "id1", "Name": "set_name1"}]} + # First auth token call + one reactive refresh after the 401. + assert token_matcher.call_count == 2 + # Data endpoint hit twice: original 401 + single retry. + assert data_matcher.call_count == 2 + + +def test_oauth_token_expires_in_as_string_is_handled(mocker, requests_mock): + """ + Given: + - An Idira OAuth token response whose `expires_in` value is a string (e.g. "900"). + + When: + - Building the Client (which requests and caches the token). + + Then: + - No TypeError is raised when computing `valid_until`. + - The cached `valid_until` is a numeric string derived from the integer TTL. + """ + from CyberArkEPMEventCollector import Client, Config + + saved_context: dict = {} + mocker.patch("CyberArkEPMEventCollector.get_integration_context", side_effect=lambda: dict(saved_context)) + mocker.patch("CyberArkEPMEventCollector.set_integration_context", side_effect=lambda ctx: saved_context.update(ctx)) + mocker.patch("CyberArkEPMEventCollector.demisto.debug") + mocker.patch("CyberArkEPMEventCollector.time.time", return_value=1000) + + identity_url = "https://tenant.id.cyberark.cloud" + server_url = "https://example.epm.cyberark.com" + # `expires_in` returned as a string. + requests_mock.post(f"{identity_url}/oauth2/token/web-app-1", json={"access_token": "TOKEN123", "expires_in": "900"}) + + client = Client( + base_url="", + username="user", + password="pass", + application_id="1", + auth_method="Idira OAuth", + identity_url=identity_url, + web_app_id="web-app-1", + server_url=server_url, + ) + + assert client._headers["Authorization"] == "Bearer TOKEN123" + # valid_until = current_time (1000) + 900 - Config.CACHE_BUFFER_SECONDS. + assert saved_context["valid_until"] == str(1000 + 900 - Config.CACHE_BUFFER_SECONDS) + + +def test_oauth_valid_cached_token_skips_token_endpoint(mocker, requests_mock): + """ + Given: + - An Idira OAuth Client with a still-valid token cached in the integration context. + + When: + - Building the Client (which resolves the access token via `_get_access_token`). + + Then: + - The cached token is used directly. + - The token endpoint is never called (zero token requests). + - The Authorization header reflects the cached token. + """ + from CyberArkEPMEventCollector import Client, Config + + mocker.patch("CyberArkEPMEventCollector.demisto.debug") + # `time.time()` = 1000; cached token valid until 5000 -> still valid. + mocker.patch("CyberArkEPMEventCollector.time.time", return_value=1000) + mocker.patch( + "CyberArkEPMEventCollector.get_integration_context", + return_value={Config.ACCESS_TOKEN: "CACHED_TOKEN", Config.VALID_UNTIL: "5000"}, + ) + set_context = mocker.patch("CyberArkEPMEventCollector.set_integration_context") + + identity_url = "https://tenant.id.cyberark.cloud" + server_url = "https://example.epm.cyberark.com" + token_matcher = requests_mock.post( + f"{identity_url}/oauth2/token/web-app-1", json={"access_token": "FRESH_TOKEN", "expires_in": 900} + ) + + client = Client( + base_url="", + username="user", + password="pass", + application_id="1", + auth_method="Idira OAuth", + identity_url=identity_url, + web_app_id="web-app-1", + server_url=server_url, + ) + + assert client._headers["Authorization"] == "Bearer CACHED_TOKEN" + # A valid cache means no token endpoint call and no context rewrite. + assert token_matcher.call_count == 0 + assert set_context.call_count == 0 + + +def test_oauth_expired_cached_token_requests_new_token(mocker, requests_mock): + """ + Given: + - An Idira OAuth Client with an EXPIRED token cached in the integration context. + + When: + - Building the Client (which resolves the access token via `_get_access_token`). + + Then: + - Exactly one token request is issued to refresh the expired token. + - The integration context is rewritten with the new token and validity. + - The Authorization header reflects the new token. + """ + from CyberArkEPMEventCollector import Client, Config + + saved_context: dict = {Config.ACCESS_TOKEN: "OLD_TOKEN", Config.VALID_UNTIL: "500"} + mocker.patch("CyberArkEPMEventCollector.demisto.debug") + # `time.time()` = 1000; cached token valid only until 500 -> expired. + mocker.patch("CyberArkEPMEventCollector.time.time", return_value=1000) + mocker.patch("CyberArkEPMEventCollector.get_integration_context", side_effect=lambda: dict(saved_context)) + set_context = mocker.patch( + "CyberArkEPMEventCollector.set_integration_context", side_effect=lambda ctx: saved_context.update(ctx) + ) + + identity_url = "https://tenant.id.cyberark.cloud" + server_url = "https://example.epm.cyberark.com" + token_matcher = requests_mock.post( + f"{identity_url}/oauth2/token/web-app-1", json={"access_token": "NEW_TOKEN", "expires_in": 900} + ) + + client = Client( + base_url="", + username="user", + password="pass", + application_id="1", + auth_method="Idira OAuth", + identity_url=identity_url, + web_app_id="web-app-1", + server_url=server_url, + ) + + assert client._headers["Authorization"] == "Bearer NEW_TOKEN" + # Exactly one token request for the expired cache, and the context was rewritten. + assert token_matcher.call_count == 1 + assert set_context.call_count == 1 + assert saved_context[Config.ACCESS_TOKEN] == "NEW_TOKEN" + assert saved_context[Config.VALID_UNTIL] == str(1000 + 900 - Config.CACHE_BUFFER_SECONDS) + + +def test_oauth_corrupt_valid_until_falls_through_to_fresh_token(mocker, requests_mock): + """ + Given: + - An Idira OAuth Client whose cached `valid_until` is not a number (e.g. "not-a-number"). + + When: + - Building the Client (which resolves the access token via `_get_access_token`). + + Then: + - No exception is raised while parsing the corrupt cache. + - The client falls through to a fresh token request (exactly one). + - The Authorization header reflects the freshly requested token. + """ + from CyberArkEPMEventCollector import Client, Config + + mocker.patch("CyberArkEPMEventCollector.demisto.debug") + mocker.patch("CyberArkEPMEventCollector.time.time", return_value=1000) + mocker.patch( + "CyberArkEPMEventCollector.get_integration_context", + return_value={Config.ACCESS_TOKEN: "CACHED_TOKEN", Config.VALID_UNTIL: "not-a-number"}, + ) + mocker.patch("CyberArkEPMEventCollector.set_integration_context") + + identity_url = "https://tenant.id.cyberark.cloud" + server_url = "https://example.epm.cyberark.com" + token_matcher = requests_mock.post( + f"{identity_url}/oauth2/token/web-app-1", json={"access_token": "FRESH_TOKEN", "expires_in": 900} + ) + + client = Client( + base_url="", + username="user", + password="pass", + application_id="1", + auth_method="Idira OAuth", + identity_url=identity_url, + web_app_id="web-app-1", + server_url=server_url, + ) + + assert client._headers["Authorization"] == "Bearer FRESH_TOKEN" + # The corrupt cache is ignored and a single fresh token request is made. + assert token_matcher.call_count == 1 + + +def test_oauth_force_refresh_bypasses_valid_cache(mocker, requests_mock): + """ + Given: + - An Idira OAuth Client with a still-valid cached token. + + When: + - `_get_access_token(force_refresh=True)` is called explicitly. + + Then: + - The valid cache is ignored and a fresh token is requested. + - The freshly requested token (not the cached one) is returned. + """ + from CyberArkEPMEventCollector import Client, Config + + mocker.patch("CyberArkEPMEventCollector.demisto.debug") + mocker.patch("CyberArkEPMEventCollector.time.time", return_value=1000) + mocker.patch("CyberArkEPMEventCollector.set_integration_context") + + identity_url = "https://tenant.id.cyberark.cloud" + server_url = "https://example.epm.cyberark.com" + + # Initial build: empty cache -> one token request returning CACHED_TOKEN. + mocker.patch( + "CyberArkEPMEventCollector.get_integration_context", + return_value={Config.ACCESS_TOKEN: "CACHED_TOKEN", Config.VALID_UNTIL: "5000"}, + ) + token_matcher = requests_mock.post( + f"{identity_url}/oauth2/token/web-app-1", json={"access_token": "FRESH_TOKEN", "expires_in": 900} + ) + + client = Client( + base_url="", + username="user", + password="pass", + application_id="1", + auth_method="Idira OAuth", + identity_url=identity_url, + web_app_id="web-app-1", + server_url=server_url, + ) + # Build used the valid cache -> no token request yet. + assert token_matcher.call_count == 0 + + token = client._get_access_token(force_refresh=True) + + assert token == "FRESH_TOKEN" + # force_refresh must bypass the valid cache and issue exactly one token request. + assert token_matcher.call_count == 1 + + +def test_oauth_missing_access_token_in_response_raises(mocker, requests_mock): + """ + Given: + - An Idira OAuth token endpoint that returns HTTP 200 but omits `access_token`. + + When: + - Building the Client (which requests the token). + + Then: + - A DemistoException is raised indicating the response is missing the access token. + """ + from CyberArkEPMEventCollector import Client + from CommonServerPython import DemistoException + + mocker.patch("CyberArkEPMEventCollector.get_integration_context", return_value={}) + mocker.patch("CyberArkEPMEventCollector.set_integration_context") + mocker.patch("CyberArkEPMEventCollector.demisto.debug") + + identity_url = "https://tenant.id.cyberark.cloud" + requests_mock.post(f"{identity_url}/oauth2/token/web-app-1", json={"expires_in": 900}) + + with pytest.raises(DemistoException, match="missing access_token"): + Client( + base_url="", + username="user", + password="pass", + application_id="1", + auth_method="Idira OAuth", + identity_url=identity_url, + web_app_id="web-app-1", + server_url="https://example.epm.cyberark.com", + ) + + +def test_oauth_data_call_non_401_error_propagates_without_refresh(mocker, requests_mock): + """ + Given: + - A valid Idira OAuth Client. + - A data endpoint that fails with a NON-401 error (e.g. 500 Server Error). + + When: + - A data request is made through the overridden `_http_request`. + + Then: + - The original exception propagates unchanged. + - No token refresh occurs (the token endpoint is called only once, for initial auth). + - The data endpoint is called only once (no retry). + """ + from CommonServerPython import DemistoException + + mocker.patch("CyberArkEPMEventCollector.get_integration_context", return_value={}) + mocker.patch("CyberArkEPMEventCollector.set_integration_context") + mocker.patch("CyberArkEPMEventCollector.demisto.error") + mocker.patch("CyberArkEPMEventCollector.demisto.debug") + + identity_url = "https://tenant.id.cyberark.cloud" + server_url = "https://example.epm.cyberark.com" + + client, token_matcher = _build_oauth_client(requests_mock, identity_url, server_url) + + data_matcher = requests_mock.get(f"{server_url}/EPM/API/26.7.0/Sets", status_code=500, json={"error": "server error"}) + + with pytest.raises(DemistoException): + client._http_request("GET", url_suffix="Sets") + + # Only the initial auth token request; no reactive refresh for a non-401 error. + assert token_matcher.call_count == 1 + # The data endpoint is hit once and NOT retried. + assert data_matcher.call_count == 1 + + +def test_is_unauthorized_error_incidental_401_not_treated_as_unauthorized(): + """ + Given: + - A DemistoException with no response object, whose message merely contains "401" + incidentally (e.g. as part of a set ID) rather than as an HTTP status. + + When: + - `Client._is_unauthorized_error` inspects the exception. + + Then: + - A message whose "401" is a standalone HTTP status token IS treated as unauthorized. + - A message where "401" is embedded inside another token (e.g. "S40199") is NOT. + """ + from CyberArkEPMEventCollector import Client + from CommonServerPython import DemistoException + + # A genuine 401 status token in the message is still recognized (fallback path). + assert Client._is_unauthorized_error(DemistoException("Error in API call [401] - Unauthorized")) is True + # "401" embedded inside an unrelated identifier must NOT be treated as unauthorized. + assert Client._is_unauthorized_error(DemistoException("No events for set S40199")) is False + + +def test_client_defaults_to_epm_when_auth_method_missing(requests_mock): + """ + Given: + - A Client configuration WITHOUT an explicit `auth_method` and WITHOUT SAML URLs. + + When: + - Building the Client. + + Then: + - The legacy inference selects the EPM authentication method (no error raised). + """ + from CyberArkEPMEventCollector import Client, Config + + requests_mock.post( + "https://url.com/EPM/API/Auth/EPM/Logon", + json={"ManagerURL": "https://mock.com", "EPMAuthenticationResult": "123"}, + ) + + client = Client("https://url.com", "test", "123456", "1") + + assert client.auth_method == Config.AUTH_METHOD_EPM + + +def test_client_defaults_to_saml_when_saml_urls_present(requests_mock, mocker): + """ + Given: + - A Client configuration WITHOUT an explicit `auth_method` but WITH both SAML URLs set. + + When: + - Building the Client. + + Then: + - The legacy inference selects the SAML authentication method (no error raised). + """ + from CyberArkEPMEventCollector import Client, Config + + # SAML flow performs its own multi-step auth; stub it so we only assert the inference result. + saml_auth = mocker.patch("CyberArkEPMEventCollector.Client.saml_auth_to_cyber_ark") + + client = Client( + "https://url.com", + "test", + "123456", + "1", + authentication_url="https://auth.example.com", + application_url="https://app.example.com", + ) + + assert client.auth_method == Config.AUTH_METHOD_SAML + assert saml_auth.call_count == 1 diff --git a/Packs/CyberArkEPM/Integrations/CyberArkEPMEventCollector/README.md b/Packs/CyberArkEPM/Integrations/CyberArkEPMEventCollector/README.md index 6f506cd271ad..acf86954b0e0 100644 --- a/Packs/CyberArkEPM/Integrations/CyberArkEPMEventCollector/README.md +++ b/Packs/CyberArkEPM/Integrations/CyberArkEPMEventCollector/README.md @@ -1,17 +1,21 @@ -CyberArk EPM Event Collector fetches events. +Collects policy audits, admin audits, and detailed (raw) events from CyberArk Endpoint Privilege Manager (EPM). This integration was integrated and tested with version 23.12.0 of CyberArk EPM. ## Configure CyberArk EPM Event Collector in Cortex | **Parameter** | **Description** | **Required** | | --- | --- | --- | -| SAML/EPM Logon URL | SAML example: https://login.epm.cyberark.com/SAML/Logon. | True | +| Authentication Method | The authentication method to use when connecting to CyberArk EPM. Options: `Idira OAuth`, `EPM`, `SAML`. | True | +| SAML/EPM Logon URL | Required for EPM and SAML authentication methods only. SAML example: `https://login.epm.cyberark.com/SAML/Logon`. | False | +| Identity URL | Required for Idira OAuth authentication only. The CyberArk Identity FQDN, e.g. `https://.id.cyberark.cloud`. Used only to obtain the OAuth token; must not include a `/oauth2/token` suffix. | False | +| Web App ID | Required for Idira OAuth authentication only. The registered OAuth2 web-app identifier in CyberArk Identity Administration, used as a URL path segment on the token endpoint (`/oauth2/token/`). | False | +| Server URL (only for Idira OAuth) | Required for OAuth 2.0 only. For example: `https://example.epm.cyberark.com/` | False | | Username | | True | | Password | | True | | Set name | A comma-separated list of set names. | True | | Application ID | Required for local\(EPM\) authentication only. | False | -| Authentication URL | Required for SAML authentication only, Example for PAN OKTA: https://paloaltonetworks.okta.com/api/v1/authn. | False | -| Application URL | Required for SAML authentication only, Example for PAN OKTA: https://paloaltonetworks.okta.com/home/\[APP_NAME\]/\[APP_ID\]. | False | +| Authentication URL | Required for SAML authentication only, Example for PAN OKTA: `https://paloaltonetworks.okta.com/api/v1/authn`. | False | +| Application URL | Required for SAML authentication only, Example for PAN OKTA: `https://paloaltonetworks.okta.com/home/[APP_NAME]/[APP_ID]`. | False | | Trust any certificate (not secure) | | False | | Use system proxy settings | | False | | Maximum number of events per fetch | | False | diff --git a/Packs/CyberArkEPM/ReleaseNotes/1_3_0.md b/Packs/CyberArkEPM/ReleaseNotes/1_3_0.md new file mode 100644 index 000000000000..d483eb0675d3 --- /dev/null +++ b/Packs/CyberArkEPM/ReleaseNotes/1_3_0.md @@ -0,0 +1,7 @@ + +#### Integrations + +##### CyberArk EPM Event Collector + +- Added support for CyberArk Identity (Idira ISPSS) OAuth 2.0 `client_credentials` authentication, selectable via the new *Authentication Method* parameter, alongside the existing EPM and SAML methods. +- Added the *Identity URL* and *Web App ID* parameters, required for the Idira OAuth authentication method. diff --git a/Packs/CyberArkEPM/pack_metadata.json b/Packs/CyberArkEPM/pack_metadata.json index 8ad08762b518..958b70892867 100644 --- a/Packs/CyberArkEPM/pack_metadata.json +++ b/Packs/CyberArkEPM/pack_metadata.json @@ -2,10 +2,11 @@ "name": "CyberArk Endpoint Privilege Manager", "description": "Endpoint Privilege Manager helps remove local admin rights while improving user experience and optimizing IT operations.", "support": "xsoar", - "currentVersion": "1.2.3", + "currentVersion": "1.3.0", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", + "created": "2021-01-01T00:00:00Z", "categories": [ "Analytics & SIEM" ], From 1e4da7224063b95246e06e98aac4e3a8f7c425e7 Mon Sep 17 00:00:00 2001 From: Yael Shamai <111040837+YaelShamai@users.noreply.github.com> Date: Mon, 17 Aug 2026 15:02:40 +0300 Subject: [PATCH 002/419] Error Handling OCI Event Collector (#45387) * fixed api error masked * rn * add unit tests * Add 2 required arguments * fix validation --- ...OracleCloudInfrastructureEventCollector.py | 35 +-- ...racleCloudInfrastructureEventCollector.yml | 12 + ...eCloudInfrastructureEventCollector_test.py | 218 +++++++++++++++++- .../ReleaseNotes/1_0_39.md | 6 + .../pack_metadata.json | 2 +- 5 files changed, 254 insertions(+), 19 deletions(-) create mode 100644 Packs/OracleCloudInfrastructure/ReleaseNotes/1_0_39.md diff --git a/Packs/OracleCloudInfrastructure/Integrations/OracleCloudInfrastructureEventCollector/OracleCloudInfrastructureEventCollector.py b/Packs/OracleCloudInfrastructure/Integrations/OracleCloudInfrastructureEventCollector/OracleCloudInfrastructureEventCollector.py index 8c1a5b528d1b..bf5f6141ae19 100644 --- a/Packs/OracleCloudInfrastructure/Integrations/OracleCloudInfrastructureEventCollector/OracleCloudInfrastructureEventCollector.py +++ b/Packs/OracleCloudInfrastructure/Integrations/OracleCloudInfrastructureEventCollector/OracleCloudInfrastructureEventCollector.py @@ -266,7 +266,13 @@ def audit_log_api_request(client: Client, start_time: str, next_page: str | None params = {"compartmentId": client.compartment_id, "startTime": start_time, "endTime": datetime.now().strftime(DATE_FORMAT)} if next_page: params["opc-next-page"] = next_page - return client._http_request(method="GET", params=params, resp_type="response") + demisto.debug(f"[API] Requesting OCI audit events. compartmentId={client.compartment_id} url={client.base_url} {params=}") + try: + return client._http_request(method="GET", params=params, resp_type="response") + except Exception as e: + raise DemistoException( + f"OCI audit events request failed for compartmentId={client.compartment_id} at {client.base_url}: {e}" + ) from e def searchlogs_api_request( @@ -292,7 +298,10 @@ def searchlogs_api_request( params["page"] = next_page demisto.debug(f"Sending http request to get search log events with {body=} {params=}") - return client._http_request(method="POST", full_url=url, params=params, json_data=body, resp_type="response") + try: + return client._http_request(method="POST", full_url=url, params=params, json_data=body, resp_type="response") + except Exception as e: + raise DemistoException(f"OCI search log events request failed at {url}: {e}") from e def add_millisecond_to_timestamp(timestamp: str) -> str: @@ -433,6 +442,12 @@ def get_events( Returns: tuple[list[dict[str, Any]], str]: A tuple of the events list and the last event time for next fetch cycle. """ + + # Initialize before the try so the except handler can safely reference them + # even if the first API call fails. + events: list[dict[str, Any]] = [] + last_event_time = first_fetch_time.strftime(DATE_FORMAT) + try: response = audit_log_api_request(client=client, start_time=first_fetch_time.strftime(DATE_FORMAT)) events = json.loads(response.content) @@ -445,21 +460,21 @@ def get_events( # pagination handling while len(events) < max_fetch and (next_page := response.headers._store.get("opc-next-page")): # type: ignore - current_start_time = add_millisecond_to_timestamp(events[-1].get("eventTime")) + current_start_time = add_millisecond_to_timestamp(events[-1].get("eventTime")) # type: ignore[arg-type] response = audit_log_api_request(client=client, start_time=current_start_time, next_page=next_page[1]) events.extend(json.loads(response.content)) last_event_time = get_last_event_time(events, first_fetch_time) events = add_time_key_to_events(events) - # handle the case where an error occurred while fetching events, + # Handle the case where an error occurred while fetching events, # and there are currently available events that can and need to be sent to XSIAM. except Exception as e: if events and push_events_on_error: last_event_time = get_last_event_time(events, first_fetch_time) events = add_time_key_to_events(events) handle_fetched_events(events, last_event_time) - raise DemistoException(f"Error while fetching events: {e}") from e + raise DemistoException(f"Error while fetching events: {e}") from e demisto.info(f"OCI: {len(events)} Events fetched from start time: {first_fetch_time}.") return events, last_event_time @@ -509,10 +524,7 @@ def test_module(client: Client, search_log_query: str, event_types_to_fetch: lis client._http_request(method="GET", params=params) except Exception as e: - if "failed" in str(e): - return "Authorization Error: make sure OCI parameters are correctly set" - else: - raise DemistoException(f"Error while testing: {e}") from e + raise DemistoException(f"Error while testing: {e}") from e if "Search Logs" in event_types_to_fetch: try: @@ -525,10 +537,7 @@ def test_module(client: Client, search_log_query: str, event_types_to_fetch: lis ) except Exception as e: - if "failed" in str(e): - return "Authorization Error: make sure OCI parameters are correctly set" - else: - raise DemistoException(f"Error while testing: {e}") from e + raise DemistoException(f"Error while testing: {e}") from e return "ok" diff --git a/Packs/OracleCloudInfrastructure/Integrations/OracleCloudInfrastructureEventCollector/OracleCloudInfrastructureEventCollector.yml b/Packs/OracleCloudInfrastructure/Integrations/OracleCloudInfrastructureEventCollector/OracleCloudInfrastructureEventCollector.yml index db7eaa64028a..a7c1d4254963 100644 --- a/Packs/OracleCloudInfrastructure/Integrations/OracleCloudInfrastructureEventCollector/OracleCloudInfrastructureEventCollector.yml +++ b/Packs/OracleCloudInfrastructure/Integrations/OracleCloudInfrastructureEventCollector/OracleCloudInfrastructureEventCollector.yml @@ -47,6 +47,18 @@ configuration: required: false type: 0 section: Connect +- display: Fetch Events + defaultvalue: 'false' + name: isFetchEvents + type: 8 + required: false + section: Collect +- display: Events Fetch Interval + name: eventFetchInterval + type: 19 + required: false + section: Collect + defaultvalue: '1' - display: First fetch time additionalinfo: This parameter is relevant for 'Audit' events only. defaultvalue: 3 days diff --git a/Packs/OracleCloudInfrastructure/Integrations/OracleCloudInfrastructureEventCollector/OracleCloudInfrastructureEventCollector_test.py b/Packs/OracleCloudInfrastructure/Integrations/OracleCloudInfrastructureEventCollector/OracleCloudInfrastructureEventCollector_test.py index 3a128a74b7e7..29beccd9f01c 100644 --- a/Packs/OracleCloudInfrastructure/Integrations/OracleCloudInfrastructureEventCollector/OracleCloudInfrastructureEventCollector_test.py +++ b/Packs/OracleCloudInfrastructure/Integrations/OracleCloudInfrastructureEventCollector/OracleCloudInfrastructureEventCollector_test.py @@ -464,6 +464,27 @@ def test_audit_log_api_request_check_compartment_id(self, mocker): assert client.compartment_id == "dummy_compartment_id" assert mocked_http_request.call_args[1]["params"] == expected_params + def test_audit_log_api_request_error_includes_context(self, mocker, dummy_client): + """ + Given: + - The underlying _http_request raises a DemistoException. + When: + - Making an audit log API request. + Then: + - Make sure the raised exception message includes both the compartmentId and the base_url, + providing enough context to diagnose the failure. + """ + from OracleCloudInfrastructureEventCollector import audit_log_api_request + + mocker.patch.object(dummy_client, "_http_request", side_effect=DemistoException("underlying failure")) + + with pytest.raises(DemistoException) as exc_info: + audit_log_api_request(dummy_client, start_time="2023-01-01T10:10:10.000Z") + + raised_text = str(exc_info.value) + assert dummy_client.compartment_id in raised_text + assert dummy_client.base_url in raised_text + @pytest.mark.parametrize("events", ([{"dummy_data": "dummy_data"}], [])) def test_handle_fetched_events(self, mocker, events): """ @@ -605,6 +626,107 @@ def test_get_events_fail_with_events(self, mocker, dummy_client, dummy_datetime= with pytest.raises(Exception): get_events(client=dummy_client, first_fetch_time=first_date_time, max_fetch=5, push_events_on_error=False) + def test_get_events_reraises_original_oci_error(self, mocker, dummy_client, dummy_datetime=dummy_datetime): + """ + Given: + - The first audit_log_api_request call raises an OCI error carrying a status code + (404) and error code (NotAuthorizedOrNotFound), and no events were fetched yet. + When: + - Fetching events from the audit log API with push_events_on_error=True. + Then: + - The function re-raises the error. + - The raised exception contains the original OCI status code and error code. + """ + from OracleCloudInfrastructureEventCollector import get_events + + oci_error_message = ( + "Error in API call [404] - Not Found\n" + "{'code': 'NotAuthorizedOrNotFound', " + "'message': 'Authorization failed or requested resource not found'}" + ) + mocker.patch( + "OracleCloudInfrastructureEventCollector.audit_log_api_request", + side_effect=DemistoException(oci_error_message), + ) + if not isinstance(dummy_datetime, datetime.datetime): + raise ValueError("first_date_time is not a datetime object") + + with pytest.raises(Exception) as exc_info: + get_events(client=dummy_client, first_fetch_time=dummy_datetime, max_fetch=5, push_events_on_error=True) + + raised_text = str(exc_info.value) + assert "404" in raised_text + assert "NotAuthorizedOrNotFound" in raised_text + + def test_get_events_pushes_collected_events_before_reraising(self, mocker, dummy_client, dummy_datetime=dummy_datetime): + """ + Given: + - The first audit_log_api_request call succeeds and returns a page of events with an + opc-next-page header (so events are already collected). + - The second audit_log_api_request call (pagination) raises a DemistoException. + - push_events_on_error=True. + When: + - Fetching events from the audit log API. + Then: + - The already-collected events are handled (handle_fetched_events is called with them). + - The original exception still propagates out of get_events. + """ + from OracleCloudInfrastructureEventCollector import get_events + + first_page_response = MockResponse(content=[{"eventTime": "2023-01-01T11:10:10.000Z"}]) + first_page_response.headers._store["opc-next-page"] = ("opc-next-page", "next_page_token") + + mocker.patch( + "OracleCloudInfrastructureEventCollector.audit_log_api_request", + side_effect=[first_page_response, DemistoException("pagination failure")], + ) + mocked_handle_fetched_events = mocker.patch("OracleCloudInfrastructureEventCollector.handle_fetched_events") + if not isinstance(dummy_datetime, datetime.datetime): + raise ValueError("first_date_time is not a datetime object") + + with pytest.raises(DemistoException) as exc_info: + get_events(client=dummy_client, first_fetch_time=dummy_datetime, max_fetch=5, push_events_on_error=True) + + # The collected events were handled before re-raising. + assert mocked_handle_fetched_events.called + handled_events = mocked_handle_fetched_events.call_args.args[0] + assert handled_events == [{"eventTime": "2023-01-01T11:10:10.000Z", "_time": "2023-01-01T11:10:10.000Z"}] + # The original exception still propagates. + assert "pagination failure" in str(exc_info.value) + + def test_get_events_pagination_with_none_event_time(self, mocker, dummy_client, dummy_datetime=dummy_datetime): + """ + Given: + - The first audit_log_api_request call returns a page whose last event has no eventTime + (eventTime is None) and an opc-next-page header, triggering the pagination branch. + - push_events_on_error=True so collected events are handled before re-raising. + When: + - Fetching events from the audit log API. + Then: + - The pagination branch computes the next start time from a None eventTime, which raises, + exercising the '# type: ignore[arg-type]' line. + - The already-collected events are handled and the exception propagates. + """ + from OracleCloudInfrastructureEventCollector import get_events + + first_page_response = MockResponse(content=[{"id": "no-time-event"}]) + first_page_response.headers._store["opc-next-page"] = ("opc-next-page", "next_page_token") + + mocker.patch( + "OracleCloudInfrastructureEventCollector.audit_log_api_request", + return_value=first_page_response, + ) + mocked_handle_fetched_events = mocker.patch("OracleCloudInfrastructureEventCollector.handle_fetched_events") + if not isinstance(dummy_datetime, datetime.datetime): + raise ValueError("first_date_time is not a datetime object") + + with pytest.raises(DemistoException): + get_events(client=dummy_client, first_fetch_time=dummy_datetime, max_fetch=5, push_events_on_error=True) + + assert mocked_handle_fetched_events.called + handled_events = mocked_handle_fetched_events.call_args.args[0] + assert handled_events == [{"id": "no-time-event"}] + class TestFetchEventsFlows: """Test class for the fetch events flows.""" @@ -880,6 +1002,31 @@ def test_searchlogs_api_request_with_custom_limit(self, mocker, dummy_client): call_kwargs = mocked_http_request.call_args[1] assert call_kwargs["params"] == {"limit": 500} + def test_searchlogs_api_request_error_includes_url(self, mocker, dummy_client): + """ + Given: + - The underlying _http_request raises a DemistoException. + When: + - Making a search logs API request. + Then: + - Make sure the raised exception message includes the search log url, + providing enough context to diagnose the failure. + """ + from OracleCloudInfrastructureEventCollector import searchlogs_api_request + + mocker.patch.object(dummy_client, "_http_request", side_effect=DemistoException("underlying failure")) + + with pytest.raises(DemistoException) as exc_info: + searchlogs_api_request( + client=dummy_client, + time_start="2023-01-01T10:10:10.000Z", + time_end="2023-01-15T10:10:10.000Z", + search_query="search query", + ) + + raised_text = str(exc_info.value) + assert dummy_client.searchlog_url in raised_text + class TestDeduplicateEvents: """Tests for the deduplicate_events function.""" @@ -1402,21 +1549,82 @@ def test_test_module_search_logs_auth_failure(self, dummy_client, mocker): Given: - event_types_to_fetch contains 'Search Logs'. When: - - test_module is called and the API returns an auth failure containing 'failed'. + - test_module is called and the Search Logs API raises an OCI error. Then: - - An authorization error message is returned. + - test_module raises and the original OCI error text is preserved. """ from OracleCloudInfrastructureEventCollector import test_module + oci_error_message = "Authorization failed or requested resource not found [NotAuthorizedOrNotFound]" mocker.patch( "OracleCloudInfrastructureEventCollector.searchlogs_api_request", - side_effect=Exception("Request failed - authorization error"), + side_effect=DemistoException(oci_error_message), + ) + + with pytest.raises(Exception) as exc_info: + test_module( + client=dummy_client, + search_log_query="search query", + event_types_to_fetch=["Search Logs"], + ) + + raised_text = str(exc_info.value) + assert "Authorization failed or requested resource not found" in raised_text + assert "NotAuthorizedOrNotFound" in raised_text + + def test_test_module_audit_failure_preserves_status_and_error_code(self, dummy_client, mocker): + """ + Given: + - event_types_to_fetch contains 'Audit'. + When: + - test_module is called and the audit API raises an OCI error carrying a status + code (404) and error code (NotAuthorizedOrNotFound). + Then: + - test_module raises and the OCI status code and error code are preserved. + """ + from OracleCloudInfrastructureEventCollector import test_module + + oci_error_message = ( + "Error in API call [404] - Not Found\n" + "{'code': 'NotAuthorizedOrNotFound', " + "'message': 'Authorization failed or requested resource not found'}" + ) + mocker.patch.object(dummy_client, "_http_request", side_effect=DemistoException(oci_error_message)) + + with pytest.raises(Exception) as exc_info: + test_module( + client=dummy_client, + search_log_query="search query", + event_types_to_fetch=["Audit"], + ) + + raised_text = str(exc_info.value) + assert "404" in raised_text + assert "NotAuthorizedOrNotFound" in raised_text + + def test_test_module_audit_and_search_logs_success(self, dummy_client, mocker): + """ + Given: + - event_types_to_fetch contains both 'Audit' and 'Search Logs' with a valid search_log_query. + When: + - test_module is called and both the audit API and the Search Logs API succeed. + Then: + - Both APIs are exercised and 'ok' is returned. + """ + from OracleCloudInfrastructureEventCollector import test_module + + mocked_http_request = mocker.patch.object(dummy_client, "_http_request", return_value={"data": "dummy_data"}) + mocked_searchlogs = mocker.patch( + "OracleCloudInfrastructureEventCollector.searchlogs_api_request", + return_value=MockResponse(content={}), ) result = test_module( client=dummy_client, search_log_query="search query", - event_types_to_fetch=["Search Logs"], + event_types_to_fetch=["Audit", "Search Logs"], ) - assert result == "Authorization Error: make sure OCI parameters are correctly set" + assert result == "ok" + assert mocked_http_request.called + assert mocked_searchlogs.called diff --git a/Packs/OracleCloudInfrastructure/ReleaseNotes/1_0_39.md b/Packs/OracleCloudInfrastructure/ReleaseNotes/1_0_39.md new file mode 100644 index 000000000000..4dd2f3f20748 --- /dev/null +++ b/Packs/OracleCloudInfrastructure/ReleaseNotes/1_0_39.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Oracle Cloud Infrastructure Event Collector + +- Improved error handling. diff --git a/Packs/OracleCloudInfrastructure/pack_metadata.json b/Packs/OracleCloudInfrastructure/pack_metadata.json index 8e31d98de275..b6c750be1fa4 100644 --- a/Packs/OracleCloudInfrastructure/pack_metadata.json +++ b/Packs/OracleCloudInfrastructure/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Oracle Cloud Infrastructure (OCI)", "description": "Oracle Cloud Infrastructure (OCI)", "support": "xsoar", - "currentVersion": "1.0.38", + "currentVersion": "1.0.39", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 2c0ed411c03767d7463e1d2b5f3cda90906a3e79 Mon Sep 17 00:00:00 2001 From: lironcohen272 Date: Mon, 17 Aug 2026 20:33:58 +0300 Subject: [PATCH 003/419] =?UTF-8?q?DBotFindSimilarIncidents=20script=20-?= =?UTF-8?q?=20escape=20special=20characters=20in=20exact=20=E2=80=A6=20(#4?= =?UTF-8?q?5538)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * DBotFindSimilarIncidents script - escape special characters in exact match fields to prevent query errors * Bump pack from version Base to 1.42.20. * Bump pack from version Base to 1.42.19. * Bump pack from version Base to 1.42.20. --------- Co-authored-by: test-split Co-authored-by: Content Bot --- Packs/Base/ReleaseNotes/1_42_20.md | 6 ++ .../DBotFindSimilarIncidents.py | 14 +++- .../DBotFindSimilarIncidents_test.py | 67 +++++++++++++++++++ Packs/Base/pack_metadata.json | 2 +- 4 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 Packs/Base/ReleaseNotes/1_42_20.md diff --git a/Packs/Base/ReleaseNotes/1_42_20.md b/Packs/Base/ReleaseNotes/1_42_20.md new file mode 100644 index 000000000000..4e6c16284b9a --- /dev/null +++ b/Packs/Base/ReleaseNotes/1_42_20.md @@ -0,0 +1,6 @@ + +#### Scripts + +##### DBotFindSimilarIncidents + +- Fixed an issue where the script failed when a field value used for exact match contained unescaped special characters (such as double quotes). diff --git a/Packs/Base/Scripts/DBotFindSimilarIncidents/DBotFindSimilarIncidents.py b/Packs/Base/Scripts/DBotFindSimilarIncidents/DBotFindSimilarIncidents.py index 84bffb74eb41..56a5218758c2 100644 --- a/Packs/Base/Scripts/DBotFindSimilarIncidents/DBotFindSimilarIncidents.py +++ b/Packs/Base/Scripts/DBotFindSimilarIncidents/DBotFindSimilarIncidents.py @@ -665,6 +665,17 @@ def get_incident_by_id(incident_id: str, populate_fields: list[str], from_date: return incidents[0] if incidents else None +def escape_query_value(value: Any) -> str: + """ + Escape special characters in a field value so it can be safely embedded inside a + double-quoted getIncidents query. + + :param value: The raw field value to escape. + :return: The escaped value as a string. + """ + return str(value).replace("\\", "\\\\").replace('"', '\\"').replace("\n", "\\n").replace("\r", "\\r") + + def get_all_incidents_for_time_window_and_exact_match( exact_match_fields: list[str], populate_fields: list[str], @@ -691,7 +702,8 @@ def get_all_incidents_for_time_window_and_exact_match( if exact_match_field not in incident: msg += f"{MESSAGE_NO_FIELD % exact_match_field} \n" else: - exact_match_fields_list.append(f'{exact_match_field}: "{incident[exact_match_field]}"') + escaped_value = escape_query_value(incident[exact_match_field]) + exact_match_fields_list.append(f'{exact_match_field}: "{escaped_value}"') query = " AND ".join(exact_match_fields_list) query += f" AND -id:{incident['id']} " if query_sup: diff --git a/Packs/Base/Scripts/DBotFindSimilarIncidents/DBotFindSimilarIncidents_test.py b/Packs/Base/Scripts/DBotFindSimilarIncidents/DBotFindSimilarIncidents_test.py index 8946565d1e39..591bfed40b1f 100644 --- a/Packs/Base/Scripts/DBotFindSimilarIncidents/DBotFindSimilarIncidents_test.py +++ b/Packs/Base/Scripts/DBotFindSimilarIncidents/DBotFindSimilarIncidents_test.py @@ -574,3 +574,70 @@ def test_create_incident_link(mocker, is_platform, version_ge, incident_id, expe mocker.patch.object(DBotFindSimilarIncidents, "is_demisto_version_ge", return_value=version_ge) link_creator = DBotFindSimilarIncidents.get_incident_link_creator() assert link_creator(incident_id) == expected_link + + +@pytest.mark.parametrize( + "value, expected", + [ + ('Payment Request "0000025803" has been "Approved".', 'Payment Request \\"0000025803\\" has been \\"Approved\\".'), + ("no special chars", "no special chars"), + ('a "quote"', 'a \\"quote\\"'), + ("line1\nline2", "line1\\nline2"), + ("carriage\rreturn", "carriage\\rreturn"), + ("back\\slash", "back\\\\slash"), + (12345, "12345"), + ], +) +def test_escape_query_value(value, expected): + """ + Given: + - A field value that may contain special characters (double quotes, newlines, backslashes). + When: + - Escaping the value before embedding it in a getIncidents query. + Then: + - Ensure special characters are escaped so the resulting query is well-formed. + """ + from DBotFindSimilarIncidents import escape_query_value + + assert escape_query_value(value) == expected + + +def test_get_all_incidents_for_time_window_and_exact_match_escapes_special_chars(mocker): + """ + Given: + - An incident whose exact-match field value contains unescaped double quotes. + When: + - Building the getIncidents query in get_all_incidents_for_time_window_and_exact_match. + Then: + - Ensure the double quotes in the field value are escaped in the query passed to + get_incidents_by_query, so the query is not malformed. + """ + import DBotFindSimilarIncidents + + captured = {} + + def fake_get_incidents_by_query(args): + captured["query"] = args["query"] + return [{"id": "1"}] + + mocker.patch.object(DBotFindSimilarIncidents, "get_incidents_by_query", side_effect=fake_get_incidents_by_query) + + incident = { + "id": "173171866", + "reportedemailsubject": 'Payment Request "0000025803" has been "Approved".', + } + + DBotFindSimilarIncidents.get_all_incidents_for_time_window_and_exact_match( + exact_match_fields=["reportedemailsubject"], + populate_fields=["id", "reportedemailsubject"], + incident=incident, + from_date="7 days ago", + to_date="now", + query_sup="", + limit=1000, + ) + + query = captured["query"] + assert 'reportedemailsubject: "Payment Request \\"0000025803\\" has been \\"Approved\\"."' in query + # No raw (unescaped) double quote should terminate the value prematurely. + assert '"Payment Request "0000025803"' not in query diff --git a/Packs/Base/pack_metadata.json b/Packs/Base/pack_metadata.json index b3263a308e67..ecdc445a6726 100644 --- a/Packs/Base/pack_metadata.json +++ b/Packs/Base/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Base", "description": "The base pack for Cortex XSOAR.", "support": "xsoar", - "currentVersion": "1.42.19", + "currentVersion": "1.42.20", "author": "Cortex XSOAR", "serverMinVersion": "6.0.0", "url": "https://www.paloaltonetworks.com/cortex", From da35e8ab4e4386f1b76a83b816ce229295ab0f26 Mon Sep 17 00:00:00 2001 From: israelpoli <72099621+israelpoli@users.noreply.github.com> Date: Tue, 18 Aug 2026 09:52:42 +0300 Subject: [PATCH 004/419] =?UTF-8?q?Revert=20"CRTX-271523:=20add=20identity?= =?UTF-8?q?.*=20to=20modeling=20rules=20(PR=202=20of=207)=20-=20clean=20pa?= =?UTF-8?q?c=E2=80=A6"=20(#45558)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 04b3507f882888fe457e0e730ce1c6d045e93d3b. --- .../CitrixADC_1_3/CitrixADC_1_3.yml | 1 - .../CitrixADC_2_11/CitrixADC_2_11.xif | 87 -- .../CitrixADC_2_11/CitrixADC_2_11.yml | 8 - .../CitrixADC_2_11/CitrixADC_2_11_schema.json | 8 - Packs/CitrixADC/ReleaseNotes/1_0_11.md | 7 - Packs/CitrixADC/pack_metadata.json | 2 +- .../CommvaultBackupSolutions.yml | 1 - .../CommvaultBackupSolutions_2_11.xif | 20 - .../CommvaultBackupSolutions_2_11.yml | 8 - .../CommvaultBackupSolutions_2_11_schema.json | 84 -- .../ReleaseNotes/1_0_6.md | 7 - .../pack_metadata.json | 2 +- .../ModelingRules/GuardiCore/GuardiCore.yml | 1 - .../GuardiCore_2_11/GuardiCore_2_11.xif | 813 ------------------ .../GuardiCore_2_11/GuardiCore_2_11.yml | 8 - .../GuardiCore_2_11_schema.json | 132 --- Packs/GuardiCore/ReleaseNotes/2_0_25.md | 7 - Packs/GuardiCore/pack_metadata.json | 2 +- .../ModelingRules/Silverfort/Silverfort.yml | 1 - .../Silverfort_2_11/Silverfort_2_11.xif | 72 -- .../Silverfort_2_11/Silverfort_2_11.yml | 8 - .../Silverfort_2_11_schema.json | 88 -- Packs/Silverfort/ReleaseNotes/2_0_40.md | 7 - Packs/Silverfort/pack_metadata.json | 2 +- 24 files changed, 4 insertions(+), 1372 deletions(-) delete mode 100644 Packs/CitrixADC/ModelingRules/CitrixADC_2_11/CitrixADC_2_11.xif delete mode 100644 Packs/CitrixADC/ModelingRules/CitrixADC_2_11/CitrixADC_2_11.yml delete mode 100644 Packs/CitrixADC/ModelingRules/CitrixADC_2_11/CitrixADC_2_11_schema.json delete mode 100644 Packs/CitrixADC/ReleaseNotes/1_0_11.md delete mode 100644 Packs/CommvaultBackupSolutions/ModelingRules/CommvaultBackupSolutions_2_11/CommvaultBackupSolutions_2_11.xif delete mode 100644 Packs/CommvaultBackupSolutions/ModelingRules/CommvaultBackupSolutions_2_11/CommvaultBackupSolutions_2_11.yml delete mode 100644 Packs/CommvaultBackupSolutions/ModelingRules/CommvaultBackupSolutions_2_11/CommvaultBackupSolutions_2_11_schema.json delete mode 100644 Packs/CommvaultBackupSolutions/ReleaseNotes/1_0_6.md delete mode 100644 Packs/GuardiCore/ModelingRules/GuardiCore_2_11/GuardiCore_2_11.xif delete mode 100644 Packs/GuardiCore/ModelingRules/GuardiCore_2_11/GuardiCore_2_11.yml delete mode 100644 Packs/GuardiCore/ModelingRules/GuardiCore_2_11/GuardiCore_2_11_schema.json delete mode 100644 Packs/GuardiCore/ReleaseNotes/2_0_25.md delete mode 100644 Packs/Silverfort/ModelingRules/Silverfort_2_11/Silverfort_2_11.xif delete mode 100644 Packs/Silverfort/ModelingRules/Silverfort_2_11/Silverfort_2_11.yml delete mode 100644 Packs/Silverfort/ModelingRules/Silverfort_2_11/Silverfort_2_11_schema.json delete mode 100644 Packs/Silverfort/ReleaseNotes/2_0_40.md diff --git a/Packs/CitrixADC/ModelingRules/CitrixADC_1_3/CitrixADC_1_3.yml b/Packs/CitrixADC/ModelingRules/CitrixADC_1_3/CitrixADC_1_3.yml index e8b48fadc2aa..155eda09b341 100644 --- a/Packs/CitrixADC/ModelingRules/CitrixADC_1_3/CitrixADC_1_3.yml +++ b/Packs/CitrixADC/ModelingRules/CitrixADC_1_3/CitrixADC_1_3.yml @@ -1,5 +1,4 @@ fromversion: 8.4.0 -toversion: 8.14.0 id: Citrix_ADC_ModelingRule name: Citrix ADC Modeling Rule rules: '' diff --git a/Packs/CitrixADC/ModelingRules/CitrixADC_2_11/CitrixADC_2_11.xif b/Packs/CitrixADC/ModelingRules/CitrixADC_2_11/CitrixADC_2_11.xif deleted file mode 100644 index 2f3a4d7070e2..000000000000 --- a/Packs/CitrixADC/ModelingRules/CitrixADC_2_11/CitrixADC_2_11.xif +++ /dev/null @@ -1,87 +0,0 @@ -[MODEL: dataset = "citrix_adc_raw"] -alter - http_method = arrayindex(regextract(_raw_log,"\s\:\s(\w+)\s\/"),0), - feature = arrayindex(regextract(_raw_log,"\:\s\w+\s(\w+)\s"),0), - message_type = arrayindex(regextract(_raw_log,"\:\s\w+\s\w+\s(\w+)\s"),0), - Status = lowercase(arrayindex(regextract(_raw_log,"Status\s\"(\w+)\""),0)), - message_type_lower = lowercase(arrayindex(regextract(_raw_log,"\:\s\w+\s\w+\s(\w+)\s"),0)) - -| alter - xdm.observer.name = arrayindex(regextract(_raw_log,"(\S+)\s\S+-\S+-\S+\s:"),0), - xdm.event.type = concat(feature, " - ", message_type), - xdm.event.id = arrayindex(regextract(_raw_log,"\:\s\w+\s\w+\s\w+\s(\d+)\s"),0), - xdm.event.description = coalesce(arrayindex(regextract(_raw_log,"\d+\s\d+\s\:\s+\"([^\"]+)\"*"),0), - arrayindex(regextract(_raw_log,"<\d+\>\s\d{2}\/\d{2}\/\d{4}\:\d{2}\:\d{2}\:\d{2}.\w{3}\s.+?\:.+?\:\s+(.+)"),0) - ), - xdm.source.ipv4 = coalesce(arrayindex(regextract(_raw_log,"Source\s(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"),0), - arrayindex(regextract(_raw_log,"Client_ip\s(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s"),0), - arrayindex(regextract(_raw_log,"Context\s[\w\d]+\@(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s"),0), - arrayindex(regextract(_raw_log,"client=(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\:"),0), - arrayindex(regextract(_raw_log,"ClientIP\s(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"),0), - arrayindex(regextract(_raw_log,"Remote.ip\s[\=\s]*(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"),0) - ), - xdm.source.ipv6 = coalesce(arrayindex(regextract(_raw_log,"Source\s([a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5})"),0), - arrayindex(regextract(_raw_log,"Client_ip\s([a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5})\s"),0), - arrayindex(regextract(_raw_log,"Context\s[\w\d]+\@([a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5})\s"),0), - arrayindex(regextract(_raw_log,"client=([a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5})\:"),0), - arrayindex(regextract(_raw_log,"ClientIP\s([a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5})"),0), - arrayindex(regextract(_raw_log,"Remote.ip\s[\=\s]*([a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5})"),0) - ), - xdm.source.port = to_integer(coalesce(arrayindex(regextract(_raw_log,"Source\s\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:(\d+)\s"),0), - arrayindex(regextract(_raw_log,"client=\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:(\d+)"),0), - arrayindex(regextract(_raw_log,"ClientPort\s(\d+)"),0), - arrayindex(regextract(_raw_log,"Remote.ip\s[\=\s]*\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:(\d+).+\sto"),0) - )), - xdm.target.port = to_integer(coalesce(arrayindex(regextract(_raw_log,"Destination\s\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:(\d+)\s"),0), - arrayindex(regextract(_raw_log,"VserverServicePort\s(\d+)\s"),0), - arrayindex(regextract(_raw_log,"Sending\srequest\sto.+?\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:(\d+)"),0), - arrayindex(regextract(_raw_log,"Vserver\s\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:(\d+)"),0), - arrayindex(regextract(_raw_log,"pcb_fport\s\=\s(\d+)"),0), - arrayindex(regextract(_raw_log,"sta-server\=\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:(\d+)"),0), - arrayindex(regextract(_raw_log,"vda\=\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:(\d+)"),0), - arrayindex(regextract(_raw_log,"received\sin\sSTA\sresponse\:\s\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:(\d+)"),0) - )), - xdm.target.ipv4 = coalesce(arrayindex(regextract(_raw_log,"Destination\s(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\:"),0), - arrayindex(regextract(_raw_log,"Vserver[ServiceIP]*\s(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"),0), - arrayindex(regextract(_raw_log,"Sending\srequest\sto.+?(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"),0), - arrayindex(regextract(_raw_log,"ADldap\-(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"),0), - arrayindex(regextract(_raw_log,"sta-server\=(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"),0), - arrayindex(regextract(_raw_log,"client\spcb\_fip\s\=\s(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"),0), - arrayindex(regextract(_raw_log,"vda\=(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"),0), - arrayindex(regextract(_raw_log,"received\sin\sSTA\sresponse\:\s(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"),0) - ), - xdm.target.ipv6 = coalesce(arrayindex(regextract(_raw_log,"Destination\s([a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5})\:"),0), - arrayindex(regextract(_raw_log,"Vserver[ServiceIP]*\s([a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5})"),0), - arrayindex(regextract(_raw_log,"Sending\srequest\sto.+?([a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5})\s"),0), - arrayindex(regextract(_raw_log,"ADldap\-([a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5})"),0), - arrayindex(regextract(_raw_log,"sta-server\=([a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5})"),0), - arrayindex(regextract(_raw_log,"vda\=([a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5})"),0), - arrayindex(regextract(_raw_log,"received\sin\sSTA\sresponse\:\s([a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5})"),0) - ), - xdm.source.sent_bytes = to_integer(arrayindex(regextract(_raw_log,"Total_bytes_send\s(\d+)\s"),0)), - xdm.target.sent_bytes = to_integer(arrayindex(regextract(_raw_log,"Total_bytes_recv\s(\d+)\s"),0)), - xdm.source.application.name = arrayindex(regextract(_raw_log,"applicationName\s(\w+)\s"),0), - xdm.session_context_id = arrayindex(regextract(_raw_log,"connectionId\s(\w+)\s"),0), - xdm.source.user.username = coalesce(arrayindex(regextract(_raw_log,"username:domainname\s(\w+)\:"),0), - xdm.source.identity.username = coalesce(arrayindex(regextract(_raw_log,"username:domainname\s(\w+)\:"),0), - arrayindex(regextract(_raw_log,"User\s([\w\@\.\d]+)\s\:"),0), - arrayindex(regextract(_raw_log,"Context\s([\w\d]+)\@"),0), - arrayindex(regextract(_raw_log,"user:\s\<([\w\d\.\_\-]+)\@"),0), - arrayindex(regextract(_raw_log,"\sUser\s(\S+)"),0) - ), - xdm.source.user.domain = arrayindex(regextract(_raw_log,"username:domainname\s\w+\:(\w+)\s"),0), - xdm.source.identity.domain = arrayindex(regextract(_raw_log,"username:domainname\s\w+\:(\w+)\s"),0), - xdm.network.http.method = if(http_method="ACL", XDM_CONST.HTTP_METHOD_ACL,http_method="BASELINE_CONTROL", XDM_CONST.HTTP_METHOD_BASELINE_CONTROL,http_method="BIND", XDM_CONST.HTTP_METHOD_BIND,http_method="CHECKIN", XDM_CONST.HTTP_METHOD_CHECKIN,http_method="CHECKOUT", XDM_CONST.HTTP_METHOD_CHECKOUT,http_method="CONNECT", XDM_CONST.HTTP_METHOD_CONNECT,http_method="COPY", XDM_CONST.HTTP_METHOD_COPY,http_method="DELETE", XDM_CONST.HTTP_METHOD_DELETE,http_method="GET", XDM_CONST.HTTP_METHOD_GET,http_method="HEAD", XDM_CONST.HTTP_METHOD_HEAD,http_method="LABEL", XDM_CONST.HTTP_METHOD_LABEL,http_method="LINK", XDM_CONST.HTTP_METHOD_LINK,http_method="LOCK", XDM_CONST.HTTP_METHOD_LOCK,http_method="MERGE", XDM_CONST.HTTP_METHOD_MERGE,http_method="MKACTIVITY", XDM_CONST.HTTP_METHOD_MKACTIVITY,http_method="MKCALENDAR", XDM_CONST.HTTP_METHOD_MKCALENDAR,http_method="MKCOL", XDM_CONST.HTTP_METHOD_MKCOL,http_method="MKREDIRECTREF", XDM_CONST.HTTP_METHOD_MKREDIRECTREF,http_method="MKWORKSPACE", XDM_CONST.HTTP_METHOD_MKWORKSPACE,http_method="MOVE", XDM_CONST.HTTP_METHOD_MOVE,http_method="OPTIONS", XDM_CONST.HTTP_METHOD_OPTIONS,http_method="ORDERPATCH", XDM_CONST.HTTP_METHOD_ORDERPATCH,http_method="PATCH", XDM_CONST.HTTP_METHOD_PATCH,http_method="POST", XDM_CONST.HTTP_METHOD_POST,http_method="PRI", XDM_CONST.HTTP_METHOD_PRI,http_method="PROPFIND", XDM_CONST.HTTP_METHOD_PROPFIND,http_method="PROPPATCH", XDM_CONST.HTTP_METHOD_PROPPATCH,http_method="PUT", XDM_CONST.HTTP_METHOD_PUT,http_method="REBIND", XDM_CONST.HTTP_METHOD_REBIND,http_method="REPORT", XDM_CONST.HTTP_METHOD_REPORT,http_method="SEARCH", XDM_CONST.HTTP_METHOD_SEARCH,http_method="TRACE", XDM_CONST.HTTP_METHOD_TRACE,http_method="UNBIND", XDM_CONST.HTTP_METHOD_UNBIND,http_method="UNCHECKOUT", XDM_CONST.HTTP_METHOD_UNCHECKOUT,http_method="UNLINK", XDM_CONST.HTTP_METHOD_UNLINK,http_method="UNLOCK", XDM_CONST.HTTP_METHOD_UNLOCK,http_method="UPDATE", XDM_CONST.HTTP_METHOD_UPDATE,http_method="UPDATEREDIRECTREF", XDM_CONST.HTTP_METHOD_UPDATEREDIRECTREF,http_method="VERSION_CONTROL", XDM_CONST.HTTP_METHOD_VERSION_CONTROL, http_method), - xdm.network.http.url = arrayindex(regextract(_raw_log,"GET\s([\w\/\.]+)\s"),0), - xdm.intermediate.host.hostname = arrayindex(regextract(_raw_log,"\:\d{2}\s\w+\s([\w\-\_\.\d\:]+)\s"),0), - xdm.network.session_id = arrayindex(regextract(_raw_log,"SessionId:\s(\d+)\s"),0), - xdm.event.outcome = if(Status = "SUCCESS", XDM_CONST.OUTCOME_SUCCESS, Status = "FAILURE", XDM_CONST.OUTCOME_FAILED, message_type_lower contains "success", XDM_CONST.OUTCOME_SUCCESS, message_type_lower contains "failure", XDM_CONST.OUTCOME_FAILED, Status), - xdm.source.user_agent = arrayindex(regextract(_raw_log,"Browser_type\s\"([^\"]+)\""),0), - xdm.intermediate.ipv4 = arrayindex(regextract(_raw_log,"Vserver\s(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\:"),0), - xdm.intermediate.port = to_integer(arrayindex(regextract(_raw_log,"Vserver\s\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:(\d+)\s"),0)), - xdm.network.tls.client_certificate.issuer = arrayindex(regextract(_raw_log, "IssuerName\s\"?\s?([^\"]+)\"?$"), 0), - xdm.network.tls.client_certificate.subject = arrayindex(regextract(_raw_log, "SubjectName\s\"?\s?([^\"]+)\"?$"), 0), - xdm.network.tls.client_certificate.version = coalesce(arrayindex(regextract(_raw_log, "ClientVersion\s([^\s]+)"), 0), - arrayindex(regextract(_raw_log, "ProtocolVersion\s([^\s]+)"), 0)), - xdm.network.tls.cipher = arrayindex(regextract(_raw_log, "CipherSuite\s\"([^\"]+)\""), 0), - xdm.event.outcome_reason = arrayindex(regextract(_raw_log, "Reason\s\"([^\"]+)\""), 0); \ No newline at end of file diff --git a/Packs/CitrixADC/ModelingRules/CitrixADC_2_11/CitrixADC_2_11.yml b/Packs/CitrixADC/ModelingRules/CitrixADC_2_11/CitrixADC_2_11.yml deleted file mode 100644 index fd54b2cba498..000000000000 --- a/Packs/CitrixADC/ModelingRules/CitrixADC_2_11/CitrixADC_2_11.yml +++ /dev/null @@ -1,8 +0,0 @@ -fromversion: 8.15.0 -id: Citrix_ADC_ModelingRule -name: Citrix ADC Modeling Rule -rules: '' -schema: '' -tags: Citrix ADC -supportedModules: -- xsiam diff --git a/Packs/CitrixADC/ModelingRules/CitrixADC_2_11/CitrixADC_2_11_schema.json b/Packs/CitrixADC/ModelingRules/CitrixADC_2_11/CitrixADC_2_11_schema.json deleted file mode 100644 index 0fdb3eea5275..000000000000 --- a/Packs/CitrixADC/ModelingRules/CitrixADC_2_11/CitrixADC_2_11_schema.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "citrix_adc_raw": { - "_raw_log": { - "type": "string", - "is_array": false - } - } -} \ No newline at end of file diff --git a/Packs/CitrixADC/ReleaseNotes/1_0_11.md b/Packs/CitrixADC/ReleaseNotes/1_0_11.md deleted file mode 100644 index 6af7fab63975..000000000000 --- a/Packs/CitrixADC/ReleaseNotes/1_0_11.md +++ /dev/null @@ -1,7 +0,0 @@ - -#### Modeling Rules - -##### New: Citrix ADC Modeling Rule - -- New: Added a new modeling rule version that maps the `xdm.*.identity.*` fields alongside the existing `xdm.*.user.*` fields. -<~XSIAM> (Available from Cortex XSIAM 2.11). diff --git a/Packs/CitrixADC/pack_metadata.json b/Packs/CitrixADC/pack_metadata.json index 019cf3f63555..9ebd3468f200 100644 --- a/Packs/CitrixADC/pack_metadata.json +++ b/Packs/CitrixADC/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Citrix ADC", "description": "Citrix ADC is an application delivery controller (ADC) is a purpose-built networking appliance used to improve the performance, security, and resiliency of applications delivered over the web.", "support": "xsoar", - "currentVersion": "1.0.11", + "currentVersion": "1.0.10", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/CommvaultBackupSolutions/ModelingRules/CommvaultBackupSolutions/CommvaultBackupSolutions.yml b/Packs/CommvaultBackupSolutions/ModelingRules/CommvaultBackupSolutions/CommvaultBackupSolutions.yml index f2720e1e798b..7875b2e7edf6 100644 --- a/Packs/CommvaultBackupSolutions/ModelingRules/CommvaultBackupSolutions/CommvaultBackupSolutions.yml +++ b/Packs/CommvaultBackupSolutions/ModelingRules/CommvaultBackupSolutions/CommvaultBackupSolutions.yml @@ -1,5 +1,4 @@ fromversion: 8.2.0 -toversion: 8.14.0 id: Commvault_Backup_Solutions_ModelingRule name: Commvault Backup Solutions Modeling Rule rules: '' diff --git a/Packs/CommvaultBackupSolutions/ModelingRules/CommvaultBackupSolutions_2_11/CommvaultBackupSolutions_2_11.xif b/Packs/CommvaultBackupSolutions/ModelingRules/CommvaultBackupSolutions_2_11/CommvaultBackupSolutions_2_11.xif deleted file mode 100644 index b286fd417225..000000000000 --- a/Packs/CommvaultBackupSolutions/ModelingRules/CommvaultBackupSolutions_2_11/CommvaultBackupSolutions_2_11.xif +++ /dev/null @@ -1,20 +0,0 @@ -[MODEL: dataset = commvault_backupsolution_raw] -alter - xdm.alert.name = coalesce(alert, alert_name), - xdm.alert.original_alert_id = to_string(alert_id), - xdm.network.rule = alert_rule_name, - xdm.alert.description = alertdescription, - xdm.alert.severity = severity, - xdm.observer.name = coalesce(commcell, commcellname), - xdm.target.host.hostname = coalesce(computer, client), - xdm.event.description = coalesce(description, details), - xdm.event.type = if( - opid != null and to_string(opid) !~= "^\s*$", "Audit", - alert_id != null and to_string(alert_id) !~= "^\s*$", "Alert", - event_id != null and to_string(event_id) !~= "^\s*$", coalesce(detected_criteria, type, "Event") - ), - xdm.event.original_event_type = to_string(event_code), - xdm.event.id = coalesce(to_string(event_id), to_string(opid)), - xdm.event.operation_sub_type = operation, - xdm.source.application.name = program, - xdm.source.user.username = user, xdm.source.identity.username = user; \ No newline at end of file diff --git a/Packs/CommvaultBackupSolutions/ModelingRules/CommvaultBackupSolutions_2_11/CommvaultBackupSolutions_2_11.yml b/Packs/CommvaultBackupSolutions/ModelingRules/CommvaultBackupSolutions_2_11/CommvaultBackupSolutions_2_11.yml deleted file mode 100644 index 28ae13fb93aa..000000000000 --- a/Packs/CommvaultBackupSolutions/ModelingRules/CommvaultBackupSolutions_2_11/CommvaultBackupSolutions_2_11.yml +++ /dev/null @@ -1,8 +0,0 @@ -fromversion: 8.15.0 -id: Commvault_Backup_Solutions_ModelingRule -name: Commvault Backup Solutions Modeling Rule -rules: '' -schema: '' -tags: -supportedModules: -- xsiam diff --git a/Packs/CommvaultBackupSolutions/ModelingRules/CommvaultBackupSolutions_2_11/CommvaultBackupSolutions_2_11_schema.json b/Packs/CommvaultBackupSolutions/ModelingRules/CommvaultBackupSolutions_2_11/CommvaultBackupSolutions_2_11_schema.json deleted file mode 100644 index 24a5abce510e..000000000000 --- a/Packs/CommvaultBackupSolutions/ModelingRules/CommvaultBackupSolutions_2_11/CommvaultBackupSolutions_2_11_schema.json +++ /dev/null @@ -1,84 +0,0 @@ -{ - "commvault_backupsolution_raw": { - "alert": { - "type": "string", - "is_array": false - }, - "alert_name": { - "type": "string", - "is_array": false - }, - "alert_rule_name": { - "type": "string", - "is_array": false - }, - "alertdescription": { - "type": "string", - "is_array": false - }, - "severity": { - "type": "string", - "is_array": false - }, - "commcell": { - "type": "string", - "is_array": false - }, - "commcellname": { - "type": "string", - "is_array": false - }, - "computer": { - "type": "string", - "is_array": false - }, - "client": { - "type": "string", - "is_array": false - }, - "description": { - "type": "string", - "is_array": false - }, - "details": { - "type": "string", - "is_array": false - }, - "detected_criteria": { - "type": "string", - "is_array": false - }, - "type": { - "type": "string", - "is_array": false - }, - "event_code": { - "type": "string", - "is_array": false - }, - "operation": { - "type": "string", - "is_array": false - }, - "program": { - "type": "string", - "is_array": false - }, - "user": { - "type": "string", - "is_array": false - }, - "event_id": { - "type": "int", - "is_array": false - }, - "opid": { - "type": "int", - "is_array": false - }, - "alert_id": { - "type": "int", - "is_array": false - } - } -} \ No newline at end of file diff --git a/Packs/CommvaultBackupSolutions/ReleaseNotes/1_0_6.md b/Packs/CommvaultBackupSolutions/ReleaseNotes/1_0_6.md deleted file mode 100644 index 6604e3b2e24f..000000000000 --- a/Packs/CommvaultBackupSolutions/ReleaseNotes/1_0_6.md +++ /dev/null @@ -1,7 +0,0 @@ - -#### Modeling Rules - -##### New: Commvault Backup Solutions Modeling Rule - -- New: Added a new modeling rule version that maps the `xdm.*.identity.*` fields alongside the existing `xdm.*.user.*` fields. -<~XSIAM> (Available from Cortex XSIAM 2.11). diff --git a/Packs/CommvaultBackupSolutions/pack_metadata.json b/Packs/CommvaultBackupSolutions/pack_metadata.json index 8405881a04d0..7a8fce4503f3 100644 --- a/Packs/CommvaultBackupSolutions/pack_metadata.json +++ b/Packs/CommvaultBackupSolutions/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Commvault Backup Solutions", "description": "This pack contains Modeling and Parsing Rules for normalizing Commvault Backup API logs", "support": "xsoar", - "currentVersion": "1.0.6", + "currentVersion": "1.0.5", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/GuardiCore/ModelingRules/GuardiCore/GuardiCore.yml b/Packs/GuardiCore/ModelingRules/GuardiCore/GuardiCore.yml index 8a8707d1cfbe..348ec34b2bb2 100644 --- a/Packs/GuardiCore/ModelingRules/GuardiCore/GuardiCore.yml +++ b/Packs/GuardiCore/ModelingRules/GuardiCore/GuardiCore.yml @@ -1,5 +1,4 @@ fromversion: 8.12.0 -toversion: 8.14.0 id: Akamai_GuardiCore_ModelingRule name: Akamai GuardiCore Modeling Rule rules: '' diff --git a/Packs/GuardiCore/ModelingRules/GuardiCore_2_11/GuardiCore_2_11.xif b/Packs/GuardiCore/ModelingRules/GuardiCore_2_11/GuardiCore_2_11.xif deleted file mode 100644 index d55564ccd906..000000000000 --- a/Packs/GuardiCore/ModelingRules/GuardiCore_2_11/GuardiCore_2_11.xif +++ /dev/null @@ -1,813 +0,0 @@ -[MODEL: dataset="akamai_guardicore_raw"] -/* ========================================== - Audit logs mapping - ========================================== */ -filter cefName ~= "Audit" -| alter //Extraction fields - src_username_from_upn = if(suser ~= "@", arrayindex(regextract(suser, "(\S+)\@"),0)), //Sometimes the suser field comes as UPN. - msg_host = arrayindex(regextract(msg, "host\:\s(\S+)\,"),0), - msg_port = arrayindex(regextract(msg, "port\:\s(\d+)"),0), - msg_protocol = arrayindex(regextract(msg, "protocol\:\s(\w+)"),0), - msg_resource_name = arrayindex(regextract(msg, "resource\:\s(\S+)"),0), - msg_status_code = arrayindex(regextract(msg, "status\scode\:\s(\d+)"),0), - msg_failed_login_reason = arrayindex(regextract(msg,"reason\:\s(.+)"),0) - -| alter //XDM Mapping - xdm.event.type = cefName, - xdm.observer.version = cefDeviceVersion, - xdm.event.operation = if( - act CONTAINS "authentication", XDM_CONST.OPERATION_TYPE_AUTHENTICATION, - act IN("Get asset*", "Access to*"), XDM_CONST.OPERATION_TYPE_READ, - act CONTAINS "Change password", XDM_CONST.OPERATION_TYPE_UPDATE, - act IN("Adding*", "Create*"), XDM_CONST.OPERATION_TYPE_CREATE, - act), - xdm.event.operation_sub_type = act, - xdm.source.user.upn = if(src_username_from_upn != null, suser), - xdm.source.identity.upn = if(src_username_from_upn != null, suser), - xdm.source.user.username = coalesce(src_username_from_upn, suser), - xdm.source.identity.username = coalesce(src_username_from_upn, suser), - xdm.source.ipv4 = if(is_ipv4(src) = TRUE, src), - xdm.source.ipv6 = if(is_ipv6(src) = TRUE, src), - xdm.event.description = msg, - xdm.target.host.hostname = msg_host, - xdm.target.port = to_integer(msg_port), - xdm.network.ip_protocol = if( - msg_protocol = null, null, - msg_protocol = "HOPOPT",XDM_CONST.IP_PROTOCOL_HOPOPT, - msg_protocol = "ICMP",XDM_CONST.IP_PROTOCOL_ICMP, - msg_protocol = "IGMP",XDM_CONST.IP_PROTOCOL_IGMP, - msg_protocol = "GGP",XDM_CONST.IP_PROTOCOL_GGP, - msg_protocol = "IP",XDM_CONST.IP_PROTOCOL_IP, - msg_protocol = "ST",XDM_CONST.IP_PROTOCOL_ST, - msg_protocol = "TCP",XDM_CONST.IP_PROTOCOL_TCP, - msg_protocol = "CBT",XDM_CONST.IP_PROTOCOL_CBT, - msg_protocol = "EGP",XDM_CONST.IP_PROTOCOL_EGP, - msg_protocol = "IGP",XDM_CONST.IP_PROTOCOL_IGP, - msg_protocol = "BBN_RCC_MON",XDM_CONST.IP_PROTOCOL_BBN_RCC_MON, - msg_protocol = "NVP_II",XDM_CONST.IP_PROTOCOL_NVP_II, - msg_protocol = "PUP",XDM_CONST.IP_PROTOCOL_PUP, - msg_protocol = "ARGUS",XDM_CONST.IP_PROTOCOL_ARGUS, - msg_protocol = "EMCON",XDM_CONST.IP_PROTOCOL_EMCON, - msg_protocol = "XNET",XDM_CONST.IP_PROTOCOL_XNET, - msg_protocol = "CHAOS",XDM_CONST.IP_PROTOCOL_CHAOS, - msg_protocol = "UDP",XDM_CONST.IP_PROTOCOL_UDP, - msg_protocol = "MUX",XDM_CONST.IP_PROTOCOL_MUX, - msg_protocol = "DCN_MEAS",XDM_CONST.IP_PROTOCOL_DCN_MEAS, - msg_protocol = "HMP",XDM_CONST.IP_PROTOCOL_HMP, - msg_protocol = "PRM",XDM_CONST.IP_PROTOCOL_PRM, - msg_protocol = "XNS_IDP",XDM_CONST.IP_PROTOCOL_XNS_IDP, - msg_protocol = "TRUNK_1",XDM_CONST.IP_PROTOCOL_TRUNK_1, - msg_protocol = "TRUNK_2",XDM_CONST.IP_PROTOCOL_TRUNK_2, - msg_protocol = "LEAF_1",XDM_CONST.IP_PROTOCOL_LEAF_1, - msg_protocol = "LEAF_2",XDM_CONST.IP_PROTOCOL_LEAF_2, - msg_protocol = "RDP",XDM_CONST.IP_PROTOCOL_RDP, - msg_protocol = "IRTP",XDM_CONST.IP_PROTOCOL_IRTP, - msg_protocol = "ISO_TP4",XDM_CONST.IP_PROTOCOL_ISO_TP4, - msg_protocol = "NETBLT",XDM_CONST.IP_PROTOCOL_NETBLT, - msg_protocol = "MFE_NSP",XDM_CONST.IP_PROTOCOL_MFE_NSP, - msg_protocol = "MERIT_INP",XDM_CONST.IP_PROTOCOL_MERIT_INP, - msg_protocol = "DCCP",XDM_CONST.IP_PROTOCOL_DCCP, - msg_protocol = "3PC",XDM_CONST.IP_PROTOCOL_3PC, - msg_protocol = "IDPR",XDM_CONST.IP_PROTOCOL_IDPR, - msg_protocol = "XTP",XDM_CONST.IP_PROTOCOL_XTP, - msg_protocol = "DDP",XDM_CONST.IP_PROTOCOL_DDP, - msg_protocol = "IDPR_CMTP",XDM_CONST.IP_PROTOCOL_IDPR_CMTP, - msg_protocol = "TP",XDM_CONST.IP_PROTOCOL_TP, - msg_protocol = "IL",XDM_CONST.IP_PROTOCOL_IL, - msg_protocol = "IPV6",XDM_CONST.IP_PROTOCOL_IPV6, - msg_protocol = "SDRP",XDM_CONST.IP_PROTOCOL_SDRP, - msg_protocol = "IPV6_ROUTE",XDM_CONST.IP_PROTOCOL_IPV6_ROUTE, - msg_protocol = "IPV6_FRAG",XDM_CONST.IP_PROTOCOL_IPV6_FRAG, - msg_protocol = "IDRP",XDM_CONST.IP_PROTOCOL_IDRP, - msg_protocol = "RSVP",XDM_CONST.IP_PROTOCOL_RSVP, - msg_protocol = "GRE",XDM_CONST.IP_PROTOCOL_GRE, - msg_protocol = "DSR",XDM_CONST.IP_PROTOCOL_DSR, - msg_protocol = "BNA",XDM_CONST.IP_PROTOCOL_BNA, - msg_protocol = "ESP",XDM_CONST.IP_PROTOCOL_ESP, - msg_protocol = "AH",XDM_CONST.IP_PROTOCOL_AH, - msg_protocol = "I_NLSP",XDM_CONST.IP_PROTOCOL_I_NLSP, - msg_protocol = "SWIPE",XDM_CONST.IP_PROTOCOL_SWIPE, - msg_protocol = "NARP",XDM_CONST.IP_PROTOCOL_NARP, - msg_protocol = "MOBILE",XDM_CONST.IP_PROTOCOL_MOBILE, - msg_protocol = "TLSP",XDM_CONST.IP_PROTOCOL_TLSP, - msg_protocol = "SKIP",XDM_CONST.IP_PROTOCOL_SKIP, - msg_protocol = "IPV6_ICMP",XDM_CONST.IP_PROTOCOL_IPV6_ICMP, - msg_protocol = "IPV6_NONXT",XDM_CONST.IP_PROTOCOL_IPV6_NONXT, - msg_protocol = "IPV6_OPTS",XDM_CONST.IP_PROTOCOL_IPV6_OPTS, - msg_protocol = "CFTP",XDM_CONST.IP_PROTOCOL_CFTP, - msg_protocol = "SAT_EXPAK",XDM_CONST.IP_PROTOCOL_SAT_EXPAK, - msg_protocol = "KRYPTOLAN",XDM_CONST.IP_PROTOCOL_KRYPTOLAN, - msg_protocol = "RVD",XDM_CONST.IP_PROTOCOL_RVD, - msg_protocol = "IPPC",XDM_CONST.IP_PROTOCOL_IPPC, - msg_protocol = "SAT_MON",XDM_CONST.IP_PROTOCOL_SAT_MON, - msg_protocol = "VISA",XDM_CONST.IP_PROTOCOL_VISA, - msg_protocol = "IPCV",XDM_CONST.IP_PROTOCOL_IPCV, - msg_protocol = "CPNX",XDM_CONST.IP_PROTOCOL_CPNX, - msg_protocol = "CPHB",XDM_CONST.IP_PROTOCOL_CPHB, - msg_protocol = "WSN",XDM_CONST.IP_PROTOCOL_WSN, - msg_protocol = "PVP",XDM_CONST.IP_PROTOCOL_PVP, - msg_protocol = "BR_SAT_MON",XDM_CONST.IP_PROTOCOL_BR_SAT_MON, - msg_protocol = "SUN_ND",XDM_CONST.IP_PROTOCOL_SUN_ND, - msg_protocol = "WB_MON",XDM_CONST.IP_PROTOCOL_WB_MON, - msg_protocol = "WB_EXPAK",XDM_CONST.IP_PROTOCOL_WB_EXPAK, - msg_protocol = "ISO_IP",XDM_CONST.IP_PROTOCOL_ISO_IP, - msg_protocol = "VMTP",XDM_CONST.IP_PROTOCOL_VMTP, - msg_protocol = "SECURE_VMTP",XDM_CONST.IP_PROTOCOL_SECURE_VMTP, - msg_protocol = "VINES",XDM_CONST.IP_PROTOCOL_VINES, - msg_protocol = "TTP",XDM_CONST.IP_PROTOCOL_TTP, - msg_protocol = "NSFNET_IGP",XDM_CONST.IP_PROTOCOL_NSFNET_IGP, - msg_protocol = "DGP",XDM_CONST.IP_PROTOCOL_DGP, - msg_protocol = "TCF",XDM_CONST.IP_PROTOCOL_TCF, - msg_protocol = "EIGRP",XDM_CONST.IP_PROTOCOL_EIGRP, - msg_protocol = "OSPFIGP",XDM_CONST.IP_PROTOCOL_OSPFIGP, - msg_protocol = "SPRITE_RPC",XDM_CONST.IP_PROTOCOL_SPRITE_RPC, - msg_protocol = "LARP",XDM_CONST.IP_PROTOCOL_LARP, - msg_protocol = "MTP",XDM_CONST.IP_PROTOCOL_MTP, - msg_protocol = "AX25",XDM_CONST.IP_PROTOCOL_AX25, - msg_protocol = "IPIP",XDM_CONST.IP_PROTOCOL_IPIP, - msg_protocol = "MICP",XDM_CONST.IP_PROTOCOL_MICP, - msg_protocol = "SCC_SP",XDM_CONST.IP_PROTOCOL_SCC_SP, - msg_protocol = "ETHERIP",XDM_CONST.IP_PROTOCOL_ETHERIP, - msg_protocol = "ENCAP",XDM_CONST.IP_PROTOCOL_ENCAP, - msg_protocol = "GMTP",XDM_CONST.IP_PROTOCOL_GMTP, - msg_protocol = "IFMP",XDM_CONST.IP_PROTOCOL_IFMP, - msg_protocol = "PNNI",XDM_CONST.IP_PROTOCOL_PNNI, - msg_protocol = "PIM",XDM_CONST.IP_PROTOCOL_PIM, - msg_protocol = "ARIS",XDM_CONST.IP_PROTOCOL_ARIS, - msg_protocol = "SCPS",XDM_CONST.IP_PROTOCOL_SCPS, - msg_protocol = "QNX",XDM_CONST.IP_PROTOCOL_QNX, - msg_protocol = "AN",XDM_CONST.IP_PROTOCOL_AN, - msg_protocol = "IPCOMP",XDM_CONST.IP_PROTOCOL_IPCOMP, - msg_protocol = "SNP",XDM_CONST.IP_PROTOCOL_SNP, - msg_protocol = "COMPAQ_PEER",XDM_CONST.IP_PROTOCOL_COMPAQ_PEER, - msg_protocol = "IPX_IN_IP",XDM_CONST.IP_PROTOCOL_IPX_IN_IP, - msg_protocol = "VRRP",XDM_CONST.IP_PROTOCOL_VRRP, - msg_protocol = "PGM",XDM_CONST.IP_PROTOCOL_PGM, - msg_protocol = "L2TP",XDM_CONST.IP_PROTOCOL_L2TP, - msg_protocol = "DDX",XDM_CONST.IP_PROTOCOL_DDX, - msg_protocol = "IATP",XDM_CONST.IP_PROTOCOL_IATP, - msg_protocol = "STP",XDM_CONST.IP_PROTOCOL_STP, - msg_protocol = "SRP",XDM_CONST.IP_PROTOCOL_SRP, - msg_protocol = "UTI",XDM_CONST.IP_PROTOCOL_UTI, - msg_protocol = "SMP",XDM_CONST.IP_PROTOCOL_SMP, - msg_protocol = "SM",XDM_CONST.IP_PROTOCOL_SM, - msg_protocol = "PTP",XDM_CONST.IP_PROTOCOL_PTP, - msg_protocol = "ISIS",XDM_CONST.IP_PROTOCOL_ISIS, - msg_protocol = "FIRE",XDM_CONST.IP_PROTOCOL_FIRE, - msg_protocol = "CRTP",XDM_CONST.IP_PROTOCOL_CRTP, - msg_protocol = "CRUDP",XDM_CONST.IP_PROTOCOL_CRUDP, - msg_protocol = "SSCOPMCE",XDM_CONST.IP_PROTOCOL_SSCOPMCE, - msg_protocol = "IPLT",XDM_CONST.IP_PROTOCOL_IPLT, - msg_protocol = "SPS",XDM_CONST.IP_PROTOCOL_SPS, - msg_protocol = "PIPE",XDM_CONST.IP_PROTOCOL_PIPE, - msg_protocol = "SCTP",XDM_CONST.IP_PROTOCOL_SCTP, - msg_protocol = "FC",XDM_CONST.IP_PROTOCOL_FC, - msg_protocol = "RSVP_E2E_IGNORE",XDM_CONST.IP_PROTOCOL_RSVP_E2E_IGNORE, - msg_protocol = "MOBILITY",XDM_CONST.IP_PROTOCOL_MOBILITY, - msg_protocol = "UDPLITE",XDM_CONST.IP_PROTOCOL_UDPLITE, - msg_protocol = "MPLS_IN_IP",XDM_CONST.IP_PROTOCOL_MPLS_IN_IP, - msg_protocol = "MANET",XDM_CONST.IP_PROTOCOL_MANET, - msg_protocol = "HIP",XDM_CONST.IP_PROTOCOL_HIP, - msg_protocol = "SHIM6",XDM_CONST.IP_PROTOCOL_SHIM6, - msg_protocol = "WESP",XDM_CONST.IP_PROTOCOL_WESP, - msg_protocol = "ROHC",XDM_CONST.IP_PROTOCOL_ROHC, - msg_protocol = "RESERVED",XDM_CONST.IP_PROTOCOL_RESERVED, - msg_protocol = "0",XDM_CONST.IP_PROTOCOL_HOPOPT, - msg_protocol = "1",XDM_CONST.IP_PROTOCOL_ICMP, - msg_protocol = "2",XDM_CONST.IP_PROTOCOL_IGMP, - msg_protocol = "3",XDM_CONST.IP_PROTOCOL_GGP, - msg_protocol = "4",XDM_CONST.IP_PROTOCOL_IP, - msg_protocol = "5",XDM_CONST.IP_PROTOCOL_ST, - msg_protocol = "6",XDM_CONST.IP_PROTOCOL_TCP, - msg_protocol = "7",XDM_CONST.IP_PROTOCOL_CBT, - msg_protocol = "8",XDM_CONST.IP_PROTOCOL_EGP, - msg_protocol = "9",XDM_CONST.IP_PROTOCOL_IGP, - msg_protocol = "10",XDM_CONST.IP_PROTOCOL_BBN_RCC_MON, - msg_protocol = "11",XDM_CONST.IP_PROTOCOL_NVP_II, - msg_protocol = "12",XDM_CONST.IP_PROTOCOL_PUP, - msg_protocol = "13",XDM_CONST.IP_PROTOCOL_ARGUS, - msg_protocol = "14",XDM_CONST.IP_PROTOCOL_EMCON, - msg_protocol = "15",XDM_CONST.IP_PROTOCOL_XNET, - msg_protocol = "16",XDM_CONST.IP_PROTOCOL_CHAOS, - msg_protocol = "17",XDM_CONST.IP_PROTOCOL_UDP, - msg_protocol = "18",XDM_CONST.IP_PROTOCOL_MUX, - msg_protocol = "19",XDM_CONST.IP_PROTOCOL_DCN_MEAS, - msg_protocol = "20",XDM_CONST.IP_PROTOCOL_HMP, - msg_protocol = "21",XDM_CONST.IP_PROTOCOL_PRM, - msg_protocol = "22",XDM_CONST.IP_PROTOCOL_XNS_IDP, - msg_protocol = "23",XDM_CONST.IP_PROTOCOL_TRUNK_1, - msg_protocol = "24",XDM_CONST.IP_PROTOCOL_TRUNK_2, - msg_protocol = "25",XDM_CONST.IP_PROTOCOL_LEAF_1, - msg_protocol = "26",XDM_CONST.IP_PROTOCOL_LEAF_2, - msg_protocol = "27",XDM_CONST.IP_PROTOCOL_RDP, - msg_protocol = "28",XDM_CONST.IP_PROTOCOL_IRTP, - msg_protocol = "29",XDM_CONST.IP_PROTOCOL_ISO_TP4, - msg_protocol = "30",XDM_CONST.IP_PROTOCOL_NETBLT, - msg_protocol = "31",XDM_CONST.IP_PROTOCOL_MFE_NSP, - msg_protocol = "32",XDM_CONST.IP_PROTOCOL_MERIT_INP, - msg_protocol = "33",XDM_CONST.IP_PROTOCOL_DCCP, - msg_protocol = "34",XDM_CONST.IP_PROTOCOL_3PC, - msg_protocol = "35",XDM_CONST.IP_PROTOCOL_IDPR, - msg_protocol = "36",XDM_CONST.IP_PROTOCOL_XTP, - msg_protocol = "37",XDM_CONST.IP_PROTOCOL_DDP, - msg_protocol = "38",XDM_CONST.IP_PROTOCOL_IDPR_CMTP, - msg_protocol = "39",XDM_CONST.IP_PROTOCOL_TP, - msg_protocol = "40",XDM_CONST.IP_PROTOCOL_IL, - msg_protocol = "41",XDM_CONST.IP_PROTOCOL_IPV6, - msg_protocol = "42",XDM_CONST.IP_PROTOCOL_SDRP, - msg_protocol = "43",XDM_CONST.IP_PROTOCOL_IPV6_ROUTE, - msg_protocol = "44",XDM_CONST.IP_PROTOCOL_IPV6_FRAG, - msg_protocol = "45",XDM_CONST.IP_PROTOCOL_IDRP, - msg_protocol = "46",XDM_CONST.IP_PROTOCOL_RSVP, - msg_protocol = "47",XDM_CONST.IP_PROTOCOL_GRE, - msg_protocol = "48",XDM_CONST.IP_PROTOCOL_DSR, - msg_protocol = "49",XDM_CONST.IP_PROTOCOL_BNA, - msg_protocol = "50",XDM_CONST.IP_PROTOCOL_ESP, - msg_protocol = "51",XDM_CONST.IP_PROTOCOL_AH, - msg_protocol = "52",XDM_CONST.IP_PROTOCOL_I_NLSP, - msg_protocol = "53",XDM_CONST.IP_PROTOCOL_SWIPE, - msg_protocol = "54",XDM_CONST.IP_PROTOCOL_NARP, - msg_protocol = "55",XDM_CONST.IP_PROTOCOL_MOBILE, - msg_protocol = "56",XDM_CONST.IP_PROTOCOL_TLSP, - msg_protocol = "57",XDM_CONST.IP_PROTOCOL_SKIP, - msg_protocol = "58",XDM_CONST.IP_PROTOCOL_IPV6_ICMP, - msg_protocol = "59",XDM_CONST.IP_PROTOCOL_IPV6_NONXT, - msg_protocol = "60",XDM_CONST.IP_PROTOCOL_IPV6_OPTS, - msg_protocol = "62",XDM_CONST.IP_PROTOCOL_CFTP, - msg_protocol = "64",XDM_CONST.IP_PROTOCOL_SAT_EXPAK, - msg_protocol = "65",XDM_CONST.IP_PROTOCOL_KRYPTOLAN, - msg_protocol = "66",XDM_CONST.IP_PROTOCOL_RVD, - msg_protocol = "67",XDM_CONST.IP_PROTOCOL_IPPC, - msg_protocol = "69",XDM_CONST.IP_PROTOCOL_SAT_MON, - msg_protocol = "70",XDM_CONST.IP_PROTOCOL_VISA, - msg_protocol = "71",XDM_CONST.IP_PROTOCOL_IPCV, - msg_protocol = "72",XDM_CONST.IP_PROTOCOL_CPNX, - msg_protocol = "73",XDM_CONST.IP_PROTOCOL_CPHB, - msg_protocol = "74",XDM_CONST.IP_PROTOCOL_WSN, - msg_protocol = "75",XDM_CONST.IP_PROTOCOL_PVP, - msg_protocol = "76",XDM_CONST.IP_PROTOCOL_BR_SAT_MON, - msg_protocol = "77",XDM_CONST.IP_PROTOCOL_SUN_ND, - msg_protocol = "78",XDM_CONST.IP_PROTOCOL_WB_MON, - msg_protocol = "79",XDM_CONST.IP_PROTOCOL_WB_EXPAK, - msg_protocol = "80",XDM_CONST.IP_PROTOCOL_ISO_IP, - msg_protocol = "81",XDM_CONST.IP_PROTOCOL_VMTP, - msg_protocol = "82",XDM_CONST.IP_PROTOCOL_SECURE_VMTP, - msg_protocol = "83",XDM_CONST.IP_PROTOCOL_VINES, - msg_protocol = "84",XDM_CONST.IP_PROTOCOL_TTP, - msg_protocol = "85",XDM_CONST.IP_PROTOCOL_NSFNET_IGP, - msg_protocol = "86",XDM_CONST.IP_PROTOCOL_DGP, - msg_protocol = "87",XDM_CONST.IP_PROTOCOL_TCF, - msg_protocol = "88",XDM_CONST.IP_PROTOCOL_EIGRP, - msg_protocol = "89",XDM_CONST.IP_PROTOCOL_OSPFIGP, - msg_protocol = "90",XDM_CONST.IP_PROTOCOL_SPRITE_RPC, - msg_protocol = "91",XDM_CONST.IP_PROTOCOL_LARP, - msg_protocol = "92",XDM_CONST.IP_PROTOCOL_MTP, - msg_protocol = "93",XDM_CONST.IP_PROTOCOL_AX25, - msg_protocol = "94",XDM_CONST.IP_PROTOCOL_IPIP, - msg_protocol = "95",XDM_CONST.IP_PROTOCOL_MICP, - msg_protocol = "96",XDM_CONST.IP_PROTOCOL_SCC_SP, - msg_protocol = "97",XDM_CONST.IP_PROTOCOL_ETHERIP, - msg_protocol = "98",XDM_CONST.IP_PROTOCOL_ENCAP, - msg_protocol = "100",XDM_CONST.IP_PROTOCOL_GMTP, - msg_protocol = "101",XDM_CONST.IP_PROTOCOL_IFMP, - msg_protocol = "102",XDM_CONST.IP_PROTOCOL_PNNI, - msg_protocol = "103",XDM_CONST.IP_PROTOCOL_PIM, - msg_protocol = "104",XDM_CONST.IP_PROTOCOL_ARIS, - msg_protocol = "105",XDM_CONST.IP_PROTOCOL_SCPS, - msg_protocol = "106",XDM_CONST.IP_PROTOCOL_QNX, - msg_protocol = "107",XDM_CONST.IP_PROTOCOL_AN, - msg_protocol = "108",XDM_CONST.IP_PROTOCOL_IPCOMP, - msg_protocol = "109",XDM_CONST.IP_PROTOCOL_SNP, - msg_protocol = "110",XDM_CONST.IP_PROTOCOL_COMPAQ_PEER, - msg_protocol = "111",XDM_CONST.IP_PROTOCOL_IPX_IN_IP, - msg_protocol = "112",XDM_CONST.IP_PROTOCOL_VRRP, - msg_protocol = "113",XDM_CONST.IP_PROTOCOL_PGM, - msg_protocol = "115",XDM_CONST.IP_PROTOCOL_L2TP, - msg_protocol = "116",XDM_CONST.IP_PROTOCOL_DDX, - msg_protocol = "117",XDM_CONST.IP_PROTOCOL_IATP, - msg_protocol = "118",XDM_CONST.IP_PROTOCOL_STP, - msg_protocol = "119",XDM_CONST.IP_PROTOCOL_SRP, - msg_protocol = "120",XDM_CONST.IP_PROTOCOL_UTI, - msg_protocol = "121",XDM_CONST.IP_PROTOCOL_SMP, - msg_protocol = "122",XDM_CONST.IP_PROTOCOL_SM, - msg_protocol = "123",XDM_CONST.IP_PROTOCOL_PTP, - msg_protocol = "124",XDM_CONST.IP_PROTOCOL_ISIS, - msg_protocol = "125",XDM_CONST.IP_PROTOCOL_FIRE, - msg_protocol = "126",XDM_CONST.IP_PROTOCOL_CRTP, - msg_protocol = "127",XDM_CONST.IP_PROTOCOL_CRUDP, - msg_protocol = "128",XDM_CONST.IP_PROTOCOL_SSCOPMCE, - msg_protocol = "129",XDM_CONST.IP_PROTOCOL_IPLT, - msg_protocol = "130",XDM_CONST.IP_PROTOCOL_SPS, - msg_protocol = "131",XDM_CONST.IP_PROTOCOL_PIPE, - msg_protocol = "132",XDM_CONST.IP_PROTOCOL_SCTP, - msg_protocol = "133",XDM_CONST.IP_PROTOCOL_FC, - msg_protocol = "134",XDM_CONST.IP_PROTOCOL_RSVP_E2E_IGNORE, - msg_protocol = "135",XDM_CONST.IP_PROTOCOL_MOBILITY, - msg_protocol = "136",XDM_CONST.IP_PROTOCOL_UDPLITE, - msg_protocol = "137",XDM_CONST.IP_PROTOCOL_MPLS_IN_IP, - msg_protocol = "138",XDM_CONST.IP_PROTOCOL_MANET, - msg_protocol = "139",XDM_CONST.IP_PROTOCOL_HIP, - msg_protocol = "140",XDM_CONST.IP_PROTOCOL_SHIM6, - msg_protocol = "141",XDM_CONST.IP_PROTOCOL_WESP, - msg_protocol = "142",XDM_CONST.IP_PROTOCOL_ROHC, - msg_protocol = "255",XDM_CONST.IP_PROTOCOL_RESERVED, - msg_protocol), - xdm.target.resource.name = msg_resource_name, - xdm.network.http.response_code = if( - msg_status_code = null, null, - msg_status_code = "100", XDM_CONST.HTTP_RSP_CODE_CONTINUE, - msg_status_code = "101", XDM_CONST.HTTP_RSP_CODE_SWITCHING_PROTOCOLS, - msg_status_code = "102", XDM_CONST.HTTP_RSP_CODE_PROCESSING, - msg_status_code = "103", XDM_CONST.HTTP_RSP_CODE_EARLY_HINTS, - msg_status_code = "200", XDM_CONST.HTTP_RSP_CODE_OK, - msg_status_code = "201", XDM_CONST.HTTP_RSP_CODE_CREATED, - msg_status_code = "202", XDM_CONST.HTTP_RSP_CODE_ACCEPTED, - msg_status_code = "203", XDM_CONST.HTTP_RSP_CODE_NON__AUTHORITATIVE_INFORMATION, - msg_status_code = "204", XDM_CONST.HTTP_RSP_CODE_NO_CONTENT, - msg_status_code = "205", XDM_CONST.HTTP_RSP_CODE_RESET_CONTENT, - msg_status_code = "206", XDM_CONST.HTTP_RSP_CODE_PARTIAL_CONTENT, - msg_status_code = "207", XDM_CONST.HTTP_RSP_CODE_MULTI__STATUS, - msg_status_code = "208", XDM_CONST.HTTP_RSP_CODE_ALREADY_REPORTED, - msg_status_code = "226", XDM_CONST.HTTP_RSP_CODE_IM_USED, - msg_status_code = "300", XDM_CONST.HTTP_RSP_CODE_MULTIPLE_CHOICES, - msg_status_code = "301", XDM_CONST.HTTP_RSP_CODE_MOVED_PERMANENTLY, - msg_status_code = "302", XDM_CONST.HTTP_RSP_CODE_FOUND, - msg_status_code = "303", XDM_CONST.HTTP_RSP_CODE_SEE_OTHER, - msg_status_code = "304", XDM_CONST.HTTP_RSP_CODE_NOT_MODIFIED, - msg_status_code = "305", XDM_CONST.HTTP_RSP_CODE_USE_PROXY, - msg_status_code = "307", XDM_CONST.HTTP_RSP_CODE_TEMPORARY_REDIRECT, - msg_status_code = "308", XDM_CONST.HTTP_RSP_CODE_PERMANENT_REDIRECT, - msg_status_code = "400", XDM_CONST.HTTP_RSP_CODE_BAD_REQUEST, - msg_status_code = "401", XDM_CONST.HTTP_RSP_CODE_UNAUTHORIZED, - msg_status_code = "402", XDM_CONST.HTTP_RSP_CODE_PAYMENT_REQUIRED, - msg_status_code = "403", XDM_CONST.HTTP_RSP_CODE_FORBIDDEN, - msg_status_code = "404", XDM_CONST.HTTP_RSP_CODE_NOT_FOUND, - msg_status_code = "405", XDM_CONST.HTTP_RSP_CODE_METHOD_NOT_ALLOWED, - msg_status_code = "406", XDM_CONST.HTTP_RSP_CODE_NOT_ACCEPTABLE, - msg_status_code = "407", XDM_CONST.HTTP_RSP_CODE_PROXY_AUTHENTICATION_REQUIRED, - msg_status_code = "408", XDM_CONST.HTTP_RSP_CODE_REQUEST_TIMEOUT, - msg_status_code = "409", XDM_CONST.HTTP_RSP_CODE_CONFLICT, - msg_status_code = "410", XDM_CONST.HTTP_RSP_CODE_GONE, - msg_status_code = "411", XDM_CONST.HTTP_RSP_CODE_LENGTH_REQUIRED, - msg_status_code = "412", XDM_CONST.HTTP_RSP_CODE_PRECONDITION_FAILED, - msg_status_code = "413", XDM_CONST.HTTP_RSP_CODE_CONTENT_TOO_LARGE, - msg_status_code = "414", XDM_CONST.HTTP_RSP_CODE_URI_TOO_LONG, - msg_status_code = "415", XDM_CONST.HTTP_RSP_CODE_UNSUPPORTED_MEDIA_TYPE, - msg_status_code = "416", XDM_CONST.HTTP_RSP_CODE_RANGE_NOT_SATISFIABLE, - msg_status_code = "417", XDM_CONST.HTTP_RSP_CODE_EXPECTATION_FAILED, - msg_status_code = "421", XDM_CONST.HTTP_RSP_CODE_MISDIRECTED_REQUEST, - msg_status_code = "422", XDM_CONST.HTTP_RSP_CODE_UNPROCESSABLE_CONTENT, - msg_status_code = "423", XDM_CONST.HTTP_RSP_CODE_LOCKED, - msg_status_code = "424", XDM_CONST.HTTP_RSP_CODE_FAILED_DEPENDENCY, - msg_status_code = "425", XDM_CONST.HTTP_RSP_CODE_TOO_EARLY, - msg_status_code = "426", XDM_CONST.HTTP_RSP_CODE_UPGRADE_REQUIRED, - msg_status_code = "428", XDM_CONST.HTTP_RSP_CODE_PRECONDITION_REQUIRED, - msg_status_code = "429", XDM_CONST.HTTP_RSP_CODE_TOO_MANY_REQUESTS, - msg_status_code = "431", XDM_CONST.HTTP_RSP_CODE_REQUEST_HEADER_FIELDS_TOO_LARGE, - msg_status_code = "451", XDM_CONST.HTTP_RSP_CODE_UNAVAILABLE_FOR_LEGAL_REASONS, - msg_status_code = "500", XDM_CONST.HTTP_RSP_CODE_INTERNAL_SERVER_ERROR, - msg_status_code = "501", XDM_CONST.HTTP_RSP_CODE_NOT_IMPLEMENTED, - msg_status_code = "502", XDM_CONST.HTTP_RSP_CODE_BAD_GATEWAY, - msg_status_code = "503", XDM_CONST.HTTP_RSP_CODE_SERVICE_UNAVAILABLE, - msg_status_code = "504", XDM_CONST.HTTP_RSP_CODE_GATEWAY_TIMEOUT, - msg_status_code = "505", XDM_CONST.HTTP_RSP_CODE_HTTP_VERSION_NOT_SUPPORTED, - msg_status_code = "506", XDM_CONST.HTTP_RSP_CODE_VARIANT_ALSO_NEGOTIATES, - msg_status_code = "507", XDM_CONST.HTTP_RSP_CODE_INSUFFICIENT_STORAGE, - msg_status_code = "508", XDM_CONST.HTTP_RSP_CODE_LOOP_DETECTED, - msg_status_code = "511", XDM_CONST.HTTP_RSP_CODE_NETWORK_AUTHENTICATION_REQUIRED, - msg_status_code), - xdm.event.outcome = if( - msg ~= "failed", XDM_CONST.OUTCOME_FAILED, - msg ~= "success", XDM_CONST.OUTCOME_SUCCESS, - msg_status_code IN("200","201","202","203","204","205","207","208","226"), XDM_CONST.OUTCOME_SUCCESS, - msg_status_code IN("4*","5*"),XDM_CONST.OUTCOME_FAILED, - msg_status_code IN("206"), XDM_CONST.OUTCOME_PARTIAL, - XDM_CONST.OUTCOME_UNKNOWN), - xdm.event.outcome_reason = msg_failed_login_reason; - -/* ========================================== - Agent logs mapping - ========================================== */ -filter cefName ~= "Agent" -| alter - trg_os = parsed_cs1 -> os_name, - trg_hostname = arrayindex(regextract(cs1, "^([^\s]+)"),0) - -| alter //XDM mapping - xdm.observer.version = cefDeviceVersion, - xdm.event.type = cefName, - xdm.event.id = id, - xdm.source.host.hostname = shost, - xdm.event.description = msg, - xdm.target.ipv4 = if(is_ipv4(parsed_cs1 -> ip) = TRUE, parsed_cs1 -> ip), - xdm.target.ipv6 = if(is_ipv6(parsed_cs1 -> ip) = TRUE, parsed_cs1 -> ip), - xdm.target.host.os = trg_os, - xdm.target.zone = parsed_cs1 -> Environment, - xdm.target.host.os_family = if( - trg_os ~= "Windows", XDM_CONST.OS_FAMILY_WINDOWS, - trg_os ~= "Mac", XDM_CONST.OS_FAMILY_MACOS, - trg_os ~= "Linux", XDM_CONST.OS_FAMILY_LINUX, - trg_os ~= "Ubuntu", XDM_CONST.OS_FAMILY_UBUNTU), - xdm.target.host.hostname = trg_hostname, - xdm.target.resource.name = trg_hostname, - xdm.target.resource.type = parsed_cs1 -> Role, - xdm.target.application.name = parsed_cs1 -> App, - xdm.event.outcome = if( - msg IN ("Success*","*success*", "*status flag was raised*"), XDM_CONST.OUTCOME_SUCCESS, - msg ~= "[Ff]ail", XDM_CONST.OUTCOME_FAILED, - XDM_CONST.OUTCOME_UNKNOWN), - xdm.alert.severity = cefSeverity; - -/* ========================================== - System logs mapping - ========================================== */ -filter cefName ~= "System" -| alter //XDM mapping - xdm.observer.version = cefDeviceVersion, - xdm.event.type = cefName, - xdm.event.id = id, - xdm.event.log_level = if( - cefSeverity ~= "EMERGENCY" , XDM_CONST.LOG_LEVEL_EMERGENCY, - cefSeverity ~= "ALERT" , XDM_CONST.LOG_LEVEL_ALERT, - cefSeverity ~= "CRITICAL" ,XDM_CONST.LOG_LEVEL_CRITICAL, - cefSeverity ~= "ERROR" ,XDM_CONST.LOG_LEVEL_ERROR, - cefSeverity ~= "WARNING" ,XDM_CONST.LOG_LEVEL_WARNING, - cefSeverity ~= "NOTICE" ,XDM_CONST.LOG_LEVEL_NOTICE, - cefSeverity ~= "INFO" ,XDM_CONST.LOG_LEVEL_INFORMATIONAL, - cefSeverity ~= "DEBUG" ,XDM_CONST.LOG_LEVEL_DEBUG, - cefSeverity), - xdm.event.is_completed = if(cefSeverity ~= "COMPLETE", to_boolean(TRUE), to_boolean(FALSE)), - xdm.source.user_agent = src, - xdm.source.host.hostname = shost, - xdm.event.description = msg; - -/* ========================================== - Network logs mapping - ========================================== */ -filter cefName ~= "Network" -| alter - proto = to_string(proto), - cs3_process_name = if(cs3 IN ("*\*"), arrayindex(regextract(cs3, "[^\\]+$"),0), cs3 IN ("*/*"), arrayindex(regextract(cs3, "[^\/]+$"),0)), - cs14_process_name = if(cs14 IN ("*\*"), arrayindex(regextract(cs14, "[^\\]+$"),0), cs14 IN ("*/*"), arrayindex(regextract(cs14, "[^\/]+$"),0)), - cs15_process_name = if(cs15 IN ("*\*"), arrayindex(regextract(cs15, "[^\\]+$"),0), cs15 IN ("*/*"), arrayindex(regextract(cs15, "[^\/]+$"),0)), - drpoc_process_name = if(drpoc IN ("*\*"), arrayindex(regextract(cs15, "[^\\]+$"),0), drpoc IN ("*/*"), arrayindex(regextract(drpoc, "[^\/]+$"),0)) - -| alter //XDM mapping - xdm.observer.version = cefDeviceVersion, - xdm.event.type = cefName, - xdm.event.id = id, - xdm.source.ipv4 = if(is_ipv4(src) = TRUE, src), - xdm.source.ipv6 = if(is_ipv6(src) = TRUE, src), - xdm.source.host.hostname = shost, - xdm.source.user.username = suser, - xdm.source.identity.username = suser, - xdm.target.ipv4 = if(is_ipv4(dst) = TRUE, dst), - xdm.target.ipv6 = if(is_ipv6(dst) = TRUE, dst), - xdm.target.port = to_integer(dpt), - xdm.target.host.hostname = dhost, - xdm.target.user.username = duser, - xdm.target.identity.username = duser, - xdm.network.ip_protocol = if( - proto = "HOPOPT",XDM_CONST.IP_PROTOCOL_HOPOPT, - proto = "ICMP",XDM_CONST.IP_PROTOCOL_ICMP, - proto = "IGMP",XDM_CONST.IP_PROTOCOL_IGMP, - proto = "GGP",XDM_CONST.IP_PROTOCOL_GGP, - proto = "IP",XDM_CONST.IP_PROTOCOL_IP, - proto = "ST",XDM_CONST.IP_PROTOCOL_ST, - proto = "TCP",XDM_CONST.IP_PROTOCOL_TCP, - proto = "CBT",XDM_CONST.IP_PROTOCOL_CBT, - proto = "EGP",XDM_CONST.IP_PROTOCOL_EGP, - proto = "IGP",XDM_CONST.IP_PROTOCOL_IGP, - proto = "BBN_RCC_MON",XDM_CONST.IP_PROTOCOL_BBN_RCC_MON, - proto = "NVP_II",XDM_CONST.IP_PROTOCOL_NVP_II, - proto = "PUP",XDM_CONST.IP_PROTOCOL_PUP, - proto = "ARGUS",XDM_CONST.IP_PROTOCOL_ARGUS, - proto = "EMCON",XDM_CONST.IP_PROTOCOL_EMCON, - proto = "XNET",XDM_CONST.IP_PROTOCOL_XNET, - proto = "CHAOS",XDM_CONST.IP_PROTOCOL_CHAOS, - proto = "UDP",XDM_CONST.IP_PROTOCOL_UDP, - proto = "MUX",XDM_CONST.IP_PROTOCOL_MUX, - proto = "DCN_MEAS",XDM_CONST.IP_PROTOCOL_DCN_MEAS, - proto = "HMP",XDM_CONST.IP_PROTOCOL_HMP, - proto = "PRM",XDM_CONST.IP_PROTOCOL_PRM, - proto = "XNS_IDP",XDM_CONST.IP_PROTOCOL_XNS_IDP, - proto = "TRUNK_1",XDM_CONST.IP_PROTOCOL_TRUNK_1, - proto = "TRUNK_2",XDM_CONST.IP_PROTOCOL_TRUNK_2, - proto = "LEAF_1",XDM_CONST.IP_PROTOCOL_LEAF_1, - proto = "LEAF_2",XDM_CONST.IP_PROTOCOL_LEAF_2, - proto = "RDP",XDM_CONST.IP_PROTOCOL_RDP, - proto = "IRTP",XDM_CONST.IP_PROTOCOL_IRTP, - proto = "ISO_TP4",XDM_CONST.IP_PROTOCOL_ISO_TP4, - proto = "NETBLT",XDM_CONST.IP_PROTOCOL_NETBLT, - proto = "MFE_NSP",XDM_CONST.IP_PROTOCOL_MFE_NSP, - proto = "MERIT_INP",XDM_CONST.IP_PROTOCOL_MERIT_INP, - proto = "DCCP",XDM_CONST.IP_PROTOCOL_DCCP, - proto = "3PC",XDM_CONST.IP_PROTOCOL_3PC, - proto = "IDPR",XDM_CONST.IP_PROTOCOL_IDPR, - proto = "XTP",XDM_CONST.IP_PROTOCOL_XTP, - proto = "DDP",XDM_CONST.IP_PROTOCOL_DDP, - proto = "IDPR_CMTP",XDM_CONST.IP_PROTOCOL_IDPR_CMTP, - proto = "TP",XDM_CONST.IP_PROTOCOL_TP, - proto = "IL",XDM_CONST.IP_PROTOCOL_IL, - proto = "IPV6",XDM_CONST.IP_PROTOCOL_IPV6, - proto = "SDRP",XDM_CONST.IP_PROTOCOL_SDRP, - proto = "IPV6_ROUTE",XDM_CONST.IP_PROTOCOL_IPV6_ROUTE, - proto = "IPV6_FRAG",XDM_CONST.IP_PROTOCOL_IPV6_FRAG, - proto = "IDRP",XDM_CONST.IP_PROTOCOL_IDRP, - proto = "RSVP",XDM_CONST.IP_PROTOCOL_RSVP, - proto = "GRE",XDM_CONST.IP_PROTOCOL_GRE, - proto = "DSR",XDM_CONST.IP_PROTOCOL_DSR, - proto = "BNA",XDM_CONST.IP_PROTOCOL_BNA, - proto = "ESP",XDM_CONST.IP_PROTOCOL_ESP, - proto = "AH",XDM_CONST.IP_PROTOCOL_AH, - proto = "I_NLSP",XDM_CONST.IP_PROTOCOL_I_NLSP, - proto = "SWIPE",XDM_CONST.IP_PROTOCOL_SWIPE, - proto = "NARP",XDM_CONST.IP_PROTOCOL_NARP, - proto = "MOBILE",XDM_CONST.IP_PROTOCOL_MOBILE, - proto = "TLSP",XDM_CONST.IP_PROTOCOL_TLSP, - proto = "SKIP",XDM_CONST.IP_PROTOCOL_SKIP, - proto = "IPV6_ICMP",XDM_CONST.IP_PROTOCOL_IPV6_ICMP, - proto = "IPV6_NONXT",XDM_CONST.IP_PROTOCOL_IPV6_NONXT, - proto = "IPV6_OPTS",XDM_CONST.IP_PROTOCOL_IPV6_OPTS, - proto = "CFTP",XDM_CONST.IP_PROTOCOL_CFTP, - proto = "SAT_EXPAK",XDM_CONST.IP_PROTOCOL_SAT_EXPAK, - proto = "KRYPTOLAN",XDM_CONST.IP_PROTOCOL_KRYPTOLAN, - proto = "RVD",XDM_CONST.IP_PROTOCOL_RVD, - proto = "IPPC",XDM_CONST.IP_PROTOCOL_IPPC, - proto = "SAT_MON",XDM_CONST.IP_PROTOCOL_SAT_MON, - proto = "VISA",XDM_CONST.IP_PROTOCOL_VISA, - proto = "IPCV",XDM_CONST.IP_PROTOCOL_IPCV, - proto = "CPNX",XDM_CONST.IP_PROTOCOL_CPNX, - proto = "CPHB",XDM_CONST.IP_PROTOCOL_CPHB, - proto = "WSN",XDM_CONST.IP_PROTOCOL_WSN, - proto = "PVP",XDM_CONST.IP_PROTOCOL_PVP, - proto = "BR_SAT_MON",XDM_CONST.IP_PROTOCOL_BR_SAT_MON, - proto = "SUN_ND",XDM_CONST.IP_PROTOCOL_SUN_ND, - proto = "WB_MON",XDM_CONST.IP_PROTOCOL_WB_MON, - proto = "WB_EXPAK",XDM_CONST.IP_PROTOCOL_WB_EXPAK, - proto = "ISO_IP",XDM_CONST.IP_PROTOCOL_ISO_IP, - proto = "VMTP",XDM_CONST.IP_PROTOCOL_VMTP, - proto = "SECURE_VMTP",XDM_CONST.IP_PROTOCOL_SECURE_VMTP, - proto = "VINES",XDM_CONST.IP_PROTOCOL_VINES, - proto = "TTP",XDM_CONST.IP_PROTOCOL_TTP, - proto = "NSFNET_IGP",XDM_CONST.IP_PROTOCOL_NSFNET_IGP, - proto = "DGP",XDM_CONST.IP_PROTOCOL_DGP, - proto = "TCF",XDM_CONST.IP_PROTOCOL_TCF, - proto = "EIGRP",XDM_CONST.IP_PROTOCOL_EIGRP, - proto = "OSPFIGP",XDM_CONST.IP_PROTOCOL_OSPFIGP, - proto = "SPRITE_RPC",XDM_CONST.IP_PROTOCOL_SPRITE_RPC, - proto = "LARP",XDM_CONST.IP_PROTOCOL_LARP, - proto = "MTP",XDM_CONST.IP_PROTOCOL_MTP, - proto = "AX25",XDM_CONST.IP_PROTOCOL_AX25, - proto = "IPIP",XDM_CONST.IP_PROTOCOL_IPIP, - proto = "MICP",XDM_CONST.IP_PROTOCOL_MICP, - proto = "SCC_SP",XDM_CONST.IP_PROTOCOL_SCC_SP, - proto = "ETHERIP",XDM_CONST.IP_PROTOCOL_ETHERIP, - proto = "ENCAP",XDM_CONST.IP_PROTOCOL_ENCAP, - proto = "GMTP",XDM_CONST.IP_PROTOCOL_GMTP, - proto = "IFMP",XDM_CONST.IP_PROTOCOL_IFMP, - proto = "PNNI",XDM_CONST.IP_PROTOCOL_PNNI, - proto = "PIM",XDM_CONST.IP_PROTOCOL_PIM, - proto = "ARIS",XDM_CONST.IP_PROTOCOL_ARIS, - proto = "SCPS",XDM_CONST.IP_PROTOCOL_SCPS, - proto = "QNX",XDM_CONST.IP_PROTOCOL_QNX, - proto = "AN",XDM_CONST.IP_PROTOCOL_AN, - proto = "IPCOMP",XDM_CONST.IP_PROTOCOL_IPCOMP, - proto = "SNP",XDM_CONST.IP_PROTOCOL_SNP, - proto = "COMPAQ_PEER",XDM_CONST.IP_PROTOCOL_COMPAQ_PEER, - proto = "IPX_IN_IP",XDM_CONST.IP_PROTOCOL_IPX_IN_IP, - proto = "VRRP",XDM_CONST.IP_PROTOCOL_VRRP, - proto = "PGM",XDM_CONST.IP_PROTOCOL_PGM, - proto = "L2TP",XDM_CONST.IP_PROTOCOL_L2TP, - proto = "DDX",XDM_CONST.IP_PROTOCOL_DDX, - proto = "IATP",XDM_CONST.IP_PROTOCOL_IATP, - proto = "STP",XDM_CONST.IP_PROTOCOL_STP, - proto = "SRP",XDM_CONST.IP_PROTOCOL_SRP, - proto = "UTI",XDM_CONST.IP_PROTOCOL_UTI, - proto = "SMP",XDM_CONST.IP_PROTOCOL_SMP, - proto = "SM",XDM_CONST.IP_PROTOCOL_SM, - proto = "PTP",XDM_CONST.IP_PROTOCOL_PTP, - proto = "ISIS",XDM_CONST.IP_PROTOCOL_ISIS, - proto = "FIRE",XDM_CONST.IP_PROTOCOL_FIRE, - proto = "CRTP",XDM_CONST.IP_PROTOCOL_CRTP, - proto = "CRUDP",XDM_CONST.IP_PROTOCOL_CRUDP, - proto = "SSCOPMCE",XDM_CONST.IP_PROTOCOL_SSCOPMCE, - proto = "IPLT",XDM_CONST.IP_PROTOCOL_IPLT, - proto = "SPS",XDM_CONST.IP_PROTOCOL_SPS, - proto = "PIPE",XDM_CONST.IP_PROTOCOL_PIPE, - proto = "SCTP",XDM_CONST.IP_PROTOCOL_SCTP, - proto = "FC",XDM_CONST.IP_PROTOCOL_FC, - proto = "RSVP_E2E_IGNORE",XDM_CONST.IP_PROTOCOL_RSVP_E2E_IGNORE, - proto = "MOBILITY",XDM_CONST.IP_PROTOCOL_MOBILITY, - proto = "UDPLITE",XDM_CONST.IP_PROTOCOL_UDPLITE, - proto = "MPLS_IN_IP",XDM_CONST.IP_PROTOCOL_MPLS_IN_IP, - proto = "MANET",XDM_CONST.IP_PROTOCOL_MANET, - proto = "HIP",XDM_CONST.IP_PROTOCOL_HIP, - proto = "SHIM6",XDM_CONST.IP_PROTOCOL_SHIM6, - proto = "WESP",XDM_CONST.IP_PROTOCOL_WESP, - proto = "ROHC",XDM_CONST.IP_PROTOCOL_ROHC, - proto = "RESERVED",XDM_CONST.IP_PROTOCOL_RESERVED, - proto = "0",XDM_CONST.IP_PROTOCOL_HOPOPT, - proto = "1",XDM_CONST.IP_PROTOCOL_ICMP, - proto = "2",XDM_CONST.IP_PROTOCOL_IGMP, - proto = "3",XDM_CONST.IP_PROTOCOL_GGP, - proto = "4",XDM_CONST.IP_PROTOCOL_IP, - proto = "5",XDM_CONST.IP_PROTOCOL_ST, - proto = "6",XDM_CONST.IP_PROTOCOL_TCP, - proto = "7",XDM_CONST.IP_PROTOCOL_CBT, - proto = "8",XDM_CONST.IP_PROTOCOL_EGP, - proto = "9",XDM_CONST.IP_PROTOCOL_IGP, - proto = "10",XDM_CONST.IP_PROTOCOL_BBN_RCC_MON, - proto = "11",XDM_CONST.IP_PROTOCOL_NVP_II, - proto = "12",XDM_CONST.IP_PROTOCOL_PUP, - proto = "13",XDM_CONST.IP_PROTOCOL_ARGUS, - proto = "14",XDM_CONST.IP_PROTOCOL_EMCON, - proto = "15",XDM_CONST.IP_PROTOCOL_XNET, - proto = "16",XDM_CONST.IP_PROTOCOL_CHAOS, - proto = "17",XDM_CONST.IP_PROTOCOL_UDP, - proto = "18",XDM_CONST.IP_PROTOCOL_MUX, - proto = "19",XDM_CONST.IP_PROTOCOL_DCN_MEAS, - proto = "20",XDM_CONST.IP_PROTOCOL_HMP, - proto = "21",XDM_CONST.IP_PROTOCOL_PRM, - proto = "22",XDM_CONST.IP_PROTOCOL_XNS_IDP, - proto = "23",XDM_CONST.IP_PROTOCOL_TRUNK_1, - proto = "24",XDM_CONST.IP_PROTOCOL_TRUNK_2, - proto = "25",XDM_CONST.IP_PROTOCOL_LEAF_1, - proto = "26",XDM_CONST.IP_PROTOCOL_LEAF_2, - proto = "27",XDM_CONST.IP_PROTOCOL_RDP, - proto = "28",XDM_CONST.IP_PROTOCOL_IRTP, - proto = "29",XDM_CONST.IP_PROTOCOL_ISO_TP4, - proto = "30",XDM_CONST.IP_PROTOCOL_NETBLT, - proto = "31",XDM_CONST.IP_PROTOCOL_MFE_NSP, - proto = "32",XDM_CONST.IP_PROTOCOL_MERIT_INP, - proto = "33",XDM_CONST.IP_PROTOCOL_DCCP, - proto = "34",XDM_CONST.IP_PROTOCOL_3PC, - proto = "35",XDM_CONST.IP_PROTOCOL_IDPR, - proto = "36",XDM_CONST.IP_PROTOCOL_XTP, - proto = "37",XDM_CONST.IP_PROTOCOL_DDP, - proto = "38",XDM_CONST.IP_PROTOCOL_IDPR_CMTP, - proto = "39",XDM_CONST.IP_PROTOCOL_TP, - proto = "40",XDM_CONST.IP_PROTOCOL_IL, - proto = "41",XDM_CONST.IP_PROTOCOL_IPV6, - proto = "42",XDM_CONST.IP_PROTOCOL_SDRP, - proto = "43",XDM_CONST.IP_PROTOCOL_IPV6_ROUTE, - proto = "44",XDM_CONST.IP_PROTOCOL_IPV6_FRAG, - proto = "45",XDM_CONST.IP_PROTOCOL_IDRP, - proto = "46",XDM_CONST.IP_PROTOCOL_RSVP, - proto = "47",XDM_CONST.IP_PROTOCOL_GRE, - proto = "48",XDM_CONST.IP_PROTOCOL_DSR, - proto = "49",XDM_CONST.IP_PROTOCOL_BNA, - proto = "50",XDM_CONST.IP_PROTOCOL_ESP, - proto = "51",XDM_CONST.IP_PROTOCOL_AH, - proto = "52",XDM_CONST.IP_PROTOCOL_I_NLSP, - proto = "53",XDM_CONST.IP_PROTOCOL_SWIPE, - proto = "54",XDM_CONST.IP_PROTOCOL_NARP, - proto = "55",XDM_CONST.IP_PROTOCOL_MOBILE, - proto = "56",XDM_CONST.IP_PROTOCOL_TLSP, - proto = "57",XDM_CONST.IP_PROTOCOL_SKIP, - proto = "58",XDM_CONST.IP_PROTOCOL_IPV6_ICMP, - proto = "59",XDM_CONST.IP_PROTOCOL_IPV6_NONXT, - proto = "60",XDM_CONST.IP_PROTOCOL_IPV6_OPTS, - proto = "62",XDM_CONST.IP_PROTOCOL_CFTP, - proto = "64",XDM_CONST.IP_PROTOCOL_SAT_EXPAK, - proto = "65",XDM_CONST.IP_PROTOCOL_KRYPTOLAN, - proto = "66",XDM_CONST.IP_PROTOCOL_RVD, - proto = "67",XDM_CONST.IP_PROTOCOL_IPPC, - proto = "69",XDM_CONST.IP_PROTOCOL_SAT_MON, - proto = "70",XDM_CONST.IP_PROTOCOL_VISA, - proto = "71",XDM_CONST.IP_PROTOCOL_IPCV, - proto = "72",XDM_CONST.IP_PROTOCOL_CPNX, - proto = "73",XDM_CONST.IP_PROTOCOL_CPHB, - proto = "74",XDM_CONST.IP_PROTOCOL_WSN, - proto = "75",XDM_CONST.IP_PROTOCOL_PVP, - proto = "76",XDM_CONST.IP_PROTOCOL_BR_SAT_MON, - proto = "77",XDM_CONST.IP_PROTOCOL_SUN_ND, - proto = "78",XDM_CONST.IP_PROTOCOL_WB_MON, - proto = "79",XDM_CONST.IP_PROTOCOL_WB_EXPAK, - proto = "80",XDM_CONST.IP_PROTOCOL_ISO_IP, - proto = "81",XDM_CONST.IP_PROTOCOL_VMTP, - proto = "82",XDM_CONST.IP_PROTOCOL_SECURE_VMTP, - proto = "83",XDM_CONST.IP_PROTOCOL_VINES, - proto = "84",XDM_CONST.IP_PROTOCOL_TTP, - proto = "85",XDM_CONST.IP_PROTOCOL_NSFNET_IGP, - proto = "86",XDM_CONST.IP_PROTOCOL_DGP, - proto = "87",XDM_CONST.IP_PROTOCOL_TCF, - proto = "88",XDM_CONST.IP_PROTOCOL_EIGRP, - proto = "89",XDM_CONST.IP_PROTOCOL_OSPFIGP, - proto = "90",XDM_CONST.IP_PROTOCOL_SPRITE_RPC, - proto = "91",XDM_CONST.IP_PROTOCOL_LARP, - proto = "92",XDM_CONST.IP_PROTOCOL_MTP, - proto = "93",XDM_CONST.IP_PROTOCOL_AX25, - proto = "94",XDM_CONST.IP_PROTOCOL_IPIP, - proto = "95",XDM_CONST.IP_PROTOCOL_MICP, - proto = "96",XDM_CONST.IP_PROTOCOL_SCC_SP, - proto = "97",XDM_CONST.IP_PROTOCOL_ETHERIP, - proto = "98",XDM_CONST.IP_PROTOCOL_ENCAP, - proto = "100",XDM_CONST.IP_PROTOCOL_GMTP, - proto = "101",XDM_CONST.IP_PROTOCOL_IFMP, - proto = "102",XDM_CONST.IP_PROTOCOL_PNNI, - proto = "103",XDM_CONST.IP_PROTOCOL_PIM, - proto = "104",XDM_CONST.IP_PROTOCOL_ARIS, - proto = "105",XDM_CONST.IP_PROTOCOL_SCPS, - proto = "106",XDM_CONST.IP_PROTOCOL_QNX, - proto = "107",XDM_CONST.IP_PROTOCOL_AN, - proto = "108",XDM_CONST.IP_PROTOCOL_IPCOMP, - proto = "109",XDM_CONST.IP_PROTOCOL_SNP, - proto = "110",XDM_CONST.IP_PROTOCOL_COMPAQ_PEER, - proto = "111",XDM_CONST.IP_PROTOCOL_IPX_IN_IP, - proto = "112",XDM_CONST.IP_PROTOCOL_VRRP, - proto = "113",XDM_CONST.IP_PROTOCOL_PGM, - proto = "115",XDM_CONST.IP_PROTOCOL_L2TP, - proto = "116",XDM_CONST.IP_PROTOCOL_DDX, - proto = "117",XDM_CONST.IP_PROTOCOL_IATP, - proto = "118",XDM_CONST.IP_PROTOCOL_STP, - proto = "119",XDM_CONST.IP_PROTOCOL_SRP, - proto = "120",XDM_CONST.IP_PROTOCOL_UTI, - proto = "121",XDM_CONST.IP_PROTOCOL_SMP, - proto = "122",XDM_CONST.IP_PROTOCOL_SM, - proto = "123",XDM_CONST.IP_PROTOCOL_PTP, - proto = "124",XDM_CONST.IP_PROTOCOL_ISIS, - proto = "125",XDM_CONST.IP_PROTOCOL_FIRE, - proto = "126",XDM_CONST.IP_PROTOCOL_CRTP, - proto = "127",XDM_CONST.IP_PROTOCOL_CRUDP, - proto = "128",XDM_CONST.IP_PROTOCOL_SSCOPMCE, - proto = "129",XDM_CONST.IP_PROTOCOL_IPLT, - proto = "130",XDM_CONST.IP_PROTOCOL_SPS, - proto = "131",XDM_CONST.IP_PROTOCOL_PIPE, - proto = "132",XDM_CONST.IP_PROTOCOL_SCTP, - proto = "133",XDM_CONST.IP_PROTOCOL_FC, - proto = "134",XDM_CONST.IP_PROTOCOL_RSVP_E2E_IGNORE, - proto = "135",XDM_CONST.IP_PROTOCOL_MOBILITY, - proto = "136",XDM_CONST.IP_PROTOCOL_UDPLITE, - proto = "137",XDM_CONST.IP_PROTOCOL_MPLS_IN_IP, - proto = "138",XDM_CONST.IP_PROTOCOL_MANET, - proto = "139",XDM_CONST.IP_PROTOCOL_HIP, - proto = "140",XDM_CONST.IP_PROTOCOL_SHIM6, - proto = "141",XDM_CONST.IP_PROTOCOL_WESP, - proto = "142",XDM_CONST.IP_PROTOCOL_ROHC, - proto = "255",XDM_CONST.IP_PROTOCOL_RESERVED, - proto), - xdm.source.process.name = coalesce(cs3,cs14), - xdm.source.user.identifier = cs11, - xdm.source.identity.identifier = cs11, - xdm.event.outcome_reason = cs6, - xdm.network.rule = cs7, - xdm.target.user.identifier = cs12, - xdm.target.identity.identifier = cs12, - xdm.source.process.executable.filename = coalesce(cs3_process_name, cs14_process_name), - xdm.source.process.executable.path = coalesce(cs13, cs14), - xdm.target.process.executable.filename = cs15_process_name, - xdm.target.process.executable.path = coalesce(cs15, drpoc_process_name), - xdm.target.application.name = cs16, - xdm.observer.action = act, - xdm.event.outcome = if( - cs1 ~= "SUCCESS", XDM_CONST.OUTCOME_SUCCESS, - cs1 ~= "FAIL", XDM_CONST.OUTCOME_FAILED, - XDM_CONST.OUTCOME_UNKNOWN - ); - -/* ========================================== - Label logs mapping - ========================================== */ -filter cefName ~= "Label" -| alter //XDM mapping - xdm.observer.version = cefDeviceVersion, - xdm.event.type = cefName, - xdm.alert.severity = cefSeverity, - xdm.event.id = id, - xdm.event.description = msg; - -/* ========================================== - Incidents logs mapping - ========================================== */ -filter cefName NOT IN ("System*", "Audit*", "Agent*", "Network*", "Label*") -| alter //extract fields - cs5_app = arrayindex(regextract(cs5, "App\:\s([^,]+)"),0), - cs5_os = arrayindex(regextract(cs5, "OS\:\s([^,]+)"),0), - cs5_env = arrayindex(regextract(cs5, "Environment\:\s([^,]+)"),0) - -| alter //XDM mapping - xdm.event.type = cefDeviceEventClassId, - xdm.observer.version = cefDeviceVersion, - xdm.event.description = cefName, - xdm.alert.severity = if( - to_string(cefSeverity) = "8", "High", - to_string(cefSeverity) = "5", "Medium", - to_string(cefSeverity) = "3", "Low", - cefSeverity), - xdm.observer.action = act, - xdm.target.ipv4 = if(is_ipv4(dvc) = TRUE, dvc), - xdm.target.ipv6 = if(is_ipv6(dvc) = TRUE, dvc), - xdm.target.host.hostname = dvchost, - xdm.event.id = cs1, - xdm.alert.source_url = cs2, - xdm.event.tags = split(cs3, ", "), - xdm.target.host.device_id = cs4, - xdm.target.application.name = cs5_app, - xdm.target.host.os = cs5_os, - xdm.target.host.os_family = if( - cs5_os ~= "Windows", XDM_CONST.OS_FAMILY_WINDOWS, - cs5_os ~= "Mac", XDM_CONST.OS_FAMILY_MACOS, - cs5_os ~= "Linux", XDM_CONST.OS_FAMILY_LINUX, - cs5_os ~= "Ubuntu", XDM_CONST.OS_FAMILY_UBUNTU), - xdm.target.zone = cs5_env; \ No newline at end of file diff --git a/Packs/GuardiCore/ModelingRules/GuardiCore_2_11/GuardiCore_2_11.yml b/Packs/GuardiCore/ModelingRules/GuardiCore_2_11/GuardiCore_2_11.yml deleted file mode 100644 index d61dc489551a..000000000000 --- a/Packs/GuardiCore/ModelingRules/GuardiCore_2_11/GuardiCore_2_11.yml +++ /dev/null @@ -1,8 +0,0 @@ -fromversion: 8.15.0 -id: Akamai_GuardiCore_ModelingRule -name: Akamai GuardiCore Modeling Rule -rules: '' -schema: '' -tags: '' -supportedModules: -- xsiam diff --git a/Packs/GuardiCore/ModelingRules/GuardiCore_2_11/GuardiCore_2_11_schema.json b/Packs/GuardiCore/ModelingRules/GuardiCore_2_11/GuardiCore_2_11_schema.json deleted file mode 100644 index 9d9ecc148b11..000000000000 --- a/Packs/GuardiCore/ModelingRules/GuardiCore_2_11/GuardiCore_2_11_schema.json +++ /dev/null @@ -1,132 +0,0 @@ -{ - "akamai_guardicore_raw": { - "cefName": { - "type": "string", - "is_array": false - }, - "cefDeviceVersion": { - "type": "string", - "is_array": false - }, - "cefDeviceEventClassId": { - "type": "string", - "is_array": false - }, - "cefSeverity": { - "type": "string", - "is_array": false - }, - "suser": { - "type": "string", - "is_array": false - }, - "msg": { - "type": "string", - "is_array": false - }, - "act": { - "type": "string", - "is_array": false - }, - "src": { - "type": "string", - "is_array": false - }, - "id": { - "type": "string", - "is_array": false - }, - "shost": { - "type": "string", - "is_array": false - }, - "dst": { - "type": "string", - "is_array": false - }, - "dpt": { - "type": "int", - "is_array": false - }, - "dhost": { - "type": "string", - "is_array": false - }, - "duser": { - "type": "string", - "is_array": false - }, - "proto": { - "type": "string", - "is_array": false - }, - "dvc": { - "type": "string", - "is_array": false - }, - "dvchost": { - "type": "string", - "is_array": false - }, - "cs1": { - "type": "string", - "is_array": false - }, - "cs2": { - "type": "string", - "is_array": false - }, - "cs3": { - "type": "string", - "is_array": false - }, - "cs4": { - "type": "string", - "is_array": false - }, - "cs5": { - "type": "string", - "is_array": false - }, - "cs6": { - "type": "string", - "is_array": false - }, - "cs7": { - "type": "string", - "is_array": false - }, - "cs11": { - "type": "string", - "is_array": false - }, - "cs12": { - "type": "string", - "is_array": false - }, - "cs13": { - "type": "string", - "is_array": false - }, - "cs14": { - "type": "string", - "is_array": false - }, - "cs15": { - "type": "string", - "is_array": false - }, - "cs16": { - "type": "string", - "is_array": false - }, - "drpoc": { - "type": "string", - "is_array": false - }, - "parsed_cs1": { - "type": "string", - "is_array": false - } - } -} \ No newline at end of file diff --git a/Packs/GuardiCore/ReleaseNotes/2_0_25.md b/Packs/GuardiCore/ReleaseNotes/2_0_25.md deleted file mode 100644 index 50321e94155b..000000000000 --- a/Packs/GuardiCore/ReleaseNotes/2_0_25.md +++ /dev/null @@ -1,7 +0,0 @@ - -#### Modeling Rules - -##### New: Akamai GuardiCore Modeling Rule - -- New: Added a new modeling rule version that maps the `xdm.*.identity.*` fields alongside the existing `xdm.*.user.*` fields. -<~XSIAM> (Available from Cortex XSIAM 2.11). diff --git a/Packs/GuardiCore/pack_metadata.json b/Packs/GuardiCore/pack_metadata.json index 351e5f854bd0..f41430b80759 100644 --- a/Packs/GuardiCore/pack_metadata.json +++ b/Packs/GuardiCore/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Akamai GuardiCore", "description": "Data center breach detection", "support": "xsoar", - "currentVersion": "2.0.25", + "currentVersion": "2.0.24", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/Silverfort/ModelingRules/Silverfort/Silverfort.yml b/Packs/Silverfort/ModelingRules/Silverfort/Silverfort.yml index 33ec650f7249..054a72680a71 100644 --- a/Packs/Silverfort/ModelingRules/Silverfort/Silverfort.yml +++ b/Packs/Silverfort/ModelingRules/Silverfort/Silverfort.yml @@ -1,5 +1,4 @@ fromversion: 8.12.0 -toversion: 8.14.0 id: Silverfort_Admin_Console_ModelingRule name: Silverfort Admin Console Modeling Rule rules: '' diff --git a/Packs/Silverfort/ModelingRules/Silverfort_2_11/Silverfort_2_11.xif b/Packs/Silverfort/ModelingRules/Silverfort_2_11/Silverfort_2_11.xif deleted file mode 100644 index d02bda171e64..000000000000 --- a/Packs/Silverfort/ModelingRules/Silverfort_2_11/Silverfort_2_11.xif +++ /dev/null @@ -1,72 +0,0 @@ -//Rule for mapping event type "Authentication" of Silverfort Admin Console -[RULE: silverfort_admin_console_authentication_fields] -alter - src_user = arrayindex(regextract(suser,"(\S+)\@"),0), //suser comes sometimes as UPN - coordinates = if(cs11 != "n/a", split(cs11, ",")), //The coordinates comes as , - outcome_reason = arrayindex(regextract(cs2, "\((.+)\)"), 0), //The format of 'cs2' is 'Denied (Bad Password)', we're extracting the outcome reason. - risks = if(cs7 != "n/a", replace(cs7, "_", " ")) //Comes with underscore instead of space delimiter -| alter - latitude = if(cs11 != "n/a", to_float(arrayindex(coordinates, 0))), - longitude = if(cs11 != "n/a", to_float(arrayindex(coordinates, 1))) - -//Mapping to XDM fields -| alter - xdm.source.user.username = coalesce(src_user,suser), - xdm.source.identity.username = coalesce(src_user,suser), - xdm.source.user.upn = if(src_user != null, suser, concat(suser, "@", sntdom)), //In some cases suser comes as UPN, and in others as username, the UPN can then be derived as suser@sntdom. - xdm.source.identity.upn = if(src_user != null, suser, concat(suser, "@", sntdom)), //In some cases suser comes as UPN, and in others as username, the UPN can then be derived as suser@sntdom. - xdm.source.user.domain = sntdom, - xdm.source.identity.domain = sntdom, - xdm.source.host.hostname = if(shost = "n/a", null, shost), - xdm.source.ipv4 = if(is_ipv4(src) = TRUE, src), - xdm.source.ipv6 = if(is_ipv6(src) = TRUE, src), - xdm.target.host.hostname = if(is_ipv4(dhost) = FALSE AND is_ipv6(dhost) = FALSE, dhost), //dhost sometimes represents IP address and sometimes hostname. - xdm.target.resource.name = if(destinationServiceName != "", destinationServiceName, dhost), - xdm.target.ipv4 = if(is_ipv4(dhost) = TRUE, dhost), - xdm.target.ipv6 = if(is_ipv6(dhost) = TRUE, dhost), - xdm.target.domain = if(dntdom != "", dntdom), - xdm.event.description = if(msg != "", msg), - xdm.alert.severity = cs1, - xdm.event.outcome = if(cs2 contains "Allowed", XDM_CONST.OUTCOME_SUCCESS, cs2 contains "Denied", XDM_CONST.OUTCOME_FAILED, XDM_CONST.OUTCOME_UNKNOWN), - xdm.observer.action = if(cs3 != "n/a",cs3), - xdm.alert.risks = split(risks ,","), - xdm.network.rule = if(cs8 != "n/a", replace(cs8, "_", " ")), - xdm.auth.auth_method = app, - xdm.source.location.country = if(cs9 != "n/a", cs9), - xdm.source.location.city = if(cs10 != "n/a", cs10), - xdm.source.location.latitude = latitude, - xdm.source.location.longitude = longitude, - xdm.event.type = "authentication", - xdm.event.original_event_type = cefdeviceeventclassid, - xdm.event.operation = XDM_CONST.OPERATION_TYPE_AUTH_LOGIN, //MFA is a different cefdeviceeventclassid "MFA", we currently don't support this event class. - xdm.event.tags = arraycreate(XDM_CONST.EVENT_TAG_AUTHENTICATION); - - -//For authentication story - should be only for SSO events. -[RULE: silverfort_admin_console_authentication_story_fields] -alter - xdm.source.port = to_integer(0), - xdm.source.user.user_type = if(suser ~= "\$$" OR suser ~= "^(http|host|cifs|krbtgt|mssql|nfs)\/" OR suser ~= "\/",XDM_CONST.USER_TYPE_MACHINE_ACCOUNT, XDM_CONST.USER_TYPE_REGULAR), - xdm.source.identity.user_type = if(suser ~= "\$$" OR suser ~= "^(http|host|cifs|krbtgt|mssql|nfs)\/" OR suser ~= "\/",XDM_CONST.USER_TYPE_MACHINE_ACCOUNT, XDM_CONST.USER_TYPE_REGULAR), - xdm.target.port = to_integer(0), - xdm.logon.type = XDM_CONST.LOGON_TYPE_INTERACTIVE, - xdm.network.ip_protocol = XDM_CONST.IP_PROTOCOL_TCP, - xdm.auth.service = "IDP", - xdm.event.outcome_reason = if( - outcome_reason IN("*Bad password*", "*Bad username*", "*Bad credentials*", "*Expired password*"), "bad_credentials", - outcome_reason IN("*Account disabled, expired or locked out*", "*Account disabled*"), "account_expired_or_disabled", - outcome_reason IN("*Locked account*"), "account_locked", - outcome_reason IN("*Expired ticket*", "*The client trust failed or is not implemented*", "*The ticket and authenticator do not match*", "*Bad server*", "*cannot accommodate requested option*", "*Clock skew is too great*", "*TGT has been revoked*", "*KDC has no support for PADATA type*", "*Requested start time is later than end time*"), "failed_login", - outcome_reason IN("*Outside authorized hours*", "*Unauthorized workstation*", "Denied (Conditional access applied*", "*Changing password is required*"), "auth_policy_access_violation", - "NOT_SPECIFIED"); - -[MODEL: dataset = silverfort_admin_console_raw] - -filter cefdeviceeventclassid = "Authentication" AND app ~= "SSO|SAML|OIDC" -| call silverfort_admin_console_authentication_fields -| call silverfort_admin_console_authentication_story_fields; - -filter cefdeviceeventclassid = "Authentication" AND app NOT IN("*SSO*","*SAML*", "*OIDC*") -| call silverfort_admin_console_authentication_fields -| alter - xdm.event.outcome_reason = if(cs5 != "n/a", cs5, outcome_reason); \ No newline at end of file diff --git a/Packs/Silverfort/ModelingRules/Silverfort_2_11/Silverfort_2_11.yml b/Packs/Silverfort/ModelingRules/Silverfort_2_11/Silverfort_2_11.yml deleted file mode 100644 index f2ebb1e158ad..000000000000 --- a/Packs/Silverfort/ModelingRules/Silverfort_2_11/Silverfort_2_11.yml +++ /dev/null @@ -1,8 +0,0 @@ -fromversion: 8.15.0 -id: Silverfort_Admin_Console_ModelingRule -name: Silverfort Admin Console Modeling Rule -rules: '' -schema: '' -tags: '' -supportedModules: -- xsiam diff --git a/Packs/Silverfort/ModelingRules/Silverfort_2_11/Silverfort_2_11_schema.json b/Packs/Silverfort/ModelingRules/Silverfort_2_11/Silverfort_2_11_schema.json deleted file mode 100644 index 48f7ed314fe1..000000000000 --- a/Packs/Silverfort/ModelingRules/Silverfort_2_11/Silverfort_2_11_schema.json +++ /dev/null @@ -1,88 +0,0 @@ -{ - "silverfort_admin_console_raw": { - "rt": { - "type": "datetime", - "is_array": false - }, - "cefdeviceeventclassid": { - "type": "string", - "is_array": false - }, - "cefseverity": { - "type": "string", - "is_array": false - }, - "msg": { - "type": "string", - "is_array": false - }, - "app": { - "type": "string", - "is_array": false - }, - "suser": { - "type": "string", - "is_array": false - }, - "sntdom": { - "type": "string", - "is_array": false - }, - "shost": { - "type": "string", - "is_array": false - }, - "src": { - "type": "string", - "is_array": false - }, - "cs1": { - "type": "string", - "is_array": false - }, - "cs2": { - "type": "string", - "is_array": false - }, - "cs3": { - "type": "string", - "is_array": false - }, - "cs5": { - "type": "string", - "is_array": false - }, - "cs7": { - "type": "string", - "is_array": false - }, - "cs8": { - "type": "string", - "is_array": false - }, - "cs9": { - "type": "string", - "is_array": false - }, - "cs10": { - "type": "string", - "is_array": false - }, - "cs11": { - "type": "string", - "is_array": false - }, - "destinationservicename": { - "type": "string", - "is_array": false - }, - "dhost": { - "type": "string", - "is_array": false - }, - "dntdom": { - "type": "string", - "is_array": false - } - } -} \ No newline at end of file diff --git a/Packs/Silverfort/ReleaseNotes/2_0_40.md b/Packs/Silverfort/ReleaseNotes/2_0_40.md deleted file mode 100644 index 2ea47d45b7ff..000000000000 --- a/Packs/Silverfort/ReleaseNotes/2_0_40.md +++ /dev/null @@ -1,7 +0,0 @@ - -#### Modeling Rules - -##### New: Silverfort Admin Console Modeling Rule - -- New: Added a new modeling rule version that maps the `xdm.*.identity.*` fields alongside the existing `xdm.*.user.*` fields. -<~XSIAM> (Available from Cortex XSIAM 2.11). diff --git a/Packs/Silverfort/pack_metadata.json b/Packs/Silverfort/pack_metadata.json index e3ad3de7869d..bca345aa8b35 100644 --- a/Packs/Silverfort/pack_metadata.json +++ b/Packs/Silverfort/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Silverfort", "description": "Silverfort protects organizations from data breaches by delivering strong authentication across entire corporate networks and cloud environments, without requiring any modifications to endpoints or servers. Using patent-pending technology, Silverfort's agentless approach enables multi-factor authentication and AI-driven adaptive authentication even for systems that don’t support it today, including proprietary systems, critical infrastructure, shared folders, IoT devices, and more. Use Silverfort integration to get & update Silverfort risk severity. This integration was integrated and tested with Silverfort version 2.12.", "support": "partner", - "currentVersion": "2.0.40", + "currentVersion": "2.0.39", "author": "Silverfort", "url": "https://support.silverfort.com/", "email": "ecosystem@silverfort.com", From 16751974702b22b201dd91f1652e78af7006be6c Mon Sep 17 00:00:00 2001 From: Shmuel Kroizer <69422117+shmuel44@users.noreply.github.com> Date: Tue, 18 Aug 2026 11:10:16 +0300 Subject: [PATCH 005/419] =?UTF-8?q?fix(SOCRadar):=20rename=20FeedSOCRadarT?= =?UTF-8?q?hreatFeed=20v2=20files=20to=20FeedSOCRadar=E2=80=A6=20(#45512)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(SOCRadar): rename FeedSOCRadarThreatFeed v2 files to FeedSOCRadarThreatFeedV2 The v2 integration YAML already declared id/name FeedSOCRadarThreatFeedV2, but its directory and file basenames were still FeedSOCRadarThreatFeed. That collided with the legacy integration in Packs/FeedSOCRadarThreatFeed, which shares the same module basename and the same docker image, so demisto-sdk batched both into one mypy run and mypy aborted with "Duplicate module named FeedSOCRadarThreatFeed" (exit code 2). Renamed the v2 directory and files to match the integration name, updated the .pack-ignore file reference and the test module imports, and bumped the pack to 2.3.3. * Documentation and metadata improvements. * update docker * bump * bump SOCRadar --- .../FeedSOCRadarThreatFeed.yml | 2 +- .../ReleaseNotes/1_0_18.md | 7 +++++ .../FeedSOCRadarThreatFeed/pack_metadata.json | 2 +- Packs/SOCRadar/.pack-ignore | 2 +- .../FeedSOCRadarThreatFeedV2.py} | 0 .../FeedSOCRadarThreatFeedV2.yml} | 0 .../FeedSOCRadarThreatFeedV2_description.md} | 0 .../FeedSOCRadarThreatFeedV2_image.png} | Bin .../FeedSOCRadarThreatFeedV2_test.py} | 28 +++++++++--------- .../README.md | 0 .../build_entry_context_expected_entry.json | 0 .../test_data/build_entry_context_input.json | 0 .../test_data/check_auth_response.json | 0 .../check_auth_response_auth_error.json | 0 .../test_data/feed_list_response.json | 0 .../fetch_indicators_expected_output.json | 0 .../get_indicators_expected_context.json | 0 Packs/SOCRadar/ReleaseNotes/2_3_4.md | 6 ++++ Packs/SOCRadar/pack_metadata.json | 2 +- 19 files changed, 31 insertions(+), 18 deletions(-) create mode 100644 Packs/FeedSOCRadarThreatFeed/ReleaseNotes/1_0_18.md rename Packs/SOCRadar/Integrations/{FeedSOCRadarThreatFeed/FeedSOCRadarThreatFeed.py => FeedSOCRadarThreatFeedV2/FeedSOCRadarThreatFeedV2.py} (100%) rename Packs/SOCRadar/Integrations/{FeedSOCRadarThreatFeed/FeedSOCRadarThreatFeed.yml => FeedSOCRadarThreatFeedV2/FeedSOCRadarThreatFeedV2.yml} (100%) rename Packs/SOCRadar/Integrations/{FeedSOCRadarThreatFeed/FeedSOCRadarThreatFeed_description.md => FeedSOCRadarThreatFeedV2/FeedSOCRadarThreatFeedV2_description.md} (100%) rename Packs/SOCRadar/Integrations/{FeedSOCRadarThreatFeed/FeedSOCRadarThreatFeed_image.png => FeedSOCRadarThreatFeedV2/FeedSOCRadarThreatFeedV2_image.png} (100%) rename Packs/SOCRadar/Integrations/{FeedSOCRadarThreatFeed/FeedSOCRadarThreatFeed_test.py => FeedSOCRadarThreatFeedV2/FeedSOCRadarThreatFeedV2_test.py} (92%) rename Packs/SOCRadar/Integrations/{FeedSOCRadarThreatFeed => FeedSOCRadarThreatFeedV2}/README.md (100%) rename Packs/SOCRadar/Integrations/{FeedSOCRadarThreatFeed => FeedSOCRadarThreatFeedV2}/test_data/build_entry_context_expected_entry.json (100%) rename Packs/SOCRadar/Integrations/{FeedSOCRadarThreatFeed => FeedSOCRadarThreatFeedV2}/test_data/build_entry_context_input.json (100%) rename Packs/SOCRadar/Integrations/{FeedSOCRadarThreatFeed => FeedSOCRadarThreatFeedV2}/test_data/check_auth_response.json (100%) rename Packs/SOCRadar/Integrations/{FeedSOCRadarThreatFeed => FeedSOCRadarThreatFeedV2}/test_data/check_auth_response_auth_error.json (100%) rename Packs/SOCRadar/Integrations/{FeedSOCRadarThreatFeed => FeedSOCRadarThreatFeedV2}/test_data/feed_list_response.json (100%) rename Packs/SOCRadar/Integrations/{FeedSOCRadarThreatFeed => FeedSOCRadarThreatFeedV2}/test_data/fetch_indicators_expected_output.json (100%) rename Packs/SOCRadar/Integrations/{FeedSOCRadarThreatFeed => FeedSOCRadarThreatFeedV2}/test_data/get_indicators_expected_context.json (100%) create mode 100644 Packs/SOCRadar/ReleaseNotes/2_3_4.md diff --git a/Packs/FeedSOCRadarThreatFeed/Integrations/FeedSOCRadarThreatFeed/FeedSOCRadarThreatFeed.yml b/Packs/FeedSOCRadarThreatFeed/Integrations/FeedSOCRadarThreatFeed/FeedSOCRadarThreatFeed.yml index 96c8fd5553e1..4d53a56d1590 100644 --- a/Packs/FeedSOCRadarThreatFeed/Integrations/FeedSOCRadarThreatFeed/FeedSOCRadarThreatFeed.yml +++ b/Packs/FeedSOCRadarThreatFeed/Integrations/FeedSOCRadarThreatFeed/FeedSOCRadarThreatFeed.yml @@ -198,7 +198,7 @@ script: type: String - description: Resets the indicator fetch history. name: socradar-reset-fetch-indicators - dockerimage: demisto/python3:3.12.13.10116658 + dockerimage: demisto/python3:3.12.13.11879924 feed: true runonce: false script: '-' diff --git a/Packs/FeedSOCRadarThreatFeed/ReleaseNotes/1_0_18.md b/Packs/FeedSOCRadarThreatFeed/ReleaseNotes/1_0_18.md new file mode 100644 index 000000000000..886115621a9b --- /dev/null +++ b/Packs/FeedSOCRadarThreatFeed/ReleaseNotes/1_0_18.md @@ -0,0 +1,7 @@ + +#### Integrations + +##### SOCRadar Threat Feed + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + diff --git a/Packs/FeedSOCRadarThreatFeed/pack_metadata.json b/Packs/FeedSOCRadarThreatFeed/pack_metadata.json index 853ac7c01af4..8edb1dc2c98c 100644 --- a/Packs/FeedSOCRadarThreatFeed/pack_metadata.json +++ b/Packs/FeedSOCRadarThreatFeed/pack_metadata.json @@ -2,7 +2,7 @@ "name": "SOCRadar ThreatFeed", "description": "Obtain indicators provided by SOCRadar to gain knowledge about the malicious activities.", "support": "partner", - "currentVersion": "1.0.17", + "currentVersion": "1.0.18", "author": "SOCRadar Cyber Intelligence Inc.", "url": "www.socradar.io", "email": "xsoar@socradar.io", diff --git a/Packs/SOCRadar/.pack-ignore b/Packs/SOCRadar/.pack-ignore index 55f74996b190..e9b04b87c3d3 100644 --- a/Packs/SOCRadar/.pack-ignore +++ b/Packs/SOCRadar/.pack-ignore @@ -20,7 +20,7 @@ ignore=BA125,BA129 [file:SOCRadarThreatFusion.yml] ignore=BA125 -[file:FeedSOCRadarThreatFeed.yml] +[file:FeedSOCRadarThreatFeedV2.yml] ignore:BA125 [file:SOCRadarIncidents.yml] diff --git a/Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeed/FeedSOCRadarThreatFeed.py b/Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeedV2/FeedSOCRadarThreatFeedV2.py similarity index 100% rename from Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeed/FeedSOCRadarThreatFeed.py rename to Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeedV2/FeedSOCRadarThreatFeedV2.py diff --git a/Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeed/FeedSOCRadarThreatFeed.yml b/Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeedV2/FeedSOCRadarThreatFeedV2.yml similarity index 100% rename from Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeed/FeedSOCRadarThreatFeed.yml rename to Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeedV2/FeedSOCRadarThreatFeedV2.yml diff --git a/Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeed/FeedSOCRadarThreatFeed_description.md b/Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeedV2/FeedSOCRadarThreatFeedV2_description.md similarity index 100% rename from Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeed/FeedSOCRadarThreatFeed_description.md rename to Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeedV2/FeedSOCRadarThreatFeedV2_description.md diff --git a/Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeed/FeedSOCRadarThreatFeed_image.png b/Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeedV2/FeedSOCRadarThreatFeedV2_image.png similarity index 100% rename from Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeed/FeedSOCRadarThreatFeed_image.png rename to Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeedV2/FeedSOCRadarThreatFeedV2_image.png diff --git a/Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeed/FeedSOCRadarThreatFeed_test.py b/Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeedV2/FeedSOCRadarThreatFeedV2_test.py similarity index 92% rename from Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeed/FeedSOCRadarThreatFeed_test.py rename to Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeedV2/FeedSOCRadarThreatFeedV2_test.py index 04ae1b2b07cb..e11e2e843f30 100755 --- a/Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeed/FeedSOCRadarThreatFeed_test.py +++ b/Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeedV2/FeedSOCRadarThreatFeedV2_test.py @@ -14,7 +14,7 @@ def util_load_json(path): def test_test_module(requests_mock): """Tests the test_module validation command.""" - from FeedSOCRadarThreatFeed import Client, test_module + from FeedSOCRadarThreatFeedV2 import Client, test_module mock_socradar_api_key = "APIKey" @@ -44,7 +44,7 @@ def test_test_module(requests_mock): def test_test_module_handles_authorization_error(requests_mock): """Tests the test_module validation command authorization error.""" - from FeedSOCRadarThreatFeed import MESSAGES, Client, test_module + from FeedSOCRadarThreatFeedV2 import MESSAGES, Client, test_module mock_socradar_api_key = "WrongAPIKey" suffix = f"threat/intelligence/check/auth?key={mock_socradar_api_key}" @@ -65,7 +65,7 @@ def test_test_module_handles_authorization_error(requests_mock): def test_fetch_indicators(requests_mock): """Tests the fetch_indicators function with the new UUID-based API.""" - from FeedSOCRadarThreatFeed import Client, fetch_indicators + from FeedSOCRadarThreatFeedV2 import Client, fetch_indicators mock_socradar_api_key = "APIKey" mock_response = util_load_json("test_data/feed_list_response.json") @@ -91,7 +91,7 @@ def test_fetch_indicators(requests_mock): def test_fetch_indicators_handles_error(requests_mock): """Tests the fetch_indicators function when API returns an error.""" - from FeedSOCRadarThreatFeed import Client, fetch_indicators + from FeedSOCRadarThreatFeedV2 import Client, fetch_indicators mock_socradar_api_key = "APIKey" feed_suffix = f"threat/intelligence/feed_list/{MOCK_COLLECTION_UUID}.json?key={mock_socradar_api_key}&v=2" @@ -116,7 +116,7 @@ def test_fetch_indicators_handles_error(requests_mock): def test_fetch_indicators_multiple_uuids(requests_mock): """Tests fetching indicators from multiple collection UUIDs.""" - from FeedSOCRadarThreatFeed import Client, fetch_indicators + from FeedSOCRadarThreatFeedV2 import Client, fetch_indicators mock_socradar_api_key = "APIKey" uuid1 = "uuid-1111-1111-1111-111111111111" @@ -145,7 +145,7 @@ def test_fetch_indicators_multiple_uuids(requests_mock): def test_fetch_indicators_multiple_uuids_with_limit(requests_mock): """Tests fetching indicators from multiple UUIDs respects global limit.""" - from FeedSOCRadarThreatFeed import Client, fetch_indicators + from FeedSOCRadarThreatFeedV2 import Client, fetch_indicators mock_socradar_api_key = "APIKey" uuid1 = "uuid-1111-1111-1111-111111111111" @@ -173,7 +173,7 @@ def test_fetch_indicators_multiple_uuids_with_limit(requests_mock): def test_get_indicators_command(requests_mock): """Tests the get_indicators_command function.""" - from FeedSOCRadarThreatFeed import Client, get_indicators_command + from FeedSOCRadarThreatFeedV2 import Client, get_indicators_command mock_socradar_api_key = "APIKey" mock_response = util_load_json("test_data/feed_list_response.json") @@ -202,7 +202,7 @@ def test_get_indicators_command(requests_mock): def test_get_indicators_command_handles_error(requests_mock): """Tests the get_indicators_command function when API returns an error.""" - from FeedSOCRadarThreatFeed import Client, get_indicators_command + from FeedSOCRadarThreatFeedV2 import Client, get_indicators_command mock_socradar_api_key = "APIKey" feed_suffix = f"threat/intelligence/feed_list/{MOCK_COLLECTION_UUID}.json?key={mock_socradar_api_key}&v=2" @@ -228,7 +228,7 @@ def test_get_indicators_command_handles_error(requests_mock): def test_date_string_to_iso_format_parsing(): """Tests the date_string_to_iso_format_parsing function.""" - from FeedSOCRadarThreatFeed import date_string_to_iso_format_parsing + from FeedSOCRadarThreatFeedV2 import date_string_to_iso_format_parsing mock_date_str = "2025-04-10 19:52:57" formatted_date = date_string_to_iso_format_parsing(mock_date_str) @@ -238,7 +238,7 @@ def test_date_string_to_iso_format_parsing(): def test_build_entry_context(): """Tests the build_entry_context function.""" - from FeedSOCRadarThreatFeed import build_entry_context + from FeedSOCRadarThreatFeedV2 import build_entry_context mock_indicators = util_load_json("test_data/build_entry_context_input.json") context_entry = build_entry_context(mock_indicators) @@ -249,7 +249,7 @@ def test_build_entry_context(): def test_reset_last_fetch_dict(): """Tests the reset_last_fetch_dict function.""" - from FeedSOCRadarThreatFeed import reset_last_fetch_dict + from FeedSOCRadarThreatFeedV2 import reset_last_fetch_dict result = reset_last_fetch_dict() @@ -271,14 +271,14 @@ def test_reset_last_fetch_dict(): CONVERT_DEMISTO_INDICATOR_TYPE_INPUTS, ) def test_convert_to_demisto_indicator_type(socradar_indicator_type, demisto_indicator_type): - from FeedSOCRadarThreatFeed import convert_to_demisto_indicator_type + from FeedSOCRadarThreatFeedV2 import convert_to_demisto_indicator_type assert convert_to_demisto_indicator_type(socradar_indicator_type) == demisto_indicator_type def test_parse_raw_indicators(): """Tests the parse_raw_indicators method of the Client class.""" - from FeedSOCRadarThreatFeed import Client + from FeedSOCRadarThreatFeedV2 import Client client = Client( base_url=SOCRADAR_API_ENDPOINT, @@ -306,7 +306,7 @@ def test_parse_raw_indicators(): def test_parse_raw_indicators_empty(): """Tests parse_raw_indicators with empty input.""" - from FeedSOCRadarThreatFeed import Client + from FeedSOCRadarThreatFeedV2 import Client client = Client( base_url=SOCRADAR_API_ENDPOINT, diff --git a/Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeed/README.md b/Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeedV2/README.md similarity index 100% rename from Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeed/README.md rename to Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeedV2/README.md diff --git a/Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeed/test_data/build_entry_context_expected_entry.json b/Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeedV2/test_data/build_entry_context_expected_entry.json similarity index 100% rename from Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeed/test_data/build_entry_context_expected_entry.json rename to Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeedV2/test_data/build_entry_context_expected_entry.json diff --git a/Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeed/test_data/build_entry_context_input.json b/Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeedV2/test_data/build_entry_context_input.json similarity index 100% rename from Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeed/test_data/build_entry_context_input.json rename to Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeedV2/test_data/build_entry_context_input.json diff --git a/Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeed/test_data/check_auth_response.json b/Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeedV2/test_data/check_auth_response.json similarity index 100% rename from Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeed/test_data/check_auth_response.json rename to Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeedV2/test_data/check_auth_response.json diff --git a/Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeed/test_data/check_auth_response_auth_error.json b/Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeedV2/test_data/check_auth_response_auth_error.json similarity index 100% rename from Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeed/test_data/check_auth_response_auth_error.json rename to Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeedV2/test_data/check_auth_response_auth_error.json diff --git a/Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeed/test_data/feed_list_response.json b/Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeedV2/test_data/feed_list_response.json similarity index 100% rename from Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeed/test_data/feed_list_response.json rename to Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeedV2/test_data/feed_list_response.json diff --git a/Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeed/test_data/fetch_indicators_expected_output.json b/Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeedV2/test_data/fetch_indicators_expected_output.json similarity index 100% rename from Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeed/test_data/fetch_indicators_expected_output.json rename to Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeedV2/test_data/fetch_indicators_expected_output.json diff --git a/Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeed/test_data/get_indicators_expected_context.json b/Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeedV2/test_data/get_indicators_expected_context.json similarity index 100% rename from Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeed/test_data/get_indicators_expected_context.json rename to Packs/SOCRadar/Integrations/FeedSOCRadarThreatFeedV2/test_data/get_indicators_expected_context.json diff --git a/Packs/SOCRadar/ReleaseNotes/2_3_4.md b/Packs/SOCRadar/ReleaseNotes/2_3_4.md new file mode 100644 index 000000000000..cf57479e6610 --- /dev/null +++ b/Packs/SOCRadar/ReleaseNotes/2_3_4.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### SOCRadar Threat Feed v2 + +- Documentation and metadata improvements. diff --git a/Packs/SOCRadar/pack_metadata.json b/Packs/SOCRadar/pack_metadata.json index 334fa5c032b6..08c95c1a1c1e 100755 --- a/Packs/SOCRadar/pack_metadata.json +++ b/Packs/SOCRadar/pack_metadata.json @@ -3,7 +3,7 @@ "created": "2021-08-05T16:43:31Z", "description": "Streamline remediation of alerts and incidents with enhanced multi-tenant capabilities. Easily manage and automate security operations across multiple tenants, including for enrichment threat intelligence, reputation checking, and IoC feeds", "support": "partner", - "currentVersion": "2.3.3", + "currentVersion": "2.3.4", "author": "SOCRadar Cyber Intelligence Inc.", "defaultDataSource": "SOCRadarIncidentsV4", "url": "www.socradar.io", From 57e0c168ae25aacced400db476a595eef17d0869 Mon Sep 17 00:00:00 2001 From: Shmuel Kroizer <69422117+shmuel44@users.noreply.github.com> Date: Tue, 18 Aug 2026 11:14:28 +0300 Subject: [PATCH 006/419] Update cvss_color & MailListener - POP3 (#45507) * fix * bump docker image * fix * Bump pack from version CommonScripts to 1.22.46. * fix validate * Bump pack from version CommonScripts to 1.22.47. * Bump pack from version CommonScripts to 1.22.48. * Bump pack from version CommonScripts to 1.22.49. --------- Co-authored-by: Content Bot --- Packs/CommonScripts/ReleaseNotes/1_22_49.md | 7 +++++++ .../CommonScripts/Scripts/CVECVSSColor/CVECVSSColor.py | 4 ++-- .../Scripts/CVECVSSColor/CVECVSSColor.yml | 2 +- .../Scripts/CVECVSSColor/CVECVSSColor_test.py | 6 +++--- Packs/CommonScripts/pack_metadata.json | 2 +- .../MailListener_POP3/MailListener_POP3.py | 2 +- .../MailListener_POP3/MailListener_POP3.yml | 10 ++++++++-- Packs/MailListener_-_POP3/ReleaseNotes/2_0_13.md | 7 +++++++ Packs/MailListener_-_POP3/pack_metadata.json | 2 +- 9 files changed, 31 insertions(+), 11 deletions(-) create mode 100644 Packs/CommonScripts/ReleaseNotes/1_22_49.md create mode 100644 Packs/MailListener_-_POP3/ReleaseNotes/2_0_13.md diff --git a/Packs/CommonScripts/ReleaseNotes/1_22_49.md b/Packs/CommonScripts/ReleaseNotes/1_22_49.md new file mode 100644 index 000000000000..f194e1f2bbdd --- /dev/null +++ b/Packs/CommonScripts/ReleaseNotes/1_22_49.md @@ -0,0 +1,7 @@ + +#### Scripts + +##### cvss_color + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + diff --git a/Packs/CommonScripts/Scripts/CVECVSSColor/CVECVSSColor.py b/Packs/CommonScripts/Scripts/CVECVSSColor/CVECVSSColor.py index 605a148fa3ea..6372ec0f4b55 100644 --- a/Packs/CommonScripts/Scripts/CVECVSSColor/CVECVSSColor.py +++ b/Packs/CommonScripts/Scripts/CVECVSSColor/CVECVSSColor.py @@ -49,9 +49,9 @@ def main(): if cvss == 0: if theme not in ("light", ""): - return_results(CommandResults(readable_output="# <-:->{{color:#FFFFFF}}(**N\A**)")) + return_results(CommandResults(readable_output="# <-:->{{color:#FFFFFF}}(**N/A**)")) else: - return_results(CommandResults(readable_output="# <-:->{{color:#000000}}(**N\A**)")) + return_results(CommandResults(readable_output="# <-:->{{color:#000000}}(**N/A**)")) else: color = get_color(cvss) return_results(CommandResults(readable_output=f"# <-:->{{{{color:{color}}}}}(**{cvss}**)")) diff --git a/Packs/CommonScripts/Scripts/CVECVSSColor/CVECVSSColor.yml b/Packs/CommonScripts/Scripts/CVECVSSColor/CVECVSSColor.yml index 49e6bc466eef..96b651627b77 100644 --- a/Packs/CommonScripts/Scripts/CVECVSSColor/CVECVSSColor.yml +++ b/Packs/CommonScripts/Scripts/CVECVSSColor/CVECVSSColor.yml @@ -11,7 +11,7 @@ enabled: true scripttarget: 0 subtype: python3 runonce: false -dockerimage: demisto/python3:3.12.13.10116658 +dockerimage: demisto/python3:3.12.13.11879924 runas: DBotWeakRole fromversion: 6.5.0 tests: diff --git a/Packs/CommonScripts/Scripts/CVECVSSColor/CVECVSSColor_test.py b/Packs/CommonScripts/Scripts/CVECVSSColor/CVECVSSColor_test.py index 4edea6a63bfa..9da3910a65d4 100644 --- a/Packs/CommonScripts/Scripts/CVECVSSColor/CVECVSSColor_test.py +++ b/Packs/CommonScripts/Scripts/CVECVSSColor/CVECVSSColor_test.py @@ -30,15 +30,15 @@ def test_cvss_color(cvss, color): ), ( {"args": {"indicator": {"CustomFields": {"cvssscore": ""}}}, "context": {"User": {"theme": "dark"}}}, - "# <-:->{{color:#FFFFFF}}(**N\\A**)", + "# <-:->{{color:#FFFFFF}}(**N/A**)", ), ( {"args": {"indicator": {"CustomFields": {"cvssscore": ""}}}, "context": {"User": {"theme": "light"}}}, - "# <-:->{{color:#000000}}(**N\\A**)", + "# <-:->{{color:#000000}}(**N/A**)", ), ( {"args": {"indicator": {"CustomFields": {"cvssscore": None}}}, "context": {"User": {"theme": "light"}}}, - "# <-:->{{color:#000000}}(**N\\A**)", + "# <-:->{{color:#000000}}(**N/A**)", ), ( {"args": {"indicator": {"CustomFields": {"cvssscore": 7.1}}}, "context": {"User": {"theme": "light"}}}, diff --git a/Packs/CommonScripts/pack_metadata.json b/Packs/CommonScripts/pack_metadata.json index 2e5bf8ff3ff9..c81315c73524 100644 --- a/Packs/CommonScripts/pack_metadata.json +++ b/Packs/CommonScripts/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Common Scripts", "description": "Frequently used scripts pack.", "support": "xsoar", - "currentVersion": "1.22.48", + "currentVersion": "1.22.49", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/MailListener_-_POP3/Integrations/MailListener_POP3/MailListener_POP3.py b/Packs/MailListener_-_POP3/Integrations/MailListener_POP3/MailListener_POP3.py index 833b01334b56..15ed15fef0da 100644 --- a/Packs/MailListener_-_POP3/Integrations/MailListener_POP3/MailListener_POP3.py +++ b/Packs/MailListener_-_POP3/Integrations/MailListener_POP3/MailListener_POP3.py @@ -83,7 +83,7 @@ def get_attachment_name(headers): if m: name = m.group(1) - if re.match("^.+\..{3,5}$", name): + if re.match(r"^.+\..{3,5}$", name): return name extension = re.match(r".*[\\/]([\d\w]{2,4}).*", headers.get("content-type", "txt")).group(1) # type: ignore diff --git a/Packs/MailListener_-_POP3/Integrations/MailListener_POP3/MailListener_POP3.yml b/Packs/MailListener_-_POP3/Integrations/MailListener_POP3/MailListener_POP3.yml index 8023f85e5b79..fe694dce72ba 100644 --- a/Packs/MailListener_-_POP3/Integrations/MailListener_POP3/MailListener_POP3.yml +++ b/Packs/MailListener_-_POP3/Integrations/MailListener_POP3/MailListener_POP3.yml @@ -51,12 +51,18 @@ configuration: type: 0 defaultvalue: 3 days required: false - section: Collect + section: Collect - display: Incident type name: incidentType type: 13 required: false section: Collect +- display: Incidents Fetch Interval + name: incidentFetchInterval + defaultvalue: '1' + type: 19 + required: false + section: Collect description: Listen to a mailbox, enable incident triggering via e-mail. display: MailListener - POP3 name: MailListener - POP3 @@ -65,7 +71,7 @@ script: script: '-' type: python subtype: python3 - dockerimage: demisto/python3:3.12.13.10116658 + dockerimage: demisto/python3:3.12.13.11879924 tests: - MailListener-POP3 - Test fromversion: 5.0.0 diff --git a/Packs/MailListener_-_POP3/ReleaseNotes/2_0_13.md b/Packs/MailListener_-_POP3/ReleaseNotes/2_0_13.md new file mode 100644 index 000000000000..68e9b23a1d6c --- /dev/null +++ b/Packs/MailListener_-_POP3/ReleaseNotes/2_0_13.md @@ -0,0 +1,7 @@ + +#### Integrations + +##### MailListener - POP3 + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + diff --git a/Packs/MailListener_-_POP3/pack_metadata.json b/Packs/MailListener_-_POP3/pack_metadata.json index 7a1a42425d6f..d368f7a04182 100644 --- a/Packs/MailListener_-_POP3/pack_metadata.json +++ b/Packs/MailListener_-_POP3/pack_metadata.json @@ -2,7 +2,7 @@ "name": "MailListener - POP3", "description": "Listen to a mailbox, enable incident triggering via e-mail", "support": "xsoar", - "currentVersion": "2.0.12", + "currentVersion": "2.0.13", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From d7889fbcee84a85b6a1a1144b2bf77e1de91a2e6 Mon Sep 17 00:00:00 2001 From: sharonfi99 <147984773+sharonfi99@users.noreply.github.com> Date: Tue, 18 Aug 2026 13:30:15 +0300 Subject: [PATCH 007/419] CRTX-271520 - correct rule version token 3_19 -> 2_11 (#45505) * CRTX-271520 - correct rule version token 3_19 -> 2_11 3.19 is not a Cortex XSIAM version. The token for fromversion 8.15.0 is 2.11, following Salesforce_2_10 / SlackModelingRules_2_10 (8.14.0) and VMwareVcenter_2_9 (8.13.0) already in master. Renames the six modeling rule folders that landed on master with the wrong token and their .xif / .yml / _schema.json, and corrects the matching release notes. The version window (fromversion 8.15.0, toversion 8.14.0 on the previous folder) is unchanged - only the label was wrong. * CRTX-271520 - bump pack versions and add release notes for 2.11 availability --------- Co-authored-by: tmizrahi@paloaltonetworks.com --- .../AzureDevOps_2_11.xif} | 0 .../AzureDevOps_2_11.yml} | 0 .../AzureDevOps_2_11_schema.json} | 0 Packs/AzureDevOps/ReleaseNotes/1_4_23.md | 2 +- Packs/AzureDevOps/ReleaseNotes/1_4_24.md | 7 +++++++ Packs/AzureDevOps/pack_metadata.json | 2 +- .../Barracuda_CGFWModelingRules_2_11.xif} | 0 .../Barracuda_CGFWModelingRules_2_11.yml} | 0 .../Barracuda_CGFWModelingRules_2_11_schema.json} | 0 Packs/Barracuda_Cloudgen_Firewall/ReleaseNotes/1_0_10.md | 7 +++++++ Packs/Barracuda_Cloudgen_Firewall/ReleaseNotes/1_0_9.md | 2 +- Packs/Barracuda_Cloudgen_Firewall/pack_metadata.json | 2 +- .../BeyondTrustRemoteSupport_2_11.xif} | 0 .../BeyondTrustRemoteSupport_2_11.yml} | 0 .../BeyondTrustRemoteSupport_2_11_schema.json} | 0 Packs/BeyondTrustRemoteSupport/ReleaseNotes/1_0_6.md | 2 +- Packs/BeyondTrustRemoteSupport/ReleaseNotes/1_0_7.md | 7 +++++++ Packs/BeyondTrustRemoteSupport/pack_metadata.json | 2 +- .../CybelAngel_2_11.xif} | 0 .../CybelAngel_2_11.yml} | 0 .../CybelAngel_2_11_schema.json} | 0 Packs/CybelAngel/ReleaseNotes/1_1_11.md | 2 +- Packs/CybelAngel/ReleaseNotes/1_1_12.md | 7 +++++++ Packs/CybelAngel/pack_metadata.json | 2 +- .../FortinetFortiwebVM_2_11.xif} | 0 .../FortinetFortiwebVM_2_11.yml} | 0 .../FortinetFortiwebVM_2_11_schema.json} | 0 Packs/FortinetFortiwebVM/ReleaseNotes/2_0_20.md | 2 +- Packs/FortinetFortiwebVM/ReleaseNotes/2_0_21.md | 7 +++++++ Packs/FortinetFortiwebVM/pack_metadata.json | 2 +- .../NetmotionVPN_2_11.xif} | 0 .../NetmotionVPN_2_11.yml} | 0 .../NetmotionVPN_2_11_schema.json} | 0 Packs/NetmotionVPN/ReleaseNotes/1_0_6.md | 2 +- Packs/NetmotionVPN/ReleaseNotes/1_0_7.md | 7 +++++++ Packs/NetmotionVPN/pack_metadata.json | 2 +- 36 files changed, 54 insertions(+), 12 deletions(-) rename Packs/AzureDevOps/ModelingRules/{AzureDevOps_3_19/AzureDevOps_3_19.xif => AzureDevOps_2_11/AzureDevOps_2_11.xif} (100%) rename Packs/AzureDevOps/ModelingRules/{AzureDevOps_3_19/AzureDevOps_3_19.yml => AzureDevOps_2_11/AzureDevOps_2_11.yml} (100%) rename Packs/AzureDevOps/ModelingRules/{AzureDevOps_3_19/AzureDevOps_3_19_schema.json => AzureDevOps_2_11/AzureDevOps_2_11_schema.json} (100%) create mode 100644 Packs/AzureDevOps/ReleaseNotes/1_4_24.md rename Packs/Barracuda_Cloudgen_Firewall/ModelingRules/{Barracuda_CGFWModelingRules_3_19/Barracuda_CGFWModelingRules_3_19.xif => Barracuda_CGFWModelingRules_2_11/Barracuda_CGFWModelingRules_2_11.xif} (100%) rename Packs/Barracuda_Cloudgen_Firewall/ModelingRules/{Barracuda_CGFWModelingRules_3_19/Barracuda_CGFWModelingRules_3_19.yml => Barracuda_CGFWModelingRules_2_11/Barracuda_CGFWModelingRules_2_11.yml} (100%) rename Packs/Barracuda_Cloudgen_Firewall/ModelingRules/{Barracuda_CGFWModelingRules_3_19/Barracuda_CGFWModelingRules_3_19_schema.json => Barracuda_CGFWModelingRules_2_11/Barracuda_CGFWModelingRules_2_11_schema.json} (100%) create mode 100644 Packs/Barracuda_Cloudgen_Firewall/ReleaseNotes/1_0_10.md rename Packs/BeyondTrustRemoteSupport/ModelingRules/{BeyondTrustRemoteSupport_3_19/BeyondTrustRemoteSupport_3_19.xif => BeyondTrustRemoteSupport_2_11/BeyondTrustRemoteSupport_2_11.xif} (100%) rename Packs/BeyondTrustRemoteSupport/ModelingRules/{BeyondTrustRemoteSupport_3_19/BeyondTrustRemoteSupport_3_19.yml => BeyondTrustRemoteSupport_2_11/BeyondTrustRemoteSupport_2_11.yml} (100%) rename Packs/BeyondTrustRemoteSupport/ModelingRules/{BeyondTrustRemoteSupport_3_19/BeyondTrustRemoteSupport_3_19_schema.json => BeyondTrustRemoteSupport_2_11/BeyondTrustRemoteSupport_2_11_schema.json} (100%) create mode 100644 Packs/BeyondTrustRemoteSupport/ReleaseNotes/1_0_7.md rename Packs/CybelAngel/ModelingRules/{CybelAngel_3_19/CybelAngel_3_19.xif => CybelAngel_2_11/CybelAngel_2_11.xif} (100%) rename Packs/CybelAngel/ModelingRules/{CybelAngel_3_19/CybelAngel_3_19.yml => CybelAngel_2_11/CybelAngel_2_11.yml} (100%) rename Packs/CybelAngel/ModelingRules/{CybelAngel_3_19/CybelAngel_3_19_schema.json => CybelAngel_2_11/CybelAngel_2_11_schema.json} (100%) create mode 100644 Packs/CybelAngel/ReleaseNotes/1_1_12.md rename Packs/FortinetFortiwebVM/ModelingRules/{FortinetFortiwebVM_3_19/FortinetFortiwebVM_3_19.xif => FortinetFortiwebVM_2_11/FortinetFortiwebVM_2_11.xif} (100%) rename Packs/FortinetFortiwebVM/ModelingRules/{FortinetFortiwebVM_3_19/FortinetFortiwebVM_3_19.yml => FortinetFortiwebVM_2_11/FortinetFortiwebVM_2_11.yml} (100%) rename Packs/FortinetFortiwebVM/ModelingRules/{FortinetFortiwebVM_3_19/FortinetFortiwebVM_3_19_schema.json => FortinetFortiwebVM_2_11/FortinetFortiwebVM_2_11_schema.json} (100%) create mode 100644 Packs/FortinetFortiwebVM/ReleaseNotes/2_0_21.md rename Packs/NetmotionVPN/ModelingRules/{NetmotionVPN_3_19/NetmotionVPN_3_19.xif => NetmotionVPN_2_11/NetmotionVPN_2_11.xif} (100%) rename Packs/NetmotionVPN/ModelingRules/{NetmotionVPN_3_19/NetmotionVPN_3_19.yml => NetmotionVPN_2_11/NetmotionVPN_2_11.yml} (100%) rename Packs/NetmotionVPN/ModelingRules/{NetmotionVPN_3_19/NetmotionVPN_3_19_schema.json => NetmotionVPN_2_11/NetmotionVPN_2_11_schema.json} (100%) create mode 100644 Packs/NetmotionVPN/ReleaseNotes/1_0_7.md diff --git a/Packs/AzureDevOps/ModelingRules/AzureDevOps_3_19/AzureDevOps_3_19.xif b/Packs/AzureDevOps/ModelingRules/AzureDevOps_2_11/AzureDevOps_2_11.xif similarity index 100% rename from Packs/AzureDevOps/ModelingRules/AzureDevOps_3_19/AzureDevOps_3_19.xif rename to Packs/AzureDevOps/ModelingRules/AzureDevOps_2_11/AzureDevOps_2_11.xif diff --git a/Packs/AzureDevOps/ModelingRules/AzureDevOps_3_19/AzureDevOps_3_19.yml b/Packs/AzureDevOps/ModelingRules/AzureDevOps_2_11/AzureDevOps_2_11.yml similarity index 100% rename from Packs/AzureDevOps/ModelingRules/AzureDevOps_3_19/AzureDevOps_3_19.yml rename to Packs/AzureDevOps/ModelingRules/AzureDevOps_2_11/AzureDevOps_2_11.yml diff --git a/Packs/AzureDevOps/ModelingRules/AzureDevOps_3_19/AzureDevOps_3_19_schema.json b/Packs/AzureDevOps/ModelingRules/AzureDevOps_2_11/AzureDevOps_2_11_schema.json similarity index 100% rename from Packs/AzureDevOps/ModelingRules/AzureDevOps_3_19/AzureDevOps_3_19_schema.json rename to Packs/AzureDevOps/ModelingRules/AzureDevOps_2_11/AzureDevOps_2_11_schema.json diff --git a/Packs/AzureDevOps/ReleaseNotes/1_4_23.md b/Packs/AzureDevOps/ReleaseNotes/1_4_23.md index c06a32ee4586..983502e63d01 100644 --- a/Packs/AzureDevOps/ReleaseNotes/1_4_23.md +++ b/Packs/AzureDevOps/ReleaseNotes/1_4_23.md @@ -4,4 +4,4 @@ ##### New: Azure DevOps Modeling Rule - New: Added a new modeling rule version that maps the `xdm.*.identity.*` fields alongside the existing `xdm.*.user.*` fields. -<~XSIAM> (Available from Cortex XSIAM 3.19). +<~XSIAM> (Available from Cortex XSIAM 2.11). diff --git a/Packs/AzureDevOps/ReleaseNotes/1_4_24.md b/Packs/AzureDevOps/ReleaseNotes/1_4_24.md new file mode 100644 index 000000000000..c70ae741c045 --- /dev/null +++ b/Packs/AzureDevOps/ReleaseNotes/1_4_24.md @@ -0,0 +1,7 @@ + +#### Modeling Rules + +##### Azure DevOps Modeling Rule + +- Updated the modeling rule to be available from Cortex XSIAM 2.11. +<~XSIAM> (Available from Cortex XSIAM 2.11). diff --git a/Packs/AzureDevOps/pack_metadata.json b/Packs/AzureDevOps/pack_metadata.json index 8b85c0d2b94b..0a6047516077 100644 --- a/Packs/AzureDevOps/pack_metadata.json +++ b/Packs/AzureDevOps/pack_metadata.json @@ -2,7 +2,7 @@ "name": "AzureDevOps", "description": "Create and manage Git repositories in Azure DevOps Services.", "support": "xsoar", - "currentVersion": "1.4.23", + "currentVersion": "1.4.24", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/Barracuda_Cloudgen_Firewall/ModelingRules/Barracuda_CGFWModelingRules_3_19/Barracuda_CGFWModelingRules_3_19.xif b/Packs/Barracuda_Cloudgen_Firewall/ModelingRules/Barracuda_CGFWModelingRules_2_11/Barracuda_CGFWModelingRules_2_11.xif similarity index 100% rename from Packs/Barracuda_Cloudgen_Firewall/ModelingRules/Barracuda_CGFWModelingRules_3_19/Barracuda_CGFWModelingRules_3_19.xif rename to Packs/Barracuda_Cloudgen_Firewall/ModelingRules/Barracuda_CGFWModelingRules_2_11/Barracuda_CGFWModelingRules_2_11.xif diff --git a/Packs/Barracuda_Cloudgen_Firewall/ModelingRules/Barracuda_CGFWModelingRules_3_19/Barracuda_CGFWModelingRules_3_19.yml b/Packs/Barracuda_Cloudgen_Firewall/ModelingRules/Barracuda_CGFWModelingRules_2_11/Barracuda_CGFWModelingRules_2_11.yml similarity index 100% rename from Packs/Barracuda_Cloudgen_Firewall/ModelingRules/Barracuda_CGFWModelingRules_3_19/Barracuda_CGFWModelingRules_3_19.yml rename to Packs/Barracuda_Cloudgen_Firewall/ModelingRules/Barracuda_CGFWModelingRules_2_11/Barracuda_CGFWModelingRules_2_11.yml diff --git a/Packs/Barracuda_Cloudgen_Firewall/ModelingRules/Barracuda_CGFWModelingRules_3_19/Barracuda_CGFWModelingRules_3_19_schema.json b/Packs/Barracuda_Cloudgen_Firewall/ModelingRules/Barracuda_CGFWModelingRules_2_11/Barracuda_CGFWModelingRules_2_11_schema.json similarity index 100% rename from Packs/Barracuda_Cloudgen_Firewall/ModelingRules/Barracuda_CGFWModelingRules_3_19/Barracuda_CGFWModelingRules_3_19_schema.json rename to Packs/Barracuda_Cloudgen_Firewall/ModelingRules/Barracuda_CGFWModelingRules_2_11/Barracuda_CGFWModelingRules_2_11_schema.json diff --git a/Packs/Barracuda_Cloudgen_Firewall/ReleaseNotes/1_0_10.md b/Packs/Barracuda_Cloudgen_Firewall/ReleaseNotes/1_0_10.md new file mode 100644 index 000000000000..50d7a08eb971 --- /dev/null +++ b/Packs/Barracuda_Cloudgen_Firewall/ReleaseNotes/1_0_10.md @@ -0,0 +1,7 @@ + +#### Modeling Rules + +##### Barracuda Cloudgen Firewall Modeling Rule + +- Updated the modeling rule to be available from Cortex XSIAM 2.11. +<~XSIAM> (Available from Cortex XSIAM 2.11). diff --git a/Packs/Barracuda_Cloudgen_Firewall/ReleaseNotes/1_0_9.md b/Packs/Barracuda_Cloudgen_Firewall/ReleaseNotes/1_0_9.md index 04f45b8028e4..3d6047aba6b2 100644 --- a/Packs/Barracuda_Cloudgen_Firewall/ReleaseNotes/1_0_9.md +++ b/Packs/Barracuda_Cloudgen_Firewall/ReleaseNotes/1_0_9.md @@ -4,4 +4,4 @@ ##### New: Barracuda Cloudgen Firewall Modeling Rule - New: Added a new modeling rule version that maps the `xdm.*.identity.*` fields alongside the existing `xdm.*.user.*` fields. -<~XSIAM> (Available from Cortex XSIAM 3.19). +<~XSIAM> (Available from Cortex XSIAM 2.11). diff --git a/Packs/Barracuda_Cloudgen_Firewall/pack_metadata.json b/Packs/Barracuda_Cloudgen_Firewall/pack_metadata.json index e554ed2c3dcf..07a1ba3045e9 100644 --- a/Packs/Barracuda_Cloudgen_Firewall/pack_metadata.json +++ b/Packs/Barracuda_Cloudgen_Firewall/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Barracuda Cloudgen Firewall", "description": "Barracuda Cloudgen Friewall modeling rule and parsing rule for XSIAM", "support": "xsoar", - "currentVersion": "1.0.9", + "currentVersion": "1.0.10", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/BeyondTrustRemoteSupport/ModelingRules/BeyondTrustRemoteSupport_3_19/BeyondTrustRemoteSupport_3_19.xif b/Packs/BeyondTrustRemoteSupport/ModelingRules/BeyondTrustRemoteSupport_2_11/BeyondTrustRemoteSupport_2_11.xif similarity index 100% rename from Packs/BeyondTrustRemoteSupport/ModelingRules/BeyondTrustRemoteSupport_3_19/BeyondTrustRemoteSupport_3_19.xif rename to Packs/BeyondTrustRemoteSupport/ModelingRules/BeyondTrustRemoteSupport_2_11/BeyondTrustRemoteSupport_2_11.xif diff --git a/Packs/BeyondTrustRemoteSupport/ModelingRules/BeyondTrustRemoteSupport_3_19/BeyondTrustRemoteSupport_3_19.yml b/Packs/BeyondTrustRemoteSupport/ModelingRules/BeyondTrustRemoteSupport_2_11/BeyondTrustRemoteSupport_2_11.yml similarity index 100% rename from Packs/BeyondTrustRemoteSupport/ModelingRules/BeyondTrustRemoteSupport_3_19/BeyondTrustRemoteSupport_3_19.yml rename to Packs/BeyondTrustRemoteSupport/ModelingRules/BeyondTrustRemoteSupport_2_11/BeyondTrustRemoteSupport_2_11.yml diff --git a/Packs/BeyondTrustRemoteSupport/ModelingRules/BeyondTrustRemoteSupport_3_19/BeyondTrustRemoteSupport_3_19_schema.json b/Packs/BeyondTrustRemoteSupport/ModelingRules/BeyondTrustRemoteSupport_2_11/BeyondTrustRemoteSupport_2_11_schema.json similarity index 100% rename from Packs/BeyondTrustRemoteSupport/ModelingRules/BeyondTrustRemoteSupport_3_19/BeyondTrustRemoteSupport_3_19_schema.json rename to Packs/BeyondTrustRemoteSupport/ModelingRules/BeyondTrustRemoteSupport_2_11/BeyondTrustRemoteSupport_2_11_schema.json diff --git a/Packs/BeyondTrustRemoteSupport/ReleaseNotes/1_0_6.md b/Packs/BeyondTrustRemoteSupport/ReleaseNotes/1_0_6.md index 83294e12dcac..7fddf714a664 100644 --- a/Packs/BeyondTrustRemoteSupport/ReleaseNotes/1_0_6.md +++ b/Packs/BeyondTrustRemoteSupport/ReleaseNotes/1_0_6.md @@ -4,4 +4,4 @@ ##### New: BeyondTrust Remote Support Modeling Rule - New: Added a new modeling rule version that maps the `xdm.*.identity.*` fields alongside the existing `xdm.*.user.*` fields. -<~XSIAM> (Available from Cortex XSIAM 3.19). +<~XSIAM> (Available from Cortex XSIAM 2.11). diff --git a/Packs/BeyondTrustRemoteSupport/ReleaseNotes/1_0_7.md b/Packs/BeyondTrustRemoteSupport/ReleaseNotes/1_0_7.md new file mode 100644 index 000000000000..952c3a49ef08 --- /dev/null +++ b/Packs/BeyondTrustRemoteSupport/ReleaseNotes/1_0_7.md @@ -0,0 +1,7 @@ + +#### Modeling Rules + +##### BeyondTrust Remote Support Modeling Rule + +- Updated the modeling rule to be available from Cortex XSIAM 2.11. +<~XSIAM> (Available from Cortex XSIAM 2.11). diff --git a/Packs/BeyondTrustRemoteSupport/pack_metadata.json b/Packs/BeyondTrustRemoteSupport/pack_metadata.json index b8656ba887a0..1c08b63a16ce 100644 --- a/Packs/BeyondTrustRemoteSupport/pack_metadata.json +++ b/Packs/BeyondTrustRemoteSupport/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Beyond Trust Remote Support", "description": "enables support organizations to access and support nearly any remote computer or mobile device.", "support": "xsoar", - "currentVersion": "1.0.6", + "currentVersion": "1.0.7", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/CybelAngel/ModelingRules/CybelAngel_3_19/CybelAngel_3_19.xif b/Packs/CybelAngel/ModelingRules/CybelAngel_2_11/CybelAngel_2_11.xif similarity index 100% rename from Packs/CybelAngel/ModelingRules/CybelAngel_3_19/CybelAngel_3_19.xif rename to Packs/CybelAngel/ModelingRules/CybelAngel_2_11/CybelAngel_2_11.xif diff --git a/Packs/CybelAngel/ModelingRules/CybelAngel_3_19/CybelAngel_3_19.yml b/Packs/CybelAngel/ModelingRules/CybelAngel_2_11/CybelAngel_2_11.yml similarity index 100% rename from Packs/CybelAngel/ModelingRules/CybelAngel_3_19/CybelAngel_3_19.yml rename to Packs/CybelAngel/ModelingRules/CybelAngel_2_11/CybelAngel_2_11.yml diff --git a/Packs/CybelAngel/ModelingRules/CybelAngel_3_19/CybelAngel_3_19_schema.json b/Packs/CybelAngel/ModelingRules/CybelAngel_2_11/CybelAngel_2_11_schema.json similarity index 100% rename from Packs/CybelAngel/ModelingRules/CybelAngel_3_19/CybelAngel_3_19_schema.json rename to Packs/CybelAngel/ModelingRules/CybelAngel_2_11/CybelAngel_2_11_schema.json diff --git a/Packs/CybelAngel/ReleaseNotes/1_1_11.md b/Packs/CybelAngel/ReleaseNotes/1_1_11.md index 893552f24ef5..141cfd18cc91 100644 --- a/Packs/CybelAngel/ReleaseNotes/1_1_11.md +++ b/Packs/CybelAngel/ReleaseNotes/1_1_11.md @@ -4,4 +4,4 @@ ##### New: CybelAngel Platform Modeling Rule - New: Added a new modeling rule version that maps the `xdm.*.identity.*` fields alongside the existing `xdm.*.user.*` fields. -<~XSIAM> (Available from Cortex XSIAM 3.19). +<~XSIAM> (Available from Cortex XSIAM 2.11). diff --git a/Packs/CybelAngel/ReleaseNotes/1_1_12.md b/Packs/CybelAngel/ReleaseNotes/1_1_12.md new file mode 100644 index 000000000000..7a12b57c595b --- /dev/null +++ b/Packs/CybelAngel/ReleaseNotes/1_1_12.md @@ -0,0 +1,7 @@ + +#### Modeling Rules + +##### CybelAngel Platform Modeling Rule + +- Updated the modeling rule to be available from Cortex XSIAM 2.11. +<~XSIAM> (Available from Cortex XSIAM 2.11). diff --git a/Packs/CybelAngel/pack_metadata.json b/Packs/CybelAngel/pack_metadata.json index d1a4cc4a2324..a65075568f81 100644 --- a/Packs/CybelAngel/pack_metadata.json +++ b/Packs/CybelAngel/pack_metadata.json @@ -2,7 +2,7 @@ "name": "CybelAngel", "description": "CybelAngel Event Collector receives reports from the CybelAngel platform, which specializes in external attack surface protection and management.", "support": "partner", - "currentVersion": "1.1.11", + "currentVersion": "1.1.12", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "david.neil@cybelangel.com", diff --git a/Packs/FortinetFortiwebVM/ModelingRules/FortinetFortiwebVM_3_19/FortinetFortiwebVM_3_19.xif b/Packs/FortinetFortiwebVM/ModelingRules/FortinetFortiwebVM_2_11/FortinetFortiwebVM_2_11.xif similarity index 100% rename from Packs/FortinetFortiwebVM/ModelingRules/FortinetFortiwebVM_3_19/FortinetFortiwebVM_3_19.xif rename to Packs/FortinetFortiwebVM/ModelingRules/FortinetFortiwebVM_2_11/FortinetFortiwebVM_2_11.xif diff --git a/Packs/FortinetFortiwebVM/ModelingRules/FortinetFortiwebVM_3_19/FortinetFortiwebVM_3_19.yml b/Packs/FortinetFortiwebVM/ModelingRules/FortinetFortiwebVM_2_11/FortinetFortiwebVM_2_11.yml similarity index 100% rename from Packs/FortinetFortiwebVM/ModelingRules/FortinetFortiwebVM_3_19/FortinetFortiwebVM_3_19.yml rename to Packs/FortinetFortiwebVM/ModelingRules/FortinetFortiwebVM_2_11/FortinetFortiwebVM_2_11.yml diff --git a/Packs/FortinetFortiwebVM/ModelingRules/FortinetFortiwebVM_3_19/FortinetFortiwebVM_3_19_schema.json b/Packs/FortinetFortiwebVM/ModelingRules/FortinetFortiwebVM_2_11/FortinetFortiwebVM_2_11_schema.json similarity index 100% rename from Packs/FortinetFortiwebVM/ModelingRules/FortinetFortiwebVM_3_19/FortinetFortiwebVM_3_19_schema.json rename to Packs/FortinetFortiwebVM/ModelingRules/FortinetFortiwebVM_2_11/FortinetFortiwebVM_2_11_schema.json diff --git a/Packs/FortinetFortiwebVM/ReleaseNotes/2_0_20.md b/Packs/FortinetFortiwebVM/ReleaseNotes/2_0_20.md index f837f9c8ab55..7b1961f0a6eb 100644 --- a/Packs/FortinetFortiwebVM/ReleaseNotes/2_0_20.md +++ b/Packs/FortinetFortiwebVM/ReleaseNotes/2_0_20.md @@ -4,4 +4,4 @@ ##### New: Fortinet Fortiweb Modeling Rule - New: Added a new modeling rule version that maps the `xdm.*.identity.*` fields alongside the existing `xdm.*.user.*` fields. -<~XSIAM> (Available from Cortex XSIAM 3.19). +<~XSIAM> (Available from Cortex XSIAM 2.11). diff --git a/Packs/FortinetFortiwebVM/ReleaseNotes/2_0_21.md b/Packs/FortinetFortiwebVM/ReleaseNotes/2_0_21.md new file mode 100644 index 000000000000..c7ac084cd472 --- /dev/null +++ b/Packs/FortinetFortiwebVM/ReleaseNotes/2_0_21.md @@ -0,0 +1,7 @@ + +#### Modeling Rules + +##### Fortinet Fortiweb Modeling Rule + +- Updated the modeling rule to be available from Cortex XSIAM 2.11. +<~XSIAM> (Available from Cortex XSIAM 2.11). diff --git a/Packs/FortinetFortiwebVM/pack_metadata.json b/Packs/FortinetFortiwebVM/pack_metadata.json index fbffa0ba0620..78a85ba4d276 100644 --- a/Packs/FortinetFortiwebVM/pack_metadata.json +++ b/Packs/FortinetFortiwebVM/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Fortinet Fortiweb", "description": "The Fortiweb integration manages WAF policies and blocks cookies, URLs, and hostnames.", "support": "xsoar", - "currentVersion": "2.0.20", + "currentVersion": "2.0.21", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/NetmotionVPN/ModelingRules/NetmotionVPN_3_19/NetmotionVPN_3_19.xif b/Packs/NetmotionVPN/ModelingRules/NetmotionVPN_2_11/NetmotionVPN_2_11.xif similarity index 100% rename from Packs/NetmotionVPN/ModelingRules/NetmotionVPN_3_19/NetmotionVPN_3_19.xif rename to Packs/NetmotionVPN/ModelingRules/NetmotionVPN_2_11/NetmotionVPN_2_11.xif diff --git a/Packs/NetmotionVPN/ModelingRules/NetmotionVPN_3_19/NetmotionVPN_3_19.yml b/Packs/NetmotionVPN/ModelingRules/NetmotionVPN_2_11/NetmotionVPN_2_11.yml similarity index 100% rename from Packs/NetmotionVPN/ModelingRules/NetmotionVPN_3_19/NetmotionVPN_3_19.yml rename to Packs/NetmotionVPN/ModelingRules/NetmotionVPN_2_11/NetmotionVPN_2_11.yml diff --git a/Packs/NetmotionVPN/ModelingRules/NetmotionVPN_3_19/NetmotionVPN_3_19_schema.json b/Packs/NetmotionVPN/ModelingRules/NetmotionVPN_2_11/NetmotionVPN_2_11_schema.json similarity index 100% rename from Packs/NetmotionVPN/ModelingRules/NetmotionVPN_3_19/NetmotionVPN_3_19_schema.json rename to Packs/NetmotionVPN/ModelingRules/NetmotionVPN_2_11/NetmotionVPN_2_11_schema.json diff --git a/Packs/NetmotionVPN/ReleaseNotes/1_0_6.md b/Packs/NetmotionVPN/ReleaseNotes/1_0_6.md index c3c2a1509e3b..73d56ee34ab2 100644 --- a/Packs/NetmotionVPN/ReleaseNotes/1_0_6.md +++ b/Packs/NetmotionVPN/ReleaseNotes/1_0_6.md @@ -4,4 +4,4 @@ ##### New: Netmotion VPN Modeling Rule - New: Added a new modeling rule version that maps the `xdm.*.identity.*` fields alongside the existing `xdm.*.user.*` fields. -<~XSIAM> (Available from Cortex XSIAM 3.19). +<~XSIAM> (Available from Cortex XSIAM 2.11). diff --git a/Packs/NetmotionVPN/ReleaseNotes/1_0_7.md b/Packs/NetmotionVPN/ReleaseNotes/1_0_7.md new file mode 100644 index 000000000000..a30b841a6290 --- /dev/null +++ b/Packs/NetmotionVPN/ReleaseNotes/1_0_7.md @@ -0,0 +1,7 @@ + +#### Modeling Rules + +##### Netmotion VPN Modeling Rule + +- Updated the modeling rule to be available from Cortex XSIAM 2.11. +<~XSIAM> (Available from Cortex XSIAM 2.11). diff --git a/Packs/NetmotionVPN/pack_metadata.json b/Packs/NetmotionVPN/pack_metadata.json index 57703b3341e5..c1248e400f98 100644 --- a/Packs/NetmotionVPN/pack_metadata.json +++ b/Packs/NetmotionVPN/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Netmotion VPN", "description": "Parsing and modeling rules for Netmotion VPN logs via syslog", "support": "xsoar", - "currentVersion": "1.0.6", + "currentVersion": "1.0.7", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From f7b23275cc2e06d490182d36f224fbfc91efc3ed Mon Sep 17 00:00:00 2001 From: eepstain <116078117+eepstain@users.noreply.github.com> Date: Tue, 18 Aug 2026 15:03:44 +0300 Subject: [PATCH 008/419] CRTX-271526: add identity.* to modeling rules (PR 6 of 7) (#45461) * CRTX-271526: add identity.* to modeling rules (PR 6 of 7) * CRTX-271526: rename modeling rule folder 3_19 -> 2_11 * fix(identity): align _2_11 modeling rule id/name with predecessors (PR6) Restore the predecessor id/name on the new *_2_11 modeling rules so BC107 recognizes them as same-id successors of the toversion-capped rules, and align the release note headings so RN107 can match them by display name. - Citrix -> Citrix_Cloud_ModelingRule / Citrix Cloud Modeling Rule - DelineaSS -> Delinea Secret Server - ManageEngine-ADSelfServicePlus -> ManageEngine_ADSelfService_Plus_ModelingRule - McAfeeWebGateway -> Mcafee_Web_Gateway_ModelingRule / Macfee Web Gateway Modeling Rule - MicrosoftWindowsEvents -> MicrosoftWindowsEvents - ProofpointCasb -> ProofpointCASB_ModelingRule Add supportedModules: [xsiam] to the new Citrix_2_11 rule. The Citrix pack declares no pack-level supportedModules, so without this the new rule would inherit all 12 platform defaults and trip BA131 (ModelingRule allows xsiam only). Setting it on the newly added file is safe because a new item has no prior module set to narrow, so BC115 does not apply. Add MR108 .pack-ignore entries for DelineaSS_2_11 and MicrosoftWindowsEvents_2_11, whose legacy ids lack the required ModelingRule suffix but cannot be renamed because BC107 requires reusing the predecessor id. Both packs already suppress MR108 on their existing _1_3 rules. * CRTX-271526: move Citrix changes to a separate branch Removes all Citrix changes from this PR so the remaining five packs are not blocked. Citrix hits an unresolvable BA131/BC115 deadlock identical to Halcyon: the pack declares no pack-level supportedModules, so the modified Citrix.yml inherits all 12 platform defaults (BA131 wants only xsiam) while BC115 forbids narrowing them on a modified file, and neither code is ignorable. The Citrix work now lives on crtx-271526-identity-halcyon alongside Halcyon. Remaining packs: DelineaSS, ManageEngine-ADSelfServicePlus, McAfeeWebGateway, MicrosoftWindowsEvents, ProofpointCasb. Committed with --no-verify: the validate-deleted-files hook raises an unhandled FileNotFoundError on Packs/Citrix/ModelingRules/Citrix_2_11/*, because it looks every deleted file up on master and those files were added and removed within this branch, so they never existed there. All other hooks passed in the preceding run. --------- Co-authored-by: sharonfi99 <147984773+sharonfi99@users.noreply.github.com> --- Packs/DelineaSS/.pack-ignore | 3 + .../DelineaSS_1_3/DelineaSS_1_3.yml | 1 + .../DelineaSS_2_11/DelineaSS_2_11.xif | 19 ++ .../DelineaSS_2_11/DelineaSS_2_11.yml | 8 + .../DelineaSS_2_11/DelineaSS_2_11_schema.json | 64 ++++++ Packs/DelineaSS/ReleaseNotes/4_0_4.md | 7 + Packs/DelineaSS/pack_metadata.json | 2 +- .../ManageEngine-ADSelfServicePlus.yml | 1 + .../ManageEngine-ADSelfServicePlus_2_11.xif | 25 +++ .../ManageEngine-ADSelfServicePlus_2_11.yml | 8 + ...eEngine-ADSelfServicePlus_2_11_schema.json | 20 ++ .../ReleaseNotes/1_0_7.md | 7 + .../pack_metadata.json | 2 +- .../McAfeeWebGateway/McAfeeWebGateway.yml | 1 + .../McAfeeWebGateway_2_11.xif | 61 ++++++ .../McAfeeWebGateway_2_11.yml | 8 + .../McAfeeWebGateway_2_11_schema.json | 8 + Packs/McAfeeWebGateway/ReleaseNotes/1_0_22.md | 7 + Packs/McAfeeWebGateway/pack_metadata.json | 2 +- Packs/MicrosoftWindowsEvents/.pack-ignore | 2 + .../MicrosoftWindowsEvents_1_3.yml | 1 + .../MicrosoftWindowsEvents_2_11.xif | 184 ++++++++++++++++++ .../MicrosoftWindowsEvents_2_11.yml | 7 + .../MicrosoftWindowsEvents_2_11_schema.json | 116 +++++++++++ .../ReleaseNotes/1_1_33.md | 7 + .../MicrosoftWindowsEvents/pack_metadata.json | 2 +- .../ProofpointCasb/ProofpointCasb.yml | 1 + .../ProofpointCasb_2_11.xif | 44 +++++ .../ProofpointCasb_2_11.yml | 7 + .../ProofpointCasb_2_11_schema.json | 10 + Packs/ProofpointCasb/ReleaseNotes/1_0_9.md | 7 + Packs/ProofpointCasb/pack_metadata.json | 2 +- 32 files changed, 639 insertions(+), 5 deletions(-) create mode 100644 Packs/DelineaSS/ModelingRules/DelineaSS_2_11/DelineaSS_2_11.xif create mode 100644 Packs/DelineaSS/ModelingRules/DelineaSS_2_11/DelineaSS_2_11.yml create mode 100644 Packs/DelineaSS/ModelingRules/DelineaSS_2_11/DelineaSS_2_11_schema.json create mode 100644 Packs/DelineaSS/ReleaseNotes/4_0_4.md create mode 100644 Packs/ManageEngine-ADSelfServicePlus/ModelingRules/ManageEngine-ADSelfServicePlus_2_11/ManageEngine-ADSelfServicePlus_2_11.xif create mode 100644 Packs/ManageEngine-ADSelfServicePlus/ModelingRules/ManageEngine-ADSelfServicePlus_2_11/ManageEngine-ADSelfServicePlus_2_11.yml create mode 100644 Packs/ManageEngine-ADSelfServicePlus/ModelingRules/ManageEngine-ADSelfServicePlus_2_11/ManageEngine-ADSelfServicePlus_2_11_schema.json create mode 100644 Packs/ManageEngine-ADSelfServicePlus/ReleaseNotes/1_0_7.md create mode 100644 Packs/McAfeeWebGateway/ModelingRules/McAfeeWebGateway_2_11/McAfeeWebGateway_2_11.xif create mode 100644 Packs/McAfeeWebGateway/ModelingRules/McAfeeWebGateway_2_11/McAfeeWebGateway_2_11.yml create mode 100644 Packs/McAfeeWebGateway/ModelingRules/McAfeeWebGateway_2_11/McAfeeWebGateway_2_11_schema.json create mode 100644 Packs/McAfeeWebGateway/ReleaseNotes/1_0_22.md create mode 100644 Packs/MicrosoftWindowsEvents/ModelingRules/MicrosoftWindowsEvents_2_11/MicrosoftWindowsEvents_2_11.xif create mode 100644 Packs/MicrosoftWindowsEvents/ModelingRules/MicrosoftWindowsEvents_2_11/MicrosoftWindowsEvents_2_11.yml create mode 100644 Packs/MicrosoftWindowsEvents/ModelingRules/MicrosoftWindowsEvents_2_11/MicrosoftWindowsEvents_2_11_schema.json create mode 100644 Packs/MicrosoftWindowsEvents/ReleaseNotes/1_1_33.md create mode 100644 Packs/ProofpointCasb/ModelingRules/ProofpointCasb_2_11/ProofpointCasb_2_11.xif create mode 100644 Packs/ProofpointCasb/ModelingRules/ProofpointCasb_2_11/ProofpointCasb_2_11.yml create mode 100644 Packs/ProofpointCasb/ModelingRules/ProofpointCasb_2_11/ProofpointCasb_2_11_schema.json create mode 100644 Packs/ProofpointCasb/ReleaseNotes/1_0_9.md diff --git a/Packs/DelineaSS/.pack-ignore b/Packs/DelineaSS/.pack-ignore index 235a504e5ee2..fb98db600357 100644 --- a/Packs/DelineaSS/.pack-ignore +++ b/Packs/DelineaSS/.pack-ignore @@ -13,3 +13,6 @@ ignore=RM116 [file:README.md] ignore=RM110 + +[file:DelineaSS_2_11.yml] +ignore=MR108 diff --git a/Packs/DelineaSS/ModelingRules/DelineaSS_1_3/DelineaSS_1_3.yml b/Packs/DelineaSS/ModelingRules/DelineaSS_1_3/DelineaSS_1_3.yml index ebb0885f52ca..94e02fd71fa7 100644 --- a/Packs/DelineaSS/ModelingRules/DelineaSS_1_3/DelineaSS_1_3.yml +++ b/Packs/DelineaSS/ModelingRules/DelineaSS_1_3/DelineaSS_1_3.yml @@ -1,4 +1,5 @@ fromversion: 6.10.0 +toversion: 8.14.0 id: Delinea Secret Server name: Delinea Secret Server rules: '' diff --git a/Packs/DelineaSS/ModelingRules/DelineaSS_2_11/DelineaSS_2_11.xif b/Packs/DelineaSS/ModelingRules/DelineaSS_2_11/DelineaSS_2_11.xif new file mode 100644 index 000000000000..bef9ba495d5b --- /dev/null +++ b/Packs/DelineaSS/ModelingRules/DelineaSS_2_11/DelineaSS_2_11.xif @@ -0,0 +1,19 @@ +[MODEL: dataset="thycotic_software_secret_server_raw"] +alter +xdm.target.file.directory=cs3, +xdm.event.description=msg, +xdm.source.ipv4=src, +xdm.target.user.identifier=duid, +xdm.target.identity.identifier=duid, +xdm.source.user.identifier=suid, +xdm.source.identity.identifier=suid, +xdm.target.user.username=coalesce(duser,cs2), +xdm.target.identity.username=coalesce(duser,cs2), +xdm.target.resource.name=fname, +xdm.source.user.username=coalesce(suser,cs4), +xdm.source.identity.username=coalesce(suser,cs4), +xdm.target.resource.id=fileId, +xdm.event.type=cefName, +xdm.target.file.file_type=fileType, +xdm.alert.severity=cefSeverity, +xdm.observer.version=cefDeviceVersion; \ No newline at end of file diff --git a/Packs/DelineaSS/ModelingRules/DelineaSS_2_11/DelineaSS_2_11.yml b/Packs/DelineaSS/ModelingRules/DelineaSS_2_11/DelineaSS_2_11.yml new file mode 100644 index 000000000000..9a0c378dbb2b --- /dev/null +++ b/Packs/DelineaSS/ModelingRules/DelineaSS_2_11/DelineaSS_2_11.yml @@ -0,0 +1,8 @@ +fromversion: 8.15.0 +id: Delinea Secret Server +name: Delinea Secret Server +rules: '' +schema: '' +tags: Delinea Secret Server +supportedModules: +- xsiam diff --git a/Packs/DelineaSS/ModelingRules/DelineaSS_2_11/DelineaSS_2_11_schema.json b/Packs/DelineaSS/ModelingRules/DelineaSS_2_11/DelineaSS_2_11_schema.json new file mode 100644 index 000000000000..f0c49fab930d --- /dev/null +++ b/Packs/DelineaSS/ModelingRules/DelineaSS_2_11/DelineaSS_2_11_schema.json @@ -0,0 +1,64 @@ +{ + "thycotic_software_secret_server_raw": { + "cs2": { + "type": "string", + "is_array": false + }, + "cs3": { + "type": "string", + "is_array": false + }, + "msg": { + "type": "string", + "is_array": false + }, + "src": { + "type": "string", + "is_array": false + }, + "duid": { + "type": "string", + "is_array": false + }, + "suid": { + "type": "string", + "is_array": false + }, + "duser": { + "type": "string", + "is_array": false + }, + "fname": { + "type": "string", + "is_array": false + }, + "suser": { + "type": "string", + "is_array": false + }, + "cs4": { + "type": "string", + "is_array": false + }, + "fileId": { + "type": "string", + "is_array": false + }, + "cefName": { + "type": "string", + "is_array": false + }, + "fileType": { + "type": "string", + "is_array": false + }, + "cefSeverity": { + "type": "string", + "is_array": false + }, + "cefDeviceVersion": { + "type": "string", + "is_array": false + } + } + } \ No newline at end of file diff --git a/Packs/DelineaSS/ReleaseNotes/4_0_4.md b/Packs/DelineaSS/ReleaseNotes/4_0_4.md new file mode 100644 index 000000000000..996be0da2350 --- /dev/null +++ b/Packs/DelineaSS/ReleaseNotes/4_0_4.md @@ -0,0 +1,7 @@ + +#### Modeling Rules + +##### New: Delinea Secret Server + +- New: Added a new modeling rule version that maps the `xdm.*.identity.*` fields alongside the existing `xdm.*.user.*` fields. +<~XSIAM> (Available from Cortex XSIAM 2.11). diff --git a/Packs/DelineaSS/pack_metadata.json b/Packs/DelineaSS/pack_metadata.json index 87988b7c6fbe..ea9014797593 100644 --- a/Packs/DelineaSS/pack_metadata.json +++ b/Packs/DelineaSS/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Delinea Secret Server", "description": "Secure privileges for service, application, root and administrator accounts across your enterprise.", "support": "partner", - "currentVersion": "4.0.3", + "currentVersion": "4.0.4", "author": "Delinea, Inc", "url": "https://delinea.com/support", "email": "support@delinea.com", diff --git a/Packs/ManageEngine-ADSelfServicePlus/ModelingRules/ManageEngine-ADSelfServicePlus/ManageEngine-ADSelfServicePlus.yml b/Packs/ManageEngine-ADSelfServicePlus/ModelingRules/ManageEngine-ADSelfServicePlus/ManageEngine-ADSelfServicePlus.yml index c447734cc54d..719f6b8eb31c 100644 --- a/Packs/ManageEngine-ADSelfServicePlus/ModelingRules/ManageEngine-ADSelfServicePlus/ManageEngine-ADSelfServicePlus.yml +++ b/Packs/ManageEngine-ADSelfServicePlus/ModelingRules/ManageEngine-ADSelfServicePlus/ManageEngine-ADSelfServicePlus.yml @@ -1,4 +1,5 @@ fromversion: 8.3.0 +toversion: 8.14.0 id: ManageEngine_ADSelfService_Plus_ModelingRule name: ManageEngine ADSelfService Plus Modeling Rule rules: '' diff --git a/Packs/ManageEngine-ADSelfServicePlus/ModelingRules/ManageEngine-ADSelfServicePlus_2_11/ManageEngine-ADSelfServicePlus_2_11.xif b/Packs/ManageEngine-ADSelfServicePlus/ModelingRules/ManageEngine-ADSelfServicePlus_2_11/ManageEngine-ADSelfServicePlus_2_11.xif new file mode 100644 index 000000000000..ca22c2c11c27 --- /dev/null +++ b/Packs/ManageEngine-ADSelfServicePlus/ModelingRules/ManageEngine-ADSelfServicePlus_2_11/ManageEngine-ADSelfServicePlus_2_11.xif @@ -0,0 +1,25 @@ +[MODEL: dataset="manageengine_adssp_raw"] +alter + status = lowercase(arrayindex(regextract(msg, "STATUS=([^\]]+)"), 0)), + name = arrayindex(regextract(msg, "\[NAME=([^\]]+)"), 0), + login_name = arrayindex(regextract(msg, "LOGIN NAME=([^\]]+)"), 0), + reason_for_restriction = arrayindex(regextract(msg, "REASON_FOR_RESTRICTION=([^\]]+)"), 0) +| alter + status = if(status contains "success", "success", status contains "invalid" or status contains "denied" or status contains "failed" or status contains "incorrect" or status contains "not found" or status contains "cannot","failed", to_string(status)) +| alter + xdm.observer.name = dvchost, + xdm.observer.unique_identifier = dvc, + xdm.event.outcome = if(status contains "success", XDM_CONST.OUTCOME_SUCCESS, status contains "failed", XDM_CONST.OUTCOME_FAILED, to_string(status)), + xdm.event.outcome_reason = if(status != "success" and status != "failed" and (status != null and status != ""), status, status = null or status = "", reason_for_restriction, null), + xdm.source.ipv4 = arrayindex(regextract(msg, "IP=(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"), 0), + xdm.source.ipv6 = arrayindex(regextract(msg, "IP=([a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5})"), 0), + xdm.source.host.hostname = arrayindex(regextract(msg, "HOST=([^\]]+)"), 0), + xdm.source.user.domain = arrayindex(regextract(msg, "DOMAIN[_\s]?NAME=([^\]]+)"), 0), + xdm.source.identity.domain = arrayindex(regextract(msg, "DOMAIN[_\s]?NAME=([^\]]+)"), 0), + xdm.source.user.username = if(name != null and name != "", name, login_name != null and login_name != "", login_name, null), + xdm.source.identity.username = if(name != null and name != "", name, login_name != null and login_name != "", login_name, null), + xdm.auth.service = arrayindex(regextract(msg, "ACCESS_MODE=([^\]]+)"), 0), + xdm.event.type = arrayindex(regextract(msg, "ACTION_NAME=([^\]]+)"), 0), + xdm.target.user.username = replex(to_string(arrayindex(regextract(msg, "USERS_LIST=\[([^\]]+)"), 0)), "\"", ""), + xdm.target.identity.username = replex(to_string(arrayindex(regextract(msg, "USERS_LIST=\[([^\]]+)"), 0)), "\"", ""), + xdm.alert.severity = cefSeverity; \ No newline at end of file diff --git a/Packs/ManageEngine-ADSelfServicePlus/ModelingRules/ManageEngine-ADSelfServicePlus_2_11/ManageEngine-ADSelfServicePlus_2_11.yml b/Packs/ManageEngine-ADSelfServicePlus/ModelingRules/ManageEngine-ADSelfServicePlus_2_11/ManageEngine-ADSelfServicePlus_2_11.yml new file mode 100644 index 000000000000..ff5c8fd53606 --- /dev/null +++ b/Packs/ManageEngine-ADSelfServicePlus/ModelingRules/ManageEngine-ADSelfServicePlus_2_11/ManageEngine-ADSelfServicePlus_2_11.yml @@ -0,0 +1,8 @@ +fromversion: 8.15.0 +id: ManageEngine_ADSelfService_Plus_ModelingRule +name: ManageEngine ADSelfService Plus Modeling Rule +rules: '' +schema: '' +tags: ManageEngine +supportedModules: +- xsiam diff --git a/Packs/ManageEngine-ADSelfServicePlus/ModelingRules/ManageEngine-ADSelfServicePlus_2_11/ManageEngine-ADSelfServicePlus_2_11_schema.json b/Packs/ManageEngine-ADSelfServicePlus/ModelingRules/ManageEngine-ADSelfServicePlus_2_11/ManageEngine-ADSelfServicePlus_2_11_schema.json new file mode 100644 index 000000000000..b9b0959cbd34 --- /dev/null +++ b/Packs/ManageEngine-ADSelfServicePlus/ModelingRules/ManageEngine-ADSelfServicePlus_2_11/ManageEngine-ADSelfServicePlus_2_11_schema.json @@ -0,0 +1,20 @@ +{ + "manageengine_adssp_raw": { + "msg": { + "type": "string", + "is_array": false + }, + "dvchost": { + "type": "string", + "is_array": false + }, + "dvc": { + "type": "string", + "is_array": false + }, + "cefSeverity": { + "type": "string", + "is_array": false + } + } +} \ No newline at end of file diff --git a/Packs/ManageEngine-ADSelfServicePlus/ReleaseNotes/1_0_7.md b/Packs/ManageEngine-ADSelfServicePlus/ReleaseNotes/1_0_7.md new file mode 100644 index 000000000000..6b39513a18ea --- /dev/null +++ b/Packs/ManageEngine-ADSelfServicePlus/ReleaseNotes/1_0_7.md @@ -0,0 +1,7 @@ + +#### Modeling Rules + +##### New: ManageEngine ADSelfService Plus Modeling Rule + +- New: Added a new modeling rule version that maps the `xdm.*.identity.*` fields alongside the existing `xdm.*.user.*` fields. +<~XSIAM> (Available from Cortex XSIAM 2.11). diff --git a/Packs/ManageEngine-ADSelfServicePlus/pack_metadata.json b/Packs/ManageEngine-ADSelfServicePlus/pack_metadata.json index 01f09f507a02..02740944124f 100644 --- a/Packs/ManageEngine-ADSelfServicePlus/pack_metadata.json +++ b/Packs/ManageEngine-ADSelfServicePlus/pack_metadata.json @@ -2,7 +2,7 @@ "name": "ManageEngine ADSelfService Plus", "description": "ManageEngine ADSelfService Plus is an identity security solution with adaptive MFA, SSO, and password management capabilities.", "support": "xsoar", - "currentVersion": "1.0.6", + "currentVersion": "1.0.7", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/McAfeeWebGateway/ModelingRules/McAfeeWebGateway/McAfeeWebGateway.yml b/Packs/McAfeeWebGateway/ModelingRules/McAfeeWebGateway/McAfeeWebGateway.yml index 8361670d2551..001ac91c98ab 100644 --- a/Packs/McAfeeWebGateway/ModelingRules/McAfeeWebGateway/McAfeeWebGateway.yml +++ b/Packs/McAfeeWebGateway/ModelingRules/McAfeeWebGateway/McAfeeWebGateway.yml @@ -1,4 +1,5 @@ fromversion: 8.4.0 +toversion: 8.14.0 id: Mcafee_Web_Gateway_ModelingRule name: Macfee Web Gateway Modeling Rule rules: '' diff --git a/Packs/McAfeeWebGateway/ModelingRules/McAfeeWebGateway_2_11/McAfeeWebGateway_2_11.xif b/Packs/McAfeeWebGateway/ModelingRules/McAfeeWebGateway_2_11/McAfeeWebGateway_2_11.xif new file mode 100644 index 000000000000..15e705b7ab51 --- /dev/null +++ b/Packs/McAfeeWebGateway/ModelingRules/McAfeeWebGateway_2_11/McAfeeWebGateway_2_11.xif @@ -0,0 +1,61 @@ +[MODEL: dataset = mcafee_webgateway_raw] +alter + get_rep_level = arraystring(regextract(_raw_log, "\|rep_level\=([^\|]+)"), ""), + get_bytes_from_client = arraystring(regextract(_raw_log, "\|bytes_from_client\=([^\|]+)"), ""), + get_virus_name = arraystring(regextract(_raw_log, "\|virus_name\=([^\|]+)"), ""), + get_bytes_to_client = arraystring(regextract(_raw_log, "\|bytes_to_client\=([^\|]+)"), ""), + get_block_reason = arraystring(regextract(_raw_log, "\|block_reason\=([^\|]+)"), ""), + get_hash = arraystring(regextract(_raw_log, "\|hash\=([^\|]+)"), ""), + get_status_code = arraystring(regextract(_raw_log, "\|status_code\=([^\|]+)"), ""), + get_application_name = arraystring(regextract(_raw_log, "\|application_name\=([^\|]+)"), ""), + get_url_port = arraystring(regextract(_raw_log, "\|url_port\=([^\|]+)"), ""), + get_method = arraystring(regextract(_raw_log, "\|method\=([^\|]+)"), ""), + get_host = arraystring(regextract(_raw_log, "\|host\=([^\|]+)"), ""), + get_auth_user = arraystring(regextract(_raw_log, "\|auth_user\=([^\|]+)"), ""), + get_media_type = arraystring(regextract(_raw_log, "\|media_type\=([^\|]+)"), ""), + get_url = arraystring(regextract(_raw_log, "\|url\=([^\|]+)"), ""), + get_filesize = arraystring(regextract(_raw_log, "\|filesize\=([^\|]+)"), ""), + get_src_ip = arraystring(regextract(_raw_log, "\|src_ip\=([^\|]+)"), ""), + get_categories = arraystring(regextract(_raw_log, "\|categories\=([^\|]+)"), ""), + get_user_agent = arraystring(regextract(_raw_log, "\|user_agent\=([^\|]+)"), ""), + get_server_ip = arraystring(regextract(_raw_log, "\|server_ip\=([^\|]+)"), ""), + get_filename = arraystring(regextract(_raw_log, "\|filename\=([^\|]+)"), "") +| alter + check_hash = len(get_hash), + check_src_ip_v4 = if(get_src_ip !~= ":", get_src_ip, null), + check_src_ip_v6 = if(get_src_ip ~= ":", get_src_ip, null), + check_server_ip_v4 = if(get_server_ip !~= ":", get_server_ip, null), + check_server_ip_v6 = if(get_server_ip ~= ":", get_server_ip, null), + get_domain = arraystring(regextract(get_url, "([a-z0-9\.]+\.[0-9a-z\-]+)[\/\?]*"), ""), + get_tld = arraystring(regextract(get_url, "[a-z0-9\.]+\.([0-9a-z\-]+)[\/\?]*"), "") +| alter + order_categories = split(get_categories, ","), + order_domain = if(get_domain ~= "www", replex(get_domain, "www\.", ""), get_domain) +| alter + xdm.source.ipv4 = check_src_ip_v4, + xdm.source.ipv6 = check_src_ip_v6, + xdm.target.ipv4 = check_server_ip_v4, + xdm.target.ipv6 = check_server_ip_v6, + xdm.alert.severity = get_rep_level, + xdm.alert.original_threat_name = get_virus_name, + xdm.source.application.name = get_application_name, + xdm.target.host.hostname = get_host, + xdm.source.user.username = get_auth_user, + xdm.source.identity.username = get_auth_user, + xdm.network.http.content_type = get_media_type, + xdm.source.user_agent = get_user_agent, + xdm.target.file.filename = get_filename, + xdm.source.sent_bytes = to_integer(get_bytes_from_client), + xdm.target.sent_bytes = to_integer(get_bytes_to_client), + xdm.target.port = to_integer(get_url_port), + xdm.target.file.size = to_integer(get_filesize), + xdm.event.outcome = if(get_block_reason ~= "\S", XDM_CONST.OUTCOME_FAILED, null), + xdm.event.outcome_reason = get_block_reason, + xdm.target.file.md5 = if(check_hash = 32, get_hash, null), + xdm.target.file.sha256 = if(check_hash = 64, get_hash, null), + xdm.network.http.url = get_url, + xdm.network.http.domain = order_domain, + xdm.network.http.tld = get_tld, + xdm.alert.subcategory = to_string(order_categories), + xdm.network.http.response_code = if(get_status_code = "100", XDM_CONST.HTTP_RSP_CODE_CONTINUE, get_status_code = "101", XDM_CONST.HTTP_RSP_CODE_SWITCHING_PROTOCOLS, get_status_code = "102", XDM_CONST.HTTP_RSP_CODE_PROCESSING, get_status_code = "103", XDM_CONST.HTTP_RSP_CODE_EARLY_HINTS, get_status_code = "200", XDM_CONST.HTTP_RSP_CODE_OK, get_status_code = "201", XDM_CONST.HTTP_RSP_CODE_CREATED, get_status_code = "202", XDM_CONST.HTTP_RSP_CODE_ACCEPTED, get_status_code = "203", XDM_CONST.HTTP_RSP_CODE_NON__AUTHORITATIVE_INFORMATION, get_status_code = "204", XDM_CONST.HTTP_RSP_CODE_NO_CONTENT, get_status_code = "205", XDM_CONST.HTTP_RSP_CODE_RESET_CONTENT, get_status_code = "206", XDM_CONST.HTTP_RSP_CODE_PARTIAL_CONTENT, get_status_code = "207", XDM_CONST.HTTP_RSP_CODE_MULTI__STATUS, get_status_code = "208", XDM_CONST.HTTP_RSP_CODE_ALREADY_REPORTED, get_status_code = "226", XDM_CONST.HTTP_RSP_CODE_IM_USED, get_status_code = "300", XDM_CONST.HTTP_RSP_CODE_MULTIPLE_CHOICES, get_status_code = "301", XDM_CONST.HTTP_RSP_CODE_MOVED_PERMANENTLY, get_status_code = "302", XDM_CONST.HTTP_RSP_CODE_FOUND, get_status_code = "303", XDM_CONST.HTTP_RSP_CODE_SEE_OTHER, get_status_code = "304", XDM_CONST.HTTP_RSP_CODE_NOT_MODIFIED, get_status_code = "305", XDM_CONST.HTTP_RSP_CODE_USE_PROXY, get_status_code = "307", XDM_CONST.HTTP_RSP_CODE_TEMPORARY_REDIRECT, get_status_code = "308", XDM_CONST.HTTP_RSP_CODE_PERMANENT_REDIRECT, get_status_code = "400", XDM_CONST.HTTP_RSP_CODE_BAD_REQUEST, get_status_code = "401", XDM_CONST.HTTP_RSP_CODE_UNAUTHORIZED, get_status_code = "402", XDM_CONST.HTTP_RSP_CODE_PAYMENT_REQUIRED, get_status_code = "403", XDM_CONST.HTTP_RSP_CODE_FORBIDDEN, get_status_code = "404", XDM_CONST.HTTP_RSP_CODE_NOT_FOUND, get_status_code = "405", XDM_CONST.HTTP_RSP_CODE_METHOD_NOT_ALLOWED, get_status_code = "406", XDM_CONST.HTTP_RSP_CODE_NOT_ACCEPTABLE, get_status_code = "407", XDM_CONST.HTTP_RSP_CODE_PROXY_AUTHENTICATION_REQUIRED, get_status_code = "408", XDM_CONST.HTTP_RSP_CODE_REQUEST_TIMEOUT, get_status_code = "409", XDM_CONST.HTTP_RSP_CODE_CONFLICT, get_status_code = "410", XDM_CONST.HTTP_RSP_CODE_GONE, get_status_code = "411", XDM_CONST.HTTP_RSP_CODE_LENGTH_REQUIRED, get_status_code = "412", XDM_CONST.HTTP_RSP_CODE_PRECONDITION_FAILED, get_status_code = "413", XDM_CONST.HTTP_RSP_CODE_CONTENT_TOO_LARGE, get_status_code = "414", XDM_CONST.HTTP_RSP_CODE_URI_TOO_LONG, get_status_code = "415", XDM_CONST.HTTP_RSP_CODE_UNSUPPORTED_MEDIA_TYPE, get_status_code = "416", XDM_CONST.HTTP_RSP_CODE_RANGE_NOT_SATISFIABLE, get_status_code = "417", XDM_CONST.HTTP_RSP_CODE_EXPECTATION_FAILED, get_status_code = "421", XDM_CONST.HTTP_RSP_CODE_MISDIRECTED_REQUEST, get_status_code = "422", XDM_CONST.HTTP_RSP_CODE_UNPROCESSABLE_CONTENT, get_status_code = "423", XDM_CONST.HTTP_RSP_CODE_LOCKED, get_status_code = "424", XDM_CONST.HTTP_RSP_CODE_FAILED_DEPENDENCY, get_status_code = "425", XDM_CONST.HTTP_RSP_CODE_TOO_EARLY, get_status_code = "426", XDM_CONST.HTTP_RSP_CODE_UPGRADE_REQUIRED, get_status_code = "428", XDM_CONST.HTTP_RSP_CODE_PRECONDITION_REQUIRED, get_status_code = "429", XDM_CONST.HTTP_RSP_CODE_TOO_MANY_REQUESTS, get_status_code = "431", XDM_CONST.HTTP_RSP_CODE_REQUEST_HEADER_FIELDS_TOO_LARGE, get_status_code = "451", XDM_CONST.HTTP_RSP_CODE_UNAVAILABLE_FOR_LEGAL_REASONS, get_status_code = "500", XDM_CONST.HTTP_RSP_CODE_INTERNAL_SERVER_ERROR, get_status_code = "501", XDM_CONST.HTTP_RSP_CODE_NOT_IMPLEMENTED, get_status_code = "502", XDM_CONST.HTTP_RSP_CODE_BAD_GATEWAY, get_status_code = "503", XDM_CONST.HTTP_RSP_CODE_SERVICE_UNAVAILABLE, get_status_code = "504", XDM_CONST.HTTP_RSP_CODE_GATEWAY_TIMEOUT, get_status_code = "505", XDM_CONST.HTTP_RSP_CODE_HTTP_VERSION_NOT_SUPPORTED, get_status_code = "506", XDM_CONST.HTTP_RSP_CODE_VARIANT_ALSO_NEGOTIATES, get_status_code = "507", XDM_CONST.HTTP_RSP_CODE_INSUFFICIENT_STORAGE, get_status_code = "508", XDM_CONST.HTTP_RSP_CODE_LOOP_DETECTED, get_status_code = "511", XDM_CONST.HTTP_RSP_CODE_NETWORK_AUTHENTICATION_REQUIRED, get_status_code = null, null, get_status_code), + xdm.network.http.method = if(get_method = "GET", XDM_CONST.HTTP_METHOD_GET, get_method = "POST", XDM_CONST.HTTP_METHOD_POST, get_method = "PUT", XDM_CONST.HTTP_METHOD_PUT, get_method = "OPTIONS", XDM_CONST.HTTP_METHOD_OPTIONS, get_method = "CONNECT", XDM_CONST.HTTP_METHOD_CONNECT, get_method = "ACL", XDM_CONST.HTTP_METHOD_ACL, get_method = "BASELINE_CONTROL", XDM_CONST.HTTP_METHOD_BASELINE_CONTROL, get_method = "BIND", XDM_CONST.HTTP_METHOD_BIND, get_method = "CHECKIN", XDM_CONST.HTTP_METHOD_CHECKIN, get_method = "CHECKOUT", XDM_CONST.HTTP_METHOD_CHECKOUT, get_method = "COPY", XDM_CONST.HTTP_METHOD_COPY, get_method = "DELETE", XDM_CONST.HTTP_METHOD_DELETE, get_method = "HEAD", XDM_CONST.HTTP_METHOD_HEAD, get_method = "LABEL", XDM_CONST.HTTP_METHOD_LABEL, get_method = "LINK", XDM_CONST.HTTP_METHOD_LINK, get_method = "LOCK", XDM_CONST.HTTP_METHOD_LOCK, get_method = "MERGE", XDM_CONST.HTTP_METHOD_MERGE, get_method = "MKACTIVITY", XDM_CONST.HTTP_METHOD_MKACTIVITY, get_method = "MKCALENDAR", XDM_CONST.HTTP_METHOD_MKCALENDAR, get_method = "MKCOL", XDM_CONST.HTTP_METHOD_MKCOL, get_method = "MKREDIRECTREF", XDM_CONST.HTTP_METHOD_MKREDIRECTREF, get_method = "MKWORKSPACE", XDM_CONST.HTTP_METHOD_MKWORKSPACE, get_method = "MOVE", XDM_CONST.HTTP_METHOD_MOVE, get_method = "ORDERPATCH", XDM_CONST.HTTP_METHOD_ORDERPATCH, get_method = "PATCH", XDM_CONST.HTTP_METHOD_PATCH, get_method = "PRI", XDM_CONST.HTTP_METHOD_PRI, get_method = "PROPFIND", XDM_CONST.HTTP_METHOD_PROPFIND, get_method = "PROPPATCH", XDM_CONST.HTTP_METHOD_PROPPATCH, get_method = "REBIND", XDM_CONST.HTTP_METHOD_REBIND, get_method = "REPORT", XDM_CONST.HTTP_METHOD_REPORT, get_method = "SEARCH", XDM_CONST.HTTP_METHOD_SEARCH, get_method = "TRACE", XDM_CONST.HTTP_METHOD_TRACE, get_method = "UNBIND", XDM_CONST.HTTP_METHOD_UNBIND, get_method = "UNCHECKOUT", XDM_CONST.HTTP_METHOD_UNCHECKOUT, get_method = "UNLINK", XDM_CONST.HTTP_METHOD_UNLINK, get_method = "UNLOCK", XDM_CONST.HTTP_METHOD_UNLOCK, get_method = "UPDATE", XDM_CONST.HTTP_METHOD_UPDATE, get_method = "UPDATEREDIRECTREF", XDM_CONST.HTTP_METHOD_UPDATEREDIRECTREF, get_method = "VERSION_CONTROL", XDM_CONST.HTTP_METHOD_VERSION_CONTROL, get_method); \ No newline at end of file diff --git a/Packs/McAfeeWebGateway/ModelingRules/McAfeeWebGateway_2_11/McAfeeWebGateway_2_11.yml b/Packs/McAfeeWebGateway/ModelingRules/McAfeeWebGateway_2_11/McAfeeWebGateway_2_11.yml new file mode 100644 index 000000000000..294c067ecb3f --- /dev/null +++ b/Packs/McAfeeWebGateway/ModelingRules/McAfeeWebGateway_2_11/McAfeeWebGateway_2_11.yml @@ -0,0 +1,8 @@ +fromversion: 8.15.0 +id: Mcafee_Web_Gateway_ModelingRule +name: Macfee Web Gateway Modeling Rule +rules: '' +schema: '' +tags: '' +supportedModules: +- xsiam diff --git a/Packs/McAfeeWebGateway/ModelingRules/McAfeeWebGateway_2_11/McAfeeWebGateway_2_11_schema.json b/Packs/McAfeeWebGateway/ModelingRules/McAfeeWebGateway_2_11/McAfeeWebGateway_2_11_schema.json new file mode 100644 index 000000000000..280e72312cde --- /dev/null +++ b/Packs/McAfeeWebGateway/ModelingRules/McAfeeWebGateway_2_11/McAfeeWebGateway_2_11_schema.json @@ -0,0 +1,8 @@ +{ + "mcafee_webgateway_raw": { + "_raw_log": { + "type": "string", + "is_array": false + } + } + } \ No newline at end of file diff --git a/Packs/McAfeeWebGateway/ReleaseNotes/1_0_22.md b/Packs/McAfeeWebGateway/ReleaseNotes/1_0_22.md new file mode 100644 index 000000000000..01fcba1a2a05 --- /dev/null +++ b/Packs/McAfeeWebGateway/ReleaseNotes/1_0_22.md @@ -0,0 +1,7 @@ + +#### Modeling Rules + +##### New: Macfee Web Gateway Modeling Rule + +- New: Added a new modeling rule version that maps the `xdm.*.identity.*` fields alongside the existing `xdm.*.user.*` fields. +<~XSIAM> (Available from Cortex XSIAM 2.11). diff --git a/Packs/McAfeeWebGateway/pack_metadata.json b/Packs/McAfeeWebGateway/pack_metadata.json index 077b35ceee1c..4a9999a3f7f6 100644 --- a/Packs/McAfeeWebGateway/pack_metadata.json +++ b/Packs/McAfeeWebGateway/pack_metadata.json @@ -2,7 +2,7 @@ "name": "McAfee Web Gateway", "description": "Blacklist/Whitelist handling", "support": "xsoar", - "currentVersion": "1.0.21", + "currentVersion": "1.0.22", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/MicrosoftWindowsEvents/.pack-ignore b/Packs/MicrosoftWindowsEvents/.pack-ignore index fab8559d85eb..caeeacb07c47 100644 --- a/Packs/MicrosoftWindowsEvents/.pack-ignore +++ b/Packs/MicrosoftWindowsEvents/.pack-ignore @@ -1,3 +1,5 @@ [file:MicrosoftWindowsEvents_1_3.yml] ignore=MR108 +[file:MicrosoftWindowsEvents_2_11.yml] +ignore=MR108 diff --git a/Packs/MicrosoftWindowsEvents/ModelingRules/MicrosoftWindowsEvents_1_3/MicrosoftWindowsEvents_1_3.yml b/Packs/MicrosoftWindowsEvents/ModelingRules/MicrosoftWindowsEvents_1_3/MicrosoftWindowsEvents_1_3.yml index 54f74ff5232b..fbc1157e0943 100644 --- a/Packs/MicrosoftWindowsEvents/ModelingRules/MicrosoftWindowsEvents_1_3/MicrosoftWindowsEvents_1_3.yml +++ b/Packs/MicrosoftWindowsEvents/ModelingRules/MicrosoftWindowsEvents_1_3/MicrosoftWindowsEvents_1_3.yml @@ -1,4 +1,5 @@ fromversion: 8.2.0 +toversion: 8.14.0 id: MicrosoftWindowsEvents name: MicrosoftWindowsEvents rules: '' diff --git a/Packs/MicrosoftWindowsEvents/ModelingRules/MicrosoftWindowsEvents_2_11/MicrosoftWindowsEvents_2_11.xif b/Packs/MicrosoftWindowsEvents/ModelingRules/MicrosoftWindowsEvents_2_11/MicrosoftWindowsEvents_2_11.xif new file mode 100644 index 000000000000..3d6ae3cdc3d2 --- /dev/null +++ b/Packs/MicrosoftWindowsEvents/ModelingRules/MicrosoftWindowsEvents_2_11/MicrosoftWindowsEvents_2_11.xif @@ -0,0 +1,184 @@ +[MODEL: dataset = microsoft_windows_raw] +// supported channels/providers +filter channel in ("System", "Application","Directory Service") or provider_name in("Microsoft-Windows-PowerShell", "Microsoft-Windows-TaskScheduler", "Microsoft-Windows-Windows Firewall With Advanced Security", "Microsoft-Windows-Windows Defender","Microsoft-Windows-ActiveDirectory_DomainService") or provider_name contains "Microsoft-Windows-Security-" +| alter event_id_num = to_integer(event_id), // used for filtering by event id ranges + event_id_string = to_string(event_id), + task_str = to_string(task) +| alter // Extract fields + action = arrayindex(regextract(message, "Action:\s*(\S+)"), 0), + action_status = arrayindex(regextract(message, "Action Status:\s*(.+?)\s+(?:\w+\s+)?\w+:"), 0), + Command_Name = arrayindex(regextract(message, "Command Name = (.*?)\s{2, }"), 0), + Command_Path = arrayindex(regextract(message, "Command Path = (.*?)\s{2, }"), 0), + dc_name = event_data -> DCName, + detection_type = arrayindex(regextract(message, "Detection Type:\s*(.+?)\s+Detection"), 0), // microsoft defender + detection_source = arrayindex(regextract(message, "Detection Source:\s*(.+?)\s+User"), 0), // microsoft defender + defender_signature_version = arrayindex(regextract(message, "Signature Version:\s*(.+?)\s+Engine"), 0), // microsoft defender + defender_security_intelligence_version = coalesce(event_data -> ["Current security intelligence Version"], event_data -> ["AV security intelligence version"]), // microsoft defender + defender_engine_version = coalesce(event_data -> ["Current Engine Version"], arrayindex(regextract(message, "Engine Version:\s*([\d\.]+)\s"), 0), arrayindex(regextract(message, "Engine Version:\s*(.+?)$"), 0)), // microsoft defender + defender_security_intelligence_type = event_data -> ["Security intelligence Type"], + error_code = coalesce(event_data -> error, arrayindex(regextract(message,"Error Code:\s*\S+"), 0)), + error_message = coalesce(event_data -> ["Error Description"], event_data -> ErrorMessage, arrayindex(regextract(message, "Error Description:\s*([^\.]+\.)"), 0)), + failure_code = arrayindex(regextract(message, "Failure Code:\s*(\S+)"), 0), + event_data_param1 = event_data -> param1, + event_data_param2 = event_data -> param2, + event_attributes = event_data -> Attributes, + event_fwlink = event_data->["FWLink"], + execution_name = event_data -> ["Execution Name"], + SubjectKeyIdentifier = event_data -> SubjectKeyIdentifier, + event_name = arrayindex(regextract(message, "^([^:.(]+)"), 0), + TicketEncryptionType = to_string(event_data -> TicketEncryptionType), + IpPort = coalesce(event_data -> IpPort, event_data -> SourcePort), + IpAddress = coalesce(event_data -> IpAddress, event_data -> SourceAddress), + DestAddress = coalesce(event_data -> DestAddress, ""), + Ipv6Address = arrayindex(regextract(message, "Source\s+Network\s+Address:\s+((?:[a-fA-F0-9]{1,4}:){7}[a-fA-F0-9]{1,4}|(?:[a-fA-F0-9]{1,4}:){1,7}:|:(?::[a-fA-F0-9]{1,4}){1,7}|::)\s?"), 0), + LogLevel = lowercase(log_level), + logonType = event_data -> LogonType, + Failure_Reason = arrayindex(regextract(message,"Failure Reason:\s*(.*?)(?:\.|\s+\S+:|$)"),0), + message_action = arrayindex(regextract(message, "action \"([^\"]+)\""), 0), + message_instance = arrayindex(regextract(message, "instance \"([^\"]+)\""), 0), + message_processID = arrayindex(regextract(message, "process ID \"([^\"]+)\""), 0), + message_task = arrayindex(regextract(message , "task \"([^\"]+)\""), 0), + new_value = event_data -> ["New Value"], + old_value = event_data -> ["Old Value"], + file_path = coalesce(arrayindex(regextract(message , "Path:\s*([^\n]+)\n"), 0), arrayindex(regextract(message , "Path:\s*([^,]*?)(?:\s{2}|,|$)"), 0), event_data -> Path), + process_name_format = coalesce(event_data -> ProcessName, event_data -> ["Process Name"], arrayindex(regextract(message, "Process Name:\s*([^,]*?)(?:\s{2}|,)"), 0), arrayindex(regextract(message, "Process Name:\s*([^\n\r]+)"), 0)), + product_name = event_data -> ["Product Name"], // microsoft defender event ids 1000 - 1005 + product_version = event_data -> ["Product Version"], // microsoft defender event ids 1000 - 1005 + rule_name1 = arraystring(regextract(message, "Rule\s+Name\:\s+(.*)\b\s+Modifying\s*User:"), ""), + rule_name2 = arraystring(regextract(message, "Rule\s*Name\:\s+(.*[^\w\s])\s+Modifying\s*User"), ""), + scan_id = event_data -> ["Scan ID"], // windows defender event ids 1000 - 1005 + scan_type = event_data -> ["Scan Type"], // windows defender event ids 1000 - 1005 + scan_params = event_data -> ["Scan Parameters"], // windows defender event ids 1000 - 1005 + scan_duration = multiply(add(add(multiply(to_integer(event_data -> ["Scan Time Hours"]), 3600), multiply(to_integer(event_data -> ["Scan Time Minutes"]), 60)), to_integer(event_data -> ["Scan Time Seconds"])), 1000), // windows defender event ids 1000 - 1005 + severity = arrayindex(regextract(message, "Severity:\s*(\w+)"), 0), + Script_Name = arrayindex(regextract(arrayindex(regextract(message, "Script Name = (.*?)\s{2, }"), 0), "\\([^\\]+)$"), 0), + Script_Path = coalesce(event_data -> Path, arrayindex(regextract(message, "Script Name = (.*?)\s{2, }"), 0)), + target_username = event_data -> TargetUserName, + // source_threat_combined = concat("[", detection_source, "]", " ", threat_category), + target_user_sid = event_data -> TargetUserSid, + target_domain_name = event_data -> TargetDomainName, + threat_id = if(provider_name = "Microsoft-Windows-Windows Defender" and ((event_id_num >= 1006 and event_id_num <= 1012) or event_id_num = 1015 or (event_id_num >= 1116 and event_id_num <= 1119)), arrayindex(regextract(message, "ID:\s*(\w+)\s+\w+:"), 0)), + threat_category = if(provider_name = "Microsoft-Windows-Windows Defender" and ((event_id_num >= 1006 and event_id_num <= 1012) or event_id_num = 1015 or (event_id_num >= 1116 and event_id_num <= 1119)), arrayindex(regextract(message, "Category:\s*(.+?)\s+\w+:"), 0)), + threat_name = if(provider_name = "Microsoft-Windows-Windows Defender" and ((event_id_num >= 1006 and event_id_num <= 1012) or event_id_num = 1015 or (event_id_num >= 1116 and event_id_num <= 1119)), arrayindex(regextract(message, "Name:\s*(.+?)\s+ID:"), 0)), + user_domain = coalesce(user -> domain, event_data -> Domain, if(event_data -> SubjectDomainName in ("-", " - "), null, event_data -> SubjectDomainName), if(user_data -> SubjectDomainName in ("-", " - "), null, user_data -> SubjectDomainName)), + user_name = coalesce(user -> name, event_data -> User, event_data -> SubjectUserName, user_data -> SubjectUserName, arrayindex(regextract(message, "User:\s*(?:[^\\]+\\)*(\S+)"), 0), arrayindex(regextract(message, "User \"([^\"]+)\""), 0), if(channel="Application" and event_data -> param3 contains "*\\*", event_data -> param3),event_data -> ["Detection User"],event_data -> ["Requester"]), + user_sid = coalesce(event_data -> SID, event_data -> SubjectUserSid, user -> identifier, user -> SubjectUserSid, event_data -> UserSid, if(provider_name = "Microsoft-Windows-Windows Firewall With Advanced Security", arrayindex(regextract(message, "Modifying\s*User\:\s+(.*)\b\s+Modifying\s+Application:"), 0))), + user_type = user -> type, + check_task_string = if(task_str ~= "\d+", null, task_str), + canonical_task = if(provider_name contains "Microsoft-Windows-Security-", + if(event_id_string in ("4624","4625","4648"), "Logon", + event_id_string in ("4634","4647"), "Logoff", + event_id_string in ("4778","4779","4800","4801","4802","4803","4825"), "Other Logon/Logoff Events", + event_id_string = "4672", "Special Logon", + event_id_string in ("4688"), "Process Creation", + event_id_string in ("4689"), "Process Termination", + event_id_string in ("4673","4674"), "Sensitive Privilege Use", + event_id_string in ("4662"), "Directory Service Access", + event_id_string in ("4768","4771"), "Kerberos Authentication Service", + event_id_string in ("4769","4770"), "Kerberos Service Ticket Operations", + event_id_string in ("4776"), "Credential Validation", + event_id_string in ("4663"), "Removable Storage", + event_id_string in ("4670","4703","4704","4705","4911"), "Authorization Policy Change", + event_id_string in ("4719"), "Audit Policy Change", + event_id_string in ("4720","4722","4723","4724","4725","4726","4738","4740","4767","4780","4781","4798"), "User Account Management", + event_id_string in ("4741","4742","4743"), "Computer Account Management", + event_id_string in ("4727","4728","4729","4730","4731","4732","4733","4734","4737","4754","4755","4756","4757","4758","4799"), "Security Group Management", + event_id_string in ("4697"), "Security System Extension", + null), + null) +| alter // post-extraction processing & validations + check_rule_name1 = if(rule_name1 ~= "\S", rule_name1, null), + check_rule_name2 = if(rule_name2 ~= "\S", rule_name2, null), + check_Command_Path = if(Command_Path ~= "\S", Command_Path, null), + check_Command_Name = if(Command_Name ~= "\S", Command_Name, null), + check_Script_Name = if(Script_Name ~= "\S", Script_Name, null), + check_Script_Path = if(Script_Path ~= "\S", Script_Path, null), + check_message_task = if(message_task ~= "\S", message_task, null), + check_message_processID = if(message_processID ~= "\S", message_processID, null), + check_message_action = if(message_action ~= "\S", message_action, null), + check_fw_description = if(provider_name = "Microsoft-Windows-Windows Firewall With Advanced Security", arraystring(regextract(message, "^[^\.]+\."), ""), null), + check_fw_process_name = if(provider_name = "Microsoft-Windows-Windows Firewall With Advanced Security", arraystring(regextract(message, "Modifying\s*Application:\s+\S+\\([^\.]+\.exe)"), ""), null), + get_message_instance_exe_path = if(message_instance ~= "exe", message_instance, null), + get_message_instance_exe_process = if(message_instance ~= "exe", arrayindex(regextract(message_instance, "\\([a-zA-Z0-9]+\.exe)$"), 0), null) +| alter event_type = coalesce(event_action, canonical_task, to_string(task), check_message_task, event_name) // set event type +| alter // XDM mappings + xdm.alert.category = threat_category, + xdm.alert.description = coalesce(if(channel="System", error_code, check_fw_description != null, check_fw_description, error_message), if(event_id_string in ("4886", "4887", "4888","4897","4898"), object_create("FW_link", event_fwlink, "Disposition", event_data -> Disposition, "cdc", arrayindex(regextract(event_attributes, "cdc:([^\n]+)") ,0), "rmd", arrayindex(regextract(event_attributes, "rmd:([^\n]+)") ,0), "ccm", arrayindex(regextract(event_attributes, "ccm:([^\n]+)") ,0), "error_code", event_data -> Status, "sub_error_code", event_data -> SubStatus))), + xdm.alert.original_threat_name = threat_name, + xdm.alert.original_threat_id = threat_id, + xdm.alert.original_alert_id = activity_id, + xdm.alert.severity = severity, + xdm.event.description = coalesce(message, if(channel="System", event_data -> updateTitle), if(channel="Application", event_data -> param3)), + xdm.event.duration = to_integer(scan_duration), + xdm.event.id = event_id_string, + xdm.event.log_level = if(LogLevel="information", XDM_CONST.LOG_LEVEL_INFORMATIONAL, LogLevel="error", XDM_CONST.LOG_LEVEL_ERROR, LogLevel="warning", XDM_CONST.LOG_LEVEL_WARNING, LogLevel="critical", XDM_CONST.LOG_LEVEL_CRITICAL, to_string(coalesce(to_string(opcode), log_level))), + xdm.event.operation_sub_type = coalesce(check_message_action, detection_type, arrayindex(regextract(message, "(^.*?)\."), 0), if(channel="System", event_data_param2)), + xdm.event.original_event_type = event_type, + xdm.event.outcome_reason = coalesce(if(channel="Application" and check_task_string = "TM", event_data_param2), action_status, error_message, Failure_Reason), + xdm.event.outcome = if(event_result = "success", XDM_CONST.OUTCOME_SUCCESS, event_result="failure", XDM_CONST.OUTCOME_FAILED, coalesce(event_result, action, error_code, failure_code)), + xdm.event.type = channel, + xdm.event.tags = arraycreate(execution_name), + xdm.logon.type = if(logonType="2", XDM_CONST.LOGON_TYPE_INTERACTIVE, logonType="3", XDM_CONST.LOGON_TYPE_NETWORK, logonType="4", XDM_CONST.LOGON_TYPE_BATCH , logonType="5", XDM_CONST.LOGON_TYPE_SERVICE , logonType ="6", XDM_CONST.LOGON_TYPE_PROXY , logonType="7", XDM_CONST.LOGON_TYPE_NEW_CREDENTIALS , logonType="8", XDM_CONST.LOGON_TYPE_NETWORK_CLEARTEXT, logonType="9", XDM_CONST.LOGON_TYPE_NEW_CREDENTIALS , logonType="10", XDM_CONST.LOGON_TYPE_REMOTE_INTERACTIVE , logonType="11", XDM_CONST.LOGON_TYPE_CACHED_INTERACTIVE, logonType="12", XDM_CONST.LOGON_TYPE_CACHED_REMOTE_INTERACTIVE , logonType="13", XDM_CONST.LOGON_TYPE_CACHED_UNLOCK, logonType), + xdm.network.rule = coalesce(check_rule_name1, check_rule_name2, threat_id), + xdm.observer.action = action, + xdm.observer.type = provider_name, + xdm.observer.unique_identifier = provider_guid, + xdm.observer.version = product_version, + xdm.session_context_id = to_string(record_id), + xdm.source.agent.type = coalesce(defender_security_intelligence_type, detection_source), + xdm.source.agent.version = defender_engine_version, + xdm.source.agent.content_version = coalesce(defender_signature_version, defender_security_intelligence_version), + xdm.source.application.name = coalesce(if(channel="System", event_data_param1), arrayindex(regextract(message, "HostApplication=([\S]+)"), 0), product_name), + xdm.source.application.version = product_version, + xdm.target.user.ou = if(event_id_string in ("4728","4729"), arrayindex(regextract(message, "Member:\n*.*?\n*\s*Account\s+Name:\s*(.*)"), 0)), + xdm.target.identity.ou = if(event_id_string in ("4728","4729"), arrayindex(regextract(message, "Member:\n*.*?\n*\s*Account\s+Name:\s*(.*)"), 0)), + xdm.source.host.fqdn = coalesce(event_data -> FQDN, event_data -> WorkstationName), + xdm.source.host.hostname = coalesce(host_name, computer_name, if(user_name contains "*$", user_name), if(channel="System", event_data -> HostName), if(channel="Application" and check_task_string = "Devices", event_data_param1)), + xdm.source.host.os = os_subtype, + xdm.source.host.os_family = XDM_CONST.OS_FAMILY_WINDOWS, + xdm.source.ipv4 = if(IpAddress ~= "(?:\d{1,3}\.){3}\d{1,3}", arrayindex(regextract(IpAddress, "((?:\d{1,3}\.){3}\d{1,3})"), 0)), + xdm.source.ipv6 = if(IpAddress ~= "(?:[a-fA-F\d]{0,4}\:){7}[\wa-fA-F]{0,4}", arrayindex(regextract(IpAddress, "((?:[a-fA-F\d]{0,4}\:){7}[\wa-fA-F]{0,4})"), 0),if(Ipv6Address != null,Ipv6Address)), + xdm.source.port = if(IpPort~="\d+", to_integer(IpPort), null), + xdm.source.process.command_line = coalesce(if(check_Command_Name != null and check_Command_Name != "", check_Command_Name), process_cmd, event_data -> CommandLine), + xdm.source.process.executable.directory = arraystring(regextract(message, "Modifying\s*Application:\s+(\S+)"), ""), + xdm.source.process.executable.filename = if(check_Script_Name != null and check_Script_Name != "", check_Script_Name, null), + xdm.source.process.executable.md5 = process_md5, + xdm.source.process.executable.path = coalesce(get_message_instance_exe_path, process_name_format, if(channel="Application", event_data -> Module), if(check_Script_Path != null and check_Script_Path != "", check_Script_Path), if(check_Command_Path != null and check_Command_Path != "", check_Command_Path), process_path, file_path), + xdm.source.process.executable.sha256 = process_sha256, + xdm.source.process.name = coalesce(check_fw_process_name, get_message_instance_exe_process,event_data -> ParentProcessName ,arrayindex(regextract(process_name_format, "\\([^\\]+)$"), 0), if(channel="System", process_name_format), process_name), + xdm.source.process.pid = to_integer(coalesce(check_message_processID, to_string(process_pid), if(channel="System", event_data -> ProcessID))), + xdm.target.process.pid = to_integer(event_data -> NewProcessID), + xdm.source.process.thread_id = to_integer(process_thread_id), + xdm.source.user.domain = user_domain, + xdm.source.identity.domain = user_domain, + xdm.source.user.identifier = user_sid, + xdm.source.identity.identifier = user_sid, + xdm.source.user.user_type = if(user_type contains "User", XDM_CONST.USER_TYPE_REGULAR, user_type contains "Service", XDM_CONST.USER_TYPE_SERVICE_ACCOUNT , user_type contains "Computer", XDM_CONST.USER_TYPE_MACHINE_ACCOUNT , user_type), + xdm.source.identity.user_type = if(user_type contains "User", XDM_CONST.USER_TYPE_REGULAR, user_type contains "Service", XDM_CONST.USER_TYPE_SERVICE_ACCOUNT , user_type contains "Computer", XDM_CONST.USER_TYPE_MACHINE_ACCOUNT , user_type), + xdm.source.user.username = user_name, + xdm.source.identity.username = user_name, + xdm.target.ipv4 = if(DestAddress ~= "(?:\d{1,3}\.){3}\d{1,3}", arrayindex(regextract(DestAddress, "((?:\d{1,3}\.){3}\d{1,3})"), 0)), + xdm.target.file.path = file_path, + xdm.target.port = coalesce(to_integer(event_data -> DestPort) ,to_integer(0)), + xdm.target.resource.id = coalesce(scan_id, SubjectKeyIdentifier), + xdm.target.resource.type = scan_type, + xdm.target.resource_before.value = old_value, + xdm.target.resource.value = coalesce(new_value, scan_params), + xdm.target.user.domain = coalesce(target_domain_name, if(channel="System", dc_name)), + xdm.target.identity.domain = coalesce(target_domain_name, if(channel="System", dc_name)), + xdm.target.user.groups = if(target_username not contains "*$" AND event_type = "Security Group Management", arraycreate(target_username)), + xdm.target.identity.groups = if(target_username not contains "*$" AND event_type = "Security Group Management", arraycreate(target_username)), + xdm.target.user.identifier = target_user_sid, + xdm.target.identity.identifier = target_user_sid, + xdm.logon.package_name = event_data -> AuthenticationPackageName, + xdm.event.operation = if(event_id_num = 4624,"AUTH_LOGIN"), + xdm.logon.is_elevated = if(event_id_num = 4624, if(event_data -> ElevatedToken in ("%%1843", "No"), to_boolean("FALSE"), event_data -> ElevatedToken in ("%%1842","Yes"), to_boolean("TRUE"))), + xdm.logon.is_virtual_account = if(event_id_num = 4624, if(event_data -> VirtualAccount in ("%%1843", "No"), to_boolean("FALSE"), event_data -> VirtualAccount in ("%%1842","Yes"), to_boolean("TRUE"))), + xdm.auth.service = event_data -> LogonProcessName, + xdm.target.process.name = event_data -> NewProcessName, + xdm.logon.is_restricted_admin_mode = if(event_id_num = 4624, if(event_data -> RestrictedAdminMode in ("-", "No"), to_boolean("FALSE"), event_data -> RestrictedAdminMode = "Yes", to_boolean("TRUE"))), + xdm.auth.kerberos_tgt.encryption_type = if(event_id_string in ("4768", "4770"), if(TicketEncryptionType="0x01", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_DES_CBC_CRC, TicketEncryptionType="0x02", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_DES_CBC_MD4, TicketEncryptionType="0x03", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_DES_CBC_MD5, TicketEncryptionType="0x04", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_DES_CBC_RAW, TicketEncryptionType="0x05", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_DES3_CBC_MD5, TicketEncryptionType="0x06", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_DES3_CBC_RAW, TicketEncryptionType="0x07", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_DES3_CBC_SHA1, TicketEncryptionType="0x08", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_DES_HMAC_SHA1, TicketEncryptionType="0x09", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_DSAWITHSHA1_CMSOID, TicketEncryptionType="0x0A", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_MD5WITHRSAENCRYPTION_CMSOID, TicketEncryptionType="0x0B", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_SHA1WITHRSAENCRYPTION_CMSOID, TicketEncryptionType="0x0C", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_RC2CBC_ENVOID, TicketEncryptionType="0x0D", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_RSAENCRYPTION_ENVOID, TicketEncryptionType="0x0E", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_RSAES_OAEP_ENV_OID, TicketEncryptionType="0x0F", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_DES_EDE3_CBC_ENV_OID, TicketEncryptionType="0x10", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_DES3_CBC_SHA1_KD, TicketEncryptionType="0x11", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_AES128_CTS_HMAC_SHA1_96, TicketEncryptionType="0x12", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_AES256_CTS_HMAC_SHA1_96, TicketEncryptionType="0x13", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_AES128_CTS_HMAC_SHA256_128, TicketEncryptionType="0x14", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_AES256_CTS_HMAC_SHA384_192, TicketEncryptionType="0x17", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_RC4_HMAC, TicketEncryptionType="0x18", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_RC4_HMAC_EXP, TicketEncryptionType="0x19", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_CAMELLIA128_CTS_CMAC, TicketEncryptionType="0x1A", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_CAMELLIA256_CTS_CMAC, TicketEncryptionType="0x41", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_SUBKEY_KEYMATERIAL, TicketEncryptionType)), + xdm.auth.kerberos_tgs.encryption_type = if(event_id_string in ("4769","4771", "4772"), if(TicketEncryptionType="0x01", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_DES_CBC_CRC, TicketEncryptionType="0x02", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_DES_CBC_MD4, TicketEncryptionType="0x03", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_DES_CBC_MD5, TicketEncryptionType="0x04", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_DES_CBC_RAW, TicketEncryptionType="0x05", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_DES3_CBC_MD5, TicketEncryptionType="0x06", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_DES3_CBC_RAW, TicketEncryptionType="0x07", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_DES3_CBC_SHA1, TicketEncryptionType="0x08", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_DES_HMAC_SHA1, TicketEncryptionType="0x09", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_DSAWITHSHA1_CMSOID, TicketEncryptionType="0x0A", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_MD5WITHRSAENCRYPTION_CMSOID, TicketEncryptionType="0x0B", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_SHA1WITHRSAENCRYPTION_CMSOID, TicketEncryptionType="0x0C", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_RC2CBC_ENVOID, TicketEncryptionType="0x0D", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_RSAENCRYPTION_ENVOID, TicketEncryptionType="0x0E", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_RSAES_OAEP_ENV_OID, TicketEncryptionType="0x0F", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_DES_EDE3_CBC_ENV_OID, TicketEncryptionType="0x10", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_DES3_CBC_SHA1_KD, TicketEncryptionType="0x11", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_AES128_CTS_HMAC_SHA1_96, TicketEncryptionType="0x12", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_AES256_CTS_HMAC_SHA1_96, TicketEncryptionType="0x13", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_AES128_CTS_HMAC_SHA256_128, TicketEncryptionType="0x14", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_AES256_CTS_HMAC_SHA384_192, TicketEncryptionType="0x17", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_RC4_HMAC, TicketEncryptionType="0x18", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_RC4_HMAC_EXP, TicketEncryptionType="0x19", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_CAMELLIA128_CTS_CMAC, TicketEncryptionType="0x1A", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_CAMELLIA256_CTS_CMAC, TicketEncryptionType="0x41", XDM_CONST.KERBEROS_ENCRYPTION_TYPE_SUBKEY_KEYMATERIAL, TicketEncryptionType)), + xdm.auth.kerberos_tgt.error_code = if(event_id_string in ("4768", "4770"), if(failure_code="0x0", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_NONE, failure_code="0x1", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_NAME_EXP, failure_code="0x2", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_SERVICE_EXP, failure_code="0x3", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_BAD_PVNO, failure_code="0x4", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_C_OLD_MAST_KVNO, failure_code="0x5", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_S_OLD_MAST_KVNO, failure_code="0x6", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_C_PRINCIPAL_UNKNOWN, failure_code="0x7", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_S_PRINCIPAL_UNKNOWN, failure_code="0x8", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_PRINCIPAL_NOT_UNIQUE, failure_code="0x9", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_NULL_KEY, failure_code="0xA", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_CANNOT_POSTDATE, failure_code="0xB", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_NEVER_VALID, failure_code="0xC", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_POLICY, failure_code="0xD", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_BADOPTION, failure_code="0xE", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_ETYPE_NOSUPP, failure_code="0xF", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_SUMTYPE_NOSUPP, failure_code="0x10", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_PADATA_TYPE_NOSUPP, failure_code="0x11", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_TRTYPE_NOSUPP, failure_code="0x12", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_CLIENT_REVOKED, failure_code="0x13", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_SERVICE_REVOKED, failure_code="0x14", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_TGT_REVOKED, failure_code="0x15", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_CLIENT_NOTYET, failure_code="0x16", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_SERVICE_NOTYET, failure_code="0x17", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_KEY_EXPIRED, failure_code="0x18", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_PREAUTH_FAILED, failure_code="0x19", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_PREAUTH_REQUIRED, failure_code="0x1A", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_SERVER_NOMATCH, failure_code="0x1B", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_MUST_USE_USER2USER, failure_code="0x1C", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_PATH_NOT_ACCEPTED, failure_code="0x1D", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_SVC_UNAVAILABLE, failure_code="0x1F", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_BAD_INTEGRITY, failure_code="0x20", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_TKT_EXPIRED, failure_code="0x21", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_TKT_NYV, failure_code="0x22", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_REPEAT, failure_code="0x23", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_NOT_US, failure_code="0x24", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_BADMATCH, failure_code="0x25", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_SKEW, failure_code="0x26", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_BADADDR, failure_code="0x27", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_BADVERSION, failure_code="0x28", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_MSG_TYPE, failure_code="0x29", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_MODIFIED, failure_code="0x2A", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_BADORDER, failure_code="0x2C", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_BADKEYVER, failure_code="0x2D", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_NOKEY, failure_code="0x2E", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_MUT_FAIL, failure_code="0x2F", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_BADDIRECTION, failure_code="0x30", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_METHOD, failure_code="0x31", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_BADSEQ, failure_code="0x32", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_INAPP_CKSUM, failure_code="0x33", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_PATH_NOT_ACCEPTED, failure_code="0x34", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_RESPONSE_TOO_BIG, failure_code="0x3C", XDM_CONST.KERBEROS_ERROR_CODE_ERR_GENERIC, failure_code="0x3D", XDM_CONST.KERBEROS_ERROR_CODE_ERR_FIELD_TOOLONG, failure_code="0x3E", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC__CLIENT_NOT_TRUSTED, failure_code="0x3F", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC__KDC_NOT_TRUSTED, failure_code="0x40", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC__INVALID_SIG, failure_code="0x41", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_KEY_TOO_WEAK, failure_code="0x42", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_CERTIFICATE_MISMATCH, failure_code="0x43", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_NO_TGT, failure_code="0x44", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_WRONG_REALM, failure_code="0x45", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_USER_TO_USER_REQUIRED, failure_code="0x46", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_CANT_VERIFY_CERTIFICATE, failure_code="0x47", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_INVALID_CERTIFICATE, failure_code="0x48", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_REVOKED_CERTIFICATE, failure_code="0x49", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_REVOCATION_STATUS_UNKNOWN, failure_code="0x4A", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_REVOCATION_STATUS_UNAVAILABLE, failure_code="0x4B", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_CLIENT_NAME_MISMATCH, failure_code="0x4C", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_KDC_NAME_MISMATCH, to_string(failure_code))), + xdm.auth.kerberos_tgs.error_code = if(event_id_string in ("4769", "4771", "4772"), if(failure_code="0x0", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_NONE, failure_code="0x1", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_NAME_EXP, failure_code="0x2", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_SERVICE_EXP, failure_code="0x3", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_BAD_PVNO, failure_code="0x4", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_C_OLD_MAST_KVNO, failure_code="0x5", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_S_OLD_MAST_KVNO, failure_code="0x6", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_C_PRINCIPAL_UNKNOWN, failure_code="0x7", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_S_PRINCIPAL_UNKNOWN, failure_code="0x8", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_PRINCIPAL_NOT_UNIQUE, failure_code="0x9", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_NULL_KEY, failure_code="0xA", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_CANNOT_POSTDATE, failure_code="0xB", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_NEVER_VALID, failure_code="0xC", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_POLICY, failure_code="0xD", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_BADOPTION, failure_code="0xE", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_ETYPE_NOSUPP, failure_code="0xF", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_SUMTYPE_NOSUPP, failure_code="0x10", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_PADATA_TYPE_NOSUPP, failure_code="0x11", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_TRTYPE_NOSUPP, failure_code="0x12", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_CLIENT_REVOKED, failure_code="0x13", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_SERVICE_REVOKED, failure_code="0x14", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_TGT_REVOKED, failure_code="0x15", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_CLIENT_NOTYET, failure_code="0x16", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_SERVICE_NOTYET, failure_code="0x17", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_KEY_EXPIRED, failure_code="0x18", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_PREAUTH_FAILED, failure_code="0x19", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_PREAUTH_REQUIRED, failure_code="0x1A", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_SERVER_NOMATCH, failure_code="0x1B", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_MUST_USE_USER2USER, failure_code="0x1C", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_PATH_NOT_ACCEPTED, failure_code="0x1D", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_SVC_UNAVAILABLE, failure_code="0x1F", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_BAD_INTEGRITY, failure_code="0x20", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_TKT_EXPIRED, failure_code="0x21", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_TKT_NYV, failure_code="0x22", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_REPEAT, failure_code="0x23", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_NOT_US, failure_code="0x24", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_BADMATCH, failure_code="0x25", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_SKEW, failure_code="0x26", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_BADADDR, failure_code="0x27", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_BADVERSION, failure_code="0x28", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_MSG_TYPE, failure_code="0x29", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_MODIFIED, failure_code="0x2A", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_BADORDER, failure_code="0x2C", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_BADKEYVER, failure_code="0x2D", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_NOKEY, failure_code="0x2E", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_MUT_FAIL, failure_code="0x2F", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_BADDIRECTION, failure_code="0x30", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_METHOD, failure_code="0x31", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_BADSEQ, failure_code="0x32", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_INAPP_CKSUM, failure_code="0x33", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_PATH_NOT_ACCEPTED, failure_code="0x34", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_RESPONSE_TOO_BIG, failure_code="0x3C", XDM_CONST.KERBEROS_ERROR_CODE_ERR_GENERIC, failure_code="0x3D", XDM_CONST.KERBEROS_ERROR_CODE_ERR_FIELD_TOOLONG, failure_code="0x3E", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC__CLIENT_NOT_TRUSTED, failure_code="0x3F", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC__KDC_NOT_TRUSTED, failure_code="0x40", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC__INVALID_SIG, failure_code="0x41", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_KEY_TOO_WEAK, failure_code="0x42", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_CERTIFICATE_MISMATCH, failure_code="0x43", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_NO_TGT, failure_code="0x44", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_WRONG_REALM, failure_code="0x45", XDM_CONST.KERBEROS_ERROR_CODE_ERR_AP_USER_TO_USER_REQUIRED, failure_code="0x46", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_CANT_VERIFY_CERTIFICATE, failure_code="0x47", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_INVALID_CERTIFICATE, failure_code="0x48", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_REVOKED_CERTIFICATE, failure_code="0x49", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_REVOCATION_STATUS_UNKNOWN, failure_code="0x4A", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_REVOCATION_STATUS_UNAVAILABLE, failure_code="0x4B", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_CLIENT_NAME_MISMATCH, failure_code="0x4C", XDM_CONST.KERBEROS_ERROR_CODE_ERR_KDC_KDC_NAME_MISMATCH, to_string(failure_code))), + xdm.target.user.username = coalesce(if(target_username not contains "*$" AND event_type != "Security Group Management", target_username), if(event_id_string in ("4886", "4887", "4888","4897","4898"), event_data -> Subject)), xdm.target.identity.username = coalesce(if(target_username not contains "*$" AND event_type != "Security Group Management", target_username), if(event_id_string in ("4886", "4887", "4888","4897","4898"), event_data -> Subject)); \ No newline at end of file diff --git a/Packs/MicrosoftWindowsEvents/ModelingRules/MicrosoftWindowsEvents_2_11/MicrosoftWindowsEvents_2_11.yml b/Packs/MicrosoftWindowsEvents/ModelingRules/MicrosoftWindowsEvents_2_11/MicrosoftWindowsEvents_2_11.yml new file mode 100644 index 000000000000..9ce2bacb9820 --- /dev/null +++ b/Packs/MicrosoftWindowsEvents/ModelingRules/MicrosoftWindowsEvents_2_11/MicrosoftWindowsEvents_2_11.yml @@ -0,0 +1,7 @@ +fromversion: 8.15.0 +id: MicrosoftWindowsEvents +name: MicrosoftWindowsEvents +rules: '' +schema: '' +supportedModules: +- xsiam diff --git a/Packs/MicrosoftWindowsEvents/ModelingRules/MicrosoftWindowsEvents_2_11/MicrosoftWindowsEvents_2_11_schema.json b/Packs/MicrosoftWindowsEvents/ModelingRules/MicrosoftWindowsEvents_2_11/MicrosoftWindowsEvents_2_11_schema.json new file mode 100644 index 000000000000..022715a9ec7d --- /dev/null +++ b/Packs/MicrosoftWindowsEvents/ModelingRules/MicrosoftWindowsEvents_2_11/MicrosoftWindowsEvents_2_11_schema.json @@ -0,0 +1,116 @@ +{ + "microsoft_windows_raw": { + "event_data": { + "type": "string", + "is_array": false + }, + "event_action": { + "type": "string", + "is_array": false + }, + "user_data": { + "type": "string", + "is_array": false + }, + "user": { + "type": "string", + "is_array": false + }, + "host_name": { + "type": "string", + "is_array": false + }, + "computer_name": { + "type": "string", + "is_array": false + }, + "channel": { + "type": "string", + "is_array": false + }, + "event_id": { + "type": "string", + "is_array": false + }, + "provider_name": { + "type": "string", + "is_array": false + }, + "opcode": { + "type": "string", + "is_array": false + }, + "log_level": { + "type": "string", + "is_array": false + }, + "event_result": { + "type": "string", + "is_array": false + }, + "message": { + "type": "string", + "is_array": false + }, + "activity_id": { + "type": "string", + "is_array": false + }, + "process_pid": { + "type": "string", + "is_array": false + }, + "process_thread_id": { + "type": "string", + "is_array": false + }, + "record_id": { + "type": "string", + "is_array": false + }, + "os_subtype": { + "type": "string", + "is_array": false + }, + "process_cmd": { + "type": "string", + "is_array": false + }, + "process_md5": { + "type": "string", + "is_array": false + }, + "process_name": { + "type": "string", + "is_array": false + }, + "process_path": { + "type": "string", + "is_array": false + }, + "process_sha256": { + "type": "string", + "is_array": false + }, + "task": { + "type": "int", + "is_array": false + }, + "event_fwlink": { + "type": "string", + "is_array": false + }, + "detection_source": { + "type": "string", + "is_array": false + }, + "threat_category": { + "type": "string", + "is_array": false + }, + "provider_guid": { + "type": "string", + "is_array": false + } + } +} \ No newline at end of file diff --git a/Packs/MicrosoftWindowsEvents/ReleaseNotes/1_1_33.md b/Packs/MicrosoftWindowsEvents/ReleaseNotes/1_1_33.md new file mode 100644 index 000000000000..866295e823a9 --- /dev/null +++ b/Packs/MicrosoftWindowsEvents/ReleaseNotes/1_1_33.md @@ -0,0 +1,7 @@ + +#### Modeling Rules + +##### New: MicrosoftWindowsEvents + +- New: Added a new modeling rule version that maps the `xdm.*.identity.*` fields alongside the existing `xdm.*.user.*` fields. +<~XSIAM> (Available from Cortex XSIAM 2.11). diff --git a/Packs/MicrosoftWindowsEvents/pack_metadata.json b/Packs/MicrosoftWindowsEvents/pack_metadata.json index 4a6b971587ae..a1622c0f1a72 100644 --- a/Packs/MicrosoftWindowsEvents/pack_metadata.json +++ b/Packs/MicrosoftWindowsEvents/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Microsoft Windows Event Logs", "description": "The Windows event log is a detailed record of system, security and application notifications stored by the Windows operating system.", "support": "xsoar", - "currentVersion": "1.1.32", + "currentVersion": "1.1.33", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/ProofpointCasb/ModelingRules/ProofpointCasb/ProofpointCasb.yml b/Packs/ProofpointCasb/ModelingRules/ProofpointCasb/ProofpointCasb.yml index f7c3c432acb9..1375a964d3d0 100644 --- a/Packs/ProofpointCasb/ModelingRules/ProofpointCasb/ProofpointCasb.yml +++ b/Packs/ProofpointCasb/ModelingRules/ProofpointCasb/ProofpointCasb.yml @@ -1,4 +1,5 @@ fromversion: 8.2.0 +toversion: 8.14.0 id: ProofpointCASB_ModelingRule name: ProofpointCASB Modeling Rule rules: '' diff --git a/Packs/ProofpointCasb/ModelingRules/ProofpointCasb_2_11/ProofpointCasb_2_11.xif b/Packs/ProofpointCasb/ModelingRules/ProofpointCasb_2_11/ProofpointCasb_2_11.xif new file mode 100644 index 000000000000..8a5aa5668ab3 --- /dev/null +++ b/Packs/ProofpointCasb/ModelingRules/ProofpointCasb_2_11/ProofpointCasb_2_11.xif @@ -0,0 +1,44 @@ +[MODEL: dataset = proofpoint_casb_raw] + alter os = lowercase(event -> remote.client.device.os.name), + email = event -> user.email, + owner = event -> resources[0].owner.user.name, + last_modified = to_string(event -> resources[0].modifiedAt), + src_ipv4 = if(event -> remote.client.ip ~= "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", event -> remote.client.ip, null), + src_ipv6 = if(event -> remote.client.ip ~= "[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}", event -> remote.client.ip, null) +| alter xdm.source.location.country = event -> remote.client.geo.address.country.name, + xdm.source.location.latitude = to_float(event -> remote.client.geo.coordinates.lat), + xdm.source.location.longitude = to_float(event -> remote.client.geo.coordinates.lon), + xdm.source.location.region = event -> remote.client.geo.address.area1.name, + xdm.source.location.city = event -> remote.client.geo.address.area2.name, + xdm.source.ipv4 = src_ipv4, + xdm.source.ipv6 = src_ipv6, + xdm.source.host.os = os, + xdm.source.host.os_family = if(os contains "windows", XDM_CONST.OS_FAMILY_WINDOWS, os contains "mac", XDM_CONST.OS_FAMILY_MACOS, os contains "linux", XDM_CONST.OS_FAMILY_LINUX, os contains "android", XDM_CONST.OS_FAMILY_ANDROID, os contains "ios", XDM_CONST.OS_FAMILY_IOS, os contains "ubuntu", XDM_CONST.OS_FAMILY_UBUNTU, os contains "debian", XDM_CONST.OS_FAMILY_DEBIAN, os contains "fedora", XDM_CONST.OS_FAMILY_FEDORA, os contains "centos", XDM_CONST.OS_FAMILY_CENTOS, os contains "chrome", XDM_CONST.OS_FAMILY_CHROMEOS, os contains "solaris", XDM_CONST.OS_FAMILY_SOLARIS, os contains "scada", XDM_CONST.OS_FAMILY_SCADA, null), + xdm.alert.subcategory = event -> activity.primaryCategory, + xdm.target.file.size = to_integer(event -> activity.stats.size), + xdm.observer.content_version = event -> rver, + xdm.network.rule = event -> incident.reasons[0].name, + xdm.source.asn.isp = event -> remote.host.ip.isp.name, + xdm.source.user_agent = event -> remote.client.agent.description, + xdm.event.id = event -> id, + xdm.target.file.path = event -> resources[0].path, + xdm.target.file.extension = event -> resources[0].extension, + xdm.target.file.file_type = event -> resources[0].kind, + xdm.target.file.filename = event -> resources[0].name, + xdm.target.file.directory = arrayindex(regextract(event -> resources[0].path, "^(.+?)\/[^\/]+$"), 0), + xdm.source.user.first_name = event -> user.firstName, + xdm.source.identity.first_name = event -> user.firstName, + xdm.source.user.last_name = event -> user.lastName, + xdm.source.identity.last_name = event -> user.lastName, + xdm.source.user.username = event -> user.name, + xdm.source.identity.username = event -> user.name, + xdm.source.user.groups = event -> user.groups[], + xdm.source.identity.groups = event -> user.groups[], + xdm.source.user.identifier = event -> user.id, + xdm.source.identity.identifier = event -> user.id, + xdm.alert.severity = event -> incident.severity, + xdm.observer.type = event -> feed.kind, + xdm.observer.name = event -> feed.data.source.kind, + xdm.network.application_protocol = event -> remote.protocol, + xdm.event.description = object_create("user.email",email,"file.owner:",owner,"file.last.modified",last_modified), + xdm.target.url = event -> resources[0].url; diff --git a/Packs/ProofpointCasb/ModelingRules/ProofpointCasb_2_11/ProofpointCasb_2_11.yml b/Packs/ProofpointCasb/ModelingRules/ProofpointCasb_2_11/ProofpointCasb_2_11.yml new file mode 100644 index 000000000000..82cf8881389d --- /dev/null +++ b/Packs/ProofpointCasb/ModelingRules/ProofpointCasb_2_11/ProofpointCasb_2_11.yml @@ -0,0 +1,7 @@ +fromversion: 8.15.0 +id: ProofpointCASB_ModelingRule +name: ProofpointCASB Modeling Rule +rules: '' +schema: '' +supportedModules: +- xsiam diff --git a/Packs/ProofpointCasb/ModelingRules/ProofpointCasb_2_11/ProofpointCasb_2_11_schema.json b/Packs/ProofpointCasb/ModelingRules/ProofpointCasb_2_11/ProofpointCasb_2_11_schema.json new file mode 100644 index 000000000000..77652bc7220c --- /dev/null +++ b/Packs/ProofpointCasb/ModelingRules/ProofpointCasb_2_11/ProofpointCasb_2_11_schema.json @@ -0,0 +1,10 @@ +{ + "proofpoint_casb_raw": { + "event": { + "type": "string", + "is_array": false + } + } + } + + diff --git a/Packs/ProofpointCasb/ReleaseNotes/1_0_9.md b/Packs/ProofpointCasb/ReleaseNotes/1_0_9.md new file mode 100644 index 000000000000..bb90ec060826 --- /dev/null +++ b/Packs/ProofpointCasb/ReleaseNotes/1_0_9.md @@ -0,0 +1,7 @@ + +#### Modeling Rules + +##### New: ProofpointCASB Modeling Rule + +- New: Added a new modeling rule version that maps the `xdm.*.identity.*` fields alongside the existing `xdm.*.user.*` fields. +<~XSIAM> (Available from Cortex XSIAM 2.11). diff --git a/Packs/ProofpointCasb/pack_metadata.json b/Packs/ProofpointCasb/pack_metadata.json index 7eeb58d47493..3c35f0b0ebb4 100644 --- a/Packs/ProofpointCasb/pack_metadata.json +++ b/Packs/ProofpointCasb/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Proofpoint CASB", "description": "Parsing and modeling rules for Proofpoint CASB logs", "support": "xsoar", - "currentVersion": "1.0.8", + "currentVersion": "1.0.9", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From b00a8edbe872759eecb10dfeb155ffa6c3f70858 Mon Sep 17 00:00:00 2001 From: israelpoli <72099621+israelpoli@users.noreply.github.com> Date: Tue, 18 Aug 2026 15:28:20 +0300 Subject: [PATCH 009/419] Bump GuardiCore and Silverfort packs (#45564) * Bump GuardiCore and Silverfort packs * Apply suggestion from @marketplace-ai-reviewer Co-authored-by: Marketplace AI reviewer * Apply suggestion from @marketplace-ai-reviewer Co-authored-by: Marketplace AI reviewer --------- Co-authored-by: rshunim <102469772+rshunim@users.noreply.github.com> Co-authored-by: Marketplace AI reviewer --- Packs/GuardiCore/ReleaseNotes/2_0_25.md | 3 +++ Packs/GuardiCore/pack_metadata.json | 2 +- Packs/Silverfort/ReleaseNotes/2_0_40.md | 3 +++ Packs/Silverfort/pack_metadata.json | 2 +- 4 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 Packs/GuardiCore/ReleaseNotes/2_0_25.md create mode 100644 Packs/Silverfort/ReleaseNotes/2_0_40.md diff --git a/Packs/GuardiCore/ReleaseNotes/2_0_25.md b/Packs/GuardiCore/ReleaseNotes/2_0_25.md new file mode 100644 index 000000000000..be4ff90021f7 --- /dev/null +++ b/Packs/GuardiCore/ReleaseNotes/2_0_25.md @@ -0,0 +1,3 @@ +## Akamai GuardiCore + +- Documentation and metadata improvements. diff --git a/Packs/GuardiCore/pack_metadata.json b/Packs/GuardiCore/pack_metadata.json index f41430b80759..351e5f854bd0 100644 --- a/Packs/GuardiCore/pack_metadata.json +++ b/Packs/GuardiCore/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Akamai GuardiCore", "description": "Data center breach detection", "support": "xsoar", - "currentVersion": "2.0.24", + "currentVersion": "2.0.25", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/Silverfort/ReleaseNotes/2_0_40.md b/Packs/Silverfort/ReleaseNotes/2_0_40.md new file mode 100644 index 000000000000..d086fcd19561 --- /dev/null +++ b/Packs/Silverfort/ReleaseNotes/2_0_40.md @@ -0,0 +1,3 @@ +## Silverfort + +- Documentation and metadata improvements. diff --git a/Packs/Silverfort/pack_metadata.json b/Packs/Silverfort/pack_metadata.json index bca345aa8b35..e3ad3de7869d 100644 --- a/Packs/Silverfort/pack_metadata.json +++ b/Packs/Silverfort/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Silverfort", "description": "Silverfort protects organizations from data breaches by delivering strong authentication across entire corporate networks and cloud environments, without requiring any modifications to endpoints or servers. Using patent-pending technology, Silverfort's agentless approach enables multi-factor authentication and AI-driven adaptive authentication even for systems that don’t support it today, including proprietary systems, critical infrastructure, shared folders, IoT devices, and more. Use Silverfort integration to get & update Silverfort risk severity. This integration was integrated and tested with Silverfort version 2.12.", "support": "partner", - "currentVersion": "2.0.39", + "currentVersion": "2.0.40", "author": "Silverfort", "url": "https://support.silverfort.com/", "email": "ecosystem@silverfort.com", From 78a10b1afa89ef55c1c1d883c07f55259bcd03d7 Mon Sep 17 00:00:00 2001 From: Yael Shamai <111040837+YaelShamai@users.noreply.github.com> Date: Tue, 18 Aug 2026 15:42:07 +0300 Subject: [PATCH 010/419] Atlasian Confluence new Oauth Authentication, new v2 commands and v1 commands deprecation. (#45378) * first version * more * more * add request logs * remove debug * deprecate commands * Bump pack from version AtlassianConfluenceCloud to 1.2.0. * api module rn * rn * improve testing * update readme * cr fixes * cr fixes * pre commit * update readme * pre commit * revert cyberArk changes --------- Co-authored-by: Content Bot --- Packs/ApiModules/ReleaseNotes/2_4_41.md | 7 + .../AtlassianApiModule/AtlassianApiModule.py | 37 +- .../AtlassianApiModule_test.py | 64 +- Packs/ApiModules/pack_metadata.json | 2 +- .../AtlassianConfluenceCloud/.secrets-ignore | 3 +- .../AtlassianConfluenceCloud.py | 909 ++++++++++++++ .../AtlassianConfluenceCloud.yml | 576 ++++++++- .../AtlassianConfluenceCloud_description.md | 30 +- .../AtlassianConfluenceCloud_test.py | 481 ++++++++ .../AtlassianConfluenceCloud/README.md | 1055 +++++++++++------ .../command_examples.txt | 11 + ...ontent_create_required_argument_error.json | 32 +- ...tent_delete_command_bad_request_error.json | 32 +- ...content_search_invalid_query_argument.json | 18 +- .../footer_comment_create_command.md | 4 + ...footer_comment_create_command_context.json | 14 + ...ooter_comment_create_command_response.json | 14 + .../test_data/input_data.py | 48 + .../page_create/page_create_command.md | 4 + .../page_create_command_context.json | 16 + .../page_create_command_response.json | 17 + .../test_data/page_list/page_list_command.md | 5 + .../page_list/page_list_command_context.json | 24 + .../page_list/page_list_command_response.json | 29 + .../space_create_v2_command.md | 4 + .../space_create_v2_command_context.json | 7 + .../space_create_v2_command_response.json | 7 + .../space_list_v2/space_list_v2_command.md | 5 + .../space_list_v2_command_context.json | 16 + .../space_list_v2_command_response.json | 18 + .../ReleaseNotes/1_2_0.md | 25 + .../pack_metadata.json | 4 +- 32 files changed, 3066 insertions(+), 452 deletions(-) create mode 100644 Packs/ApiModules/ReleaseNotes/2_4_41.md create mode 100644 Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/command_examples.txt create mode 100644 Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/footer_comment_create/footer_comment_create_command.md create mode 100644 Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/footer_comment_create/footer_comment_create_command_context.json create mode 100644 Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/footer_comment_create/footer_comment_create_command_response.json create mode 100644 Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/page_create/page_create_command.md create mode 100644 Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/page_create/page_create_command_context.json create mode 100644 Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/page_create/page_create_command_response.json create mode 100644 Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/page_list/page_list_command.md create mode 100644 Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/page_list/page_list_command_context.json create mode 100644 Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/page_list/page_list_command_response.json create mode 100644 Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/space_create_v2/space_create_v2_command.md create mode 100644 Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/space_create_v2/space_create_v2_command_context.json create mode 100644 Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/space_create_v2/space_create_v2_command_response.json create mode 100644 Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/space_list_v2/space_list_v2_command.md create mode 100644 Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/space_list_v2/space_list_v2_command_context.json create mode 100644 Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/space_list_v2/space_list_v2_command_response.json create mode 100644 Packs/AtlassianConfluenceCloud/ReleaseNotes/1_2_0.md diff --git a/Packs/ApiModules/ReleaseNotes/2_4_41.md b/Packs/ApiModules/ReleaseNotes/2_4_41.md new file mode 100644 index 000000000000..acaee2cc9e61 --- /dev/null +++ b/Packs/ApiModules/ReleaseNotes/2_4_41.md @@ -0,0 +1,7 @@ + +#### Scripts + +##### AtlassianApiModule + +- Added support for the OAuth authentication method. +- Added support for new v2 commands. diff --git a/Packs/ApiModules/Scripts/AtlassianApiModule/AtlassianApiModule.py b/Packs/ApiModules/Scripts/AtlassianApiModule/AtlassianApiModule.py index b43301ac07bd..c74287ce8586 100644 --- a/Packs/ApiModules/Scripts/AtlassianApiModule/AtlassianApiModule.py +++ b/Packs/ApiModules/Scripts/AtlassianApiModule/AtlassianApiModule.py @@ -238,17 +238,42 @@ def get_oauth_scopes(self) -> list[str]: """ Return the OAuth scopes required for Confluence Cloud. + This is the full granular scope set required to authorize both the v2 + page/blogpost/space/comment commands and the retained v1 search/user/group/audit + commands with a single access token. Granular scopes must not be mixed with + classic scopes in the same authorize request. + Returns: List of required OAuth scopes """ return [ + "read:content:confluence", + "write:content:confluence", + "read:content-details:confluence", + "read:space-details:confluence", + "delete:content:confluence", "read:audit-log:confluence", - "read:confluence-content.all", - "read:confluence-space.summary", - "read:confluence-user", - "read:confluence-groups", - "write:confluence-content", - "write:confluence-space", + "read:page:confluence", + "write:page:confluence", + "delete:page:confluence", + "read:blogpost:confluence", + "write:blogpost:confluence", + "delete:blogpost:confluence", + "read:custom-content:confluence", + "write:custom-content:confluence", + "delete:custom-content:confluence", + "read:comment:confluence", + "write:comment:confluence", + "delete:comment:confluence", + "read:template:confluence", + "write:template:confluence", + "read:label:confluence", + "write:label:confluence", + "read:watcher:confluence", + "read:space:confluence", + "write:space:confluence", + "delete:space:confluence", + "read:group:confluence", "offline_access", # For refresh token ] diff --git a/Packs/ApiModules/Scripts/AtlassianApiModule/AtlassianApiModule_test.py b/Packs/ApiModules/Scripts/AtlassianApiModule/AtlassianApiModule_test.py index 9c4cda3342be..8d96e47e4a15 100644 --- a/Packs/ApiModules/Scripts/AtlassianApiModule/AtlassianApiModule_test.py +++ b/Packs/ApiModules/Scripts/AtlassianApiModule/AtlassianApiModule_test.py @@ -250,14 +250,66 @@ def oauth_client(self): def test_get_oauth_scopes(self, oauth_client): """Test that correct Confluence OAuth scopes are returned.""" scopes = oauth_client.get_oauth_scopes() + assert "read:content:confluence" in scopes + assert "write:content:confluence" in scopes + assert "read:content-details:confluence" in scopes + assert "read:space-details:confluence" in scopes + assert "delete:content:confluence" in scopes assert "read:audit-log:confluence" in scopes - assert "read:confluence-content.all" in scopes - assert "read:confluence-space.summary" in scopes - assert "read:confluence-user" in scopes - assert "read:confluence-groups" in scopes - assert "write:confluence-content" in scopes - assert "write:confluence-space" in scopes + assert "read:page:confluence" in scopes + assert "write:page:confluence" in scopes + assert "delete:page:confluence" in scopes + assert "read:blogpost:confluence" in scopes + assert "write:blogpost:confluence" in scopes + assert "delete:blogpost:confluence" in scopes + assert "read:custom-content:confluence" in scopes + assert "write:custom-content:confluence" in scopes + assert "delete:custom-content:confluence" in scopes + assert "read:comment:confluence" in scopes + assert "write:comment:confluence" in scopes + assert "delete:comment:confluence" in scopes + assert "read:template:confluence" in scopes + assert "write:template:confluence" in scopes + assert "read:label:confluence" in scopes + assert "write:label:confluence" in scopes + assert "read:watcher:confluence" in scopes + assert "read:space:confluence" in scopes + assert "write:space:confluence" in scopes + assert "delete:space:confluence" in scopes + assert "read:group:confluence" in scopes assert "offline_access" in scopes + # Guard against future scope drift: assert the exact expected set is returned. + expected_scopes = { + "read:content:confluence", + "write:content:confluence", + "read:content-details:confluence", + "read:space-details:confluence", + "delete:content:confluence", + "read:audit-log:confluence", + "read:page:confluence", + "write:page:confluence", + "delete:page:confluence", + "read:blogpost:confluence", + "write:blogpost:confluence", + "delete:blogpost:confluence", + "read:custom-content:confluence", + "write:custom-content:confluence", + "delete:custom-content:confluence", + "read:comment:confluence", + "write:comment:confluence", + "delete:comment:confluence", + "read:template:confluence", + "write:template:confluence", + "read:label:confluence", + "write:label:confluence", + "read:watcher:confluence", + "read:space:confluence", + "write:space:confluence", + "delete:space:confluence", + "read:group:confluence", + "offline_access", + } + assert set(scopes) == expected_scopes @patch("AtlassianApiModule.get_integration_context") def test_get_access_token_valid(self, mock_get_context, oauth_client): diff --git a/Packs/ApiModules/pack_metadata.json b/Packs/ApiModules/pack_metadata.json index 4c85dad79101..a6357eceb1c8 100644 --- a/Packs/ApiModules/pack_metadata.json +++ b/Packs/ApiModules/pack_metadata.json @@ -2,7 +2,7 @@ "name": "ApiModules", "description": "API Modules", "support": "xsoar", - "currentVersion": "2.4.40", + "currentVersion": "2.4.41", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/AtlassianConfluenceCloud/.secrets-ignore b/Packs/AtlassianConfluenceCloud/.secrets-ignore index d1c54e1dec2f..008a9709d3c6 100644 --- a/Packs/AtlassianConfluenceCloud/.secrets-ignore +++ b/Packs/AtlassianConfluenceCloud/.secrets-ignore @@ -23,4 +23,5 @@ https://xsoar-bd.atlassian.net/wiki https://xsoar-bd.atlassian.net/wiki/rest/api/space/XSOAR https://xsoar-bd.atlassian.net/wiki/rest/api/space/TRIAL https://mysite.atlassian.net -https://auth.atlassian.com \ No newline at end of file +https://auth.atlassian.com +https://your-site.atlassian.net \ No newline at end of file diff --git a/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/AtlassianConfluenceCloud.py b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/AtlassianConfluenceCloud.py index ce6a677baaaf..a63ed94cf02f 100644 --- a/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/AtlassianConfluenceCloud.py +++ b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/AtlassianConfluenceCloud.py @@ -39,6 +39,13 @@ "BASE": "/wiki", "NEXT_LINK_TEMPLATE": "/rest/api/audit/?end_date={}&next=true&limit={}&start={}&startDate={}", } +# Confluence Cloud REST API v2 (/wiki/api/v2) URL suffixes. +URL_SUFFIX_V2 = { + "PAGES": "/wiki/api/v2/pages", + "BLOGPOSTS": "/wiki/api/v2/blogposts", + "SPACES": "/wiki/api/v2/spaces", + "FOOTER_COMMENTS": "/wiki/api/v2/footer-comments", +} MESSAGES = { "REQUIRED_URL_FIELD": "Site Name can not be empty.", @@ -62,6 +69,7 @@ "PERMISSION_FORMAT": "Please provide the permission in the valid JSON format. " "Format accepted - 'operation1:targetType1,operation2:targetType2'", "ADVANCE_PERMISSION_FORMAT": "Please provide the 'advanced_permissions' in the valid JSON format. ", + "INVALID_ROLE_ASSIGNMENTS_V2": "Please provide the 'role_assignments' argument in valid JSON format.", "INVALID_SPACE_STATUS": "Invalid value for status. Status must be one of 'current' or 'archived'.", "INVALID_CONTENT_TYPE_UPDATE_CONTENT": "Invalid value for content type. Content type parameter can be 'page', " "'blogpost', 'comment' or 'attachment'.", @@ -74,6 +82,38 @@ "INVALID_SPACE_KEY": "Space Key cannot be longer than 255 characters and should contain alphanumeric characters only.", "PRIVATE_SPACE_PERMISSION": "Permission can not be granted for a private space.", "MISSING_CONTENT_ID": "Argument 'content_id' is required for this command.", + "INVALID_BODY_REPRESENTATION_V2": "Invalid value for body_representation. Body representation must be one of " + "'storage', 'atlas_doc_format' or 'wiki'.", + "INVALID_COMMENT_BODY_REPRESENTATION_V2": "Invalid value for body_representation. Body representation must be " + "one of 'storage' or 'atlas_doc_format'.", + "INVALID_BODY_FORMAT_V2": "Invalid value for body_format. Body format must be one of 'storage', " + "'atlas_doc_format' or 'view'.", + "INVALID_STATUS_CREATE_V2": "Invalid value for status. Status must be one of 'current' or 'draft'.", + "INVALID_STATUS_UPDATE_V2": "Invalid value for status. Status must be one of 'current' or 'draft'.", + "INVALID_PAGE_STATUS_LIST_V2": "Invalid value for status. Status must be one of 'current', 'archived', " + "'deleted' or 'trashed'.", + "INVALID_PAGE_STATUS_SINGLE_V2": "Invalid value for status. Status must be one of 'current', 'archived', " + "'deleted', 'trashed', 'historical' or 'draft'.", + "INVALID_BLOGPOST_STATUS_LIST_V2": "Invalid value for status. Status must be one of 'current', 'deleted' " "or 'trashed'.", + "INVALID_BLOGPOST_STATUS_SINGLE_V2": "Invalid value for status. Status must be one of 'current', 'deleted', " + "'trashed', 'historical' or 'draft'.", + "INVALID_SUBTYPE_FILTER_V2": "Invalid value for subtype. Subtype must be one of 'page' or 'live'.", + "MUTUALLY_EXCLUSIVE_PARENT_ROOT_LEVEL": "Arguments 'parent_id' and 'root_level' are mutually exclusive.", + "MISSING_COMMENT_CONTAINER_V2": "One of the following arguments is required: 'page_id', 'blogpost_id', " + "'parent_comment_id', 'attachment_id' or 'custom_content_id'.", + "INVALID_SPACE_TYPE_V2": "Invalid value for type. Type must be one of 'global' or 'personal'.", + "INVALID_SPACE_STATUS_V2": "Invalid value for status. Status must be one of 'current' or 'archived'.", + "INVALID_DESCRIPTION_FORMAT_V2": "Invalid value for description_format. Description format must be one of " + "'plain' or 'view'.", + "INVALID_LIMIT_V2": "{} is an invalid value for limit. Limit must be a positive integer (greater than 0).", + "HR_PAGE_CREATE": "Page with ID {} was created successfully.", + "HR_PAGE_UPDATE": "Page with ID {} was updated successfully.", + "HR_PAGE_DELETE": "Page with ID {} was deleted successfully.", + "HR_BLOGPOST_CREATE": "Blog post with ID {} was created successfully.", + "HR_BLOGPOST_UPDATE": "Blog post with ID {} was updated successfully.", + "HR_BLOGPOST_DELETE": "Blog post with ID {} was deleted successfully.", + "HR_FOOTER_COMMENT_CREATE": "Footer comment with ID {} was created successfully.", + "HR_SPACE_CREATE_V2": "Space with ID {} was created successfully.", } OUTPUT_PREFIX = { "GROUP": "ConfluenceCloud.Group", @@ -83,6 +123,8 @@ "SPACE": "ConfluenceCloud.Space", "PAGETOKEN": "ConfluenceCloud.PageToken.Content", "EVENT": "ConfluenceCloud.Event", + "PAGE": "ConfluenceCloud.Page", + "BLOGPOST": "ConfluenceCloud.Blogpost", "FILE_CONTENT": "FileContent", } @@ -113,6 +155,53 @@ ONE_MINUTE_IN_MILL_SECONDS = 60000 ONE_WEEK_IN_MILL_SECONDS = 604800000 _last_run_cache = None + +# --- Confluence Cloud REST API v2 constants --- +LEGAL_BODY_REPRESENTATION_V2 = ["storage", "atlas_doc_format", "wiki"] +LEGAL_COMMENT_BODY_REPRESENTATION_V2 = ["storage", "atlas_doc_format"] +LEGAL_BODY_FORMAT_V2 = ["storage", "atlas_doc_format", "view"] +LEGAL_STATUS_CREATE_V2 = ["current", "draft"] +LEGAL_STATUS_UPDATE_V2 = ["current", "draft"] +LEGAL_PAGE_SUBTYPE_FILTER_V2 = ["page", "live"] +LEGAL_PAGE_LIST_STATUS_V2 = ["current", "archived", "deleted", "trashed"] +LEGAL_PAGE_SINGLE_STATUS_V2 = [*LEGAL_PAGE_LIST_STATUS_V2, "historical", "draft"] +LEGAL_BLOGPOST_LIST_STATUS_V2 = ["current", "deleted", "trashed"] +LEGAL_BLOGPOST_SINGLE_STATUS_V2 = [*LEGAL_BLOGPOST_LIST_STATUS_V2, "historical", "draft"] +LEGAL_SPACE_TYPE_V2 = ["global", "personal"] +LEGAL_SPACE_STATUS_V2 = ["current", "archived"] +LEGAL_DESCRIPTION_FORMAT_V2 = ["plain", "view"] +DEFAULT_LIMIT_V2 = 50 +MIN_LIMIT_V2 = 1 +MAX_LIMIT_V2 = 250 + +# Configuration shared between the page and blogpost v2 commands (they are near-identical +# typed resources split from the polymorphic v1 'content' object). +CONTENT_V2_CONFIG: dict[str, dict[str, Any]] = { + "page": { + "url_suffix": URL_SUFFIX_V2["PAGES"], + "output_prefix": OUTPUT_PREFIX["PAGE"], + "id_arg": "page_id", + "list_status": LEGAL_PAGE_LIST_STATUS_V2, + "single_status": LEGAL_PAGE_SINGLE_STATUS_V2, + "list_status_message": "INVALID_PAGE_STATUS_LIST_V2", + "single_status_message": "INVALID_PAGE_STATUS_SINGLE_V2", + "supports_subtype_filter": True, + "supports_direct_children": True, + "label": "Page", + }, + "blogpost": { + "url_suffix": URL_SUFFIX_V2["BLOGPOSTS"], + "output_prefix": OUTPUT_PREFIX["BLOGPOST"], + "id_arg": "blogpost_id", + "list_status": LEGAL_BLOGPOST_LIST_STATUS_V2, + "single_status": LEGAL_BLOGPOST_SINGLE_STATUS_V2, + "list_status_message": "INVALID_BLOGPOST_STATUS_LIST_V2", + "single_status_message": "INVALID_BLOGPOST_STATUS_SINGLE_V2", + "supports_subtype_filter": False, + "supports_direct_children": False, + "label": "Blog post", + }, +} """ CLIENT CLASS """ @@ -983,6 +1072,558 @@ def validate_update_content_args(args: dict[str, str]): raise ValueError(MESSAGES["REQUIRED_ARGUMENT"].format("version")) +""" HELPER FUNCTIONS (REST API v2) """ + + +def prepare_cursor_from_link_header(response: requests.Response) -> str: + """ + Extract the pagination cursor from a v2 API response's ``Link`` header. + + The Confluence REST API v2 returns pagination information in the ``Link`` HTTP response + header (RFC 5988), e.g. ``; rel="next"``. + This function parses that header, isolates the URL marked with ``rel="next"`` and returns + the value of the ``cursor`` query parameter. + + :type response: ``requests.Response`` + :param response: The raw API response object. + + :return: Next page cursor (empty string when there is no next page). + :rtype: ``str`` + """ + link_header = response.headers.get("Link", "") + if not link_header: + return "" + + for part in link_header.split(","): + section = part.split(";") + if len(section) < 2: + continue + rel = section[1].strip() + if rel not in ('rel="next"', "rel=next"): + continue + url = section[0].strip().strip("<>") + query = urllib.parse.urlparse(url).query + cursor_values = urllib.parse.parse_qs(query).get("cursor", []) + if cursor_values: + return cursor_values[0] + + return "" + + +def paginate_v2_results( + client: "Client", url_suffix: str, params: dict[str, Any], limit: int +) -> tuple[list[dict[str, Any]], dict[str, Any]]: + """ + Retrieve v2 list results, automatically following the ``Link: rel="next"`` cursor + until ``limit`` records are accumulated or there are no more pages. + + The Confluence REST API v2 caps a single page at ``MAX_LIMIT_V2`` (250) results, so this + helper transparently issues additional requests to satisfy larger ``limit`` values. + + :type client: ``Client`` + :param client: Client object used to issue the HTTP requests. + :type url_suffix: ``str`` + :param url_suffix: The v2 endpoint URL suffix to query. + :type params: ``Dict[str, Any]`` + :param params: The base query parameters (the per-request ``limit`` is managed internally). + :type limit: ``int`` + :param limit: The total number of records the caller wants to accumulate. + + :return: A tuple of (accumulated results, last page's raw JSON response). + :rtype: ``Tuple[List[Dict[str, Any]], Dict[str, Any]]`` + """ + accumulated: list[dict[str, Any]] = [] + request_params = dict(params) + response_json: dict[str, Any] = {} + + while len(accumulated) < limit: + request_params["limit"] = min(MAX_LIMIT_V2, limit - len(accumulated)) + + response = client.http_request(method="GET", url_suffix=url_suffix, params=request_params) + response_json = response.json() + page_results = response_json.get("results", []) + accumulated.extend(page_results) + + next_cursor = prepare_cursor_from_link_header(response) + if not next_cursor or not page_results: + break + request_params["cursor"] = next_cursor + + return accumulated[:limit], response_json + + +def validate_limit_v2(args: dict[str, str]) -> Optional[int]: + """ + Validate and normalize the ``limit`` argument for v2 list commands. + + :type args: ``Dict[str, str]`` + :param args: The command arguments provided by the user. + + :return: The validated limit or ``None`` when not provided. + :rtype: ``Optional[int]`` + """ + limit = arg_to_number(args.get("limit"), arg_name="limit") + if limit is None: + return None + if limit < MIN_LIMIT_V2: + raise ValueError(MESSAGES["INVALID_LIMIT_V2"].format(limit)) + return limit + + +def prepare_content_body_v2(args: dict[str, str], legal_representations: list[str], message_key: str) -> dict[str, Any]: + """ + Build the v2 ``body`` object for page/blogpost/comment create and update requests. + + The v2 body format differs from v1 and is shaped as + ``{"representation": "storage", "value": "

...

"}``. + + :type args: ``Dict[str, str]`` + :param args: The command arguments provided by the user. + :type legal_representations: ``list[str]`` + :param legal_representations: The allowed body representation values for the resource. + :type message_key: ``str`` + :param message_key: The MESSAGES key to use when the representation is invalid. + + :return: The v2 body object (empty dict when no body value is provided). + :rtype: ``Dict[str, Any]`` + """ + body_value = args.get("body_value") + if not body_value: + return {} + + representation = args.get("body_representation", "storage").lower() + if representation not in legal_representations: + raise ValueError(f"{MESSAGES[message_key]} Received: '{representation}'.") + + return {"representation": representation, "value": body_value} + + +def validate_content_create_args_v2(args: dict[str, str]) -> None: + """ + Validate arguments shared by page-create and blogpost-create v2 commands. + + :type args: ``Dict[str, str]`` + :param args: The command arguments provided by the user. + + :return: None + """ + if not args.get("space_id"): + raise ValueError(MESSAGES["REQUIRED_ARGUMENT"].format("space_id")) + + status = args.get("status", "current").lower() + if status not in LEGAL_STATUS_CREATE_V2: + raise ValueError(f"{MESSAGES['INVALID_STATUS_CREATE_V2']} Received: '{status}'.") + + representation = args.get("body_representation", "storage").lower() + if representation not in LEGAL_BODY_REPRESENTATION_V2: + raise ValueError(f"{MESSAGES['INVALID_BODY_REPRESENTATION_V2']} Received: '{representation}'.") + + +def prepare_content_create_params_v2(args: dict[str, str]) -> dict[str, Any]: + """ + Build the request body for page-create and blogpost-create v2 commands. + + :type args: ``Dict[str, str]`` + :param args: The command arguments provided by the user. + + :return: The request body object. + :rtype: ``Dict[str, Any]`` + """ + validate_content_create_args_v2(args) + + body = prepare_content_body_v2(args, LEGAL_BODY_REPRESENTATION_V2, "INVALID_BODY_REPRESENTATION_V2") + params = { + "spaceId": args["space_id"], + "status": args.get("status", "current").lower(), + "title": args.get("title"), + "body": body or None, + } + + parent_id = args.get("parent_id") + if parent_id: + params["parentId"] = parent_id + + return assign_params(**params) + + +def validate_content_update_args_v2(args: dict[str, str], config: dict[str, Any]) -> None: + """ + Validate arguments shared by page-update and blogpost-update v2 commands. + + :type args: ``Dict[str, str]`` + :param args: The command arguments provided by the user. + :type config: ``Dict[str, Any]`` + :param config: The resource configuration from ``CONTENT_V2_CONFIG``. + + :return: None + """ + id_arg = config["id_arg"] + if not args.get(id_arg): + raise ValueError(MESSAGES["REQUIRED_ARGUMENT"].format(id_arg)) + + if not args.get("version_number"): + raise ValueError(MESSAGES["REQUIRED_ARGUMENT"].format("version_number")) + + status = args.get("status", "current").lower() + if status not in LEGAL_STATUS_UPDATE_V2: + raise ValueError(f"{MESSAGES['INVALID_STATUS_UPDATE_V2']} Received: '{status}'.") + + representation = args.get("body_representation", "storage").lower() + if representation not in LEGAL_BODY_REPRESENTATION_V2: + raise ValueError(f"{MESSAGES['INVALID_BODY_REPRESENTATION_V2']} Received: '{representation}'.") + + +def prepare_content_update_params_v2(args: dict[str, str], config: dict[str, Any]) -> dict[str, Any]: + """ + Build the request body for page-update and blogpost-update v2 commands. + + v2 update requires an explicit ``version.number`` increment supplied by the caller. + + :type args: ``Dict[str, str]`` + :param args: The command arguments provided by the user. + :type config: ``Dict[str, Any]`` + :param config: The resource configuration from ``CONTENT_V2_CONFIG``. + + :return: The request body object. + :rtype: ``Dict[str, Any]`` + """ + validate_content_update_args_v2(args, config) + + content_id = args[config["id_arg"]] + version_number = arg_to_number(args.get("version_number"), arg_name="version_number") + body = prepare_content_body_v2(args, LEGAL_BODY_REPRESENTATION_V2, "INVALID_BODY_REPRESENTATION_V2") + + params = { + "id": content_id, + "status": args.get("status", "current").lower(), + "title": args.get("title"), + "body": body or None, + "version": {"number": version_number, "message": args.get("version_message")}, + } + + if config["label"] == "Page" and args.get("space_id"): + params["spaceId"] = args["space_id"] + + return assign_params(**params) + + +def validate_content_list_args_v2(args: dict[str, str], config: dict[str, Any]) -> None: + """ + Validate arguments for page-list and blogpost-list v2 commands. + + :type args: ``Dict[str, str]`` + :param args: The command arguments provided by the user. + :type config: ``Dict[str, Any]`` + :param config: The resource configuration from ``CONTENT_V2_CONFIG``. + + :return: None + """ + validate_limit_v2(args) + + status = args.get("status", "").lower() + if status and status not in config["list_status"]: + raise ValueError(MESSAGES[config["list_status_message"]]) + + if config["supports_subtype_filter"]: + subtype = args.get("subtype", "").lower() + if subtype and subtype not in LEGAL_PAGE_SUBTYPE_FILTER_V2: + raise ValueError(MESSAGES["INVALID_SUBTYPE_FILTER_V2"]) + + +def prepare_content_list_params_v2(args: dict[str, str], config: dict[str, Any]) -> dict[str, Any]: + """ + Build the query parameters for page-list and blogpost-list v2 commands. + + :type args: ``Dict[str, str]`` + :param args: The command arguments provided by the user. + :type config: ``Dict[str, Any]`` + :param config: The resource configuration from ``CONTENT_V2_CONFIG``. + + :return: The query parameters. + :rtype: ``Dict[str, Any]`` + """ + validate_content_list_args_v2(args, config) + # The per-page ``limit`` is managed by ``paginate_v2_results`` so that the user-supplied + # ``limit`` represents the total number of records accumulated across all pages. + validate_limit_v2(args) + + params: dict[str, Any] = { + "id": argToList(args.get("id")), + "space-id": argToList(args.get("space_id")), + "status": argToList(args.get("status")), + "title": args.get("title"), + "sort": args.get("sort"), + } + + if config["supports_subtype_filter"] and args.get("subtype"): + params["subtype"] = args["subtype"].lower() + + return assign_params(**params) + + +def prepare_hr_for_content_v2(content: dict[str, Any], label: str) -> str: + """ + Prepare human-readable output for a single v2 page/blogpost. + + :type content: ``Dict[str, Any]`` + :param content: The page or blogpost data. + :type label: ``str`` + :param label: The resource label (e.g. ``Page`` or ``Blog post``). + + :rtype: ``str`` + :return: Human readable. + """ + hr_record = { + "ID": content.get("id", ""), + "Title": content.get("title", ""), + "Status": content.get("status", ""), + "Space ID": content.get("spaceId", ""), + "Author ID": content.get("authorId", ""), + "Created At": content.get("createdAt", ""), + "Version": (content.get("version") or {}).get("number", ""), + } + return tableToMarkdown( + label, hr_record, ["ID", "Title", "Status", "Space ID", "Author ID", "Created At", "Version"], removeNull=True + ) + + +def prepare_hr_for_content_list_v2(contents: list[dict[str, Any]], label: str) -> str: + """ + Prepare human-readable output for a list of v2 pages/blogposts. + + :type contents: ``list[Dict[str, Any]]`` + :param contents: The page or blogpost data. + :type label: ``str`` + :param label: The resource label (e.g. ``Page`` or ``Blog post``). + + :rtype: ``str`` + :return: Human readable. + """ + hr_list = [] + for content in contents: + hr_list.append( + { + "ID": content.get("id", ""), + "Title": content.get("title", ""), + "Status": content.get("status", ""), + "Space ID": content.get("spaceId", ""), + "Author ID": content.get("authorId", ""), + "Created At": content.get("createdAt", ""), + } + ) + return tableToMarkdown( + f"{label}(s)", hr_list, ["ID", "Title", "Status", "Space ID", "Author ID", "Created At"], removeNull=True + ) + + +def validate_comment_create_args_v2(args: dict[str, str]) -> None: + """ + Validate arguments for footer-comment-create v2 command. + + :type args: ``Dict[str, str]`` + :param args: The command arguments provided by the user. + + :return: None + """ + if not args.get("body_value"): + raise ValueError(MESSAGES["REQUIRED_ARGUMENT"].format("body_value")) + + representation = args.get("body_representation", "storage").lower() + if representation not in LEGAL_COMMENT_BODY_REPRESENTATION_V2: + raise ValueError(MESSAGES["INVALID_COMMENT_BODY_REPRESENTATION_V2"]) + + container_args = ("page_id", "blogpost_id", "parent_comment_id", "attachment_id", "custom_content_id") + if not any(args.get(arg) for arg in container_args): + raise ValueError(MESSAGES["MISSING_COMMENT_CONTAINER_V2"]) + + +def prepare_comment_create_params_v2(args: dict[str, str]) -> dict[str, Any]: + """ + Build the request body for footer-comment-create v2 command. + + :type args: ``Dict[str, str]`` + :param args: The command arguments provided by the user. + + :return: The request body object. + :rtype: ``Dict[str, Any]`` + """ + validate_comment_create_args_v2(args) + + body = prepare_content_body_v2(args, LEGAL_COMMENT_BODY_REPRESENTATION_V2, "INVALID_COMMENT_BODY_REPRESENTATION_V2") + params: dict[str, Any] = { + "body": body, + "pageId": args.get("page_id"), + "blogPostId": args.get("blogpost_id"), + "parentCommentId": args.get("parent_comment_id"), + "attachmentId": args.get("attachment_id"), + "customContentId": args.get("custom_content_id"), + } + + return assign_params(**params) + + +def prepare_hr_for_comment_v2(comment: dict[str, Any], label: str) -> str: + """ + Prepare human-readable output for a created v2 footer comment. + + :type comment: ``Dict[str, Any]`` + :param comment: The comment data. + :type label: ``str`` + :param label: The comment label (e.g. ``Footer Comment``). + + :rtype: ``str`` + :return: Human readable. + """ + hr_record = { + "ID": comment.get("id", ""), + "Status": comment.get("status", ""), + "Page ID": comment.get("pageId", ""), + "Blog Post ID": comment.get("blogPostId", ""), + "Parent Comment ID": comment.get("parentCommentId", ""), + "Version": (comment.get("version") or {}).get("number", ""), + } + return tableToMarkdown( + label, hr_record, ["ID", "Status", "Page ID", "Blog Post ID", "Parent Comment ID", "Version"], removeNull=True + ) + + +def validate_space_list_args_v2(args: dict[str, str]) -> None: + """ + Validate arguments for space-listv2 command. + + :type args: ``Dict[str, str]`` + :param args: The command arguments provided by the user. + + :return: None + """ + validate_limit_v2(args) + + space_type = args.get("type", "").lower() + if space_type and space_type not in LEGAL_SPACE_TYPE_V2: + raise ValueError(MESSAGES["INVALID_SPACE_TYPE_V2"]) + + status = args.get("status", "").lower() + if status and status not in LEGAL_SPACE_STATUS_V2: + raise ValueError(MESSAGES["INVALID_SPACE_STATUS_V2"]) + + +def prepare_space_list_params_v2(args: dict[str, str]) -> dict[str, Any]: + """ + Build the query parameters for space-listv2 command. + + :type args: ``Dict[str, str]`` + :param args: The command arguments provided by the user. + + :return: The query parameters. + :rtype: ``Dict[str, Any]`` + """ + validate_space_list_args_v2(args) + # The per-page ``limit`` is managed by ``paginate_v2_results`` so that the user-supplied + # ``limit`` represents the total number of records accumulated across all pages. + validate_limit_v2(args) + + params = { + "ids": argToList(args.get("ids")), + "keys": argToList(args.get("keys")), + "type": args.get("type"), + "status": args.get("status"), + "sort": args.get("sort"), + } + return assign_params(**params) + + +def validate_space_create_args_v2(args: dict[str, str]) -> None: + """ + Validate arguments for space-createv2 command. + + :type args: ``Dict[str, str]`` + :param args: The command arguments provided by the user. + + :return: None + """ + if not args.get("name"): + raise ValueError(MESSAGES["REQUIRED_ARGUMENT"].format("name")) + if not args.get("key"): + raise ValueError(MESSAGES["REQUIRED_ARGUMENT"].format("key")) + + description_format = args.get("description_format", "plain").lower() + if description_format not in LEGAL_DESCRIPTION_FORMAT_V2: + raise ValueError(MESSAGES["INVALID_DESCRIPTION_FORMAT_V2"]) + + +def prepare_space_create_params_v2(args: dict[str, str]) -> dict[str, Any]: + """ + Build the request body for space-createv2 command. + + :type args: ``Dict[str, str]`` + :param args: The command arguments provided by the user. + + :return: The request body object. + :rtype: ``Dict[str, Any]`` + """ + validate_space_create_args_v2(args) + + params: dict[str, Any] = {"name": args["name"], "key": args["key"]} + + description_value = args.get("description_value") + if description_value: + description_format = args.get("description_format", "plain").lower() + params["description"] = {description_format: {"value": description_value, "representation": description_format}} + + role_assignments = args.get("role_assignments") + if role_assignments: + try: + params["roleAssignments"] = json.loads(role_assignments) + except (json.JSONDecodeError, TypeError): + raise ValueError(MESSAGES["INVALID_ROLE_ASSIGNMENTS_V2"]) + + return assign_params(**params) + + +def prepare_hr_for_space_create_v2(space: dict[str, Any]) -> str: + """ + Prepare human-readable output for a created v2 space. + + :type space: ``Dict[str, Any]`` + :param space: The space data. + + :rtype: ``str`` + :return: Human readable. + """ + hr_record = { + "ID": space.get("id", ""), + "Key": space.get("key", ""), + "Name": space.get("name", ""), + "Type": space.get("type", ""), + "Status": space.get("status", ""), + } + return tableToMarkdown("Space", hr_record, ["ID", "Key", "Name", "Type", "Status"], removeNull=True) + + +def prepare_hr_for_space_list_v2(spaces: list[dict[str, Any]]) -> str: + """ + Prepare human-readable output for a list of v2 spaces. + + :type spaces: ``list[Dict[str, Any]]`` + :param spaces: The space data. + + :rtype: ``str`` + :return: Human readable. + """ + hr_list = [] + for space in spaces: + hr_list.append( + { + "ID": space.get("id", ""), + "Key": space.get("key", ""), + "Name": space.get("name", ""), + "Type": space.get("type", ""), + "Status": space.get("status", ""), + } + ) + return tableToMarkdown("Space(s)", hr_list, ["ID", "Key", "Name", "Type", "Status"], removeNull=True) + + """ COMMAND FUNCTIONS """ @@ -1417,6 +2058,262 @@ def confluence_cloud_content_get_command(client: Client, args: dict[str, str]) - ) +""" COMMAND FUNCTIONS (REST API v2) """ + + +def confluence_cloud_content_create_command_v2(client: Client, args: dict[str, str], content_type: str) -> CommandResults: + """ + Create a page or blogpost using the Confluence Cloud REST API v2. + + :type client: ``Client`` + :param client: Client object to be used. + :type args: ``Dict[str, str]`` + :param args: The command arguments provided by the user. + :type content_type: ``str`` + :param content_type: Either ``page`` or ``blogpost``. + + :return: Standard command result. + :rtype: ``CommandResults`` + """ + config = CONTENT_V2_CONFIG[content_type] + params = prepare_content_create_params_v2(args) + + response = client.http_request(method="POST", url_suffix=config["url_suffix"], json_data=params) + response_json = response.json() + + context = remove_empty_elements_for_context(response_json) + readable_hr = prepare_hr_for_content_v2(response_json, config["label"]) + + return CommandResults( + outputs_prefix=config["output_prefix"], + outputs_key_field="id", + outputs=context, + readable_output=readable_hr, + raw_response=response_json, + ) + + +def confluence_cloud_content_list_command_v2(client: Client, args: dict[str, str], content_type: str) -> CommandResults: + """ + List pages or blogposts using the Confluence Cloud REST API v2. + + :type client: ``Client`` + :param client: Client object to be used. + :type args: ``Dict[str, str]`` + :param args: The command arguments provided by the user. + :type content_type: ``str`` + :param content_type: Either ``page`` or ``blogpost``. + + :return: Standard command result or no records found message. + :rtype: ``CommandResults`` + """ + config = CONTENT_V2_CONFIG[content_type] + params = prepare_content_list_params_v2(args, config) + # ``limit`` is the total number of records to return across all pages. + limit = validate_limit_v2(args) or DEFAULT_LIMIT_V2 + + total_records, response_json = paginate_v2_results(client, config["url_suffix"], params, limit) + + if not total_records: + return CommandResults(readable_output=MESSAGES["NO_RECORDS_FOUND"].format(f"{config['label'].lower()}(s)")) + + context = remove_empty_elements_for_context(total_records) + outputs: dict[str, Any] = {f"{config['output_prefix']}(val.id == obj.id)": context} + + readable_hr = prepare_hr_for_content_list_v2(total_records, config["label"]) + + return CommandResults(outputs=outputs, readable_output=readable_hr, raw_response=response_json) + + +def confluence_cloud_content_update_command_v2(client: Client, args: dict[str, str], content_type: str) -> CommandResults: + """ + Update a page or blogpost using the Confluence Cloud REST API v2. + + :type client: ``Client`` + :param client: Client object to be used. + :type args: ``Dict[str, str]`` + :param args: The command arguments provided by the user. + :type content_type: ``str`` + :param content_type: Either ``page`` or ``blogpost``. + + :return: Standard command result. + :rtype: ``CommandResults`` + """ + config = CONTENT_V2_CONFIG[content_type] + content_id = args[config["id_arg"]] + params = prepare_content_update_params_v2(args, config) + request_url = urljoin(config["url_suffix"], content_id) + + response = client.http_request(method="PUT", url_suffix=request_url, json_data=params) + response_json = response.json() + + context = remove_empty_elements_for_context(response_json) + readable_hr = prepare_hr_for_content_v2(response_json, config["label"]) + + return CommandResults( + outputs_prefix=config["output_prefix"], + outputs_key_field="id", + outputs=context, + readable_output=readable_hr, + raw_response=response_json, + ) + + +def confluence_cloud_content_delete_command_v2(client: Client, args: dict[str, str], content_type: str) -> CommandResults: + """ + Delete a page or blogpost using the Confluence Cloud REST API v2. + + :type client: ``Client`` + :param client: Client object to be used. + :type args: ``Dict[str, str]`` + :param args: The command arguments provided by the user. + :type content_type: ``str`` + :param content_type: Either ``page`` or ``blogpost``. + + :return: Standard command result. + :rtype: ``CommandResults`` + """ + config = CONTENT_V2_CONFIG[content_type] + content_id = args.get(config["id_arg"]) + if not content_id: + raise ValueError(MESSAGES["REQUIRED_ARGUMENT"].format(config["id_arg"])) + + params = assign_params(purge=argToBoolean(args["purge"]) if args.get("purge") else None) + request_url = urljoin(config["url_suffix"], content_id) + + client.http_request(method="DELETE", url_suffix=request_url, params=params) + + hr_key = "HR_PAGE_DELETE" if content_type == "page" else "HR_BLOGPOST_DELETE" + return CommandResults(readable_output=MESSAGES[hr_key].format(content_id)) + + +def confluence_cloud_page_create_command(client: Client, args: dict[str, str]) -> CommandResults: + """Create a page (Confluence Cloud REST API v2).""" + return confluence_cloud_content_create_command_v2(client, args, "page") + + +def confluence_cloud_page_list_command(client: Client, args: dict[str, str]) -> CommandResults: + """List pages (Confluence Cloud REST API v2).""" + return confluence_cloud_content_list_command_v2(client, args, "page") + + +def confluence_cloud_page_update_command(client: Client, args: dict[str, str]) -> CommandResults: + """Update a page (Confluence Cloud REST API v2).""" + return confluence_cloud_content_update_command_v2(client, args, "page") + + +def confluence_cloud_page_delete_command(client: Client, args: dict[str, str]) -> CommandResults: + """Delete a page (Confluence Cloud REST API v2).""" + return confluence_cloud_content_delete_command_v2(client, args, "page") + + +def confluence_cloud_blogpost_create_command(client: Client, args: dict[str, str]) -> CommandResults: + """Create a blogpost (Confluence Cloud REST API v2).""" + return confluence_cloud_content_create_command_v2(client, args, "blogpost") + + +def confluence_cloud_blogpost_list_command(client: Client, args: dict[str, str]) -> CommandResults: + """List blogposts (Confluence Cloud REST API v2).""" + return confluence_cloud_content_list_command_v2(client, args, "blogpost") + + +def confluence_cloud_blogpost_update_command(client: Client, args: dict[str, str]) -> CommandResults: + """Update a blogpost (Confluence Cloud REST API v2).""" + return confluence_cloud_content_update_command_v2(client, args, "blogpost") + + +def confluence_cloud_blogpost_delete_command(client: Client, args: dict[str, str]) -> CommandResults: + """Delete a blogpost (Confluence Cloud REST API v2).""" + return confluence_cloud_content_delete_command_v2(client, args, "blogpost") + + +def confluence_cloud_footer_comment_create_command(client: Client, args: dict[str, str]) -> CommandResults: + """ + Create a footer comment using the Confluence Cloud REST API v2. + + :type client: ``Client`` + :param client: Client object to be used. + :type args: ``Dict[str, str]`` + :param args: The command arguments provided by the user. + + :return: Standard command result. + :rtype: ``CommandResults`` + """ + params = prepare_comment_create_params_v2(args) + + response = client.http_request(method="POST", url_suffix=URL_SUFFIX_V2["FOOTER_COMMENTS"], json_data=params) + response_json = response.json() + + context = remove_empty_elements_for_context(response_json) + readable_hr = prepare_hr_for_comment_v2(response_json, "Footer Comment") + + return CommandResults( + outputs_prefix=OUTPUT_PREFIX["COMMENT"], + outputs_key_field="id", + outputs=context, + readable_output=readable_hr, + raw_response=response_json, + ) + + +def confluence_cloud_space_list_command_v2(client: Client, args: dict[str, str]) -> CommandResults: + """ + List spaces using the Confluence Cloud REST API v2. + + :type client: ``Client`` + :param client: Client object to be used. + :type args: ``Dict[str, str]`` + :param args: The command arguments provided by the user. + + :return: Standard command result or no records found message. + :rtype: ``CommandResults`` + """ + params = prepare_space_list_params_v2(args) + # ``limit`` is the total number of records to return across all pages. + limit = validate_limit_v2(args) or DEFAULT_LIMIT_V2 + + total_records, response_json = paginate_v2_results(client, URL_SUFFIX_V2["SPACES"], params, limit) + + if not total_records: + return CommandResults(readable_output=MESSAGES["NO_RECORDS_FOUND"].format("space(s)")) + + context = remove_empty_elements_for_context(total_records) + outputs: dict[str, Any] = {f"{OUTPUT_PREFIX['SPACE']}(val.id == obj.id)": context} + + readable_hr = prepare_hr_for_space_list_v2(total_records) + + return CommandResults(outputs=outputs, readable_output=readable_hr, raw_response=response_json) + + +def confluence_cloud_space_create_command_v2(client: Client, args: dict[str, str]) -> CommandResults: + """ + Create a space using the Confluence Cloud REST API v2. + + :type client: ``Client`` + :param client: Client object to be used. + :type args: ``Dict[str, str]`` + :param args: The command arguments provided by the user. + + :return: Standard command result. + :rtype: ``CommandResults`` + """ + params = prepare_space_create_params_v2(args) + + response = client.http_request(method="POST", url_suffix=URL_SUFFIX_V2["SPACES"], json_data=params) + response_json = response.json() + + context = remove_empty_elements_for_context(response_json) + readable_hr = prepare_hr_for_space_create_v2(response_json) + + return CommandResults( + outputs_prefix=OUTPUT_PREFIX["SPACE"], + outputs_key_field="id", + outputs=context, + readable_output=readable_hr, + raw_response=response_json, + ) + + def _extract_content_id_from_url(url: str) -> str: """ Extract the Confluence content ID from a Confluence page URL. @@ -1727,6 +2624,18 @@ def main() -> None: # pragma: no cover "confluence-cloud-content-create": confluence_cloud_content_create_command, "confluence-cloud-space-create": confluence_cloud_space_create_command, "confluence-cloud-content-get": confluence_cloud_content_get_command, + # --- REST API v2 commands --- + "confluence-cloud-page-create": confluence_cloud_page_create_command, + "confluence-cloud-page-list": confluence_cloud_page_list_command, + "confluence-cloud-page-update": confluence_cloud_page_update_command, + "confluence-cloud-page-delete": confluence_cloud_page_delete_command, + "confluence-cloud-blogpost-create": confluence_cloud_blogpost_create_command, + "confluence-cloud-blogpost-list": confluence_cloud_blogpost_list_command, + "confluence-cloud-blogpost-update": confluence_cloud_blogpost_update_command, + "confluence-cloud-blogpost-delete": confluence_cloud_blogpost_delete_command, + "confluence-cloud-footer-comment-create": confluence_cloud_footer_comment_create_command, + "confluence-cloud-space-listv2": confluence_cloud_space_list_command_v2, + "confluence-cloud-space-createv2": confluence_cloud_space_create_command_v2, "get-file-content": confluence_cloud_generic_file_get_command, } diff --git a/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/AtlassianConfluenceCloud.yml b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/AtlassianConfluenceCloud.yml index 007fcf12fe78..9a62b37bc68c 100644 --- a/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/AtlassianConfluenceCloud.yml +++ b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/AtlassianConfluenceCloud.yml @@ -1,5 +1,6 @@ category: Utilities provider: Atlassian +supportlevelheader: xsoar sectionorder: - Connect - Collect @@ -95,6 +96,508 @@ display: Atlassian Confluence Cloud name: Atlassian Confluence Cloud script: commands: + - arguments: + - description: |- + The ID of the space where the page is created. Retrieve using the confluence-cloud-space-listv2 command. + name: space_id + required: true + - description: The title of the page. + name: title + required: true + - description: The status of the page to be created. + name: status + auto: PREDEFINED + defaultValue: current + predefined: + - current + - draft + - description: |- + The content body value of the page. + name: body_value + required: true + - description: |- + The content format type of the body value. + name: body_representation + auto: PREDEFINED + defaultValue: storage + predefined: + - storage + - atlas_doc_format + - wiki + - description: |- + The ID of the parent page under which the new page is created. + name: parent_id + description: |- + Creates a new page in Confluence Cloud (REST API v2). + name: confluence-cloud-page-create + outputs: + - contextPath: ConfluenceCloud.Page.id + description: The ID of the page. + type: String + - contextPath: ConfluenceCloud.Page.status + description: The status of the page. + type: String + - contextPath: ConfluenceCloud.Page.title + description: The title of the page. + type: String + - contextPath: ConfluenceCloud.Page.spaceId + description: The ID of the space the page belongs to. + type: String + - contextPath: ConfluenceCloud.Page.parentId + description: The ID of the parent page. + type: String + - contextPath: ConfluenceCloud.Page.authorId + description: The account ID of the page author. + type: String + - contextPath: ConfluenceCloud.Page.createdAt + description: Date and time, in ISO 8601 format, when the page was created (e.g., 2024-01-15T12:34:56Z). + type: Date + - contextPath: ConfluenceCloud.Page.version.number + description: The version number of the page. + type: Number + - arguments: + - description: |- + A comma-separated list of page IDs to filter by. + name: id + isArray: true + - description: "A comma-separated list of space IDs to filter by." + name: space_id + isArray: true + - description: The status of pages to filter by. + name: status + auto: PREDEFINED + predefined: + - current + - archived + - deleted + - trashed + - description: |- + The title of pages to filter by. + name: title + - description: |- + The subtype of pages to filter by. + name: subtype + auto: PREDEFINED + predefined: + - page + - live + - description: |- + Ordering of the results by a particular field. Prefix with '-' for descending order. + name: sort + - description: |- + The maximum number of records to return. Value must be between 1 and 250. + name: limit + defaultValue: '50' + - description: The cursor to use for fetching the next page of results (from a previous run's ConfluenceCloud.PageToken output). + name: cursor + description: |- + Returns a list of pages from Confluence Cloud (REST API v2). + name: confluence-cloud-page-list + outputs: + - contextPath: ConfluenceCloud.Page.id + description: The ID of the page. + type: String + - contextPath: ConfluenceCloud.Page.status + description: The status of the page. + type: String + - contextPath: ConfluenceCloud.Page.title + description: The title of the page. + type: String + - contextPath: ConfluenceCloud.Page.spaceId + description: The ID of the space the page belongs to. + type: String + - contextPath: ConfluenceCloud.Page.authorId + description: The account ID of the page author. + type: String + - contextPath: ConfluenceCloud.Page.createdAt + description: Date and time, in ISO 8601 format, when the page was created (e.g., 2024-01-15T12:34:56Z). + type: Date + - contextPath: ConfluenceCloud.PageToken.Content.next_page_token + description: The cursor to use for fetching the next page of results. + type: String + - contextPath: ConfluenceCloud.PageToken.Content.name + description: The name of the command that produced the page token. + type: String + - arguments: + - description: |- + The ID of the page to update. + name: page_id + required: true + - description: |- + The new version number for the page. Must be one greater than the current version. + name: version_number + required: true + - description: |- + The title of the page. + name: title + required: true + - description: |- + The status of the page. + name: status + required: true + auto: PREDEFINED + defaultValue: current + predefined: + - current + - draft + - description: |- + The content body value of the page. + name: body_value + required: true + - auto: PREDEFINED + description: |- + The content format type of the body value. + name: body_representation + predefined: + - storage + - atlas_doc_format + - wiki + defaultValue: storage + - description: The ID of the space to move the page to. + name: space_id + - description: A message describing the update for the version history. + name: version_message + description: |- + Updates an existing page in Confluence Cloud (REST API v2). + name: confluence-cloud-page-update + outputs: + - contextPath: ConfluenceCloud.Page.id + description: The ID of the page. + type: String + - contextPath: ConfluenceCloud.Page.status + description: The status of the page. + type: String + - contextPath: ConfluenceCloud.Page.title + description: The title of the page. + type: String + - contextPath: ConfluenceCloud.Page.spaceId + description: The ID of the space the page belongs to. + type: String + - contextPath: ConfluenceCloud.Page.version.number + description: The version number of the page. + type: Number + - arguments: + - description: |- + The ID of the page to delete. + name: page_id + required: true + - defaultValue: 'false' + description: |- + Whether to permanently purge the page from the trash. Requires the page to already be in the trash. + name: purge + auto: PREDEFINED + predefined: + - 'true' + - 'false' + description: Deletes a page in Confluence Cloud (REST API v2). + name: confluence-cloud-page-delete + outputs: [] + - arguments: + - description: |- + The ID of the space where the blog post is created. Retrieve using the confluence-cloud-space-listv2 command. + name: space_id + required: true + - description: |- + The title of the blog post. + name: title + required: true + - description: The status of the blog post to be created. + name: status + auto: PREDEFINED + defaultValue: current + predefined: + - current + - draft + - description: "The content body value of the blog post." + name: body_value + required: true + - auto: PREDEFINED + description: |- + The content format type of the body value. + name: body_representation + predefined: + - storage + - atlas_doc_format + - wiki + defaultValue: storage + description: Creates a new blog post in Confluence Cloud (REST API v2). + name: confluence-cloud-blogpost-create + outputs: + - contextPath: ConfluenceCloud.Blogpost.id + description: The ID of the blog post. + type: String + - contextPath: ConfluenceCloud.Blogpost.status + description: The status of the blog post. + type: String + - contextPath: ConfluenceCloud.Blogpost.title + description: The title of the blog post. + type: String + - contextPath: ConfluenceCloud.Blogpost.spaceId + description: The ID of the space the blog post belongs to. + type: String + - contextPath: ConfluenceCloud.Blogpost.authorId + description: The account ID of the blog post author. + type: String + - contextPath: ConfluenceCloud.Blogpost.createdAt + description: Date and time, in ISO 8601 format, when the blog post was created (e.g., 2024-01-15T12:34:56Z). + type: Date + - contextPath: ConfluenceCloud.Blogpost.version.number + description: The version number of the blog post. + type: Number + - arguments: + - description: A comma-separated list of blog post IDs to filter by. + name: id + isArray: true + - description: |- + A comma-separated list of space IDs to filter by. + name: space_id + isArray: true + - auto: PREDEFINED + description: The status of blog posts to filter by. + name: status + predefined: + - current + - deleted + - trashed + - description: The title of blog posts to filter by. + name: title + - description: Ordering of the results by a particular field. Prefix with '-' for descending order. + name: sort + - defaultValue: '50' + description: The maximum number of records to return. Value must be between 1 and 250. + name: limit + - description: The cursor to use for fetching the next page of results (from a previous run's ConfluenceCloud.PageToken output). + name: cursor + description: |- + Returns a list of blog posts from Confluence Cloud (REST API v2). + name: confluence-cloud-blogpost-list + outputs: + - contextPath: ConfluenceCloud.Blogpost.id + description: The ID of the blog post. + type: String + - contextPath: ConfluenceCloud.Blogpost.status + description: The status of the blog post. + type: String + - contextPath: ConfluenceCloud.Blogpost.title + description: The title of the blog post. + type: String + - contextPath: ConfluenceCloud.Blogpost.spaceId + description: The ID of the space the blog post belongs to. + type: String + - contextPath: ConfluenceCloud.Blogpost.authorId + description: The account ID of the blog post author. + type: String + - contextPath: ConfluenceCloud.Blogpost.createdAt + description: Date and time, in ISO 8601 format, when the blog post was created (e.g., 2024-01-15T12:34:56Z). + type: Date + - contextPath: ConfluenceCloud.PageToken.Content.next_page_token + description: The cursor to use for fetching the next page of results. + type: String + - contextPath: ConfluenceCloud.PageToken.Content.name + description: The name of the command that produced the page token. + type: String + - arguments: + - description: The ID of the blog post to update. + name: blogpost_id + required: true + - description: |- + The new version number for the blog post. Must be one greater than the current version. + name: version_number + required: true + - description: |- + The title of the blog post. + name: title + required: true + - description: |- + The status of the blog post. + name: status + auto: PREDEFINED + defaultValue: current + predefined: + - current + - draft + - description: |- + The content body value of the blog post. + name: body_value + required: true + - description: |- + The content format type of the body value. + name: body_representation + auto: PREDEFINED + defaultValue: storage + predefined: + - storage + - atlas_doc_format + - wiki + - description: |- + A message describing the update for the version history. + name: version_message + description: |- + Updates an existing blog post in Confluence Cloud (REST API v2). + name: confluence-cloud-blogpost-update + outputs: + - contextPath: ConfluenceCloud.Blogpost.id + description: The ID of the blog post. + type: String + - contextPath: ConfluenceCloud.Blogpost.status + description: The status of the blog post. + type: String + - contextPath: ConfluenceCloud.Blogpost.title + description: The title of the blog post. + type: String + - contextPath: ConfluenceCloud.Blogpost.spaceId + description: The ID of the space the blog post belongs to. + type: String + - contextPath: ConfluenceCloud.Blogpost.version.number + description: The version number of the blog post. + type: Number + - arguments: + - description: The ID of the blog post to delete. + name: blogpost_id + required: true + - defaultValue: 'false' + description: |- + Whether to permanently purge the blog post from the trash. Requires the blog post to already be in the trash. + name: purge + auto: PREDEFINED + predefined: + - 'true' + - 'false' + description: |- + Deletes a blog post in Confluence Cloud (REST API v2). + name: confluence-cloud-blogpost-delete + outputs: [] + - arguments: + - description: |- + The content body value of the comment. + name: body_value + required: true + - defaultValue: 'storage' + description: |- + The content format type of the body value. + name: body_representation + auto: PREDEFINED + predefined: + - storage + - atlas_doc_format + - description: The ID of the page to attach the comment to. One of page_id, blogpost_id, parent_comment_id, attachment_id, or custom_content_id is required. + name: page_id + - description: The ID of the blog post to attach the comment to. + name: blogpost_id + - description: The ID of the parent comment to reply to. + name: parent_comment_id + - description: The ID of the attachment to attach the comment to. + name: attachment_id + - description: The ID of the custom content to attach the comment to. + name: custom_content_id + description: Creates a footer comment in Confluence Cloud (REST API v2). + name: confluence-cloud-footer-comment-create + outputs: + - contextPath: ConfluenceCloud.Comment.id + description: The ID of the comment. + type: String + - contextPath: ConfluenceCloud.Comment.status + description: The status of the comment. + type: String + - contextPath: ConfluenceCloud.Comment.pageId + description: The ID of the page the comment belongs to. + type: String + - contextPath: ConfluenceCloud.Comment.blogPostId + description: The ID of the blog post the comment belongs to. + type: String + - contextPath: ConfluenceCloud.Comment.parentCommentId + description: The ID of the parent comment. + type: String + - contextPath: ConfluenceCloud.Comment.version.number + description: The version number of the comment. + type: Number + - arguments: + - name: ids + description: A comma-separated list of space IDs to filter by. + isArray: true + - name: keys + description: A comma-separated list of space keys to filter by. + isArray: true + - name: type + description: The type of spaces to filter by. + auto: PREDEFINED + predefined: + - global + - personal + - auto: PREDEFINED + description: The status of spaces to filter by. + name: status + predefined: + - current + - archived + - description: Ordering of the results by a particular field. Prefix with '-' for descending order. + name: sort + - defaultValue: '50' + description: The maximum number of records to return. Value must be between 1 and 250. + name: limit + - description: The cursor to use for fetching the next page of results (from a previous run's ConfluenceCloud.PageToken output). + name: cursor + name: confluence-cloud-space-listv2 + description: Returns a list of spaces from Confluence Cloud (REST API v2). + outputs: + - contextPath: ConfluenceCloud.Space.id + description: The ID of the space. + type: String + - contextPath: ConfluenceCloud.Space.key + description: The key of the space. + type: String + - contextPath: ConfluenceCloud.Space.name + description: The name of the space. + type: String + - contextPath: ConfluenceCloud.Space.type + description: The type of the space. + type: String + - contextPath: ConfluenceCloud.Space.status + description: The status of the space. + type: String + - contextPath: ConfluenceCloud.PageToken.Content.next_page_token + description: The cursor to use for fetching the next page of results. + type: String + - contextPath: ConfluenceCloud.PageToken.Content.name + description: The name of the command that produced the page token. + type: String + - arguments: + - description: The name of the new space. The maximum length is 200 characters. + name: name + required: true + - description: The key for the new space. It can contain any alphanumeric character (a-z, 0-9). The maximum length is 255 characters. + name: key + required: true + - description: The description text of the new space. + name: description_value + - auto: PREDEFINED + defaultValue: plain + description: The format of the space description. + name: description_format + predefined: + - plain + - view + - description: |- + A JSON array of role assignments granting access to principals. For example: [{"principal": {"type": "user", "id": ""}, "roleId": ""}]. + name: role_assignments + description: Creates a new space in Confluence Cloud (REST API v2). + name: confluence-cloud-space-createv2 + outputs: + - contextPath: ConfluenceCloud.Space.id + description: The ID of the space. + type: String + - contextPath: ConfluenceCloud.Space.key + description: The key of the space. + type: String + - contextPath: ConfluenceCloud.Space.name + description: The name of the space. + type: String + - contextPath: ConfluenceCloud.Space.type + description: The type of the space. + type: String + - contextPath: ConfluenceCloud.Space.status + description: The status of the space. + type: String - arguments: - description: |- The key for the new space. It can contain any alphanumeric character (a-z, 0-9). The maximum length is 255 characters. @@ -344,10 +847,12 @@ script: Note: Supported for content type page only. To retrieve the ancestor_id, execute the confluence-cloud-content-search command using the query="type=page" argument. name: ancestor_id + name: confluence-cloud-content-create + deprecated: true description: |- + Deprecated. Use confluence-cloud-page-create or confluence-cloud-blogpost-create instead. Creates a page or blogpost for a given space. Note: To view the expansion of content properties, execute the confluence-cloud-content-list and confluence-cloud-content-search commands. - name: confluence-cloud-content-create outputs: - contextPath: ConfluenceCloud.Content.id description: The ID of the content. @@ -440,7 +945,7 @@ script: description: Link to the creator of the content. type: String - contextPath: ConfluenceCloud.Content.history.createdDate - description: Date and time, in ISO 8601 format, when the content was created. + description: Date and time, in ISO 8601 format, when the content was created (e.g., 2024-01-15T12:34:56Z). type: Date - contextPath: ConfluenceCloud.Content.history._links.self description: Link to the history of the content. @@ -482,7 +987,7 @@ script: description: Link to the user who last updated the content. type: String - contextPath: ConfluenceCloud.Content.version.when - description: Date and time, in ISO 8601 format, when the content was updated. + description: Date and time, in ISO 8601 format, when the content was updated (e.g., 2024-01-15T12:34:56Z). type: Date - contextPath: ConfluenceCloud.Content.version.friendlyWhen description: Displays when the content was created. @@ -584,14 +1089,14 @@ script: description: Base link to the content. type: String - arguments: - - auto: PREDEFINED - defaultValue: current - description: |- + - description: |- The status of the new content. Possible values: current, trashed, draft. Note: The term 'current' refers to the comment that is currently active. name: status + auto: PREDEFINED + defaultValue: current predefined: - current - trashed @@ -631,10 +1136,12 @@ script: predefined: - page - blogpost + name: confluence-cloud-comment-create + deprecated: true description: |- + Deprecated. Use confluence-cloud-footer-comment-create instead. Creates a comment for the given content. Note: To view the expansion of the content properties, execute the confluence-cloud-content-list and confluence-cloud-content-search commands. - name: confluence-cloud-comment-create outputs: - contextPath: ConfluenceCloud.Comment.id description: The ID of the comment. @@ -727,7 +1234,7 @@ script: description: Link to the creator of the comment. type: String - contextPath: ConfluenceCloud.Comment.history.createdDate - description: Date and time, in ISO 8601 format, when the comment was created. + description: Date and time, in ISO 8601 format, when the comment was created (e.g., 2024-01-15T12:34:56Z). type: Date - contextPath: ConfluenceCloud.Comment.history._links.self description: Link to the history of the comment. @@ -769,7 +1276,7 @@ script: description: Link to the user who last updated the comment. type: String - contextPath: ConfluenceCloud.Comment.version.when - description: Date and time, in ISO 8601 format, when the comment was updated. + description: Date and time, in ISO 8601 format, when the comment was updated (e.g., 2024-01-15T12:34:56Z). type: Date - contextPath: ConfluenceCloud.Comment.version.friendlyWhen description: Displays when the content was created. @@ -918,8 +1425,9 @@ script: - description: "Indicates which properties to expand. \nFor reference, visit https://developer.atlassian.com/cloud/confluence/rest/api-group-space/#api-wiki-rest-api-space-get.\n\nNote: To separate multiple values, use commas. Expanded properties will be populated in context data only." isArray: true name: expand - description: Returns a list of all Confluence spaces. name: confluence-cloud-space-list + deprecated: true + description: Deprecated. Use confluence-cloud-space-listv2 instead. Returns a list of all Confluence spaces. outputs: - contextPath: ConfluenceCloud.Space.id description: ID of the space. @@ -1121,8 +1629,9 @@ script: Note: To separate multiple values, use commas. Expanded properties will be populated in context data only. isArray: true name: expand - description: Returns the list of content of Confluence. + description: Deprecated. Use confluence-cloud-page-list or confluence-cloud-blogpost-list instead. Returns the list of content of Confluence. name: confluence-cloud-content-list + deprecated: true outputs: - contextPath: ConfluenceCloud.Content.id description: The ID of the content. @@ -1215,7 +1724,7 @@ script: description: Link to the creator of the content. type: String - contextPath: ConfluenceCloud.Content.history.createdDate - description: Date and time, in ISO 8601 format, when the content was created. + description: Date and time, in ISO 8601 format, when the content was created (e.g., 2024-01-15T12:34:56Z). type: Date - contextPath: ConfluenceCloud.Content.history._links.self description: Link to the history of the content. @@ -1257,7 +1766,7 @@ script: description: Link to the user who last updated the content. type: String - contextPath: ConfluenceCloud.Content.version.when - description: Date and time, in ISO 8601 format, when the content was updated. + description: Date and time, in ISO 8601 format, when the content was updated (e.g., 2024-01-15T12:34:56Z). type: Date - contextPath: ConfluenceCloud.Content.version.friendlyWhen description: Displays when the content was created. @@ -1345,11 +1854,13 @@ script: - permanent delete - permanent delete draft description: |- + Deprecated. Use confluence-cloud-page-delete or confluence-cloud-blogpost-delete instead. Delete the content depending on the content's type and status. Note: If the content's type is page or blogpost, it should be moved to trash before deleting permanently. execution: true name: confluence-cloud-content-delete + deprecated: true - arguments: - description: The ID of the content to be updated. name: content_id @@ -1412,9 +1923,11 @@ script: - editor2 - anonymous_export_view description: |- + Deprecated. Use confluence-cloud-page-update or confluence-cloud-blogpost-update instead. Update the existing content with new content. Note: Updating draft content is currently not supported. name: confluence-cloud-content-update + deprecated: true outputs: - contextPath: ConfluenceCloud.Content.id description: The ID of the content. @@ -1507,7 +2020,7 @@ script: description: Link to the creator of the content. type: String - contextPath: ConfluenceCloud.Content.history.createdDate - description: Date and time, in ISO 8601 format, when the content was created. + description: Date and time, in ISO 8601 format, when the content was created (e.g., 2024-01-15T12:34:56Z). type: Date - contextPath: ConfluenceCloud.Content.history._links.self description: Link to the history of the content. @@ -1549,7 +2062,7 @@ script: description: Link to the user who last updated the content. type: String - contextPath: ConfluenceCloud.Content.version.when - description: Date and time, in ISO 8601 format, when the content was updated. + description: Date and time, in ISO 8601 format, when the content was updated (e.g., 2024-01-15T12:34:56Z). type: Date - contextPath: ConfluenceCloud.Content.version.friendlyWhen description: Display the information of when the content was created. @@ -1775,7 +2288,7 @@ script: description: Link to the creator of the content. type: String - contextPath: ConfluenceCloud.Content.history.createdDate - description: Date and time, in ISO 8601 format, when the content was created. + description: Date and time, in ISO 8601 format, when the content was created (e.g., 2024-01-15T12:34:56Z). type: Date - contextPath: ConfluenceCloud.Content.history._links.self description: Link to the history of the content. @@ -1817,7 +2330,7 @@ script: description: Link to the user who last updated the content. type: String - contextPath: ConfluenceCloud.Content.version.when - description: Date and time, in ISO 8601 format, when the content was updated. + description: Date and time, in ISO 8601 format, when the content was updated (e.g., 2024-01-15T12:34:56Z). type: Date - contextPath: ConfluenceCloud.Content.version.friendlyWhen description: Displays when the content was created. @@ -1984,19 +2497,19 @@ script: description: Link to the group. type: String - arguments: - - name: should_push_events - description: Set this argument to True in order to create events, otherwise the command will only display them. - auto: PREDEFINED - predefined: - - "true" - - "false" - defaultValue: "false" - - name: start_date - description: Filters the results to the records on or after the start date. The start date must be specified as epoch time in milliseconds. - - name: limit - description: The maximum number of records to return per page. Note, this may be restricted by fixed system limits. + - name: should_push_events + description: Set this argument to True in order to create events, otherwise the command will only display them. + auto: PREDEFINED + predefined: + - "true" + - "false" + defaultValue: "false" + - name: start_date + description: Filters the results to the records on or after the start date. The start date must be specified as epoch time in milliseconds. + - name: limit + description: The maximum number of records to return per page. Note, this may be restricted by fixed system limits. name: confluence-cloud-get-events - description: Retrieves a list of events from the Atlassian Confluence Cloud instance. + description: Retrieves a list of events from the Atlassian Confluence Cloud instance. Use this command for development and debugging only, as it may produce duplicate events, exceed API rate limits, or disrupt the fetch mechanism. outputs: - contextPath: ConfluenceCloud.Event.author.type description: The type of author who created this event. @@ -2080,8 +2593,9 @@ script: - description: The ID of the Content that should be retrieved. name: content_id required: true - description: Retrieves a Content Item by its Content ID. - name: confluence-cloud-content-get + description: Deprecated. Use confluence-cloud-page-list or confluence-cloud-blogpost-list instead. Retrieves a Content Item by its Content ID. + name: confluence-cloud-content-get + deprecated: true outputs: - contextPath: ConfluenceCloud.Content.id description: The content ID. diff --git a/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/AtlassianConfluenceCloud_description.md b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/AtlassianConfluenceCloud_description.md index d9e4fdaacfb3..7cc5c756f995 100644 --- a/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/AtlassianConfluenceCloud_description.md +++ b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/AtlassianConfluenceCloud_description.md @@ -21,19 +21,23 @@ OAuth 2.0 provides a more secure authentication method using the Atlassian Devel #### Create an OAuth 2.0 App 1. Go to the [Atlassian Developer Console](https://developer.atlassian.com/console/myapps/) -2. Click "Create" and select "OAuth 2.0 integration" -3. Enter a name for your app and click "Create" -4. Navigate to "Permissions" and add the required Confluence API scopes: +2. Click **Create** and select **OAuth 2.0 integration** +3. Enter a name for your app and click **Create** +4. Navigate to **Permissions** and add the required Confluence API scopes. The integration uses the Confluence REST API v2 and requires the following granular scopes: - `read:audit-log:confluence` — **Required for event fetching** (audit log access) - - `read:confluence-content.all` — Read all Confluence content - - `read:confluence-space.summary` — Read space summaries - - `read:confluence-user` — Read user information - - `read:confluence-groups` — Read group information - - `write:confluence-content` — Write content - - `write:confluence-space` — Write space data + - `read:content:confluence`, `write:content:confluence`, `delete:content:confluence` — Read, write, and delete content + - `read:content-details:confluence` — Read content details + - `read:page:confluence`, `write:page:confluence`, `delete:page:confluence` — Read, write, and delete pages + - `read:blogpost:confluence`, `write:blogpost:confluence`, `delete:blogpost:confluence` — Read, write, and delete blog posts + - `read:custom-content:confluence`, `write:custom-content:confluence`, `delete:custom-content:confluence` — Manage custom content + - `read:comment:confluence`, `write:comment:confluence` — Read and write footer comments + - `write:template:confluence` — Manage templates + - `read:space:confluence`, `write:space:confluence`, `delete:space:confluence` — Read, write, and delete spaces + - `read:space-details:confluence` — Read space details + - `read:group:confluence` — Read group information - `offline_access` — Enables refresh token for unattended access -5. Navigate to "Authorization" and configure the callback URL -6. Navigate to "Settings" to find your Client ID and Client Secret +5. Navigate to **Authorization** and configure the callback URL +6. Navigate to **Settings** to find your Client ID and Client Secret #### Find Your Cloud ID Your Cloud ID can be found by: @@ -42,7 +46,9 @@ Your Cloud ID can be found by: 3. The `cloudId` field contains your Cloud ID #### Configure the Integration -1. Select "oauth" as the Authentication Type +1. Select **oauth** as the **Authentication Type** 2. Enter your Client ID 3. Enter your Client Secret 4. Enter your Cloud ID + +> **Note:** Upgrading from a previous version? The new REST API v2 commands (pages, blog posts, footer comments, and spaces) need additional granular OAuth scopes. Add the scopes listed above to your OAuth 2.0 app, then re-authenticate by running `!confluence-cloud-oauth-start` and `!confluence-cloud-oauth-complete`. This reissues the access token with the new permissions. \ No newline at end of file diff --git a/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/AtlassianConfluenceCloud_test.py b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/AtlassianConfluenceCloud_test.py index 978a84d58f40..0352084f0254 100644 --- a/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/AtlassianConfluenceCloud_test.py +++ b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/AtlassianConfluenceCloud_test.py @@ -6,6 +6,7 @@ DEFAULT_GET_EVENTS_LIMIT, MESSAGES, URL_SUFFIX, + URL_SUFFIX_V2, Client, create_client, create_oauth_client, @@ -1444,6 +1445,486 @@ def test_create_client_site_name_only(self): assert isinstance(result, Client) +# --- REST API v2 command tests --- + + +def test_confluence_cloud_page_create_command(requests_mock): + """ + Given: Command arguments for the page-create command. + When: Calling `confluence-cloud-page-create`. + Then: The response data is returned in the ConfluenceCloud.Page context. + """ + from AtlassianConfluenceCloud import confluence_cloud_page_create_command + + expected_response = util_load_json(os.path.join("test_data", "page_create/page_create_command_response.json")) + requests_mock.post(BASE_URL + URL_SUFFIX_V2["PAGES"], json=expected_response) + expected_context = util_load_json(os.path.join("test_data", "page_create/page_create_command_context.json")) + with open(os.path.join("test_data", "page_create/page_create_command.md")) as f: + expected_readable_output = f.read() + + args = {"space_id": "98765", "title": "XSOAR_Page", "body_value": "

Hello

"} + response = confluence_cloud_page_create_command(client, args) + + assert response.outputs_prefix == "ConfluenceCloud.Page" + assert response.outputs_key_field == "id" + assert response.outputs == expected_context + assert response.readable_output == expected_readable_output + + +@pytest.mark.parametrize("args, err_msg", input_data.content_create_v2_invalid_args) +def test_confluence_cloud_page_create_command_invalid_args(args, err_msg): + """ + Given: Invalid command arguments for the page-create command. + When: Calling the validation helper. + Then: A ValueError with the expected message is raised. + """ + from AtlassianConfluenceCloud import validate_content_create_args_v2 + + with pytest.raises(ValueError) as de: + validate_content_create_args_v2(args) + assert str(de.value) == err_msg + + +def test_confluence_cloud_page_list_command(requests_mock): + """ + Given: Command arguments for the page-list command with a single page of results. + When: Calling `confluence-cloud-page-list` with a limit larger than the available results. + Then: The results are returned and no manual next-page token is emitted (auto-pagination). + """ + from AtlassianConfluenceCloud import confluence_cloud_page_list_command + + expected_response = util_load_json(os.path.join("test_data", "page_list/page_list_command_response.json")) + requests_mock.get(BASE_URL + URL_SUFFIX_V2["PAGES"], json=expected_response) + expected_context = util_load_json(os.path.join("test_data", "page_list/page_list_command_context.json")) + + response = confluence_cloud_page_list_command(client, {"space_id": "98765"}) + + assert response.outputs["ConfluenceCloud.Page(val.id == obj.id)"] == expected_context + # Auto-pagination replaced the manual cursor output; no PageToken should be emitted. + assert "ConfluenceCloud.PageToken.Content(val.name == obj.name)" not in response.outputs + + +def test_confluence_cloud_page_list_command_empty(requests_mock): + """ + Given: A page-list response with no results. + When: Calling `confluence-cloud-page-list`. + Then: A no-records-found message is returned. + """ + from AtlassianConfluenceCloud import confluence_cloud_page_list_command + + requests_mock.get(BASE_URL + URL_SUFFIX_V2["PAGES"], json={"results": []}) + response = confluence_cloud_page_list_command(client, {}) + assert response.readable_output == MESSAGES["NO_RECORDS_FOUND"].format("page(s)") + + +@pytest.mark.parametrize("args, err_msg", input_data.content_list_v2_invalid_args) +def test_confluence_cloud_page_list_command_invalid_args(args, err_msg): + """ + Given: Invalid arguments for the page-list command. + When: Calling the validation helper. + Then: A ValueError with the expected message is raised. + """ + from AtlassianConfluenceCloud import CONTENT_V2_CONFIG, validate_content_list_args_v2 + + with pytest.raises(ValueError) as de: + validate_content_list_args_v2(args, CONTENT_V2_CONFIG["page"]) + assert str(de.value) == err_msg + + +def test_confluence_cloud_page_update_command(requests_mock): + """ + Given: Command arguments for the page-update command. + When: Calling `confluence-cloud-page-update`. + Then: The updated page is returned. + """ + from AtlassianConfluenceCloud import confluence_cloud_page_update_command + + expected_response = util_load_json(os.path.join("test_data", "page_create/page_create_command_response.json")) + requests_mock.put(BASE_URL + URL_SUFFIX_V2["PAGES"] + "/12345", json=expected_response) + + args = {"page_id": "12345", "version_number": "2", "title": "XSOAR_Page", "body_value": "

Updated

"} + response = confluence_cloud_page_update_command(client, args) + + assert response.outputs_prefix == "ConfluenceCloud.Page" + assert response.outputs_key_field == "id" + + +def test_confluence_cloud_page_delete_command(requests_mock): + """ + Given: Command arguments for the page-delete command. + When: Calling `confluence-cloud-page-delete`. + Then: A success message is returned. + """ + from AtlassianConfluenceCloud import confluence_cloud_page_delete_command + + requests_mock.delete(BASE_URL + URL_SUFFIX_V2["PAGES"] + "/12345", status_code=204) + response = confluence_cloud_page_delete_command(client, {"page_id": "12345"}) + assert response.readable_output == MESSAGES["HR_PAGE_DELETE"].format("12345") + + +def test_confluence_cloud_blogpost_create_command(requests_mock): + """ + Given: Command arguments for the blogpost-create command. + When: Calling `confluence-cloud-blogpost-create`. + Then: The response data is returned in the ConfluenceCloud.Blogpost context. + """ + from AtlassianConfluenceCloud import confluence_cloud_blogpost_create_command + + expected_response = util_load_json(os.path.join("test_data", "page_create/page_create_command_response.json")) + requests_mock.post(BASE_URL + URL_SUFFIX_V2["BLOGPOSTS"], json=expected_response) + + args = {"space_id": "98765", "title": "XSOAR_Page", "body_value": "

Hello

"} + response = confluence_cloud_blogpost_create_command(client, args) + + assert response.outputs_prefix == "ConfluenceCloud.Blogpost" + assert response.outputs_key_field == "id" + + +def test_confluence_cloud_blogpost_delete_command(requests_mock): + """ + Given: Command arguments for the blogpost-delete command. + When: Calling `confluence-cloud-blogpost-delete`. + Then: A success message is returned. + """ + from AtlassianConfluenceCloud import confluence_cloud_blogpost_delete_command + + requests_mock.delete(BASE_URL + URL_SUFFIX_V2["BLOGPOSTS"] + "/12345", status_code=204) + response = confluence_cloud_blogpost_delete_command(client, {"blogpost_id": "12345"}) + assert response.readable_output == MESSAGES["HR_BLOGPOST_DELETE"].format("12345") + + +def test_confluence_cloud_footer_comment_create_command(requests_mock): + """ + Given: Command arguments for the footer-comment-create command. + When: Calling `confluence-cloud-footer-comment-create`. + Then: The response data is returned in the ConfluenceCloud.Comment context. + """ + from AtlassianConfluenceCloud import confluence_cloud_footer_comment_create_command + + expected_response = util_load_json( + os.path.join("test_data", "footer_comment_create/footer_comment_create_command_response.json") + ) + requests_mock.post(BASE_URL + URL_SUFFIX_V2["FOOTER_COMMENTS"], json=expected_response) + expected_context = util_load_json( + os.path.join("test_data", "footer_comment_create/footer_comment_create_command_context.json") + ) + with open(os.path.join("test_data", "footer_comment_create/footer_comment_create_command.md")) as f: + expected_readable_output = f.read() + + args = {"body_value": "

This is a footer comment

", "page_id": "12345"} + response = confluence_cloud_footer_comment_create_command(client, args) + + assert response.outputs_prefix == "ConfluenceCloud.Comment" + assert response.outputs == expected_context + assert response.readable_output == expected_readable_output + + +@pytest.mark.parametrize("args, err_msg", input_data.comment_create_v2_invalid_args) +def test_confluence_cloud_comment_create_command_invalid_args(args, err_msg): + """ + Given: Invalid arguments for the comment-create commands. + When: Calling the validation helper. + Then: A ValueError with the expected message is raised. + """ + from AtlassianConfluenceCloud import validate_comment_create_args_v2 + + with pytest.raises(ValueError) as de: + validate_comment_create_args_v2(args) + assert str(de.value) == err_msg + + +def test_confluence_cloud_space_list_command_v2(requests_mock): + """ + Given: Command arguments for the space-listv2 command. + When: Calling `confluence-cloud-space-listv2`. + Then: The space results are returned. + """ + from AtlassianConfluenceCloud import confluence_cloud_space_list_command_v2 + + expected_response = util_load_json(os.path.join("test_data", "space_list_v2/space_list_v2_command_response.json")) + requests_mock.get(BASE_URL + URL_SUFFIX_V2["SPACES"], json=expected_response) + expected_context = util_load_json(os.path.join("test_data", "space_list_v2/space_list_v2_command_context.json")) + with open(os.path.join("test_data", "space_list_v2/space_list_v2_command.md")) as f: + expected_readable_output = f.read() + + response = confluence_cloud_space_list_command_v2(client, {}) + + assert response.outputs["ConfluenceCloud.Space(val.id == obj.id)"] == expected_context + assert response.readable_output == expected_readable_output + + +@pytest.mark.parametrize("args, err_msg", input_data.space_list_v2_invalid_args) +def test_confluence_cloud_space_list_command_v2_invalid_args(args, err_msg): + """ + Given: Invalid arguments for the space-listv2 command. + When: Calling the validation helper. + Then: A ValueError with the expected message is raised. + """ + from AtlassianConfluenceCloud import validate_space_list_args_v2 + + with pytest.raises(ValueError) as de: + validate_space_list_args_v2(args) + assert str(de.value) == err_msg + + +def test_confluence_cloud_space_create_command_v2(requests_mock): + """ + Given: Command arguments for the space-createv2 command. + When: Calling `confluence-cloud-space-createv2`. + Then: The created space is returned. + """ + from AtlassianConfluenceCloud import confluence_cloud_space_create_command_v2 + + expected_response = util_load_json(os.path.join("test_data", "space_create_v2/space_create_v2_command_response.json")) + requests_mock.post(BASE_URL + URL_SUFFIX_V2["SPACES"], json=expected_response) + expected_context = util_load_json(os.path.join("test_data", "space_create_v2/space_create_v2_command_context.json")) + with open(os.path.join("test_data", "space_create_v2/space_create_v2_command.md")) as f: + expected_readable_output = f.read() + + args = {"name": "XSOAR Space", "key": "XSOAR"} + response = confluence_cloud_space_create_command_v2(client, args) + + assert response.outputs_prefix == "ConfluenceCloud.Space" + assert response.outputs == expected_context + assert response.readable_output == expected_readable_output + + +@pytest.mark.parametrize("args, err_msg", input_data.space_create_v2_invalid_args) +def test_confluence_cloud_space_create_command_v2_invalid_args(args, err_msg): + """ + Given: Invalid arguments for the space-createv2 command. + When: Calling the validation helper. + Then: A ValueError with the expected message is raised. + """ + from AtlassianConfluenceCloud import validate_space_create_args_v2 + + with pytest.raises(ValueError) as de: + validate_space_create_args_v2(args) + assert str(de.value) == err_msg + + +def test_confluence_cloud_blogpost_list_command(requests_mock): + """ + Given: Command arguments for the blogpost-list command with a single page of results. + When: Calling `confluence-cloud-blogpost-list`. + Then: The results are returned under the Blogpost context and no next-page token is emitted. + """ + from AtlassianConfluenceCloud import confluence_cloud_blogpost_list_command + + expected_response = util_load_json(os.path.join("test_data", "page_list/page_list_command_response.json")) + requests_mock.get(BASE_URL + URL_SUFFIX_V2["BLOGPOSTS"], json=expected_response) + + response = confluence_cloud_blogpost_list_command(client, {"space_id": "98765"}) + + assert "ConfluenceCloud.Blogpost(val.id == obj.id)" in response.outputs + assert len(response.outputs["ConfluenceCloud.Blogpost(val.id == obj.id)"]) == 2 + assert "ConfluenceCloud.PageToken.Content(val.name == obj.name)" not in response.outputs + + +def test_confluence_cloud_blogpost_list_command_empty(requests_mock): + """ + Given: A blogpost-list response with no results. + When: Calling `confluence-cloud-blogpost-list`. + Then: A no-records-found message is returned. + """ + from AtlassianConfluenceCloud import confluence_cloud_blogpost_list_command + + requests_mock.get(BASE_URL + URL_SUFFIX_V2["BLOGPOSTS"], json={"results": []}) + response = confluence_cloud_blogpost_list_command(client, {}) + assert response.readable_output == MESSAGES["NO_RECORDS_FOUND"].format("blog post(s)") + + +def test_confluence_cloud_blogpost_update_command(requests_mock): + """ + Given: Command arguments for the blogpost-update command. + When: Calling `confluence-cloud-blogpost-update`. + Then: The updated blogpost is returned under the Blogpost context. + """ + from AtlassianConfluenceCloud import confluence_cloud_blogpost_update_command + + expected_response = util_load_json(os.path.join("test_data", "page_create/page_create_command_response.json")) + requests_mock.put(BASE_URL + URL_SUFFIX_V2["BLOGPOSTS"] + "/12345", json=expected_response) + + args = {"blogpost_id": "12345", "version_number": "2", "title": "XSOAR_Blogpost", "body_value": "

Updated

"} + response = confluence_cloud_blogpost_update_command(client, args) + + assert response.outputs_prefix == "ConfluenceCloud.Blogpost" + assert response.outputs_key_field == "id" + + +def test_confluence_cloud_page_list_command_auto_paginates_to_limit(requests_mock): + """ + Given: A page-list request with limit=3 and an API that returns 2 results per page with a next cursor. + When: Calling `confluence-cloud-page-list`. + Then: The command follows the cursor across pages and returns exactly `limit` (3) records. + """ + from AtlassianConfluenceCloud import confluence_cloud_page_list_command + + first_page = { + "results": [{"id": "1", "title": "P1"}, {"id": "2", "title": "P2"}], + "_links": {"base": f"{BASE_URL}/wiki"}, + } + second_page = { + "results": [{"id": "3", "title": "P3"}, {"id": "4", "title": "P4"}], + "_links": {"base": f"{BASE_URL}/wiki"}, + } + next_link = f'<{BASE_URL}/wiki/api/v2/pages?cursor=NEXT_CURSOR>; rel="next"' + requests_mock.get( + BASE_URL + URL_SUFFIX_V2["PAGES"], + [ + {"json": first_page, "headers": {"Link": next_link}}, + {"json": second_page}, + ], + ) + + response = confluence_cloud_page_list_command(client, {"space_id": "98765", "limit": "3"}) + + results = response.outputs["ConfluenceCloud.Page(val.id == obj.id)"] + assert [item["id"] for item in results] == ["1", "2", "3"] + assert requests_mock.call_count == 2 + + +def test_confluence_cloud_page_list_command_stops_when_no_next_cursor(requests_mock): + """ + Given: A page-list request with a large limit but the API returns a single page with no next cursor. + When: Calling `confluence-cloud-page-list`. + Then: The command returns the available results without issuing further requests. + """ + from AtlassianConfluenceCloud import confluence_cloud_page_list_command + + single_page = {"results": [{"id": "1", "title": "P1"}], "_links": {"base": f"{BASE_URL}/wiki"}} + requests_mock.get(BASE_URL + URL_SUFFIX_V2["PAGES"], json=single_page) + + response = confluence_cloud_page_list_command(client, {"space_id": "98765", "limit": "500"}) + + assert len(response.outputs["ConfluenceCloud.Page(val.id == obj.id)"]) == 1 + assert requests_mock.call_count == 1 + + +def test_paginate_v2_results_caps_per_page_request_at_max(requests_mock): + """ + Given: A total limit larger than the API single-page maximum (MAX_LIMIT_V2). + When: Calling paginate_v2_results. + Then: The first per-page request uses limit=MAX_LIMIT_V2, not the full total. + """ + from AtlassianConfluenceCloud import MAX_LIMIT_V2, URL_SUFFIX_V2, paginate_v2_results + + page = {"results": [{"id": str(i)} for i in range(MAX_LIMIT_V2)], "_links": {}} + next_link = f'<{BASE_URL}/wiki/api/v2/pages?cursor=C2>; rel="next"' + last_page = {"results": [{"id": "last"}], "_links": {}} + requests_mock.get( + BASE_URL + URL_SUFFIX_V2["PAGES"], + [ + {"json": page, "headers": {"Link": next_link}}, + {"json": last_page}, + ], + ) + + results, _ = paginate_v2_results(client, URL_SUFFIX_V2["PAGES"], {}, MAX_LIMIT_V2 + 1) + + assert len(results) == MAX_LIMIT_V2 + 1 + assert int(requests_mock.request_history[0].qs["limit"][0]) == MAX_LIMIT_V2 + + +def test_validate_limit_v2_allows_value_above_previous_cap(): + """ + Given: A limit value larger than the old 250 hard cap. + When: Calling validate_limit_v2. + Then: The value is accepted and returned (the artificial cap was removed). + """ + from AtlassianConfluenceCloud import validate_limit_v2 + + assert validate_limit_v2({"limit": "1000"}) == 1000 + + +@pytest.mark.parametrize("bad_limit", ["0", "-5"]) +def test_validate_limit_v2_rejects_non_positive(bad_limit): + """ + Given: A non-positive limit value. + When: Calling validate_limit_v2. + Then: A ValueError with the INVALID_LIMIT_V2 message is raised. + """ + from AtlassianConfluenceCloud import validate_limit_v2 + + with pytest.raises(ValueError) as de: + validate_limit_v2({"limit": bad_limit}) + assert str(de.value) == MESSAGES["INVALID_LIMIT_V2"].format(int(bad_limit)) + + +def test_prepare_space_create_params_v2_invalid_role_assignments(): + """ + Given: A role_assignments argument that is not valid JSON. + When: Building space-create v2 params. + Then: A ValueError with the role_assignments-specific message is raised (not the advanced_permissions one). + """ + from AtlassianConfluenceCloud import prepare_space_create_params_v2 + + args = {"name": "XSOAR Space", "key": "XSOAR", "role_assignments": "not-json"} + with pytest.raises(ValueError) as de: + prepare_space_create_params_v2(args) + assert str(de.value) == MESSAGES["INVALID_ROLE_ASSIGNMENTS_V2"] + + +def test_validate_content_update_args_v2_invalid_status_uses_update_message(): + """ + Given: An invalid status on the content-update v2 path. + When: Validating update args. + Then: The error uses the update-specific message and echoes the received value. + """ + from AtlassianConfluenceCloud import CONTENT_V2_CONFIG, validate_content_update_args_v2 + + args = {"page_id": "12345", "version_number": "2", "status": "archived"} + with pytest.raises(ValueError) as de: + validate_content_update_args_v2(args, CONTENT_V2_CONFIG["page"]) + assert str(de.value) == f"{MESSAGES['INVALID_STATUS_UPDATE_V2']} Received: 'archived'." + + +def test_prepare_hr_for_content_v2_handles_null_version(): + """ + Given: A content object where the API returned version as null. + When: Preparing the human-readable output. + Then: No AttributeError is raised and the Version field is empty. + """ + from AtlassianConfluenceCloud import prepare_hr_for_content_list_v2 + + content = [{"id": "1", "title": "P1", "status": "current", "createdAt": "2024-01-01T10:00:00.000Z", "version": None}] + # Should not raise AttributeError on null version. + hr = prepare_hr_for_content_list_v2(content, "Page") + assert "P1" in hr + + +def test_prepare_hr_for_comment_v2_handles_null_version(): + """ + Given: A comment object where the API returned version as null. + When: Preparing the human-readable output. + Then: No AttributeError is raised. + """ + from AtlassianConfluenceCloud import prepare_hr_for_comment_v2 + + comment = {"id": "1", "status": "current", "version": None} + # Should not raise AttributeError on null version. + prepare_hr_for_comment_v2(comment, "Footer Comment") + + +def test_prepare_cursor_from_link_header(): + """ + Given: A requests.Response with a Link header containing a next cursor. + When: Calling prepare_cursor_from_link_header. + Then: The cursor value is extracted correctly. + """ + from AtlassianConfluenceCloud import prepare_cursor_from_link_header + + response = MagicMock() + response.headers = {"Link": f'<{BASE_URL}/wiki/api/v2/pages?limit=25&cursor=ABC123>; rel="next"'} + assert prepare_cursor_from_link_header(response) == "ABC123" + + response.headers = {} + assert prepare_cursor_from_link_header(response) == "" + + response.headers = {"Link": f'<{BASE_URL}/wiki/api/v2/pages?cursor=PREV>; rel="prev"'} + assert prepare_cursor_from_link_header(response) == "" + + @pytest.mark.parametrize( "url, expected_id", [ diff --git a/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/README.md b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/README.md index b8427061df62..0efaa2bbe799 100644 --- a/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/README.md +++ b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/README.md @@ -3687,7 +3687,9 @@ Note: Updating draft content is currently not supported. ### confluence-cloud-content-search *** -Retrieves a list of content using the Confluence Query Language (CQL).

For more information on CQL, see: https://developer.atlassian.com/cloud/confluence/advanced-searching-using-cql/. +Retrieves a list of content using the Confluence Query Language (CQL). + +For more information on CQL, see: https://developer.atlassian.com/cloud/confluence/advanced-searching-using-cql/. #### Base Command @@ -3698,10 +3700,10 @@ Retrieves a list of content using the Confluence Query Language (CQL).

| **Argument Name** | **Description** | **Required** | | --- | --- | --- | | query | The CQL (Confluence Query Language) string that is used to find the requested content. | Required | -| limit | Number of records to retrieve in the response.

Note: The minimum value supported is 0 and the maximum value supported is int32.

Default is 50. | Optional | -| content_status | Filter the result based on the content status.
Possible values: current, draft, archived.

Note: Supports multiple comma-separated values. | Optional | +| limit | Number of records to retrieve in the response.

Note: The minimum value supported is 0 and the maximum value supported is int32. Default is 50. | Optional | +| content_status | Filter the result based on the content status.
Possible values: current, draft, archived.

Note: Supports multiple comma-separated values. Possible values are: . | Optional | | next_page_token | Retrieves the next page records for the given query (next_page_token retrieved in previous content response). | Optional | -| expand | Indicates which properties to expand.
For reference, visit https://developer.atlassian.com/cloud/confluence/rest/api-group-content/#api-wiki-rest-api-content-search-get.

Note: To separate multiple values, use commas. Expanded properties will be populated in context data only. | Optional | +| expand | Indicates which properties to expand.
For reference, visit https://developer.atlassian.com/cloud/confluence/rest/api-group-content/#api-wiki-rest-api-content-search-get.

Note: To separate multiple values, use commas. Expanded properties will be populated in context data only. | Optional | #### Context Output @@ -3716,7 +3718,7 @@ Retrieves a list of content using the Confluence Query Language (CQL).

| ConfluenceCloud.Content.childTypes.comment.value | Boolean | Whether a comment is associated with the given content. | | ConfluenceCloud.Content.childTypes.comment._links.self | String | Link to the comment associated with the given content. | | ConfluenceCloud.Content.childTypes.page.value | Boolean | Whether the page is associated with the given content. | -| ConfluenceCloud.Content.childTypes.page._links.self | String | Link to the page associated with given content. | +| ConfluenceCloud.Content.childTypes.page._links.self | String | Link to the page associated with the given content. | | ConfluenceCloud.Content.space.id | Number | ID of the space that the content is being created in. | | ConfluenceCloud.Content.space.key | String | Key of the space that the content is being created in. | | ConfluenceCloud.Content.space.name | String | Name of the space that the content is being created in. | @@ -3737,7 +3739,7 @@ Retrieves a list of content using the Confluence Query Language (CQL).

| ConfluenceCloud.Content.history.createdBy.displayName | String | Display name of the user who created the content. | | ConfluenceCloud.Content.history.createdBy.isExternalCollaborator | Boolean | Whether the user is an external collaborator. | | ConfluenceCloud.Content.history.createdBy._links.self | String | Link to the creator of the content. | -| ConfluenceCloud.Content.history.createdDate | Date | Date and time, in ISO 8601 format, when the content was created. | +| ConfluenceCloud.Content.history.createdDate | Date | Date and time, in ISO 8601 format, when the content was created \(e.g., 2024-01-15T12:34:56Z\). | | ConfluenceCloud.Content.history._links.self | String | Link to the history of the content. | | ConfluenceCloud.Content.version.by.type | String | Type of the user who last updated the content. | | ConfluenceCloud.Content.version.by.accountId | String | Account ID of the user who last updated the content. | @@ -3751,13 +3753,13 @@ Retrieves a list of content using the Confluence Query Language (CQL).

| ConfluenceCloud.Content.version.by.displayName | String | Display name of the user who last updated the content. | | ConfluenceCloud.Content.version.by.isExternalCollaborator | Boolean | Whether the user is an external collaborator. | | ConfluenceCloud.Content.version.by._links.self | String | Link to the user who last updated the content. | -| ConfluenceCloud.Content.version.when | Date | Date and time, in ISO 8601 format, when the content was updated. | +| ConfluenceCloud.Content.version.when | Date | Date and time, in ISO 8601 format, when the content was updated \(e.g., 2024-01-15T12:34:56Z\). | | ConfluenceCloud.Content.version.friendlyWhen | String | Displays when the content was created. | | ConfluenceCloud.Content.version.message | String | Message of the updated content. | | ConfluenceCloud.Content.version.number | Number | Version number of the updated content. | | ConfluenceCloud.Content.version.minorEdit | Boolean | Whether the edit was minor. | | ConfluenceCloud.Content.version.confRev | String | The revision ID provided by Confluence to be used as a revision in Synchrony. | -| ConfluenceCloud.Content.version.contentTypeModified | Boolean | True if the content type is modified in the version. \(e.g., page to blog\) | +| ConfluenceCloud.Content.version.contentTypeModified | Boolean | True if the content type is modified in the version. \(e.g., page to blog\). | | ConfluenceCloud.Content.version._links.self | String | Link to the new version of the content. | | ConfluenceCloud.Content.ancestors.id | String | ID of the parent page of the content. | | ConfluenceCloud.Content.ancestors.type | String | Type of the parent page of the content. | @@ -3779,350 +3781,6 @@ Retrieves a list of content using the Confluence Query Language (CQL).

| ConfluenceCloud.PageToken.name | String | The command name. | | ConfluenceCloud.PageToken.next_token | String | The next page token. | -#### Command Example - -```!confluence-cloud-content-search query="type=page" limit=2``` - -#### Context Example - -```json -{ - "ConfluenceCloud": { - "Content": [ - { - "_expandable": { - "children": "/rest/api/content/8912897/child", - "descendants": "/rest/api/content/8912897/descendant", - "restrictions": "/rest/api/content/8912897/restriction/byOperation" - }, - "_links": { - "editui": "/pages/resumedraft.action?draftId=8912897", - "self": "https://xsoar-bd.atlassian.net/wiki/rest/api/content/8912897", - "tinyui": "/x/AQCI", - "webui": "/spaces/TRIAL/pages/8912897/Trial_1" - }, - "ancestors": [ - { - "_expandable": { - "children": "/rest/api/content/7798799/child", - "container": "/rest/api/space/TRIAL", - "descendants": "/rest/api/content/7798799/descendant", - "history": "/rest/api/content/7798799/history", - "restrictions": "/rest/api/content/7798799/restriction/byOperation", - "space": "/rest/api/space/TRIAL" - }, - "_links": { - "editui": "/pages/resumedraft.action?draftId=7798799", - "self": "https://xsoar-bd.atlassian.net/wiki/rest/api/content/7798799", - "tinyui": "/x/DwB3", - "webui": "/spaces/TRIAL/pages/7798799/Trial1212" - }, - "extensions": { - "position": 4059 - }, - "id": "7798799", - "status": "current", - "title": "Trial1212", - "type": "page" - } - ], - "childTypes": { - "attachment": { - "_links": { - "self": "https://xsoar-bd.atlassian.net/wiki/rest/api/content/8912897/child/attachment" - }, - "value": false - }, - "comment": { - "_links": { - "self": "https://xsoar-bd.atlassian.net/wiki/rest/api/content/8912897/child/comment" - }, - "value": false - }, - "page": { - "_links": { - "self": "https://xsoar-bd.atlassian.net/wiki/rest/api/content/8912897/child/page" - }, - "value": false - } - }, - "container": { - "_expandable": { - "lookAndFeel": "/rest/api/settings/lookandfeel?spaceKey=TRIAL", - "settings": "/rest/api/space/TRIAL/settings", - "theme": "/rest/api/space/TRIAL/theme" - }, - "_links": { - "self": "https://xsoar-bd.atlassian.net/wiki/rest/api/space/TRIAL", - "webui": "/spaces/TRIAL" - }, - "id": 33012, - "key": "TRIAL", - "name": "Trial", - "status": "current", - "type": "global" - }, - "extensions": { - "position": 96200139 - }, - "history": { - "_links": { - "self": "https://xsoar-bd.atlassian.net/wiki/rest/api/content/8912897/history" - }, - "createdBy": { - "_links": { - "self": "https://xsoar-bd.atlassian.net/wiki/rest/api/user?accountId=5ff2e30b4d2179006ea18449" - }, - "accountId": "5ff2e30b4d2179006ea18449", - "accountType": "atlassian", - "displayName": "John Doe", - "email": "dummy.dummy@dummy.com", - "isExternalCollaborator": false, - "profilePicture": { - "height": 48, - "isDefault": false, - "path": "/wiki/aa-avatar/5ff2e30b4d2179006ea18449", - "width": 48 - }, - "publicName": "John Doe", - "type": "known" - }, - "createdDate": "2021-08-19T09:11:19.755Z", - "latest": true - }, - "id": "8912897", - "space": { - "_expandable": { - "lookAndFeel": "/rest/api/settings/lookandfeel?spaceKey=TRIAL", - "settings": "/rest/api/space/TRIAL/settings", - "theme": "/rest/api/space/TRIAL/theme" - }, - "_links": { - "self": "https://xsoar-bd.atlassian.net/wiki/rest/api/space/TRIAL", - "webui": "/spaces/TRIAL" - }, - "id": 33012, - "key": "TRIAL", - "name": "Trial", - "status": "current", - "type": "global" - }, - "status": "current", - "title": "Trial_1", - "type": "page", - "version": { - "_expandable": { - "content": "/rest/api/content/8912897" - }, - "_links": { - "self": "https://xsoar-bd.atlassian.net/wiki/rest/api/content/8912897/version/1" - }, - "by": { - "_links": { - "self": "https://xsoar-bd.atlassian.net/wiki/rest/api/user?accountId=5ff2e30b4d2179006ea18449" - }, - "accountId": "5ff2e30b4d2179006ea18449", - "accountType": "atlassian", - "displayName": "John Doe", - "email": "dummy.dummy@dummy.com", - "isExternalCollaborator": false, - "profilePicture": { - "height": 48, - "isDefault": false, - "path": "/wiki/aa-avatar/5ff2e30b4d2179006ea18449", - "width": 48 - }, - "publicName": "John Doe", - "type": "known" - }, - "confRev": "confluence$content$8912897.4", - "contentTypeModified": false, - "friendlyWhen": "Aug 19, 2021", - "minorEdit": false, - "number": 1, - "syncRev": "0.confluence$content$8912897.2", - "syncRevSource": "synchrony-ack", - "when": "2021-08-19T09:11:19.755Z" - } - }, - { - "_expandable": { - "children": "/rest/api/content/8847372/child", - "descendants": "/rest/api/content/8847372/descendant", - "restrictions": "/rest/api/content/8847372/restriction/byOperation" - }, - "_links": { - "editui": "/pages/resumedraft.action?draftId=8847372", - "self": "https://xsoar-bd.atlassian.net/wiki/rest/api/content/8847372", - "tinyui": "/x/DACH", - "webui": "/spaces/TRIAL/pages/8847372/Testing_XSOAR" - }, - "ancestors": [ - { - "_expandable": { - "children": "/rest/api/content/7798799/child", - "container": "/rest/api/space/TRIAL", - "descendants": "/rest/api/content/7798799/descendant", - "history": "/rest/api/content/7798799/history", - "restrictions": "/rest/api/content/7798799/restriction/byOperation", - "space": "/rest/api/space/TRIAL" - }, - "_links": { - "editui": "/pages/resumedraft.action?draftId=7798799", - "self": "https://xsoar-bd.atlassian.net/wiki/rest/api/content/7798799", - "tinyui": "/x/DwB3", - "webui": "/spaces/TRIAL/pages/7798799/Trial1212" - }, - "extensions": { - "position": 4059 - }, - "id": "7798799", - "status": "current", - "title": "Trial1212", - "type": "page" - } - ], - "childTypes": { - "attachment": { - "_links": { - "self": "https://xsoar-bd.atlassian.net/wiki/rest/api/content/8847372/child/attachment" - }, - "value": false - }, - "comment": { - "_links": { - "self": "https://xsoar-bd.atlassian.net/wiki/rest/api/content/8847372/child/comment" - }, - "value": false - }, - "page": { - "_links": { - "self": "https://xsoar-bd.atlassian.net/wiki/rest/api/content/8847372/child/page" - }, - "value": false - } - }, - "container": { - "_expandable": { - "lookAndFeel": "/rest/api/settings/lookandfeel?spaceKey=TRIAL", - "settings": "/rest/api/space/TRIAL/settings", - "theme": "/rest/api/space/TRIAL/theme" - }, - "_links": { - "self": "https://xsoar-bd.atlassian.net/wiki/rest/api/space/TRIAL", - "webui": "/spaces/TRIAL" - }, - "id": 33012, - "key": "TRIAL", - "name": "Trial", - "status": "current", - "type": "global" - }, - "extensions": { - "position": 633071049 - }, - "history": { - "_links": { - "self": "https://xsoar-bd.atlassian.net/wiki/rest/api/content/8847372/history" - }, - "createdBy": { - "_links": { - "self": "https://xsoar-bd.atlassian.net/wiki/rest/api/user?accountId=5ff2e30b4d2179006ea18449" - }, - "accountId": "5ff2e30b4d2179006ea18449", - "accountType": "atlassian", - "displayName": "John Doe", - "email": "dummy.dummy@dummy.com", - "isExternalCollaborator": false, - "profilePicture": { - "height": 48, - "isDefault": false, - "path": "/wiki/aa-avatar/5ff2e30b4d2179006ea18449", - "width": 48 - }, - "publicName": "John Doe", - "type": "known" - }, - "createdDate": "2021-08-19T10:09:37.066Z", - "latest": true - }, - "id": "8847372", - "space": { - "_expandable": { - "lookAndFeel": "/rest/api/settings/lookandfeel?spaceKey=TRIAL", - "settings": "/rest/api/space/TRIAL/settings", - "theme": "/rest/api/space/TRIAL/theme" - }, - "_links": { - "self": "https://xsoar-bd.atlassian.net/wiki/rest/api/space/TRIAL", - "webui": "/spaces/TRIAL" - }, - "id": 33012, - "key": "TRIAL", - "name": "Trial", - "status": "current", - "type": "global" - }, - "status": "current", - "title": "Testing_XSOAR", - "type": "page", - "version": { - "_expandable": { - "content": "/rest/api/content/8847372" - }, - "_links": { - "self": "https://xsoar-bd.atlassian.net/wiki/rest/api/content/8847372/version/1" - }, - "by": { - "_links": { - "self": "https://xsoar-bd.atlassian.net/wiki/rest/api/user?accountId=5ff2e30b4d2179006ea18449" - }, - "accountId": "5ff2e30b4d2179006ea18449", - "accountType": "atlassian", - "displayName": "John Doe", - "email": "dummy.dummy@dummy.com", - "isExternalCollaborator": false, - "profilePicture": { - "height": 48, - "isDefault": false, - "path": "/wiki/aa-avatar/5ff2e30b4d2179006ea18449", - "width": 48 - }, - "publicName": "John Doe", - "type": "known" - }, - "confRev": "confluence$content$8847372.4", - "contentTypeModified": false, - "friendlyWhen": "Aug 19, 2021", - "minorEdit": false, - "number": 1, - "syncRev": "0.confluence$content$8847372.2", - "syncRevSource": "synchrony-ack", - "when": "2021-08-19T10:09:37.066Z" - } - } - ], - "PageToken": { - "Content": { - "name": "confluence-cloud-content-search", - "next_token": "_sa_WyJcdDg4NDczNzIgUU5aRTlIVzxbclZnSitSZXBSTU4gY3AiXQ==" - } - } - } -} -``` - -#### Human Readable Output - ->### Content(s) -> ->|ID|Title|Type|Status|Space Name|Created By|Created At|Version| ->|---|---|---|---|---|---|---|---| ->| 8912897 | [Trial_1](https://xsoar-bd.atlassian.net/wiki/spaces/TRIAL/pages/8912897/Trial_1) | page | current | Trial | John Doe | 2021-08-19T09:11:19.755Z | 3 | ->| 8847372 | [Testing_XSOAR](https://xsoar-bd.atlassian.net/wiki/spaces/TRIAL/pages/8847372/Testing_XSOAR) | page | current | Trial | John Doe | 2021-08-19T10:09:37.066Z | 3 | -> -Run the command with argument next_page_token=_sa_WyJcdDg4NDczNzIgUU5aRTlIVzxbclZnSitSZXBSTU4gY3AiXQ== to see the next set of contents. - ### confluence-cloud-user-list *** @@ -4531,3 +4189,696 @@ There is no context output for this command. ```bash !confluence-cloud-oauth-test ``` + +### confluence-cloud-get-events + +*** +Retrieves a list of events from the Atlassian Confluence Cloud instance. Use this command for development and debugging only, as it may produce duplicate events, exceed API rate limits, or disrupt the fetch mechanism. + +#### Base Command + +`confluence-cloud-get-events` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| should_push_events | Set this argument to True in order to create events, otherwise the command will only display them. Possible values are: true, false. Default is false. | Optional | +| start_date | Filters the results to the records on or after the start date. The start date must be specified as epoch time in milliseconds. | Optional | +| limit | The maximum number of records to return per page. Note, this may be restricted by fixed system limits. | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| ConfluenceCloud.Event.author.type | String | The type of author who created this event. | +| ConfluenceCloud.Event.author.displayName | String | The display name of the author who created this event. | +| ConfluenceCloud.Event.author.operations | String | Nullable. Author's operations. | +| ConfluenceCloud.Event.author.username | String | Username of the author of this event. | +| ConfluenceCloud.Event.author.userKey | String | User key of the author of this event. | +| ConfluenceCloud.Event.author.accountId | String | Account ID of the author of this event. | +| ConfluenceCloud.Event.author.accountType | String | Type of account of the author of this event. | +| ConfluenceCloud.Event.author.externalCollaborator | Boolean | Deprecated. Is the author of this event an external collaborator. | +| ConfluenceCloud.Event.author.isExternalCollaborator | Boolean | Deprecated. Is the author of this event an external collaborator. | +| ConfluenceCloud.Event.author.publicName | String | The public name of the author of this event. | +| ConfluenceCloud.Event.remoteAddress | String | The remote address from which the event was performed. | +| ConfluenceCloud.Event.creationDate | Number | The creation date-time of the audit record, as a timestamp. | +| ConfluenceCloud.Event.summary | Strings | Summary of the audit. | +| ConfluenceCloud.Event.description | String | Description of the audit. | +| ConfluenceCloud.Event.category | String | Category of the event. | +| ConfluenceCloud.Event.sysAdmin | Boolean | Was the event created by a system administrator. | +| ConfluenceCloud.Event.superAdmin | Boolean | Was the event created by a super administrator. | +| ConfluenceCloud.Event.affectedObject.name | String | Name of the object affected by the event. | +| ConfluenceCloud.Event.affectedObject.objectType | String | Type of the object affected by the event. | +| ConfluenceCloud.Event.changedValues.name | String | Name of the changed value. | +| ConfluenceCloud.Event.changedValues.oldValue | String | The old value before the change the event describes. | +| ConfluenceCloud.Event.changedValues.hiddenOldValue | String | The old hidden value before the change the event describes. | +| ConfluenceCloud.Event.changedValues.newValue | String | The new value after the change the event describes. | +| ConfluenceCloud.Event.changedValues.hiddenNewValue | String | The new hidden value after the change the event describes. | +| ConfluenceCloud.Event.associatedObjects.name | String | Name of the associated object. | +| ConfluenceCloud.Event.associatedObjects.objectType | String | The type of the associated object. | + +### confluence-cloud-blogpost-create + +*** +Creates a new blog post in Confluence Cloud (REST API v2). + +#### Base Command + +`confluence-cloud-blogpost-create` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| space_id | The ID of the space where the blog post is created. Retrieve using the confluence-cloud-space-listv2 command. | Required | +| title | The title of the blog post. | Required | +| status | The status of the blog post to be created. Possible values are: current, draft. Default is current. | Optional | +| body_value | The content body value of the blog post. | Required | +| body_representation | The content format type of the body value. Possible values are: storage, atlas_doc_format, wiki. Default is storage. | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| ConfluenceCloud.Blogpost.id | String | The ID of the blog post. | +| ConfluenceCloud.Blogpost.status | String | The status of the blog post. | +| ConfluenceCloud.Blogpost.title | String | The title of the blog post. | +| ConfluenceCloud.Blogpost.spaceId | String | The ID of the space the blog post belongs to. | +| ConfluenceCloud.Blogpost.authorId | String | The account ID of the blog post author. | +| ConfluenceCloud.Blogpost.createdAt | Date | Date and time, in ISO 8601 format, when the blog post was created \(e.g., 2024-01-15T12:34:56Z\). | +| ConfluenceCloud.Blogpost.version.number | Number | The version number of the blog post. | + +#### Command example + +```!confluence-cloud-blogpost-create space_id=98765 title="XSOAR Blogpost" body_value="Blog content" body_representation=storage``` + +#### Context Example + +```json +{ + "ConfluenceCloud": { + "Blogpost": { + "id": "12345", + "status": "current", + "title": "XSOAR Blogpost", + "spaceId": "98765", + "authorId": "5ff2e30b4d2179006ea18449", + "createdAt": "2024-01-01T10:00:00.000Z", + "version": { + "number": 1 + } + } + } +} +``` + +#### Human Readable Output + +>### Blogpost +> +>|ID|Title|Status|Space Id|Author Id|Created At|Version| +>|---|---|---|---|---|---|---| +>| 12345 | XSOAR Blogpost | current | 98765 | 5ff2e30b4d2179006ea18449 | 2024-01-01T10:00:00.000Z | 1 | + +### confluence-cloud-blogpost-update + +*** +Updates an existing blog post in Confluence Cloud (REST API v2). + +#### Base Command + +`confluence-cloud-blogpost-update` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| blogpost_id | The ID of the blog post to update. | Required | +| version_number | The new version number for the blog post. Must be one greater than the current version. | Required | +| title | The title of the blog post. | Required | +| status | The status of the blog post. Possible values are: current, draft. Default is current. | Optional | +| body_value | The content body value of the blog post. | Required | +| body_representation | The content format type of the body value. Possible values are: storage, atlas_doc_format, wiki. Default is storage. | Optional | +| version_message | A message describing the update for the version history. | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| ConfluenceCloud.Blogpost.id | String | The ID of the blog post. | +| ConfluenceCloud.Blogpost.status | String | The status of the blog post. | +| ConfluenceCloud.Blogpost.title | String | The title of the blog post. | +| ConfluenceCloud.Blogpost.spaceId | String | The ID of the space the blog post belongs to. | +| ConfluenceCloud.Blogpost.version.number | Number | The version number of the blog post. | + +#### Command example + +```!confluence-cloud-blogpost-update blogpost_id=12345 version_number=2 title="XSOAR Blogpost Updated" body_value="Updated blog"``` + +#### Context Example + +```json +{ + "ConfluenceCloud": { + "Blogpost": { + "id": "12345", + "status": "current", + "title": "XSOAR Blogpost Updated", + "spaceId": "98765", + "version": { + "number": 2 + } + } + } +} +``` + +#### Human Readable Output + +>### Blogpost +> +>|ID|Title|Status|Space Id|Version| +>|---|---|---|---|---| +>| 12345 | XSOAR Blogpost Updated | current | 98765 | 2 | + +### confluence-cloud-footer-comment-create + +*** +Creates a footer comment in Confluence Cloud (REST API v2). + +#### Base Command + +`confluence-cloud-footer-comment-create` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| body_value | The content body value of the comment. | Required | +| body_representation | The content format type of the body value. Possible values are: storage, atlas_doc_format. Default is storage. | Optional | +| page_id | The ID of the page to attach the comment to. One of page_id, blogpost_id, parent_comment_id, attachment_id, or custom_content_id is required. | Optional | +| blogpost_id | The ID of the blog post to attach the comment to. | Optional | +| parent_comment_id | The ID of the parent comment to reply to. | Optional | +| attachment_id | The ID of the attachment to attach the comment to. | Optional | +| custom_content_id | The ID of the custom content to attach the comment to. | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| ConfluenceCloud.Comment.id | String | The ID of the comment. | +| ConfluenceCloud.Comment.status | String | The status of the comment. | +| ConfluenceCloud.Comment.pageId | String | The ID of the page the comment belongs to. | +| ConfluenceCloud.Comment.blogPostId | String | The ID of the blog post the comment belongs to. | +| ConfluenceCloud.Comment.parentCommentId | String | The ID of the parent comment. | +| ConfluenceCloud.Comment.version.number | Number | The version number of the comment. | + +#### Command example + +```!confluence-cloud-footer-comment-create page_id=12345 body_value="A footer comment"``` + +#### Context Example + +```json +{ + "ConfluenceCloud": { + "Comment": { + "id": "98765", + "status": "current", + "pageId": "12345", + "version": { + "number": 1 + } + } + } +} +``` + +#### Human Readable Output + +>### Footer Comment +> +>|ID|Status|Page Id|Version| +>|---|---|---|---| +>| 98765 | current | 12345 | 1 | + +### confluence-cloud-page-update + +*** +Updates an existing page in Confluence Cloud (REST API v2). + +#### Base Command + +`confluence-cloud-page-update` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| page_id | The ID of the page to update. | Required | +| version_number | The new version number for the page. Must be one greater than the current version. | Required | +| title | The title of the page. | Required | +| status | The status of the page. Possible values are: current, draft. Default is current. | Required | +| body_value | The content body value of the page. | Required | +| body_representation | The content format type of the body value. Possible values are: storage, atlas_doc_format, wiki. Default is storage. | Optional | +| space_id | The ID of the space to move the page to. | Optional | +| version_message | A message describing the update for the version history. | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| ConfluenceCloud.Page.id | String | The ID of the page. | +| ConfluenceCloud.Page.status | String | The status of the page. | +| ConfluenceCloud.Page.title | String | The title of the page. | +| ConfluenceCloud.Page.spaceId | String | The ID of the space the page belongs to. | +| ConfluenceCloud.Page.version.number | Number | The version number of the page. | + +#### Command example + +```!confluence-cloud-page-update page_id=12345 version_number=2 title="XSOAR Page Updated" body_value="Updated content"``` + +#### Context Example + +```json +{ + "ConfluenceCloud": { + "Page": { + "id": "12345", + "status": "current", + "title": "XSOAR Page Updated", + "spaceId": "98765", + "version": { + "number": 2 + } + } + } +} +``` + +#### Human Readable Output + +>### Page +> +>|ID|Title|Status|Space Id|Version| +>|---|---|---|---|---| +>| 12345 | XSOAR Page Updated | current | 98765 | 2 | + +### confluence-cloud-space-createv2 + +*** +Creates a new space in Confluence Cloud (REST API v2). + +#### Base Command + +`confluence-cloud-space-createv2` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| name | The name of the new space. The maximum length is 200 characters. | Required | +| key | The key for the new space. It can contain any alphanumeric character (a-z, 0-9). The maximum length is 255 characters. | Required | +| description_value | The description text of the new space. | Optional | +| description_format | The format of the space description. Possible values are: plain, view. Default is plain. | Optional | +| role_assignments | A JSON array of role assignments granting access to principals. For example: [{"principal": {"type": "user", "id": "<accountId>"}, "roleId": "<roleId>"}]. | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| ConfluenceCloud.Space.id | String | The ID of the space. | +| ConfluenceCloud.Space.key | String | The key of the space. | +| ConfluenceCloud.Space.name | String | The name of the space. | +| ConfluenceCloud.Space.type | String | The type of the space. | +| ConfluenceCloud.Space.status | String | The status of the space. | + +#### Command example + +```!confluence-cloud-space-createv2 name="Engineering" key="ENG"``` + +#### Context Example + +```json +{ + "ConfluenceCloud": { + "Space": { + "id": "98765", + "key": "ENG", + "name": "Engineering", + "status": "current", + "type": "global" + } + } +} +``` + +#### Human Readable Output + +>### Space +> +>|Id|Key|Name|Type|Status| +>|---|---|---|---|---| +>| 98765 | ENG | Engineering | global | current | + +### confluence-cloud-page-create + +*** +Creates a new page in Confluence Cloud (REST API v2). + +#### Base Command + +`confluence-cloud-page-create` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| space_id | The ID of the space where the page is created. Retrieve using the confluence-cloud-space-listv2 command. | Required | +| title | The title of the page. | Required | +| status | The status of the page to be created. Possible values are: current, draft. Default is current. | Optional | +| body_value | The content body value of the page. | Required | +| body_representation | The content format type of the body value. Possible values are: storage, atlas_doc_format, wiki. Default is storage. | Optional | +| parent_id | The ID of the parent page under which the new page is created. | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| ConfluenceCloud.Page.id | String | The ID of the page. | +| ConfluenceCloud.Page.status | String | The status of the page. | +| ConfluenceCloud.Page.title | String | The title of the page. | +| ConfluenceCloud.Page.spaceId | String | The ID of the space the page belongs to. | +| ConfluenceCloud.Page.parentId | String | The ID of the parent page. | +| ConfluenceCloud.Page.authorId | String | The account ID of the page author. | +| ConfluenceCloud.Page.createdAt | Date | Date and time, in ISO 8601 format, when the page was created \(e.g., 2024-01-15T12:34:56Z\). | +| ConfluenceCloud.Page.version.number | Number | The version number of the page. | + +#### Command example + +```!confluence-cloud-page-create space_id=98765 title="Getting Started" body_value="Welcome to the team"``` + +#### Context Example + +```json +{ + "ConfluenceCloud": { + "Page": { + "authorId": "5ff2e30b4d2179006ea18449", + "createdAt": "2024-01-15T12:34:56Z", + "id": "12345", + "spaceId": "98765", + "status": "current", + "title": "Getting Started", + "version": { + "number": 1 + } + } + } +} +``` + +#### Human Readable Output + +>### Page +> +>|Id|Title|Status|Space Id|Author Id|Created At|Version| +>|---|---|---|---|---|---|---| +>| 12345 | Getting Started | current | 98765 | 5ff2e30b4d2179006ea18449 | 2024-01-15T12:34:56Z | 1 | + +### confluence-cloud-space-listv2 + +*** +Returns a list of spaces from Confluence Cloud (REST API v2). + +#### Base Command + +`confluence-cloud-space-listv2` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| ids | A comma-separated list of space IDs to filter by. | Optional | +| keys | A comma-separated list of space keys to filter by. | Optional | +| type | The type of spaces to filter by. Possible values are: global, personal. | Optional | +| status | The status of spaces to filter by. Possible values are: current, archived. | Optional | +| sort | Ordering of the results by a particular field. Prefix with '-' for descending order. | Optional | +| limit | The maximum number of records to return. Value must be between 1 and 250. Default is 50. | Optional | +| cursor | The cursor to use for fetching the next page of results (from a previous run's ConfluenceCloud.PageToken output). | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| ConfluenceCloud.Space.id | String | The ID of the space. | +| ConfluenceCloud.Space.key | String | The key of the space. | +| ConfluenceCloud.Space.name | String | The name of the space. | +| ConfluenceCloud.Space.type | String | The type of the space. | +| ConfluenceCloud.Space.status | String | The status of the space. | +| ConfluenceCloud.PageToken.Content.next_page_token | String | The cursor to use for fetching the next page of results. | +| ConfluenceCloud.PageToken.Content.name | String | The name of the command that produced the page token. | + +#### Command example + +```!confluence-cloud-space-listv2 limit=2``` + +#### Context Example + +```json +{ + "ConfluenceCloud": { + "Space": [ + { + "id": "98765", + "key": "ENG", + "name": "Engineering", + "status": "current", + "type": "global" + }, + { + "id": "98766", + "key": "MKT", + "name": "Marketing", + "status": "current", + "type": "global" + } + ] + } +} +``` + +#### Human Readable Output + +>### Space(s) +> +>|Id|Key|Name|Type|Status| +>|---|---|---|---|---| +>| 98765 | ENG | Engineering | global | current | +>| 98766 | MKT | Marketing | global | current | + +### confluence-cloud-blogpost-delete + +*** +Deletes a blog post in Confluence Cloud (REST API v2). + +#### Base Command + +`confluence-cloud-blogpost-delete` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| blogpost_id | The ID of the blog post to delete. | Required | +| purge | Whether to permanently purge the blog post from the trash. Requires the blog post to already be in the trash. Possible values are: true, false. Default is false. | Optional | + +#### Context Output + +There is no context output for this command. + +#### Command example + +```!confluence-cloud-blogpost-delete blogpost_id=12345``` + +#### Human Readable Output + +>Blogpost with ID "12345" was deleted successfully. + +### confluence-cloud-page-list + +*** +Returns a list of pages from Confluence Cloud (REST API v2). + +#### Base Command + +`confluence-cloud-page-list` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| id | A comma-separated list of page IDs to filter by. | Optional | +| space_id | A comma-separated list of space IDs to filter by. | Optional | +| status | The status of pages to filter by. Possible values are: current, archived, deleted, trashed. | Optional | +| title | The title of pages to filter by. | Optional | +| subtype | The subtype of pages to filter by. Possible values are: page, live. | Optional | +| sort | Ordering of the results by a particular field. Prefix with '-' for descending order. | Optional | +| limit | The maximum number of records to return. Value must be between 1 and 250. Default is 50. | Optional | +| cursor | The cursor to use for fetching the next page of results (from a previous run's ConfluenceCloud.PageToken output). | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| ConfluenceCloud.Page.id | String | The ID of the page. | +| ConfluenceCloud.Page.status | String | The status of the page. | +| ConfluenceCloud.Page.title | String | The title of the page. | +| ConfluenceCloud.Page.spaceId | String | The ID of the space the page belongs to. | +| ConfluenceCloud.Page.authorId | String | The account ID of the page author. | +| ConfluenceCloud.Page.createdAt | Date | Date and time, in ISO 8601 format, when the page was created \(e.g., 2024-01-15T12:34:56Z\). | +| ConfluenceCloud.PageToken.Content.next_page_token | String | The cursor to use for fetching the next page of results. | +| ConfluenceCloud.PageToken.Content.name | String | The name of the command that produced the page token. | + +#### Command example + +```!confluence-cloud-page-list limit=2``` + +#### Context Example + +```json +{ + "ConfluenceCloud": { + "Page": [ + { + "authorId": "5ff2e30b4d2179006ea18449", + "createdAt": "2024-01-15T12:34:56Z", + "id": "12345", + "spaceId": "98765", + "status": "current", + "title": "Getting Started" + }, + { + "authorId": "5ff2e30b4d2179006ea18449", + "createdAt": "2024-01-14T09:10:11Z", + "id": "12346", + "spaceId": "98765", + "status": "current", + "title": "Onboarding Guide" + } + ] + } +} +``` + +#### Human Readable Output + +>### Page(s) +> +>|Id|Title|Status|Space Id|Author Id|Created At| +>|---|---|---|---|---|---| +>| 12345 | Getting Started | current | 98765 | 5ff2e30b4d2179006ea18449 | 2024-01-15T12:34:56Z | +>| 12346 | Onboarding Guide | current | 98765 | 5ff2e30b4d2179006ea18449 | 2024-01-14T09:10:11Z | + +### confluence-cloud-blogpost-list + +*** +Returns a list of blog posts from Confluence Cloud (REST API v2). + +#### Base Command + +`confluence-cloud-blogpost-list` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| id | A comma-separated list of blog post IDs to filter by. | Optional | +| space_id | A comma-separated list of space IDs to filter by. | Optional | +| status | The status of blog posts to filter by. Possible values are: current, deleted, trashed. | Optional | +| title | The title of blog posts to filter by. | Optional | +| sort | Ordering of the results by a particular field. Prefix with '-' for descending order. | Optional | +| limit | The maximum number of records to return. Value must be between 1 and 250. Default is 50. | Optional | +| cursor | The cursor to use for fetching the next page of results (from a previous run's ConfluenceCloud.PageToken output). | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| ConfluenceCloud.Blogpost.id | String | The ID of the blog post. | +| ConfluenceCloud.Blogpost.status | String | The status of the blog post. | +| ConfluenceCloud.Blogpost.title | String | The title of the blog post. | +| ConfluenceCloud.Blogpost.spaceId | String | The ID of the space the blog post belongs to. | +| ConfluenceCloud.Blogpost.authorId | String | The account ID of the blog post author. | +| ConfluenceCloud.Blogpost.createdAt | Date | Date and time, in ISO 8601 format, when the blog post was created \(e.g., 2024-01-15T12:34:56Z\). | +| ConfluenceCloud.PageToken.Content.next_page_token | String | The cursor to use for fetching the next page of results. | +| ConfluenceCloud.PageToken.Content.name | String | The name of the command that produced the page token. | + +#### Command example + +```!confluence-cloud-blogpost-list limit=2``` + +#### Context Example + +```json +{ + "ConfluenceCloud": { + "Blogpost": [ + { + "authorId": "5ff2e30b4d2179006ea18449", + "createdAt": "2024-01-15T12:34:56Z", + "id": "12345", + "spaceId": "98765", + "status": "current", + "title": "Quarterly Update" + }, + { + "authorId": "5ff2e30b4d2179006ea18449", + "createdAt": "2024-01-14T09:10:11Z", + "id": "12346", + "spaceId": "98765", + "status": "current", + "title": "Release Announcement" + } + ] + } +} +``` + +#### Human Readable Output + +>### Blogpost(s) +> +>|Id|Title|Status|Space Id|Author Id|Created At| +>|---|---|---|---|---|---| +>| 12345 | Quarterly Update | current | 98765 | 5ff2e30b4d2179006ea18449 | 2024-01-15T12:34:56Z | +>| 12346 | Release Announcement | current | 98765 | 5ff2e30b4d2179006ea18449 | 2024-01-14T09:10:11Z | + +### confluence-cloud-page-delete + +*** +Deletes a page in Confluence Cloud (REST API v2). + +#### Base Command + +`confluence-cloud-page-delete` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| page_id | The ID of the page to delete. | Required | +| purge | Whether to permanently purge the page from the trash. Requires the page to already be in the trash. Possible values are: true, false. Default is false. | Optional | + +#### Context Output + +There is no context output for this command. + +#### Command example + +```!confluence-cloud-page-delete page_id=12345``` + +#### Human Readable Output + +>Page with ID "12345" was deleted successfully. diff --git a/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/command_examples.txt b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/command_examples.txt new file mode 100644 index 000000000000..1f22d323d1bc --- /dev/null +++ b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/command_examples.txt @@ -0,0 +1,11 @@ +!confluence-cloud-page-create space_id=98765 title="XSOAR Page" body_value="Hello World" body_representation=storage +!confluence-cloud-page-list space_id=98765 limit=2 +!confluence-cloud-page-update page_id=12345 version_number=2 title="XSOAR Page Updated" body_value="Updated content" +!confluence-cloud-page-delete page_id=12345 +!confluence-cloud-blogpost-create space_id=98765 title="XSOAR Blogpost" body_value="Blog content" body_representation=storage +!confluence-cloud-blogpost-list space_id=98765 limit=2 +!confluence-cloud-blogpost-update blogpost_id=12345 version_number=2 title="XSOAR Blogpost Updated" body_value="Updated blog" +!confluence-cloud-blogpost-delete blogpost_id=12345 +!confluence-cloud-footer-comment-create page_id=12345 body_value="A footer comment" +!confluence-cloud-space-listv2 limit=2 +!confluence-cloud-space-createv2 name="XSOAR Space" key=XSOAR diff --git a/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/content_create/content_create_required_argument_error.json b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/content_create/content_create_required_argument_error.json index e42912114c07..e235eaa26ace 100644 --- a/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/content_create/content_create_required_argument_error.json +++ b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/content_create/content_create_required_argument_error.json @@ -1,17 +1,17 @@ { - "statusCode": 400, - "data": { - "authorized": true, - "valid": false, - "errors": [ - { - "message": { - "key": "Title cannot be longer than 255 characters.", - "args": [] - } - } - ], - "successful": false - }, - "message": "com.atlassian.confluence.api.service.exceptions.BadRequestException: Could not create content with type page" -} + "data": { + "authorized": true, + "valid": false, + "errors": [ + { + "message": { + "key": "Title cannot be longer than 255 characters.", + "args": [] + } + } + ], + "successful": false + }, + "version": -1, + "fromVersion": "6.10.0" +} \ No newline at end of file diff --git a/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/content_delete/content_delete_command_bad_request_error.json b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/content_delete/content_delete_command_bad_request_error.json index 2b2aae146c77..3f3842eae288 100644 --- a/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/content_delete/content_delete_command_bad_request_error.json +++ b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/content_delete/content_delete_command_bad_request_error.json @@ -1,17 +1,17 @@ { - "statusCode": 400, - "data": { - "authorized": true, - "valid": false, - "errors": [ - { - "message": { - "translation": "Trashable Content must be trashed before it can be purged", - "args": [] - } - } - ], - "successful": false - }, - "message": "com.atlassian.confluence.api.service.exceptions.BadRequestException: Unable to purge content with id: ContentId{id=2064771}" -} + "data": { + "authorized": true, + "valid": false, + "errors": [ + { + "message": { + "translation": "Trashable Content must be trashed before it can be purged", + "args": [] + } + } + ], + "successful": false + }, + "version": -1, + "fromVersion": "6.10.0" +} \ No newline at end of file diff --git a/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/content_search/content_search_invalid_query_argument.json b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/content_search/content_search_invalid_query_argument.json index 8f2e740a9faf..e3775e9388e6 100644 --- a/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/content_search/content_search_invalid_query_argument.json +++ b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/content_search/content_search_invalid_query_argument.json @@ -1,10 +1,10 @@ { - "statusCode": 400, - "data": { - "authorized": false, - "valid": true, - "errors": [], - "successful": false - }, - "message": "com.atlassian.confluence.api.service.exceptions.BadRequestException: Unsupported value for type, got : pagenjkkj, expected one of : [space, user, page, blogpost, comment, attachment, com.atlassian.confluence.extra.team-calendars:calendar-content-type, com.atlassian.confluence.extra.team-calendars:space-calendars-view-content-type, ac:com.addonengine.analytics:space-analytics]" -} + "data": { + "authorized": false, + "valid": true, + "errors": [], + "successful": false + }, + "version": -1, + "fromVersion": "6.10.0" +} \ No newline at end of file diff --git a/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/footer_comment_create/footer_comment_create_command.md b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/footer_comment_create/footer_comment_create_command.md new file mode 100644 index 000000000000..e44a33af08f2 --- /dev/null +++ b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/footer_comment_create/footer_comment_create_command.md @@ -0,0 +1,4 @@ +### Footer Comment +|ID|Status|Page ID|Version| +|---|---|---|---| +| 55555 | current | 12345 | 1 | diff --git a/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/footer_comment_create/footer_comment_create_command_context.json b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/footer_comment_create/footer_comment_create_command_context.json new file mode 100644 index 000000000000..2b444628d1e5 --- /dev/null +++ b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/footer_comment_create/footer_comment_create_command_context.json @@ -0,0 +1,14 @@ +{ + "id": "55555", + "status": "current", + "pageId": "12345", + "version": { + "number": 1 + }, + "body": { + "storage": { + "representation": "storage", + "value": "

This is a footer comment

" + } + } +} diff --git a/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/footer_comment_create/footer_comment_create_command_response.json b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/footer_comment_create/footer_comment_create_command_response.json new file mode 100644 index 000000000000..2b444628d1e5 --- /dev/null +++ b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/footer_comment_create/footer_comment_create_command_response.json @@ -0,0 +1,14 @@ +{ + "id": "55555", + "status": "current", + "pageId": "12345", + "version": { + "number": 1 + }, + "body": { + "storage": { + "representation": "storage", + "value": "

This is a footer comment

" + } + } +} diff --git a/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/input_data.py b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/input_data.py index 8da47a085f8f..b35f69425d2a 100644 --- a/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/input_data.py +++ b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/input_data.py @@ -30,6 +30,20 @@ "INVALID_SPACE_NAME_LENGTH": "Space name cannot be longer than 200 characters.", "INVALID_SPACE_KEY": "Space Key cannot be longer than 255 characters and should contain alphanumeric characters " "only.", "PRIVATE_SPACE_PERMISSION": "Permission can not be granted for a private space.", + "INVALID_BODY_REPRESENTATION_V2": "Invalid value for body_representation. Body representation must be one of " + "'storage', 'atlas_doc_format' or 'wiki'.", + "INVALID_COMMENT_BODY_REPRESENTATION_V2": "Invalid value for body_representation. Body representation must be " + "one of 'storage' or 'atlas_doc_format'.", + "INVALID_STATUS_CREATE_V2": "Invalid value for status. Status must be one of 'current' or 'draft'.", + "INVALID_PAGE_STATUS_LIST_V2": "Invalid value for status. Status must be one of 'current', 'archived', " + "'deleted' or 'trashed'.", + "INVALID_SUBTYPE_FILTER_V2": "Invalid value for subtype. Subtype must be one of 'page' or 'live'.", + "MISSING_COMMENT_CONTAINER_V2": "One of the following arguments is required: 'page_id', 'blogpost_id', " + "'parent_comment_id', 'attachment_id' or 'custom_content_id'.", + "INVALID_SPACE_TYPE_V2": "Invalid value for type. Type must be one of 'global' or 'personal'.", + "INVALID_DESCRIPTION_FORMAT_V2": "Invalid value for description_format. Description format must be one of " + "'plain' or 'view'.", + "INVALID_LIMIT_V2": "{} is an invalid value for limit. Limit must be a positive integer (greater than 0).", } exception_handler_params = [ @@ -202,3 +216,37 @@ ({"content_id": "", "title": "dummy", "type": "page", "version": 2}, MESSAGES["REQUIRED_ARGUMENT"].format("content_id")), ({"content_id": "2097159", "title": "dummy", "type": "page", "version": ""}, MESSAGES["REQUIRED_ARGUMENT"].format("version")), ] + +# --- REST API v2 invalid argument test data --- +content_create_v2_invalid_args = [ + ({"space_id": "", "title": "abc"}, MESSAGES["REQUIRED_ARGUMENT"].format("space_id")), + ({"space_id": "123", "title": "abc", "status": "invalid"}, f"{MESSAGES['INVALID_STATUS_CREATE_V2']} Received: 'invalid'."), + ( + {"space_id": "123", "title": "abc", "body_representation": "invalid"}, + f"{MESSAGES['INVALID_BODY_REPRESENTATION_V2']} Received: 'invalid'.", + ), +] + +content_list_v2_invalid_args = [ + ({"limit": 0}, MESSAGES["INVALID_LIMIT_V2"].format(0)), + ({"limit": -5}, MESSAGES["INVALID_LIMIT_V2"].format(-5)), + ({"status": "invalid"}, MESSAGES["INVALID_PAGE_STATUS_LIST_V2"]), + ({"subtype": "invalid"}, MESSAGES["INVALID_SUBTYPE_FILTER_V2"]), +] + +comment_create_v2_invalid_args = [ + ({"body_value": "", "page_id": "123"}, MESSAGES["REQUIRED_ARGUMENT"].format("body_value")), + ({"body_value": "test", "body_representation": "wiki", "page_id": "123"}, MESSAGES["INVALID_COMMENT_BODY_REPRESENTATION_V2"]), + ({"body_value": "test"}, MESSAGES["MISSING_COMMENT_CONTAINER_V2"]), +] + +space_list_v2_invalid_args = [ + ({"limit": 0}, MESSAGES["INVALID_LIMIT_V2"].format(0)), + ({"type": "invalid"}, MESSAGES["INVALID_SPACE_TYPE_V2"]), +] + +space_create_v2_invalid_args = [ + ({"name": "", "key": "XSOAR"}, MESSAGES["REQUIRED_ARGUMENT"].format("name")), + ({"name": "XSOAR", "key": ""}, MESSAGES["REQUIRED_ARGUMENT"].format("key")), + ({"name": "XSOAR", "key": "XSOAR", "description_format": "invalid"}, MESSAGES["INVALID_DESCRIPTION_FORMAT_V2"]), +] diff --git a/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/page_create/page_create_command.md b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/page_create/page_create_command.md new file mode 100644 index 000000000000..700797a5ebee --- /dev/null +++ b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/page_create/page_create_command.md @@ -0,0 +1,4 @@ +### Page +|ID|Title|Status|Space ID|Author ID|Created At|Version| +|---|---|---|---|---|---|---| +| 12345 | XSOAR_Page | current | 98765 | 5ff2e30b4d2179006ea18449 | 2024-01-01T10:00:00.000Z | 1 | diff --git a/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/page_create/page_create_command_context.json b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/page_create/page_create_command_context.json new file mode 100644 index 000000000000..68e49d2e7a14 --- /dev/null +++ b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/page_create/page_create_command_context.json @@ -0,0 +1,16 @@ +{ + "id": "12345", + "status": "current", + "title": "XSOAR_Page", + "spaceId": "98765", + "parentId": "11111", + "authorId": "5ff2e30b4d2179006ea18449", + "createdAt": "2024-01-01T10:00:00.000Z", + "version": { + "number": 1, + "createdAt": "2024-01-01T10:00:00.000Z" + }, + "_links": { + "webui": "/spaces/XSOAR/pages/12345/XSOAR_Page" + } +} diff --git a/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/page_create/page_create_command_response.json b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/page_create/page_create_command_response.json new file mode 100644 index 000000000000..384ac4264239 --- /dev/null +++ b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/page_create/page_create_command_response.json @@ -0,0 +1,17 @@ +{ + "id": "12345", + "status": "current", + "title": "XSOAR_Page", + "spaceId": "98765", + "parentId": "11111", + "authorId": "5ff2e30b4d2179006ea18449", + "createdAt": "2024-01-01T10:00:00.000Z", + "version": { + "number": 1, + "message": "", + "createdAt": "2024-01-01T10:00:00.000Z" + }, + "_links": { + "webui": "/spaces/XSOAR/pages/12345/XSOAR_Page" + } +} diff --git a/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/page_list/page_list_command.md b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/page_list/page_list_command.md new file mode 100644 index 000000000000..c436c36a51fa --- /dev/null +++ b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/page_list/page_list_command.md @@ -0,0 +1,5 @@ +### Page(s) +|ID|Title|Status|Space ID|Author ID|Created At| +|---|---|---|---|---|---| +| 12345 | XSOAR_Page | current | 98765 | 5ff2e30b4d2179006ea18449 | 2024-01-01T10:00:00.000Z | +| 67890 | Second_Page | current | 98765 | 5ff2e30b4d2179006ea18450 | 2024-01-02T10:00:00.000Z | diff --git a/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/page_list/page_list_command_context.json b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/page_list/page_list_command_context.json new file mode 100644 index 000000000000..e795c8c38959 --- /dev/null +++ b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/page_list/page_list_command_context.json @@ -0,0 +1,24 @@ +[ + { + "id": "12345", + "status": "current", + "title": "XSOAR_Page", + "spaceId": "98765", + "authorId": "5ff2e30b4d2179006ea18449", + "createdAt": "2024-01-01T10:00:00.000Z", + "version": { + "number": 1 + } + }, + { + "id": "67890", + "status": "current", + "title": "Second_Page", + "spaceId": "98765", + "authorId": "5ff2e30b4d2179006ea18450", + "createdAt": "2024-01-02T10:00:00.000Z", + "version": { + "number": 2 + } + } +] diff --git a/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/page_list/page_list_command_response.json b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/page_list/page_list_command_response.json new file mode 100644 index 000000000000..d30360f40d16 --- /dev/null +++ b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/page_list/page_list_command_response.json @@ -0,0 +1,29 @@ +{ + "results": [ + { + "id": "12345", + "status": "current", + "title": "XSOAR_Page", + "spaceId": "98765", + "authorId": "5ff2e30b4d2179006ea18449", + "createdAt": "2024-01-01T10:00:00.000Z", + "version": { + "number": 1 + } + }, + { + "id": "67890", + "status": "current", + "title": "Second_Page", + "spaceId": "98765", + "authorId": "5ff2e30b4d2179006ea18450", + "createdAt": "2024-01-02T10:00:00.000Z", + "version": { + "number": 2 + } + } + ], + "_links": { + "base": "https://dummy.atlassian.com/wiki" + } +} diff --git a/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/space_create_v2/space_create_v2_command.md b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/space_create_v2/space_create_v2_command.md new file mode 100644 index 000000000000..9dbb909aca7f --- /dev/null +++ b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/space_create_v2/space_create_v2_command.md @@ -0,0 +1,4 @@ +### Space +|ID|Key|Name|Type|Status| +|---|---|---|---|---| +| 98765 | XSOAR | XSOAR Space | global | current | diff --git a/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/space_create_v2/space_create_v2_command_context.json b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/space_create_v2/space_create_v2_command_context.json new file mode 100644 index 000000000000..dcbf31aba040 --- /dev/null +++ b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/space_create_v2/space_create_v2_command_context.json @@ -0,0 +1,7 @@ +{ + "id": "98765", + "key": "XSOAR", + "name": "XSOAR Space", + "type": "global", + "status": "current" +} diff --git a/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/space_create_v2/space_create_v2_command_response.json b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/space_create_v2/space_create_v2_command_response.json new file mode 100644 index 000000000000..dcbf31aba040 --- /dev/null +++ b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/space_create_v2/space_create_v2_command_response.json @@ -0,0 +1,7 @@ +{ + "id": "98765", + "key": "XSOAR", + "name": "XSOAR Space", + "type": "global", + "status": "current" +} diff --git a/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/space_list_v2/space_list_v2_command.md b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/space_list_v2/space_list_v2_command.md new file mode 100644 index 000000000000..b797a7129ef4 --- /dev/null +++ b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/space_list_v2/space_list_v2_command.md @@ -0,0 +1,5 @@ +### Space(s) +|ID|Key|Name|Type|Status| +|---|---|---|---|---| +| 98765 | XSOAR | XSOAR Space | global | current | +| 98766 | DEV | Dev Space | global | current | diff --git a/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/space_list_v2/space_list_v2_command_context.json b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/space_list_v2/space_list_v2_command_context.json new file mode 100644 index 000000000000..6a286fdcfbb7 --- /dev/null +++ b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/space_list_v2/space_list_v2_command_context.json @@ -0,0 +1,16 @@ +[ + { + "id": "98765", + "key": "XSOAR", + "name": "XSOAR Space", + "type": "global", + "status": "current" + }, + { + "id": "98766", + "key": "DEV", + "name": "Dev Space", + "type": "global", + "status": "current" + } +] diff --git a/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/space_list_v2/space_list_v2_command_response.json b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/space_list_v2/space_list_v2_command_response.json new file mode 100644 index 000000000000..50cbcea7c377 --- /dev/null +++ b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/test_data/space_list_v2/space_list_v2_command_response.json @@ -0,0 +1,18 @@ +{ + "results": [ + { + "id": "98765", + "key": "XSOAR", + "name": "XSOAR Space", + "type": "global", + "status": "current" + }, + { + "id": "98766", + "key": "DEV", + "name": "Dev Space", + "type": "global", + "status": "current" + } + ] +} diff --git a/Packs/AtlassianConfluenceCloud/ReleaseNotes/1_2_0.md b/Packs/AtlassianConfluenceCloud/ReleaseNotes/1_2_0.md new file mode 100644 index 000000000000..695999d1e74a --- /dev/null +++ b/Packs/AtlassianConfluenceCloud/ReleaseNotes/1_2_0.md @@ -0,0 +1,25 @@ +#### Integrations + +##### Atlassian Confluence Cloud + +- Added support for the Confluence Cloud REST API v2 with the following new commands: + - ***confluence-cloud-page-create*** + - ***confluence-cloud-page-list*** + - ***confluence-cloud-page-update*** + - ***confluence-cloud-page-delete*** + - ***confluence-cloud-blogpost-create*** + - ***confluence-cloud-blogpost-list*** + - ***confluence-cloud-blogpost-update*** + - ***confluence-cloud-blogpost-delete*** + - ***confluence-cloud-footer-comment-create*** + - ***confluence-cloud-space-listv2*** + - ***confluence-cloud-space-createv2*** +- Updated the required OAuth 2.0 scopes to the granular Confluence REST API v2 scope set. When using OAuth 2.0 authentication, you must add the new scopes to your app and re-authenticate. See the integration description for details. +- Deprecated the following commands: + - ***confluence-cloud-content-create***. Use ***confluence-cloud-page-create*** or ***confluence-cloud-blogpost-create*** instead. + - ***confluence-cloud-content-update***. Use ***confluence-cloud-page-update*** or ***confluence-cloud-blogpost-update*** instead. + - ***confluence-cloud-content-delete***. Use ***confluence-cloud-page-delete*** or ***confluence-cloud-blogpost-delete*** instead. + - ***confluence-cloud-content-list***. Use ***confluence-cloud-page-list*** or ***confluence-cloud-blogpost-list*** instead. + - ***confluence-cloud-content-get***. Use ***confluence-cloud-page-list*** or ***confluence-cloud-blogpost-list*** instead. + - ***confluence-cloud-comment-create***. Use ***confluence-cloud-footer-comment-create*** instead. + - ***confluence-cloud-space-list***. Use ***confluence-cloud-space-listv2*** instead. diff --git a/Packs/AtlassianConfluenceCloud/pack_metadata.json b/Packs/AtlassianConfluenceCloud/pack_metadata.json index 962b4c293c57..1dbe90be216a 100644 --- a/Packs/AtlassianConfluenceCloud/pack_metadata.json +++ b/Packs/AtlassianConfluenceCloud/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Atlassian Confluence Cloud", "description": "Atlassian Confluence Cloud allows users to interact with confluence entities like content, space, users and groups. Users can also manage the space permissions.", "support": "xsoar", - "currentVersion": "1.1.17", + "currentVersion": "1.2.0", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", @@ -14,7 +14,7 @@ "IT" ], "useCases": [], - "keywords": [], + "keywords": ["Atlassian"], "dependencies": {}, "marketplaces": [ "xsoar", From 39819bd9dfdbfc80dedfb0ee48200667d7b3a263 Mon Sep 17 00:00:00 2001 From: rshunim <102469772+rshunim@users.noreply.github.com> Date: Tue, 18 Aug 2026 20:11:16 +0300 Subject: [PATCH 011/419] fix(McAfee TIE v2): remove no-op statement and add debug logs to DXL config (#45552) --- .../McAfee-TIE/Integrations/McAfeeTIEV2/McAfeeTIEV2.py | 6 +++++- .../Integrations/McAfeeTIEV2/McAfeeTIEV2.yml | 10 ++++++++++ Packs/McAfee-TIE/ReleaseNotes/2_0_25.md | 6 ++++++ Packs/McAfee-TIE/pack_metadata.json | 2 +- 4 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 Packs/McAfee-TIE/ReleaseNotes/2_0_25.md diff --git a/Packs/McAfee-TIE/Integrations/McAfeeTIEV2/McAfeeTIEV2.py b/Packs/McAfee-TIE/Integrations/McAfeeTIEV2/McAfeeTIEV2.py index bbd05be0e176..c801eced35b4 100644 --- a/Packs/McAfee-TIE/Integrations/McAfeeTIEV2/McAfeeTIEV2.py +++ b/Packs/McAfee-TIE/Integrations/McAfeeTIEV2/McAfeeTIEV2.py @@ -527,7 +527,7 @@ def create_dxl_config(instance_cert: InstanceCertificates) -> DxlClientConfig: tempfile.NamedTemporaryFile(mode="w+", dir="./", suffix=".crt") as client_cert_file, tempfile.NamedTemporaryFile(mode="w+", dir="./", suffix=".key") as private_key_file, ): - broker_certs_file.delete # noqa: B018 + demisto.debug("McAfeeTIEV2: created temp files for broker CA bundle, client cert, and private key") create_temp_credentials(broker_certs_file, instance_cert.broker_ca_bundle) create_temp_credentials(client_cert_file, instance_cert.client_cert) create_temp_credentials(private_key_file, instance_cert.private_key) @@ -537,6 +537,10 @@ def create_dxl_config(instance_cert: InstanceCertificates) -> DxlClientConfig: private_key_file=private_key_file.name, broker_urls=instance_cert.broker_urls, ) + demisto.debug( + f"McAfeeTIEV2: wrote credentials to temp files, building DXL client config " + f"for brokers {instance_cert.broker_urls}" + ) yield get_client_config(dxl_config_files=dxl_config_files) diff --git a/Packs/McAfee-TIE/Integrations/McAfeeTIEV2/McAfeeTIEV2.yml b/Packs/McAfee-TIE/Integrations/McAfeeTIEV2/McAfeeTIEV2.yml index 8f4c979d91d2..950a866c5a5d 100644 --- a/Packs/McAfee-TIE/Integrations/McAfeeTIEV2/McAfeeTIEV2.yml +++ b/Packs/McAfee-TIE/Integrations/McAfeeTIEV2/McAfeeTIEV2.yml @@ -1,5 +1,8 @@ category: Data Enrichment & Threat Intelligence provider: Trellix +sectionorder: +- Connect +- Collect commonfields: id: McAfee Threat Intelligence Exchange V2 version: -1 @@ -9,21 +12,25 @@ configuration: required: true type: 12 additionalinfo: From `brokercerts.crt` file. + section: Connect - display: Client certificates name: cert_file required: true type: 12 additionalinfo: From `client.crt` file. + section: Connect - display: Client private key name: private_key required: true type: 14 additionalinfo: From `client.key` file. Make sure that the type of the field is not `encrypted` when filling it out. + section: Connect - display: Broker URLs name: broker_urls required: true type: 0 additionalinfo: "The format should be: [ssl://][:port]. Get the hostname and port from the `brokerlist.properties` file. The broker should be reachable from the Cortex XSOAR server." + section: Connect - additionalinfo: Reliability of the source providing the intelligence data. defaultvalue: C - Fairly reliable display: Source Reliability @@ -38,6 +45,7 @@ configuration: - F - Reliability cannot be judged type: 15 required: false + section: Collect - defaultvalue: indicatorType name: feedExpirationPolicy display: "" @@ -48,11 +56,13 @@ configuration: - suddenDeath type: 17 required: false + section: Collect - defaultvalue: "20160" name: feedExpirationInterval display: "" type: 1 required: false + section: Collect description: Connect to McAfee TIE using the McAfee DXL client. display: McAfee Threat Intelligence Exchange v2 name: McAfee Threat Intelligence Exchange V2 diff --git a/Packs/McAfee-TIE/ReleaseNotes/2_0_25.md b/Packs/McAfee-TIE/ReleaseNotes/2_0_25.md new file mode 100644 index 000000000000..d59b0564f2a4 --- /dev/null +++ b/Packs/McAfee-TIE/ReleaseNotes/2_0_25.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### McAfee Threat Intelligence Exchange v2 + +- Removed a redundant no-op statement in the DXL client configuration flow. diff --git a/Packs/McAfee-TIE/pack_metadata.json b/Packs/McAfee-TIE/pack_metadata.json index bcd0d2dd97b6..a1d68f3a805f 100644 --- a/Packs/McAfee-TIE/pack_metadata.json +++ b/Packs/McAfee-TIE/pack_metadata.json @@ -2,7 +2,7 @@ "name": "McAfee Threat Intelligence Exchange", "description": "Connect to McAfee TIE using the McAfee DXL client.", "support": "xsoar", - "currentVersion": "2.0.24", + "currentVersion": "2.0.25", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From e849805225a0e03a550ee0a9f91ff1cb24fba66f Mon Sep 17 00:00:00 2001 From: Judah Schwartz Date: Wed, 19 Aug 2026 10:42:18 +0300 Subject: [PATCH 012/419] fixed backwards resolution ucp (#45548) * fixed backwards resolution ucp * Address AI reviewer feedback: use argToList for log_types, italicize credentials RN, add keyword, fix ruff-format --- Packs/PAN-OS/Integrations/Panorama/Panorama.py | 14 ++++++++++---- Packs/PAN-OS/ReleaseNotes/2_6_48.md | 7 +++++++ Packs/PAN-OS/pack_metadata.json | 3 ++- 3 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 Packs/PAN-OS/ReleaseNotes/2_6_48.md diff --git a/Packs/PAN-OS/Integrations/Panorama/Panorama.py b/Packs/PAN-OS/Integrations/Panorama/Panorama.py index 8baa5d76852d..006dc990122e 100644 --- a/Packs/PAN-OS/Integrations/Panorama/Panorama.py +++ b/Packs/PAN-OS/Integrations/Panorama/Panorama.py @@ -9082,7 +9082,7 @@ def initialize_instance(args: Dict[str, str], params: Dict[str, str]): raise DemistoException("Set a port for the instance") URL = params.get("server", "").rstrip("/:") + ":" + params.get("port", "") + "/api/" - API_KEY = str(params.get("key")) or str((params.get("credentials") or {}).get("password", "")) # type: ignore + API_KEY = (params.get("credentials") or {}).get("password") or params.get("key") or "" # type: ignore if not API_KEY: raise Exception("API Key must be provided.") USE_SSL = not params.get("insecure") @@ -13085,7 +13085,7 @@ def get_topology() -> Topology: port = arg_to_number(arg=params.get("port", "443")) parsed_url = urlparse(server_url) hostname = parsed_url.hostname - api_key = str(params.get("key")) or str((params.get("credentials") or {}).get("password", "")) # type: ignore + api_key = (params.get("credentials") or {}).get("password") or params.get("key") or "" # type: ignore return Topology.build_from_string(hostname, username="", password="", api_key=api_key, port=port) @@ -16300,7 +16300,10 @@ def log_types_queries_to_dict(params: dict[str, str]) -> QueryMap: QueryMap: queries per log type dictionary """ queries_dict = QueryMap() # type: ignore[typeddict-item] - if log_types := params.get("log_types"): + # Code default: if no Log Types were selected (empty/None), treat as "All". + # This handles existing/ConnectUs instances that never persisted a log_types value, + # where a YML defaultvalue would not apply. + if log_types := (argToList(params.get("log_types")) or ["All"]): # if 'All' is chosen in Log Type (log_types) parameter then all query parameters are used, else only the chosen query parameters are used. active_log_type_queries = FETCH_INCIDENTS_LOG_TYPES if "All" in log_types else log_types queries_dict |= { # type: ignore[assignment, typeddict-item] @@ -16433,7 +16436,10 @@ def fetch_incidents( def test_fetch_incidents_parameters(fetch_params): - if log_types := fetch_params.get("log_types"): + # Code default: if no Log Types were selected (empty/None), treat as "All". + # This keeps existing/ConnectUs instances that never persisted a log_types value + # from failing the test module, where a YML defaultvalue would not apply. + if log_types := (argToList(fetch_params.get("log_types")) or ["All"]): # if 'All' is chosen in Log Type (log_types) parameter then all query parameters are used, else only the chosen query parameters are used. active_log_type_queries = FETCH_INCIDENTS_LOG_TYPES if "All" in log_types else log_types if "match_time" in fetch_params.get("correlation_query", ""): diff --git a/Packs/PAN-OS/ReleaseNotes/2_6_48.md b/Packs/PAN-OS/ReleaseNotes/2_6_48.md new file mode 100644 index 000000000000..5c39cc1fe3fc --- /dev/null +++ b/Packs/PAN-OS/ReleaseNotes/2_6_48.md @@ -0,0 +1,7 @@ + +#### Integrations + +##### Palo Alto Networks PAN-OS + +- Fixed an issue where the API key was not correctly resolved when provided through the *credentials* parameter. +- Fixed an issue where fetching incidents failed for existing instances that did not have the *Log Types* parameter set, by defaulting to *All* when no log types are selected. diff --git a/Packs/PAN-OS/pack_metadata.json b/Packs/PAN-OS/pack_metadata.json index d88c4789bc90..e2bf46e24dd3 100644 --- a/Packs/PAN-OS/pack_metadata.json +++ b/Packs/PAN-OS/pack_metadata.json @@ -2,7 +2,7 @@ "name": "PAN-OS by Palo Alto Networks", "description": "Manage Palo Alto Networks Firewall and Panorama. Use this pack to manage Prisma Access through Panorama. For more information see Panorama documentation.", "support": "xsoar", - "currentVersion": "2.6.47", + "currentVersion": "2.6.48", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", @@ -15,6 +15,7 @@ ], "useCases": [], "keywords": [ + "Palo Alto Networks", "Panorama", "Firewall", "vsys", From 84184df8f9043286f35d8a2e17e7d3f14bec1ba3 Mon Sep 17 00:00:00 2001 From: eepstain <116078117+eepstain@users.noreply.github.com> Date: Wed, 19 Aug 2026 10:43:40 +0300 Subject: [PATCH 013/419] CRTX-271525: add identity.* to modeling rules (PR 1 of 7) (#45448) * CRTX-271525: add identity.* to modeling rules (PR 1 of 7) * Bump pack from version Slack to 3.8.14. * CRTX-271525: rename modeling rule folder 3_19 -> 2_11 * Bump pack from version Slack to 3.8.15. * fixed bug with removed logic in if and coalesce * modified old fromversion due to validation error (equal value as toversion) --------- Co-authored-by: Content Bot Co-authored-by: yasta5 <112320333+yasta5@users.noreply.github.com> Co-authored-by: Yehonatan Asta --- .../SlackModelingRules_2_10.yml | 3 +- .../SlackModelingRules_2_11.xif | 336 ++++++++++++++++++ .../SlackModelingRules_2_11.yml | 8 + .../SlackModelingRules_2_11_schema.json | 32 ++ Packs/Slack/ReleaseNotes/3_8_15.md | 7 + Packs/Slack/pack_metadata.json | 2 +- 6 files changed, 386 insertions(+), 2 deletions(-) create mode 100644 Packs/Slack/ModelingRules/SlackModelingRules_2_11/SlackModelingRules_2_11.xif create mode 100644 Packs/Slack/ModelingRules/SlackModelingRules_2_11/SlackModelingRules_2_11.yml create mode 100644 Packs/Slack/ModelingRules/SlackModelingRules_2_11/SlackModelingRules_2_11_schema.json create mode 100644 Packs/Slack/ReleaseNotes/3_8_15.md diff --git a/Packs/Slack/ModelingRules/SlackModelingRules_2_10/SlackModelingRules_2_10.yml b/Packs/Slack/ModelingRules/SlackModelingRules_2_10/SlackModelingRules_2_10.yml index 9f5d604cf110..43df70c43ef1 100644 --- a/Packs/Slack/ModelingRules/SlackModelingRules_2_10/SlackModelingRules_2_10.yml +++ b/Packs/Slack/ModelingRules/SlackModelingRules_2_10/SlackModelingRules_2_10.yml @@ -1,4 +1,5 @@ -fromversion: 8.14.0 +fromversion: 8.13.0 +toversion: 8.14.0 id: Slack_ModelingRule name: Slack Modeling Rule rules: '' diff --git a/Packs/Slack/ModelingRules/SlackModelingRules_2_11/SlackModelingRules_2_11.xif b/Packs/Slack/ModelingRules/SlackModelingRules_2_11/SlackModelingRules_2_11.xif new file mode 100644 index 000000000000..1f1d59795cb7 --- /dev/null +++ b/Packs/Slack/ModelingRules/SlackModelingRules_2_11/SlackModelingRules_2_11.xif @@ -0,0 +1,336 @@ +[MODEL: dataset="slack_slack_raw"] +filter action IN("user_login", "user_login*", "user_logout_compromised", "user_logout_non_compliant_mobile_app_version", "cli_login") //Authentication events mapping +// Extract actor and context fields +| alter + get_actor_user_email = json_extract_scalar(actor, "$['user']['email']"), + get_actor_user_id = json_extract_scalar(actor, "$['user']['id']"), + get_actor_user_name = json_extract_scalar(actor, "$['user']['name']"), + get_actor_user_team = json_extract_scalar(actor, "$['user']['team']"), + get_context_ua = json_extract_scalar(context, "$['ua']"), + get_entity_app_scopes = json_extract_scalar_array(entity, "$.app.scopes"), + get_entity_type = json_extract_scalar(entity, "$['type']") + +// Parse email into username and domain +| alter + array_actor_user_email = if(get_actor_user_email != NULL, split(get_actor_user_email, "@")) + +| alter //XDM Mapping + xdm.event.type = "authentication", + xdm.event.tags = arraycreate(XDM_CONST.EVENT_TAG_AUTHENTICATION), + xdm.event.operation = XDM_CONST.OPERATION_TYPE_AUTH_LOGIN, + xdm.event.id = id, + xdm.event.outcome = if( + action = "user_login_failed", XDM_CONST.OUTCOME_FAILED, + action IN("user_logout_compromised", "user_logout_non_compliant_mobile_app_version"), XDM_CONST.OUTCOME_FAILED, + action IN("user_login","cli_login") ,XDM_CONST.OUTCOME_SUCCESS + ), + xdm.event.outcome_reason = if( + action = "user_login_failed", "failed_login", + action IN("user_logout_non_compliant_mobile_app_version", "user_logout_compromised"), "auth_policy_access_violation", + "OTHER" + ), + xdm.event.original_event_type = action, + xdm.network.ip_protocol = XDM_CONST.IP_PROTOCOL_TCP, + xdm.auth.service = "SP", + xdm.auth.privilege_level = XDM_CONST.PRIVILEGE_LEVEL_USER, + xdm.source.ipv4 = if(is_ipv4(json_extract_scalar(context, "$['ip_address']")), json_extract_scalar(context, "$['ip_address']")), + xdm.source.ipv6 = if(is_ipv6(json_extract_scalar(context, "$['ip_address']")), json_extract_scalar(context, "$['ip_address']")), + xdm.target.ipv4 = "", + xdm.source.port = to_integer(0), + xdm.target.port = to_integer(0), + xdm.network.session_id = json_extract_scalar(context, "$['session_id']"), + + xdm.source.user.user_type = XDM_CONST.USER_TYPE_REGULAR, + xdm.source.identity.user_type = XDM_CONST.USER_TYPE_REGULAR, + xdm.source.user.scope = XDM_CONST.SCOPE_TYPE_SAAS, + xdm.source.identity.scope = XDM_CONST.SCOPE_TYPE_SAAS, + xdm.source.user.upn = get_actor_user_email, + xdm.source.identity.upn = get_actor_user_email, + xdm.source.user.username = arrayindex(array_actor_user_email, 0), + xdm.source.identity.username = arrayindex(array_actor_user_email, 0), + xdm.source.user.identifier = get_actor_user_id, + xdm.source.identity.identifier = get_actor_user_id, + xdm.source.user.identity_type = if( + get_actor_user_id IN("*USLACKBOT*","*USLACKSECURITY*"), XDM_CONST.IDENTITY_TYPE_APPLICATION, + arrayindex(array_actor_user_email, 1) CONTAINS "slack-bots.com", XDM_CONST.IDENTITY_TYPE_APPLICATION, + get_actor_user_id ~= "^A", XDM_CONST.IDENTITY_TYPE_APPLICATION, + get_actor_user_id CONTAINS "USLACKUSER", XDM_CONST.IDENTITY_TYPE_UNKNOWN, + XDM_CONST.IDENTITY_TYPE_USER + ), + xdm.source.identity.identity_type = if( + get_actor_user_id IN("*USLACKBOT*","*USLACKSECURITY*"), XDM_CONST.IDENTITY_TYPE_APPLICATION, + arrayindex(array_actor_user_email, 1) CONTAINS "slack-bots.com", XDM_CONST.IDENTITY_TYPE_APPLICATION, + get_actor_user_id ~= "^A", XDM_CONST.IDENTITY_TYPE_APPLICATION, + get_actor_user_id CONTAINS "USLACKUSER", XDM_CONST.IDENTITY_TYPE_UNKNOWN, + XDM_CONST.IDENTITY_TYPE_USER + ), + xdm.source.user_agent = get_context_ua, + xdm.source.user.full_domain_name = arrayindex(array_actor_user_email, 1), + xdm.source.identity.full_domain_name = arrayindex(array_actor_user_email, 1), + xdm.source.user.domain = arrayindex(array_actor_user_email, 1), + xdm.source.identity.domain = arrayindex(array_actor_user_email, 1), + xdm.source.user.first_name = if( + get_actor_user_name IN("*slack*","*Slack*"), NULL, + get_actor_user_name = arrayindex(array_actor_user_email, 0), NULL, + arrayindex(regextract(get_actor_user_name, "(^\w+)\s+"),0) + ), + xdm.source.identity.first_name = if( + get_actor_user_name IN("*slack*","*Slack*"), NULL, + get_actor_user_name = arrayindex(array_actor_user_email, 0), NULL, + arrayindex(regextract(get_actor_user_name, "(^\w+)\s+"),0) + ), + xdm.source.user.last_name = if( + get_actor_user_name IN("*@*","*slack*","*Slack*"), NULL, + get_actor_user_name = arrayindex(array_actor_user_email, 0), NULL, + arrayindex(regextract(get_actor_user_name, "\s+(\S+)$"),0) + ), + xdm.source.identity.last_name = if( + get_actor_user_name IN("*@*","*slack*","*Slack*"), NULL, + get_actor_user_name = arrayindex(array_actor_user_email, 0), NULL, + arrayindex(regextract(get_actor_user_name, "\s+(\S+)$"),0) + ), + xdm.source.user.groups = if(get_actor_user_team != null, arraycreate(get_actor_user_team)), + xdm.source.identity.groups = if(get_actor_user_team != null, arraycreate(get_actor_user_team)), + xdm.source.host.os = arrayindex(regextract(get_context_ua, "\(([^;)]+)"),0), + xdm.source.host.os_family = if( + get_context_ua CONTAINS "Windows", XDM_CONST.OS_FAMILY_WINDOWS, + get_context_ua CONTAINS "Android", XDM_CONST.OS_FAMILY_ANDROID, + get_context_ua IN("*iPhone*", "*iPad*"), XDM_CONST.OS_FAMILY_IOS, + get_context_ua IN("*Macintosh*", "*Mac OS X*"), XDM_CONST.OS_FAMILY_MACOS, + get_context_ua IN("*Linux*", "*X11*"), XDM_CONST.OS_FAMILY_LINUX, + get_context_ua), + xdm.source.cloud.project = json_extract_scalar(context, "$['location']['domain']"), + xdm.source.cloud.project_id = json_extract_scalar(context, "$['location']['id']"), + + xdm.logon.type = if( + json_extract_scalar(actor, "$['type']") ~= "[Uu]ser", XDM_CONST.LOGON_TYPE_INTERACTIVE, + XDM_CONST.LOGON_TYPE_SERVICE), + + xdm.source.application.name = json_extract_scalar(entity, "$['app']['name']"), + xdm.source.application.bundle_id = json_extract_scalar(entity, "$['app']['id']"), + + xdm.target.user.upn = json_extract_scalar(entity, "$['user']['email']"), + xdm.target.identity.upn = json_extract_scalar(entity, "$['user']['email']"), + xdm.target.user.scope = if(get_entity_type = "user", XDM_CONST.SCOPE_TYPE_SAAS), + xdm.target.identity.scope = if(get_entity_type = "user", XDM_CONST.SCOPE_TYPE_SAAS), + xdm.target.user.roles = get_entity_app_scopes, + xdm.target.identity.roles = get_entity_app_scopes, + xdm.target.user.identity_type = if(get_entity_type = "user", XDM_CONST.IDENTITY_TYPE_USER), + xdm.target.identity.identity_type = if(get_entity_type = "user", XDM_CONST.IDENTITY_TYPE_USER), + xdm.target.user.groups = arraycreate(json_extract_scalar(entity, "$['user']['team']")), + xdm.target.identity.groups = arraycreate(json_extract_scalar(entity, "$['user']['team']")), + xdm.target.user.identifier = json_extract_scalar(entity, "$['user']['id']"), + xdm.target.identity.identifier = json_extract_scalar(entity, "$['user']['id']"), + xdm.target.user.username = json_extract_scalar(entity, "$['user']['name']"), + xdm.target.identity.username = json_extract_scalar(entity, "$['user']['name']"), + xdm.target.file.filename = json_extract_scalar(entity, "$['file']['name']"), + xdm.target.file.file_type = json_extract_scalar(entity, "$['file']['filetype']"), + xdm.target.file.extension = arrayindex(regextract(json_extract_scalar(entity, "$['file']['name']"), "\.(\w+)$"),0), + xdm.alert.source_url = json_extract_scalar(details, "$['url_private']"); + +filter action NOT IN("user_login", "user_login*", "user_logout_compromised", "user_logout_non_compliant_mobile_app_version", "cli_login") //SaaS Audit Mapping +// Extract actor and context fields +| alter + get_actor_user_email = json_extract_scalar(actor, "$['user']['email']"), + get_actor_user_id = json_extract_scalar(actor, "$['user']['id']"), + get_context_app_id = json_extract_scalar(context, "$['app']['id']"), + get_actor_user_name = json_extract_scalar(actor, "$['user']['name']"), + get_actor_user_team = json_extract_scalar(actor, "$['user']['team']"), + get_context_app_scopes = json_extract_scalar_array(context, "$.app.scopes"), + get_context_app_scopes_bot = json_extract_scalar_array(context, "$.app.scopes_bot"), + get_entity_app_scopes = json_extract_scalar_array(entity, "$.app.scopes"), + get_entity_type = json_extract_scalar(entity, "$['type']") + +// Parse email into username and domain +| alter + array_actor_user_email = if(get_actor_user_email != NULL, split(get_actor_user_email, "@")) + +// XDM mapping +| alter + xdm.event.type = "saas audit", + xdm.event.id = id, + xdm.source.cloud.project_id = json_extract_scalar(context, "$['location']['id']"), + xdm.session_context_id = json_extract_scalar(context, "$['session_id']"), + xdm.event.original_event_type = action, + xdm.event.operation = if( + action ~= "_created|_installed|_published|_added|_generated|_deployed|_started", XDM_CONST.OPERATION_TYPE_CREATE, + action ~= "_deleted|_uninstalled|_archive|_revoked|_removed|_deactivated|_tombstoned", XDM_CONST.OPERATION_TYPE_DELETE, + action ~= "pref\.|_updated|_renamed|_converted|_changed|_reset|_resumed|_upgraded|_downgraded|_expanded", XDM_CONST.OPERATION_TYPE_UPDATE, + action ~= "_searched|_export|_download|_preview|_opened", XDM_CONST.OPERATION_TYPE_READ, + action ~= "_forwarded|_moved|_merged", XDM_CONST.OPERATION_TYPE_COPY, + action ~= "_login$|_logout", XDM_CONST.OPERATION_TYPE_AUTHENTICATION, + action ~= "_paused|_expired", XDM_CONST.OPERATION_TYPE_STATUS_CHANGE, + action ~= "_notification|_requested|_failed|_join|_leave", XDM_CONST.OPERATION_TYPE_AUDIT, + "OTHER" + ), + xdm.source.user.upn = get_actor_user_email, + xdm.source.identity.upn = get_actor_user_email, + xdm.source.user.identifier = get_actor_user_id, + xdm.source.identity.identifier = get_actor_user_id, + xdm.source.user.identity_type = if( + get_actor_user_id IN("*USLACKBOT*","*USLACKSECURITY*"), XDM_CONST.IDENTITY_TYPE_APPLICATION, + arrayindex(array_actor_user_email, 1) CONTAINS "slack-bots.com", XDM_CONST.IDENTITY_TYPE_APPLICATION, + get_actor_user_id ~= "^A", XDM_CONST.IDENTITY_TYPE_APPLICATION, + get_actor_user_id CONTAINS "USLACKUSER", XDM_CONST.IDENTITY_TYPE_UNKNOWN, + XDM_CONST.IDENTITY_TYPE_USER + ), + xdm.source.identity.identity_type = if( + get_actor_user_id IN("*USLACKBOT*","*USLACKSECURITY*"), XDM_CONST.IDENTITY_TYPE_APPLICATION, + arrayindex(array_actor_user_email, 1) CONTAINS "slack-bots.com", XDM_CONST.IDENTITY_TYPE_APPLICATION, + get_actor_user_id ~= "^A", XDM_CONST.IDENTITY_TYPE_APPLICATION, + get_actor_user_id CONTAINS "USLACKUSER", XDM_CONST.IDENTITY_TYPE_UNKNOWN, + XDM_CONST.IDENTITY_TYPE_USER + ), + xdm.auth.privilege_level = XDM_CONST.PRIVILEGE_LEVEL_USER, + xdm.intermediate.identity.username = json_extract_scalar(context, "$['app']['name']"), + xdm.intermediate.identity.identifier = get_context_app_id, + xdm.intermediate.identity.identity_type = if(get_context_app_id != null, XDM_CONST.IDENTITY_TYPE_APPLICATION), + xdm.event.outcome = if( + action in ("user_login_failed", "app_restricted", "file_download_blocked", "team_unsupported_versions_start_failure"), XDM_CONST.OUTCOME_FAILED, + XDM_CONST.OUTCOME_SUCCESS + ), + xdm.target.resource.type = get_entity_type, + xdm.target.resource.id = coalesce( + json_extract_scalar(entity, "$['app']['id']"), + json_extract_scalar(entity, "$['enterprise']['id']"), + json_extract_scalar(entity, "$['role']['id']"), + json_extract_scalar(entity, "$['workflow']['id']"), + json_extract_scalar(entity, "$['channel']['id']"), + json_extract_scalar(entity, "$['file']['id']"), + json_extract_scalar(entity, "$['workspace']['id']"), + json_extract_scalar(entity, "$['user']['id']"), + json_extract_scalar(entity, "$['account_type_role']['id']"), + json_extract_scalar(entity, "$['message']['id']"), + json_extract_scalar(entity, "$['usergroups']['id']"), + json_extract_scalar(entity, "$['huddles']['id']") + ), + xdm.target.resource.name = coalesce( + json_extract_scalar(entity, "$['app']['name']"), + json_extract_scalar(entity, "$['enterprise']['name']"), + json_extract_scalar(entity, "$['role']['name']"), + json_extract_scalar(entity, "$['workflow']['name']"), + json_extract_scalar(entity, "$['channel']['name']"), + json_extract_scalar(entity, "$['file']['name']"), + json_extract_scalar(entity, "$['workspace']['name']"), + json_extract_scalar(entity, "$['user']['name']"), + json_extract_scalar(entity, "$['account_type_role']['name']"), + json_extract_scalar(entity, "$['message']['name']"), + json_extract_scalar(entity, "$['usergroups']['name']"), + json_extract_scalar(entity, "$['huddles']['name']") + ), + xdm.source.user_agent = json_extract_scalar(context, "$['ua']"), + xdm.source.ipv4 = if(is_ipv4(json_extract_scalar(context, "$['ip_address']")), json_extract_scalar(context, "$['ip_address']"), ""), + xdm.source.ipv6 = if(is_ipv6(json_extract_scalar(context, "$['ip_address']")), json_extract_scalar(context, "$['ip_address']"), ""), + xdm.observer.type = "Slack", + xdm.observer.sub_type = "Audit Logs", + xdm.source.user.user_type = XDM_CONST.USER_TYPE_REGULAR, + xdm.source.identity.user_type = XDM_CONST.USER_TYPE_REGULAR, + xdm.source.user.scope = XDM_CONST.SCOPE_TYPE_SAAS, + xdm.source.identity.scope = XDM_CONST.SCOPE_TYPE_SAAS, + xdm.source.user.full_domain_name = arrayindex(array_actor_user_email, 1), + xdm.source.identity.full_domain_name = arrayindex(array_actor_user_email, 1), + xdm.event.outcome_reason = if( + action in ("user_login_failed", "app_restricted", "file_download_blocked", "team_unsupported_versions_start_failure"), action, + "OTHER"), + xdm.source.user.username = arrayindex(array_actor_user_email, 0), + xdm.source.identity.username = arrayindex(array_actor_user_email, 0), + xdm.source.user.domain = arrayindex(array_actor_user_email, 1), + xdm.source.identity.domain = arrayindex(array_actor_user_email, 1), + xdm.source.user.first_name = if( + get_actor_user_name IN("*slack*","*Slack*"), NULL, + get_actor_user_name = arrayindex(array_actor_user_email, 0), NULL, + arrayindex(regextract(get_actor_user_name, "(^\w+)\s+"),0) + ), + xdm.source.identity.first_name = if( + get_actor_user_name IN("*slack*","*Slack*"), NULL, + get_actor_user_name = arrayindex(array_actor_user_email, 0), NULL, + arrayindex(regextract(get_actor_user_name, "(^\w+)\s+"),0) + ), + xdm.source.user.last_name = if( + get_actor_user_name IN("*@*","*slack*","*Slack*"), NULL, + get_actor_user_name = arrayindex(array_actor_user_email, 0), NULL, + arrayindex(regextract(get_actor_user_name, "\s+(\S+)$"),0) + ), + xdm.source.identity.last_name = if( + get_actor_user_name IN("*@*","*slack*","*Slack*"), NULL, + get_actor_user_name = arrayindex(array_actor_user_email, 0), NULL, + arrayindex(regextract(get_actor_user_name, "\s+(\S+)$"),0) + ), + xdm.source.user.groups = if(get_actor_user_team != null, arraycreate(get_actor_user_team)), + xdm.source.identity.groups = if(get_actor_user_team != null, arraycreate(get_actor_user_team)), + xdm.source.cloud.project = json_extract_scalar(context, "$['location']['domain']"), + xdm.intermediate.user.scope = if(get_context_app_id != NULL, XDM_CONST.SCOPE_TYPE_SAAS), + xdm.intermediate.identity.scope = if(get_context_app_id != NULL, XDM_CONST.SCOPE_TYPE_SAAS), + xdm.intermediate.user.roles = if( + get_context_app_scopes != NULL and get_context_app_scopes_bot != NULL, arrayconcat(get_context_app_scopes, get_context_app_scopes_bot), + get_context_app_scopes != NULL, get_context_app_scopes, + get_context_app_scopes_bot + ), + xdm.intermediate.identity.roles = if( + get_context_app_scopes != NULL and get_context_app_scopes_bot != NULL, arrayconcat(get_context_app_scopes, get_context_app_scopes_bot), + get_context_app_scopes != NULL, get_context_app_scopes, + get_context_app_scopes_bot + ), + xdm.intermediate.user.groups = arraycreate(json_extract_scalar(context, "$['app']['team']")), + xdm.intermediate.identity.groups = arraycreate(json_extract_scalar(context, "$['app']['team']")), + + xdm.target.application.name = json_extract_scalar(entity, "$['app']['name']"), + xdm.target.application.bundle_id = json_extract_scalar(entity, "$['app']['id']"), + xdm.target.user.identifier = coalesce( + json_extract_scalar(entity, "$['app']['id']"), + json_extract_scalar(entity, "$['user']['id']") + ), + xdm.target.identity.identifier = coalesce( + json_extract_scalar(entity, "$['app']['id']"), + json_extract_scalar(entity, "$['user']['id']") + ), + xdm.target.user.upn = json_extract_scalar(entity, "$['user']['email']"), + xdm.target.identity.upn = json_extract_scalar(entity, "$['user']['email']"), + xdm.target.user.username = coalesce( + json_extract_scalar(entity, "$['app']['name']"), + json_extract_scalar(entity, "$['enterprise']['name']"), + json_extract_scalar(entity, "$['role']['name']"), + json_extract_scalar(entity, "$['workflow']['name']"), + json_extract_scalar(entity, "$['channel']['name']"), + json_extract_scalar(entity, "$['file']['name']"), + json_extract_scalar(entity, "$['workspace']['name']"), + json_extract_scalar(entity, "$['user']['name']"), + json_extract_scalar(entity, "$['account_type_role']['name']"), + json_extract_scalar(entity, "$['message']['name']"), + json_extract_scalar(entity, "$['usergroups']['name']"), + json_extract_scalar(entity, "$['huddles']['name']") + ), + xdm.target.identity.username = coalesce( + json_extract_scalar(entity, "$['app']['name']"), + json_extract_scalar(entity, "$['enterprise']['name']"), + json_extract_scalar(entity, "$['role']['name']"), + json_extract_scalar(entity, "$['workflow']['name']"), + json_extract_scalar(entity, "$['channel']['name']"), + json_extract_scalar(entity, "$['file']['name']"), + json_extract_scalar(entity, "$['workspace']['name']"), + json_extract_scalar(entity, "$['user']['name']"), + json_extract_scalar(entity, "$['account_type_role']['name']"), + json_extract_scalar(entity, "$['message']['name']"), + json_extract_scalar(entity, "$['usergroups']['name']"), + json_extract_scalar(entity, "$['huddles']['name']") + ), + xdm.target.user.scope = XDM_CONST.SCOPE_TYPE_SAAS, + xdm.target.identity.scope = XDM_CONST.SCOPE_TYPE_SAAS, + xdm.target.user.roles = get_entity_app_scopes, + xdm.target.identity.roles = get_entity_app_scopes, + xdm.target.user.identity_type = if( + get_entity_type = "user", XDM_CONST.IDENTITY_TYPE_USER, + get_entity_type = "app", XDM_CONST.IDENTITY_TYPE_APPLICATION, + XDM_CONST.IDENTITY_TYPE_VIRTUAL + ), + xdm.target.identity.identity_type = if( + get_entity_type = "user", XDM_CONST.IDENTITY_TYPE_USER, + get_entity_type = "app", XDM_CONST.IDENTITY_TYPE_APPLICATION, + XDM_CONST.IDENTITY_TYPE_VIRTUAL + ), + xdm.target.user.groups = arraycreate(json_extract_scalar(entity, "$['user']['team']")), + xdm.target.identity.groups = arraycreate(json_extract_scalar(entity, "$['user']['team']")), + xdm.target.file.filename = json_extract_scalar(entity, "$['file']['name']"), + xdm.target.file.file_type = json_extract_scalar(entity, "$['file']['filetype']"), + xdm.target.file.extension = arrayindex(regextract(json_extract_scalar(entity, "$['file']['name']"), "\.(\w+)$"),0), + xdm.alert.source_url = json_extract_scalar(details, "$['url_private']"); diff --git a/Packs/Slack/ModelingRules/SlackModelingRules_2_11/SlackModelingRules_2_11.yml b/Packs/Slack/ModelingRules/SlackModelingRules_2_11/SlackModelingRules_2_11.yml new file mode 100644 index 000000000000..639ed3c739f5 --- /dev/null +++ b/Packs/Slack/ModelingRules/SlackModelingRules_2_11/SlackModelingRules_2_11.yml @@ -0,0 +1,8 @@ +fromversion: 8.15.0 +id: Slack_ModelingRule +name: Slack Modeling Rule +rules: '' +schema: '' +supportedModules: +- xsiam +tags: 'slack' diff --git a/Packs/Slack/ModelingRules/SlackModelingRules_2_11/SlackModelingRules_2_11_schema.json b/Packs/Slack/ModelingRules/SlackModelingRules_2_11/SlackModelingRules_2_11_schema.json new file mode 100644 index 000000000000..ae4f94f8e0e0 --- /dev/null +++ b/Packs/Slack/ModelingRules/SlackModelingRules_2_11/SlackModelingRules_2_11_schema.json @@ -0,0 +1,32 @@ +{ + "slack_slack_raw": { + "id": { + "type": "string", + "is_array": false + }, + "date_create": { + "type": "int", + "is_array": false + }, + "action": { + "type": "string", + "is_array": false + }, + "actor": { + "type": "string", + "is_array": false + }, + "entity": { + "type": "string", + "is_array": false + }, + "context": { + "type": "string", + "is_array": false + }, + "details": { + "type": "string", + "is_array": false + } + } +} \ No newline at end of file diff --git a/Packs/Slack/ReleaseNotes/3_8_15.md b/Packs/Slack/ReleaseNotes/3_8_15.md new file mode 100644 index 000000000000..3ac5d49cb5a4 --- /dev/null +++ b/Packs/Slack/ReleaseNotes/3_8_15.md @@ -0,0 +1,7 @@ + +#### Modeling Rules + +##### New: Slack Modeling Rule + +- New: Added a new modeling rule version that maps the `xdm.*.identity.*` fields alongside the existing `xdm.*.user.*` fields. +<~XSIAM> (Available from Cortex XSIAM 2.11). diff --git a/Packs/Slack/pack_metadata.json b/Packs/Slack/pack_metadata.json index 02a10d6e0b77..3448dd4065d6 100644 --- a/Packs/Slack/pack_metadata.json +++ b/Packs/Slack/pack_metadata.json @@ -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.8.14", + "currentVersion": "3.8.15", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From bc1bde961eeb04368769814259d74ff29306342c Mon Sep 17 00:00:00 2001 From: tmizrahiPA Date: Wed, 19 Aug 2026 11:09:32 +0300 Subject: [PATCH 014/419] CRTX-271523: add identity.* to modeling rules (PR 2 of 7) + fix CitrixADC_2_11 malformed coalesce nesting (#45565) * CRTX-271523 - fix CitrixADC_2_11 malformed coalesce nesting (re-land pr2) * Bump pack from version GuardiCore to 2.0.26. * Bump pack from version Silverfort to 2.0.41. --------- Co-authored-by: Content Bot --- .../CitrixADC_1_3/CitrixADC_1_3.yml | 1 + .../CitrixADC_2_11/CitrixADC_2_11.xif | 92 ++ .../CitrixADC_2_11/CitrixADC_2_11.yml | 8 + .../CitrixADC_2_11/CitrixADC_2_11_schema.json | 8 + Packs/CitrixADC/ReleaseNotes/1_0_11.md | 7 + Packs/CitrixADC/pack_metadata.json | 2 +- .../CommvaultBackupSolutions.yml | 1 + .../CommvaultBackupSolutions_2_11.xif | 20 + .../CommvaultBackupSolutions_2_11.yml | 8 + .../CommvaultBackupSolutions_2_11_schema.json | 84 ++ .../ReleaseNotes/1_0_6.md | 7 + .../pack_metadata.json | 2 +- .../ModelingRules/GuardiCore/GuardiCore.yml | 1 + .../GuardiCore_2_11/GuardiCore_2_11.xif | 813 ++++++++++++++++++ .../GuardiCore_2_11/GuardiCore_2_11.yml | 8 + .../GuardiCore_2_11_schema.json | 132 +++ Packs/GuardiCore/ReleaseNotes/2_0_26.md | 7 + Packs/GuardiCore/pack_metadata.json | 2 +- .../ModelingRules/Silverfort/Silverfort.yml | 1 + .../Silverfort_2_11/Silverfort_2_11.xif | 72 ++ .../Silverfort_2_11/Silverfort_2_11.yml | 8 + .../Silverfort_2_11_schema.json | 88 ++ Packs/Silverfort/ReleaseNotes/2_0_41.md | 7 + Packs/Silverfort/pack_metadata.json | 2 +- 24 files changed, 1377 insertions(+), 4 deletions(-) create mode 100644 Packs/CitrixADC/ModelingRules/CitrixADC_2_11/CitrixADC_2_11.xif create mode 100644 Packs/CitrixADC/ModelingRules/CitrixADC_2_11/CitrixADC_2_11.yml create mode 100644 Packs/CitrixADC/ModelingRules/CitrixADC_2_11/CitrixADC_2_11_schema.json create mode 100644 Packs/CitrixADC/ReleaseNotes/1_0_11.md create mode 100644 Packs/CommvaultBackupSolutions/ModelingRules/CommvaultBackupSolutions_2_11/CommvaultBackupSolutions_2_11.xif create mode 100644 Packs/CommvaultBackupSolutions/ModelingRules/CommvaultBackupSolutions_2_11/CommvaultBackupSolutions_2_11.yml create mode 100644 Packs/CommvaultBackupSolutions/ModelingRules/CommvaultBackupSolutions_2_11/CommvaultBackupSolutions_2_11_schema.json create mode 100644 Packs/CommvaultBackupSolutions/ReleaseNotes/1_0_6.md create mode 100644 Packs/GuardiCore/ModelingRules/GuardiCore_2_11/GuardiCore_2_11.xif create mode 100644 Packs/GuardiCore/ModelingRules/GuardiCore_2_11/GuardiCore_2_11.yml create mode 100644 Packs/GuardiCore/ModelingRules/GuardiCore_2_11/GuardiCore_2_11_schema.json create mode 100644 Packs/GuardiCore/ReleaseNotes/2_0_26.md create mode 100644 Packs/Silverfort/ModelingRules/Silverfort_2_11/Silverfort_2_11.xif create mode 100644 Packs/Silverfort/ModelingRules/Silverfort_2_11/Silverfort_2_11.yml create mode 100644 Packs/Silverfort/ModelingRules/Silverfort_2_11/Silverfort_2_11_schema.json create mode 100644 Packs/Silverfort/ReleaseNotes/2_0_41.md diff --git a/Packs/CitrixADC/ModelingRules/CitrixADC_1_3/CitrixADC_1_3.yml b/Packs/CitrixADC/ModelingRules/CitrixADC_1_3/CitrixADC_1_3.yml index 155eda09b341..e8b48fadc2aa 100644 --- a/Packs/CitrixADC/ModelingRules/CitrixADC_1_3/CitrixADC_1_3.yml +++ b/Packs/CitrixADC/ModelingRules/CitrixADC_1_3/CitrixADC_1_3.yml @@ -1,4 +1,5 @@ fromversion: 8.4.0 +toversion: 8.14.0 id: Citrix_ADC_ModelingRule name: Citrix ADC Modeling Rule rules: '' diff --git a/Packs/CitrixADC/ModelingRules/CitrixADC_2_11/CitrixADC_2_11.xif b/Packs/CitrixADC/ModelingRules/CitrixADC_2_11/CitrixADC_2_11.xif new file mode 100644 index 000000000000..fcf7a7fda605 --- /dev/null +++ b/Packs/CitrixADC/ModelingRules/CitrixADC_2_11/CitrixADC_2_11.xif @@ -0,0 +1,92 @@ +[MODEL: dataset = "citrix_adc_raw"] +alter + http_method = arrayindex(regextract(_raw_log,"\s\:\s(\w+)\s\/"),0), + feature = arrayindex(regextract(_raw_log,"\:\s\w+\s(\w+)\s"),0), + message_type = arrayindex(regextract(_raw_log,"\:\s\w+\s\w+\s(\w+)\s"),0), + Status = lowercase(arrayindex(regextract(_raw_log,"Status\s\"(\w+)\""),0)), + message_type_lower = lowercase(arrayindex(regextract(_raw_log,"\:\s\w+\s\w+\s(\w+)\s"),0)) + +| alter + xdm.observer.name = arrayindex(regextract(_raw_log,"(\S+)\s\S+-\S+-\S+\s:"),0), + xdm.event.type = concat(feature, " - ", message_type), + xdm.event.id = arrayindex(regextract(_raw_log,"\:\s\w+\s\w+\s\w+\s(\d+)\s"),0), + xdm.event.description = coalesce(arrayindex(regextract(_raw_log,"\d+\s\d+\s\:\s+\"([^\"]+)\"*"),0), + arrayindex(regextract(_raw_log,"<\d+\>\s\d{2}\/\d{2}\/\d{4}\:\d{2}\:\d{2}\:\d{2}.\w{3}\s.+?\:.+?\:\s+(.+)"),0) + ), + xdm.source.ipv4 = coalesce(arrayindex(regextract(_raw_log,"Source\s(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"),0), + arrayindex(regextract(_raw_log,"Client_ip\s(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s"),0), + arrayindex(regextract(_raw_log,"Context\s[\w\d]+\@(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s"),0), + arrayindex(regextract(_raw_log,"client=(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\:"),0), + arrayindex(regextract(_raw_log,"ClientIP\s(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"),0), + arrayindex(regextract(_raw_log,"Remote.ip\s[\=\s]*(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"),0) + ), + xdm.source.ipv6 = coalesce(arrayindex(regextract(_raw_log,"Source\s([a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5})"),0), + arrayindex(regextract(_raw_log,"Client_ip\s([a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5})\s"),0), + arrayindex(regextract(_raw_log,"Context\s[\w\d]+\@([a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5})\s"),0), + arrayindex(regextract(_raw_log,"client=([a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5})\:"),0), + arrayindex(regextract(_raw_log,"ClientIP\s([a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5})"),0), + arrayindex(regextract(_raw_log,"Remote.ip\s[\=\s]*([a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5})"),0) + ), + xdm.source.port = to_integer(coalesce(arrayindex(regextract(_raw_log,"Source\s\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:(\d+)\s"),0), + arrayindex(regextract(_raw_log,"client=\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:(\d+)"),0), + arrayindex(regextract(_raw_log,"ClientPort\s(\d+)"),0), + arrayindex(regextract(_raw_log,"Remote.ip\s[\=\s]*\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:(\d+).+\sto"),0) + )), + xdm.target.port = to_integer(coalesce(arrayindex(regextract(_raw_log,"Destination\s\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:(\d+)\s"),0), + arrayindex(regextract(_raw_log,"VserverServicePort\s(\d+)\s"),0), + arrayindex(regextract(_raw_log,"Sending\srequest\sto.+?\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:(\d+)"),0), + arrayindex(regextract(_raw_log,"Vserver\s\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:(\d+)"),0), + arrayindex(regextract(_raw_log,"pcb_fport\s\=\s(\d+)"),0), + arrayindex(regextract(_raw_log,"sta-server\=\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:(\d+)"),0), + arrayindex(regextract(_raw_log,"vda\=\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:(\d+)"),0), + arrayindex(regextract(_raw_log,"received\sin\sSTA\sresponse\:\s\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:(\d+)"),0) + )), + xdm.target.ipv4 = coalesce(arrayindex(regextract(_raw_log,"Destination\s(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\:"),0), + arrayindex(regextract(_raw_log,"Vserver[ServiceIP]*\s(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"),0), + arrayindex(regextract(_raw_log,"Sending\srequest\sto.+?(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"),0), + arrayindex(regextract(_raw_log,"ADldap\-(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"),0), + arrayindex(regextract(_raw_log,"sta-server\=(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"),0), + arrayindex(regextract(_raw_log,"client\spcb\_fip\s\=\s(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"),0), + arrayindex(regextract(_raw_log,"vda\=(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"),0), + arrayindex(regextract(_raw_log,"received\sin\sSTA\sresponse\:\s(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"),0) + ), + xdm.target.ipv6 = coalesce(arrayindex(regextract(_raw_log,"Destination\s([a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5})\:"),0), + arrayindex(regextract(_raw_log,"Vserver[ServiceIP]*\s([a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5})"),0), + arrayindex(regextract(_raw_log,"Sending\srequest\sto.+?([a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5})\s"),0), + arrayindex(regextract(_raw_log,"ADldap\-([a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5})"),0), + arrayindex(regextract(_raw_log,"sta-server\=([a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5})"),0), + arrayindex(regextract(_raw_log,"vda\=([a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5})"),0), + arrayindex(regextract(_raw_log,"received\sin\sSTA\sresponse\:\s([a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5}[a-fA-F0-9\:]{1,5})"),0) + ), + xdm.source.sent_bytes = to_integer(arrayindex(regextract(_raw_log,"Total_bytes_send\s(\d+)\s"),0)), + xdm.target.sent_bytes = to_integer(arrayindex(regextract(_raw_log,"Total_bytes_recv\s(\d+)\s"),0)), + xdm.source.application.name = arrayindex(regextract(_raw_log,"applicationName\s(\w+)\s"),0), + xdm.session_context_id = arrayindex(regextract(_raw_log,"connectionId\s(\w+)\s"),0), + xdm.source.user.username = coalesce(arrayindex(regextract(_raw_log,"username:domainname\s(\w+)\:"),0), + arrayindex(regextract(_raw_log,"User\s([\w\@\.\d]+)\s\:"),0), + arrayindex(regextract(_raw_log,"Context\s([\w\d]+)\@"),0), + arrayindex(regextract(_raw_log,"user:\s\<([\w\d\.\_\-]+)\@"),0), + arrayindex(regextract(_raw_log,"\sUser\s(\S+)"),0) + ), + xdm.source.identity.username = coalesce(arrayindex(regextract(_raw_log,"username:domainname\s(\w+)\:"),0), + arrayindex(regextract(_raw_log,"User\s([\w\@\.\d]+)\s\:"),0), + arrayindex(regextract(_raw_log,"Context\s([\w\d]+)\@"),0), + arrayindex(regextract(_raw_log,"user:\s\<([\w\d\.\_\-]+)\@"),0), + arrayindex(regextract(_raw_log,"\sUser\s(\S+)"),0) + ), + xdm.source.user.domain = arrayindex(regextract(_raw_log,"username:domainname\s\w+\:(\w+)\s"),0), + xdm.source.identity.domain = arrayindex(regextract(_raw_log,"username:domainname\s\w+\:(\w+)\s"),0), + xdm.network.http.method = if(http_method="ACL", XDM_CONST.HTTP_METHOD_ACL,http_method="BASELINE_CONTROL", XDM_CONST.HTTP_METHOD_BASELINE_CONTROL,http_method="BIND", XDM_CONST.HTTP_METHOD_BIND,http_method="CHECKIN", XDM_CONST.HTTP_METHOD_CHECKIN,http_method="CHECKOUT", XDM_CONST.HTTP_METHOD_CHECKOUT,http_method="CONNECT", XDM_CONST.HTTP_METHOD_CONNECT,http_method="COPY", XDM_CONST.HTTP_METHOD_COPY,http_method="DELETE", XDM_CONST.HTTP_METHOD_DELETE,http_method="GET", XDM_CONST.HTTP_METHOD_GET,http_method="HEAD", XDM_CONST.HTTP_METHOD_HEAD,http_method="LABEL", XDM_CONST.HTTP_METHOD_LABEL,http_method="LINK", XDM_CONST.HTTP_METHOD_LINK,http_method="LOCK", XDM_CONST.HTTP_METHOD_LOCK,http_method="MERGE", XDM_CONST.HTTP_METHOD_MERGE,http_method="MKACTIVITY", XDM_CONST.HTTP_METHOD_MKACTIVITY,http_method="MKCALENDAR", XDM_CONST.HTTP_METHOD_MKCALENDAR,http_method="MKCOL", XDM_CONST.HTTP_METHOD_MKCOL,http_method="MKREDIRECTREF", XDM_CONST.HTTP_METHOD_MKREDIRECTREF,http_method="MKWORKSPACE", XDM_CONST.HTTP_METHOD_MKWORKSPACE,http_method="MOVE", XDM_CONST.HTTP_METHOD_MOVE,http_method="OPTIONS", XDM_CONST.HTTP_METHOD_OPTIONS,http_method="ORDERPATCH", XDM_CONST.HTTP_METHOD_ORDERPATCH,http_method="PATCH", XDM_CONST.HTTP_METHOD_PATCH,http_method="POST", XDM_CONST.HTTP_METHOD_POST,http_method="PRI", XDM_CONST.HTTP_METHOD_PRI,http_method="PROPFIND", XDM_CONST.HTTP_METHOD_PROPFIND,http_method="PROPPATCH", XDM_CONST.HTTP_METHOD_PROPPATCH,http_method="PUT", XDM_CONST.HTTP_METHOD_PUT,http_method="REBIND", XDM_CONST.HTTP_METHOD_REBIND,http_method="REPORT", XDM_CONST.HTTP_METHOD_REPORT,http_method="SEARCH", XDM_CONST.HTTP_METHOD_SEARCH,http_method="TRACE", XDM_CONST.HTTP_METHOD_TRACE,http_method="UNBIND", XDM_CONST.HTTP_METHOD_UNBIND,http_method="UNCHECKOUT", XDM_CONST.HTTP_METHOD_UNCHECKOUT,http_method="UNLINK", XDM_CONST.HTTP_METHOD_UNLINK,http_method="UNLOCK", XDM_CONST.HTTP_METHOD_UNLOCK,http_method="UPDATE", XDM_CONST.HTTP_METHOD_UPDATE,http_method="UPDATEREDIRECTREF", XDM_CONST.HTTP_METHOD_UPDATEREDIRECTREF,http_method="VERSION_CONTROL", XDM_CONST.HTTP_METHOD_VERSION_CONTROL, http_method), + xdm.network.http.url = arrayindex(regextract(_raw_log,"GET\s([\w\/\.]+)\s"),0), + xdm.intermediate.host.hostname = arrayindex(regextract(_raw_log,"\:\d{2}\s\w+\s([\w\-\_\.\d\:]+)\s"),0), + xdm.network.session_id = arrayindex(regextract(_raw_log,"SessionId:\s(\d+)\s"),0), + xdm.event.outcome = if(Status = "SUCCESS", XDM_CONST.OUTCOME_SUCCESS, Status = "FAILURE", XDM_CONST.OUTCOME_FAILED, message_type_lower contains "success", XDM_CONST.OUTCOME_SUCCESS, message_type_lower contains "failure", XDM_CONST.OUTCOME_FAILED, Status), + xdm.source.user_agent = arrayindex(regextract(_raw_log,"Browser_type\s\"([^\"]+)\""),0), + xdm.intermediate.ipv4 = arrayindex(regextract(_raw_log,"Vserver\s(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\:"),0), + xdm.intermediate.port = to_integer(arrayindex(regextract(_raw_log,"Vserver\s\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:(\d+)\s"),0)), + xdm.network.tls.client_certificate.issuer = arrayindex(regextract(_raw_log, "IssuerName\s\"?\s?([^\"]+)\"?$"), 0), + xdm.network.tls.client_certificate.subject = arrayindex(regextract(_raw_log, "SubjectName\s\"?\s?([^\"]+)\"?$"), 0), + xdm.network.tls.client_certificate.version = coalesce(arrayindex(regextract(_raw_log, "ClientVersion\s([^\s]+)"), 0), + arrayindex(regextract(_raw_log, "ProtocolVersion\s([^\s]+)"), 0)), + xdm.network.tls.cipher = arrayindex(regextract(_raw_log, "CipherSuite\s\"([^\"]+)\""), 0), + xdm.event.outcome_reason = arrayindex(regextract(_raw_log, "Reason\s\"([^\"]+)\""), 0); \ No newline at end of file diff --git a/Packs/CitrixADC/ModelingRules/CitrixADC_2_11/CitrixADC_2_11.yml b/Packs/CitrixADC/ModelingRules/CitrixADC_2_11/CitrixADC_2_11.yml new file mode 100644 index 000000000000..fd54b2cba498 --- /dev/null +++ b/Packs/CitrixADC/ModelingRules/CitrixADC_2_11/CitrixADC_2_11.yml @@ -0,0 +1,8 @@ +fromversion: 8.15.0 +id: Citrix_ADC_ModelingRule +name: Citrix ADC Modeling Rule +rules: '' +schema: '' +tags: Citrix ADC +supportedModules: +- xsiam diff --git a/Packs/CitrixADC/ModelingRules/CitrixADC_2_11/CitrixADC_2_11_schema.json b/Packs/CitrixADC/ModelingRules/CitrixADC_2_11/CitrixADC_2_11_schema.json new file mode 100644 index 000000000000..0fdb3eea5275 --- /dev/null +++ b/Packs/CitrixADC/ModelingRules/CitrixADC_2_11/CitrixADC_2_11_schema.json @@ -0,0 +1,8 @@ +{ + "citrix_adc_raw": { + "_raw_log": { + "type": "string", + "is_array": false + } + } +} \ No newline at end of file diff --git a/Packs/CitrixADC/ReleaseNotes/1_0_11.md b/Packs/CitrixADC/ReleaseNotes/1_0_11.md new file mode 100644 index 000000000000..6af7fab63975 --- /dev/null +++ b/Packs/CitrixADC/ReleaseNotes/1_0_11.md @@ -0,0 +1,7 @@ + +#### Modeling Rules + +##### New: Citrix ADC Modeling Rule + +- New: Added a new modeling rule version that maps the `xdm.*.identity.*` fields alongside the existing `xdm.*.user.*` fields. +<~XSIAM> (Available from Cortex XSIAM 2.11). diff --git a/Packs/CitrixADC/pack_metadata.json b/Packs/CitrixADC/pack_metadata.json index 9ebd3468f200..019cf3f63555 100644 --- a/Packs/CitrixADC/pack_metadata.json +++ b/Packs/CitrixADC/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Citrix ADC", "description": "Citrix ADC is an application delivery controller (ADC) is a purpose-built networking appliance used to improve the performance, security, and resiliency of applications delivered over the web.", "support": "xsoar", - "currentVersion": "1.0.10", + "currentVersion": "1.0.11", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/CommvaultBackupSolutions/ModelingRules/CommvaultBackupSolutions/CommvaultBackupSolutions.yml b/Packs/CommvaultBackupSolutions/ModelingRules/CommvaultBackupSolutions/CommvaultBackupSolutions.yml index 7875b2e7edf6..f2720e1e798b 100644 --- a/Packs/CommvaultBackupSolutions/ModelingRules/CommvaultBackupSolutions/CommvaultBackupSolutions.yml +++ b/Packs/CommvaultBackupSolutions/ModelingRules/CommvaultBackupSolutions/CommvaultBackupSolutions.yml @@ -1,4 +1,5 @@ fromversion: 8.2.0 +toversion: 8.14.0 id: Commvault_Backup_Solutions_ModelingRule name: Commvault Backup Solutions Modeling Rule rules: '' diff --git a/Packs/CommvaultBackupSolutions/ModelingRules/CommvaultBackupSolutions_2_11/CommvaultBackupSolutions_2_11.xif b/Packs/CommvaultBackupSolutions/ModelingRules/CommvaultBackupSolutions_2_11/CommvaultBackupSolutions_2_11.xif new file mode 100644 index 000000000000..b286fd417225 --- /dev/null +++ b/Packs/CommvaultBackupSolutions/ModelingRules/CommvaultBackupSolutions_2_11/CommvaultBackupSolutions_2_11.xif @@ -0,0 +1,20 @@ +[MODEL: dataset = commvault_backupsolution_raw] +alter + xdm.alert.name = coalesce(alert, alert_name), + xdm.alert.original_alert_id = to_string(alert_id), + xdm.network.rule = alert_rule_name, + xdm.alert.description = alertdescription, + xdm.alert.severity = severity, + xdm.observer.name = coalesce(commcell, commcellname), + xdm.target.host.hostname = coalesce(computer, client), + xdm.event.description = coalesce(description, details), + xdm.event.type = if( + opid != null and to_string(opid) !~= "^\s*$", "Audit", + alert_id != null and to_string(alert_id) !~= "^\s*$", "Alert", + event_id != null and to_string(event_id) !~= "^\s*$", coalesce(detected_criteria, type, "Event") + ), + xdm.event.original_event_type = to_string(event_code), + xdm.event.id = coalesce(to_string(event_id), to_string(opid)), + xdm.event.operation_sub_type = operation, + xdm.source.application.name = program, + xdm.source.user.username = user, xdm.source.identity.username = user; \ No newline at end of file diff --git a/Packs/CommvaultBackupSolutions/ModelingRules/CommvaultBackupSolutions_2_11/CommvaultBackupSolutions_2_11.yml b/Packs/CommvaultBackupSolutions/ModelingRules/CommvaultBackupSolutions_2_11/CommvaultBackupSolutions_2_11.yml new file mode 100644 index 000000000000..28ae13fb93aa --- /dev/null +++ b/Packs/CommvaultBackupSolutions/ModelingRules/CommvaultBackupSolutions_2_11/CommvaultBackupSolutions_2_11.yml @@ -0,0 +1,8 @@ +fromversion: 8.15.0 +id: Commvault_Backup_Solutions_ModelingRule +name: Commvault Backup Solutions Modeling Rule +rules: '' +schema: '' +tags: +supportedModules: +- xsiam diff --git a/Packs/CommvaultBackupSolutions/ModelingRules/CommvaultBackupSolutions_2_11/CommvaultBackupSolutions_2_11_schema.json b/Packs/CommvaultBackupSolutions/ModelingRules/CommvaultBackupSolutions_2_11/CommvaultBackupSolutions_2_11_schema.json new file mode 100644 index 000000000000..24a5abce510e --- /dev/null +++ b/Packs/CommvaultBackupSolutions/ModelingRules/CommvaultBackupSolutions_2_11/CommvaultBackupSolutions_2_11_schema.json @@ -0,0 +1,84 @@ +{ + "commvault_backupsolution_raw": { + "alert": { + "type": "string", + "is_array": false + }, + "alert_name": { + "type": "string", + "is_array": false + }, + "alert_rule_name": { + "type": "string", + "is_array": false + }, + "alertdescription": { + "type": "string", + "is_array": false + }, + "severity": { + "type": "string", + "is_array": false + }, + "commcell": { + "type": "string", + "is_array": false + }, + "commcellname": { + "type": "string", + "is_array": false + }, + "computer": { + "type": "string", + "is_array": false + }, + "client": { + "type": "string", + "is_array": false + }, + "description": { + "type": "string", + "is_array": false + }, + "details": { + "type": "string", + "is_array": false + }, + "detected_criteria": { + "type": "string", + "is_array": false + }, + "type": { + "type": "string", + "is_array": false + }, + "event_code": { + "type": "string", + "is_array": false + }, + "operation": { + "type": "string", + "is_array": false + }, + "program": { + "type": "string", + "is_array": false + }, + "user": { + "type": "string", + "is_array": false + }, + "event_id": { + "type": "int", + "is_array": false + }, + "opid": { + "type": "int", + "is_array": false + }, + "alert_id": { + "type": "int", + "is_array": false + } + } +} \ No newline at end of file diff --git a/Packs/CommvaultBackupSolutions/ReleaseNotes/1_0_6.md b/Packs/CommvaultBackupSolutions/ReleaseNotes/1_0_6.md new file mode 100644 index 000000000000..6604e3b2e24f --- /dev/null +++ b/Packs/CommvaultBackupSolutions/ReleaseNotes/1_0_6.md @@ -0,0 +1,7 @@ + +#### Modeling Rules + +##### New: Commvault Backup Solutions Modeling Rule + +- New: Added a new modeling rule version that maps the `xdm.*.identity.*` fields alongside the existing `xdm.*.user.*` fields. +<~XSIAM> (Available from Cortex XSIAM 2.11). diff --git a/Packs/CommvaultBackupSolutions/pack_metadata.json b/Packs/CommvaultBackupSolutions/pack_metadata.json index 7a8fce4503f3..8405881a04d0 100644 --- a/Packs/CommvaultBackupSolutions/pack_metadata.json +++ b/Packs/CommvaultBackupSolutions/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Commvault Backup Solutions", "description": "This pack contains Modeling and Parsing Rules for normalizing Commvault Backup API logs", "support": "xsoar", - "currentVersion": "1.0.5", + "currentVersion": "1.0.6", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/GuardiCore/ModelingRules/GuardiCore/GuardiCore.yml b/Packs/GuardiCore/ModelingRules/GuardiCore/GuardiCore.yml index 348ec34b2bb2..8a8707d1cfbe 100644 --- a/Packs/GuardiCore/ModelingRules/GuardiCore/GuardiCore.yml +++ b/Packs/GuardiCore/ModelingRules/GuardiCore/GuardiCore.yml @@ -1,4 +1,5 @@ fromversion: 8.12.0 +toversion: 8.14.0 id: Akamai_GuardiCore_ModelingRule name: Akamai GuardiCore Modeling Rule rules: '' diff --git a/Packs/GuardiCore/ModelingRules/GuardiCore_2_11/GuardiCore_2_11.xif b/Packs/GuardiCore/ModelingRules/GuardiCore_2_11/GuardiCore_2_11.xif new file mode 100644 index 000000000000..d55564ccd906 --- /dev/null +++ b/Packs/GuardiCore/ModelingRules/GuardiCore_2_11/GuardiCore_2_11.xif @@ -0,0 +1,813 @@ +[MODEL: dataset="akamai_guardicore_raw"] +/* ========================================== + Audit logs mapping + ========================================== */ +filter cefName ~= "Audit" +| alter //Extraction fields + src_username_from_upn = if(suser ~= "@", arrayindex(regextract(suser, "(\S+)\@"),0)), //Sometimes the suser field comes as UPN. + msg_host = arrayindex(regextract(msg, "host\:\s(\S+)\,"),0), + msg_port = arrayindex(regextract(msg, "port\:\s(\d+)"),0), + msg_protocol = arrayindex(regextract(msg, "protocol\:\s(\w+)"),0), + msg_resource_name = arrayindex(regextract(msg, "resource\:\s(\S+)"),0), + msg_status_code = arrayindex(regextract(msg, "status\scode\:\s(\d+)"),0), + msg_failed_login_reason = arrayindex(regextract(msg,"reason\:\s(.+)"),0) + +| alter //XDM Mapping + xdm.event.type = cefName, + xdm.observer.version = cefDeviceVersion, + xdm.event.operation = if( + act CONTAINS "authentication", XDM_CONST.OPERATION_TYPE_AUTHENTICATION, + act IN("Get asset*", "Access to*"), XDM_CONST.OPERATION_TYPE_READ, + act CONTAINS "Change password", XDM_CONST.OPERATION_TYPE_UPDATE, + act IN("Adding*", "Create*"), XDM_CONST.OPERATION_TYPE_CREATE, + act), + xdm.event.operation_sub_type = act, + xdm.source.user.upn = if(src_username_from_upn != null, suser), + xdm.source.identity.upn = if(src_username_from_upn != null, suser), + xdm.source.user.username = coalesce(src_username_from_upn, suser), + xdm.source.identity.username = coalesce(src_username_from_upn, suser), + xdm.source.ipv4 = if(is_ipv4(src) = TRUE, src), + xdm.source.ipv6 = if(is_ipv6(src) = TRUE, src), + xdm.event.description = msg, + xdm.target.host.hostname = msg_host, + xdm.target.port = to_integer(msg_port), + xdm.network.ip_protocol = if( + msg_protocol = null, null, + msg_protocol = "HOPOPT",XDM_CONST.IP_PROTOCOL_HOPOPT, + msg_protocol = "ICMP",XDM_CONST.IP_PROTOCOL_ICMP, + msg_protocol = "IGMP",XDM_CONST.IP_PROTOCOL_IGMP, + msg_protocol = "GGP",XDM_CONST.IP_PROTOCOL_GGP, + msg_protocol = "IP",XDM_CONST.IP_PROTOCOL_IP, + msg_protocol = "ST",XDM_CONST.IP_PROTOCOL_ST, + msg_protocol = "TCP",XDM_CONST.IP_PROTOCOL_TCP, + msg_protocol = "CBT",XDM_CONST.IP_PROTOCOL_CBT, + msg_protocol = "EGP",XDM_CONST.IP_PROTOCOL_EGP, + msg_protocol = "IGP",XDM_CONST.IP_PROTOCOL_IGP, + msg_protocol = "BBN_RCC_MON",XDM_CONST.IP_PROTOCOL_BBN_RCC_MON, + msg_protocol = "NVP_II",XDM_CONST.IP_PROTOCOL_NVP_II, + msg_protocol = "PUP",XDM_CONST.IP_PROTOCOL_PUP, + msg_protocol = "ARGUS",XDM_CONST.IP_PROTOCOL_ARGUS, + msg_protocol = "EMCON",XDM_CONST.IP_PROTOCOL_EMCON, + msg_protocol = "XNET",XDM_CONST.IP_PROTOCOL_XNET, + msg_protocol = "CHAOS",XDM_CONST.IP_PROTOCOL_CHAOS, + msg_protocol = "UDP",XDM_CONST.IP_PROTOCOL_UDP, + msg_protocol = "MUX",XDM_CONST.IP_PROTOCOL_MUX, + msg_protocol = "DCN_MEAS",XDM_CONST.IP_PROTOCOL_DCN_MEAS, + msg_protocol = "HMP",XDM_CONST.IP_PROTOCOL_HMP, + msg_protocol = "PRM",XDM_CONST.IP_PROTOCOL_PRM, + msg_protocol = "XNS_IDP",XDM_CONST.IP_PROTOCOL_XNS_IDP, + msg_protocol = "TRUNK_1",XDM_CONST.IP_PROTOCOL_TRUNK_1, + msg_protocol = "TRUNK_2",XDM_CONST.IP_PROTOCOL_TRUNK_2, + msg_protocol = "LEAF_1",XDM_CONST.IP_PROTOCOL_LEAF_1, + msg_protocol = "LEAF_2",XDM_CONST.IP_PROTOCOL_LEAF_2, + msg_protocol = "RDP",XDM_CONST.IP_PROTOCOL_RDP, + msg_protocol = "IRTP",XDM_CONST.IP_PROTOCOL_IRTP, + msg_protocol = "ISO_TP4",XDM_CONST.IP_PROTOCOL_ISO_TP4, + msg_protocol = "NETBLT",XDM_CONST.IP_PROTOCOL_NETBLT, + msg_protocol = "MFE_NSP",XDM_CONST.IP_PROTOCOL_MFE_NSP, + msg_protocol = "MERIT_INP",XDM_CONST.IP_PROTOCOL_MERIT_INP, + msg_protocol = "DCCP",XDM_CONST.IP_PROTOCOL_DCCP, + msg_protocol = "3PC",XDM_CONST.IP_PROTOCOL_3PC, + msg_protocol = "IDPR",XDM_CONST.IP_PROTOCOL_IDPR, + msg_protocol = "XTP",XDM_CONST.IP_PROTOCOL_XTP, + msg_protocol = "DDP",XDM_CONST.IP_PROTOCOL_DDP, + msg_protocol = "IDPR_CMTP",XDM_CONST.IP_PROTOCOL_IDPR_CMTP, + msg_protocol = "TP",XDM_CONST.IP_PROTOCOL_TP, + msg_protocol = "IL",XDM_CONST.IP_PROTOCOL_IL, + msg_protocol = "IPV6",XDM_CONST.IP_PROTOCOL_IPV6, + msg_protocol = "SDRP",XDM_CONST.IP_PROTOCOL_SDRP, + msg_protocol = "IPV6_ROUTE",XDM_CONST.IP_PROTOCOL_IPV6_ROUTE, + msg_protocol = "IPV6_FRAG",XDM_CONST.IP_PROTOCOL_IPV6_FRAG, + msg_protocol = "IDRP",XDM_CONST.IP_PROTOCOL_IDRP, + msg_protocol = "RSVP",XDM_CONST.IP_PROTOCOL_RSVP, + msg_protocol = "GRE",XDM_CONST.IP_PROTOCOL_GRE, + msg_protocol = "DSR",XDM_CONST.IP_PROTOCOL_DSR, + msg_protocol = "BNA",XDM_CONST.IP_PROTOCOL_BNA, + msg_protocol = "ESP",XDM_CONST.IP_PROTOCOL_ESP, + msg_protocol = "AH",XDM_CONST.IP_PROTOCOL_AH, + msg_protocol = "I_NLSP",XDM_CONST.IP_PROTOCOL_I_NLSP, + msg_protocol = "SWIPE",XDM_CONST.IP_PROTOCOL_SWIPE, + msg_protocol = "NARP",XDM_CONST.IP_PROTOCOL_NARP, + msg_protocol = "MOBILE",XDM_CONST.IP_PROTOCOL_MOBILE, + msg_protocol = "TLSP",XDM_CONST.IP_PROTOCOL_TLSP, + msg_protocol = "SKIP",XDM_CONST.IP_PROTOCOL_SKIP, + msg_protocol = "IPV6_ICMP",XDM_CONST.IP_PROTOCOL_IPV6_ICMP, + msg_protocol = "IPV6_NONXT",XDM_CONST.IP_PROTOCOL_IPV6_NONXT, + msg_protocol = "IPV6_OPTS",XDM_CONST.IP_PROTOCOL_IPV6_OPTS, + msg_protocol = "CFTP",XDM_CONST.IP_PROTOCOL_CFTP, + msg_protocol = "SAT_EXPAK",XDM_CONST.IP_PROTOCOL_SAT_EXPAK, + msg_protocol = "KRYPTOLAN",XDM_CONST.IP_PROTOCOL_KRYPTOLAN, + msg_protocol = "RVD",XDM_CONST.IP_PROTOCOL_RVD, + msg_protocol = "IPPC",XDM_CONST.IP_PROTOCOL_IPPC, + msg_protocol = "SAT_MON",XDM_CONST.IP_PROTOCOL_SAT_MON, + msg_protocol = "VISA",XDM_CONST.IP_PROTOCOL_VISA, + msg_protocol = "IPCV",XDM_CONST.IP_PROTOCOL_IPCV, + msg_protocol = "CPNX",XDM_CONST.IP_PROTOCOL_CPNX, + msg_protocol = "CPHB",XDM_CONST.IP_PROTOCOL_CPHB, + msg_protocol = "WSN",XDM_CONST.IP_PROTOCOL_WSN, + msg_protocol = "PVP",XDM_CONST.IP_PROTOCOL_PVP, + msg_protocol = "BR_SAT_MON",XDM_CONST.IP_PROTOCOL_BR_SAT_MON, + msg_protocol = "SUN_ND",XDM_CONST.IP_PROTOCOL_SUN_ND, + msg_protocol = "WB_MON",XDM_CONST.IP_PROTOCOL_WB_MON, + msg_protocol = "WB_EXPAK",XDM_CONST.IP_PROTOCOL_WB_EXPAK, + msg_protocol = "ISO_IP",XDM_CONST.IP_PROTOCOL_ISO_IP, + msg_protocol = "VMTP",XDM_CONST.IP_PROTOCOL_VMTP, + msg_protocol = "SECURE_VMTP",XDM_CONST.IP_PROTOCOL_SECURE_VMTP, + msg_protocol = "VINES",XDM_CONST.IP_PROTOCOL_VINES, + msg_protocol = "TTP",XDM_CONST.IP_PROTOCOL_TTP, + msg_protocol = "NSFNET_IGP",XDM_CONST.IP_PROTOCOL_NSFNET_IGP, + msg_protocol = "DGP",XDM_CONST.IP_PROTOCOL_DGP, + msg_protocol = "TCF",XDM_CONST.IP_PROTOCOL_TCF, + msg_protocol = "EIGRP",XDM_CONST.IP_PROTOCOL_EIGRP, + msg_protocol = "OSPFIGP",XDM_CONST.IP_PROTOCOL_OSPFIGP, + msg_protocol = "SPRITE_RPC",XDM_CONST.IP_PROTOCOL_SPRITE_RPC, + msg_protocol = "LARP",XDM_CONST.IP_PROTOCOL_LARP, + msg_protocol = "MTP",XDM_CONST.IP_PROTOCOL_MTP, + msg_protocol = "AX25",XDM_CONST.IP_PROTOCOL_AX25, + msg_protocol = "IPIP",XDM_CONST.IP_PROTOCOL_IPIP, + msg_protocol = "MICP",XDM_CONST.IP_PROTOCOL_MICP, + msg_protocol = "SCC_SP",XDM_CONST.IP_PROTOCOL_SCC_SP, + msg_protocol = "ETHERIP",XDM_CONST.IP_PROTOCOL_ETHERIP, + msg_protocol = "ENCAP",XDM_CONST.IP_PROTOCOL_ENCAP, + msg_protocol = "GMTP",XDM_CONST.IP_PROTOCOL_GMTP, + msg_protocol = "IFMP",XDM_CONST.IP_PROTOCOL_IFMP, + msg_protocol = "PNNI",XDM_CONST.IP_PROTOCOL_PNNI, + msg_protocol = "PIM",XDM_CONST.IP_PROTOCOL_PIM, + msg_protocol = "ARIS",XDM_CONST.IP_PROTOCOL_ARIS, + msg_protocol = "SCPS",XDM_CONST.IP_PROTOCOL_SCPS, + msg_protocol = "QNX",XDM_CONST.IP_PROTOCOL_QNX, + msg_protocol = "AN",XDM_CONST.IP_PROTOCOL_AN, + msg_protocol = "IPCOMP",XDM_CONST.IP_PROTOCOL_IPCOMP, + msg_protocol = "SNP",XDM_CONST.IP_PROTOCOL_SNP, + msg_protocol = "COMPAQ_PEER",XDM_CONST.IP_PROTOCOL_COMPAQ_PEER, + msg_protocol = "IPX_IN_IP",XDM_CONST.IP_PROTOCOL_IPX_IN_IP, + msg_protocol = "VRRP",XDM_CONST.IP_PROTOCOL_VRRP, + msg_protocol = "PGM",XDM_CONST.IP_PROTOCOL_PGM, + msg_protocol = "L2TP",XDM_CONST.IP_PROTOCOL_L2TP, + msg_protocol = "DDX",XDM_CONST.IP_PROTOCOL_DDX, + msg_protocol = "IATP",XDM_CONST.IP_PROTOCOL_IATP, + msg_protocol = "STP",XDM_CONST.IP_PROTOCOL_STP, + msg_protocol = "SRP",XDM_CONST.IP_PROTOCOL_SRP, + msg_protocol = "UTI",XDM_CONST.IP_PROTOCOL_UTI, + msg_protocol = "SMP",XDM_CONST.IP_PROTOCOL_SMP, + msg_protocol = "SM",XDM_CONST.IP_PROTOCOL_SM, + msg_protocol = "PTP",XDM_CONST.IP_PROTOCOL_PTP, + msg_protocol = "ISIS",XDM_CONST.IP_PROTOCOL_ISIS, + msg_protocol = "FIRE",XDM_CONST.IP_PROTOCOL_FIRE, + msg_protocol = "CRTP",XDM_CONST.IP_PROTOCOL_CRTP, + msg_protocol = "CRUDP",XDM_CONST.IP_PROTOCOL_CRUDP, + msg_protocol = "SSCOPMCE",XDM_CONST.IP_PROTOCOL_SSCOPMCE, + msg_protocol = "IPLT",XDM_CONST.IP_PROTOCOL_IPLT, + msg_protocol = "SPS",XDM_CONST.IP_PROTOCOL_SPS, + msg_protocol = "PIPE",XDM_CONST.IP_PROTOCOL_PIPE, + msg_protocol = "SCTP",XDM_CONST.IP_PROTOCOL_SCTP, + msg_protocol = "FC",XDM_CONST.IP_PROTOCOL_FC, + msg_protocol = "RSVP_E2E_IGNORE",XDM_CONST.IP_PROTOCOL_RSVP_E2E_IGNORE, + msg_protocol = "MOBILITY",XDM_CONST.IP_PROTOCOL_MOBILITY, + msg_protocol = "UDPLITE",XDM_CONST.IP_PROTOCOL_UDPLITE, + msg_protocol = "MPLS_IN_IP",XDM_CONST.IP_PROTOCOL_MPLS_IN_IP, + msg_protocol = "MANET",XDM_CONST.IP_PROTOCOL_MANET, + msg_protocol = "HIP",XDM_CONST.IP_PROTOCOL_HIP, + msg_protocol = "SHIM6",XDM_CONST.IP_PROTOCOL_SHIM6, + msg_protocol = "WESP",XDM_CONST.IP_PROTOCOL_WESP, + msg_protocol = "ROHC",XDM_CONST.IP_PROTOCOL_ROHC, + msg_protocol = "RESERVED",XDM_CONST.IP_PROTOCOL_RESERVED, + msg_protocol = "0",XDM_CONST.IP_PROTOCOL_HOPOPT, + msg_protocol = "1",XDM_CONST.IP_PROTOCOL_ICMP, + msg_protocol = "2",XDM_CONST.IP_PROTOCOL_IGMP, + msg_protocol = "3",XDM_CONST.IP_PROTOCOL_GGP, + msg_protocol = "4",XDM_CONST.IP_PROTOCOL_IP, + msg_protocol = "5",XDM_CONST.IP_PROTOCOL_ST, + msg_protocol = "6",XDM_CONST.IP_PROTOCOL_TCP, + msg_protocol = "7",XDM_CONST.IP_PROTOCOL_CBT, + msg_protocol = "8",XDM_CONST.IP_PROTOCOL_EGP, + msg_protocol = "9",XDM_CONST.IP_PROTOCOL_IGP, + msg_protocol = "10",XDM_CONST.IP_PROTOCOL_BBN_RCC_MON, + msg_protocol = "11",XDM_CONST.IP_PROTOCOL_NVP_II, + msg_protocol = "12",XDM_CONST.IP_PROTOCOL_PUP, + msg_protocol = "13",XDM_CONST.IP_PROTOCOL_ARGUS, + msg_protocol = "14",XDM_CONST.IP_PROTOCOL_EMCON, + msg_protocol = "15",XDM_CONST.IP_PROTOCOL_XNET, + msg_protocol = "16",XDM_CONST.IP_PROTOCOL_CHAOS, + msg_protocol = "17",XDM_CONST.IP_PROTOCOL_UDP, + msg_protocol = "18",XDM_CONST.IP_PROTOCOL_MUX, + msg_protocol = "19",XDM_CONST.IP_PROTOCOL_DCN_MEAS, + msg_protocol = "20",XDM_CONST.IP_PROTOCOL_HMP, + msg_protocol = "21",XDM_CONST.IP_PROTOCOL_PRM, + msg_protocol = "22",XDM_CONST.IP_PROTOCOL_XNS_IDP, + msg_protocol = "23",XDM_CONST.IP_PROTOCOL_TRUNK_1, + msg_protocol = "24",XDM_CONST.IP_PROTOCOL_TRUNK_2, + msg_protocol = "25",XDM_CONST.IP_PROTOCOL_LEAF_1, + msg_protocol = "26",XDM_CONST.IP_PROTOCOL_LEAF_2, + msg_protocol = "27",XDM_CONST.IP_PROTOCOL_RDP, + msg_protocol = "28",XDM_CONST.IP_PROTOCOL_IRTP, + msg_protocol = "29",XDM_CONST.IP_PROTOCOL_ISO_TP4, + msg_protocol = "30",XDM_CONST.IP_PROTOCOL_NETBLT, + msg_protocol = "31",XDM_CONST.IP_PROTOCOL_MFE_NSP, + msg_protocol = "32",XDM_CONST.IP_PROTOCOL_MERIT_INP, + msg_protocol = "33",XDM_CONST.IP_PROTOCOL_DCCP, + msg_protocol = "34",XDM_CONST.IP_PROTOCOL_3PC, + msg_protocol = "35",XDM_CONST.IP_PROTOCOL_IDPR, + msg_protocol = "36",XDM_CONST.IP_PROTOCOL_XTP, + msg_protocol = "37",XDM_CONST.IP_PROTOCOL_DDP, + msg_protocol = "38",XDM_CONST.IP_PROTOCOL_IDPR_CMTP, + msg_protocol = "39",XDM_CONST.IP_PROTOCOL_TP, + msg_protocol = "40",XDM_CONST.IP_PROTOCOL_IL, + msg_protocol = "41",XDM_CONST.IP_PROTOCOL_IPV6, + msg_protocol = "42",XDM_CONST.IP_PROTOCOL_SDRP, + msg_protocol = "43",XDM_CONST.IP_PROTOCOL_IPV6_ROUTE, + msg_protocol = "44",XDM_CONST.IP_PROTOCOL_IPV6_FRAG, + msg_protocol = "45",XDM_CONST.IP_PROTOCOL_IDRP, + msg_protocol = "46",XDM_CONST.IP_PROTOCOL_RSVP, + msg_protocol = "47",XDM_CONST.IP_PROTOCOL_GRE, + msg_protocol = "48",XDM_CONST.IP_PROTOCOL_DSR, + msg_protocol = "49",XDM_CONST.IP_PROTOCOL_BNA, + msg_protocol = "50",XDM_CONST.IP_PROTOCOL_ESP, + msg_protocol = "51",XDM_CONST.IP_PROTOCOL_AH, + msg_protocol = "52",XDM_CONST.IP_PROTOCOL_I_NLSP, + msg_protocol = "53",XDM_CONST.IP_PROTOCOL_SWIPE, + msg_protocol = "54",XDM_CONST.IP_PROTOCOL_NARP, + msg_protocol = "55",XDM_CONST.IP_PROTOCOL_MOBILE, + msg_protocol = "56",XDM_CONST.IP_PROTOCOL_TLSP, + msg_protocol = "57",XDM_CONST.IP_PROTOCOL_SKIP, + msg_protocol = "58",XDM_CONST.IP_PROTOCOL_IPV6_ICMP, + msg_protocol = "59",XDM_CONST.IP_PROTOCOL_IPV6_NONXT, + msg_protocol = "60",XDM_CONST.IP_PROTOCOL_IPV6_OPTS, + msg_protocol = "62",XDM_CONST.IP_PROTOCOL_CFTP, + msg_protocol = "64",XDM_CONST.IP_PROTOCOL_SAT_EXPAK, + msg_protocol = "65",XDM_CONST.IP_PROTOCOL_KRYPTOLAN, + msg_protocol = "66",XDM_CONST.IP_PROTOCOL_RVD, + msg_protocol = "67",XDM_CONST.IP_PROTOCOL_IPPC, + msg_protocol = "69",XDM_CONST.IP_PROTOCOL_SAT_MON, + msg_protocol = "70",XDM_CONST.IP_PROTOCOL_VISA, + msg_protocol = "71",XDM_CONST.IP_PROTOCOL_IPCV, + msg_protocol = "72",XDM_CONST.IP_PROTOCOL_CPNX, + msg_protocol = "73",XDM_CONST.IP_PROTOCOL_CPHB, + msg_protocol = "74",XDM_CONST.IP_PROTOCOL_WSN, + msg_protocol = "75",XDM_CONST.IP_PROTOCOL_PVP, + msg_protocol = "76",XDM_CONST.IP_PROTOCOL_BR_SAT_MON, + msg_protocol = "77",XDM_CONST.IP_PROTOCOL_SUN_ND, + msg_protocol = "78",XDM_CONST.IP_PROTOCOL_WB_MON, + msg_protocol = "79",XDM_CONST.IP_PROTOCOL_WB_EXPAK, + msg_protocol = "80",XDM_CONST.IP_PROTOCOL_ISO_IP, + msg_protocol = "81",XDM_CONST.IP_PROTOCOL_VMTP, + msg_protocol = "82",XDM_CONST.IP_PROTOCOL_SECURE_VMTP, + msg_protocol = "83",XDM_CONST.IP_PROTOCOL_VINES, + msg_protocol = "84",XDM_CONST.IP_PROTOCOL_TTP, + msg_protocol = "85",XDM_CONST.IP_PROTOCOL_NSFNET_IGP, + msg_protocol = "86",XDM_CONST.IP_PROTOCOL_DGP, + msg_protocol = "87",XDM_CONST.IP_PROTOCOL_TCF, + msg_protocol = "88",XDM_CONST.IP_PROTOCOL_EIGRP, + msg_protocol = "89",XDM_CONST.IP_PROTOCOL_OSPFIGP, + msg_protocol = "90",XDM_CONST.IP_PROTOCOL_SPRITE_RPC, + msg_protocol = "91",XDM_CONST.IP_PROTOCOL_LARP, + msg_protocol = "92",XDM_CONST.IP_PROTOCOL_MTP, + msg_protocol = "93",XDM_CONST.IP_PROTOCOL_AX25, + msg_protocol = "94",XDM_CONST.IP_PROTOCOL_IPIP, + msg_protocol = "95",XDM_CONST.IP_PROTOCOL_MICP, + msg_protocol = "96",XDM_CONST.IP_PROTOCOL_SCC_SP, + msg_protocol = "97",XDM_CONST.IP_PROTOCOL_ETHERIP, + msg_protocol = "98",XDM_CONST.IP_PROTOCOL_ENCAP, + msg_protocol = "100",XDM_CONST.IP_PROTOCOL_GMTP, + msg_protocol = "101",XDM_CONST.IP_PROTOCOL_IFMP, + msg_protocol = "102",XDM_CONST.IP_PROTOCOL_PNNI, + msg_protocol = "103",XDM_CONST.IP_PROTOCOL_PIM, + msg_protocol = "104",XDM_CONST.IP_PROTOCOL_ARIS, + msg_protocol = "105",XDM_CONST.IP_PROTOCOL_SCPS, + msg_protocol = "106",XDM_CONST.IP_PROTOCOL_QNX, + msg_protocol = "107",XDM_CONST.IP_PROTOCOL_AN, + msg_protocol = "108",XDM_CONST.IP_PROTOCOL_IPCOMP, + msg_protocol = "109",XDM_CONST.IP_PROTOCOL_SNP, + msg_protocol = "110",XDM_CONST.IP_PROTOCOL_COMPAQ_PEER, + msg_protocol = "111",XDM_CONST.IP_PROTOCOL_IPX_IN_IP, + msg_protocol = "112",XDM_CONST.IP_PROTOCOL_VRRP, + msg_protocol = "113",XDM_CONST.IP_PROTOCOL_PGM, + msg_protocol = "115",XDM_CONST.IP_PROTOCOL_L2TP, + msg_protocol = "116",XDM_CONST.IP_PROTOCOL_DDX, + msg_protocol = "117",XDM_CONST.IP_PROTOCOL_IATP, + msg_protocol = "118",XDM_CONST.IP_PROTOCOL_STP, + msg_protocol = "119",XDM_CONST.IP_PROTOCOL_SRP, + msg_protocol = "120",XDM_CONST.IP_PROTOCOL_UTI, + msg_protocol = "121",XDM_CONST.IP_PROTOCOL_SMP, + msg_protocol = "122",XDM_CONST.IP_PROTOCOL_SM, + msg_protocol = "123",XDM_CONST.IP_PROTOCOL_PTP, + msg_protocol = "124",XDM_CONST.IP_PROTOCOL_ISIS, + msg_protocol = "125",XDM_CONST.IP_PROTOCOL_FIRE, + msg_protocol = "126",XDM_CONST.IP_PROTOCOL_CRTP, + msg_protocol = "127",XDM_CONST.IP_PROTOCOL_CRUDP, + msg_protocol = "128",XDM_CONST.IP_PROTOCOL_SSCOPMCE, + msg_protocol = "129",XDM_CONST.IP_PROTOCOL_IPLT, + msg_protocol = "130",XDM_CONST.IP_PROTOCOL_SPS, + msg_protocol = "131",XDM_CONST.IP_PROTOCOL_PIPE, + msg_protocol = "132",XDM_CONST.IP_PROTOCOL_SCTP, + msg_protocol = "133",XDM_CONST.IP_PROTOCOL_FC, + msg_protocol = "134",XDM_CONST.IP_PROTOCOL_RSVP_E2E_IGNORE, + msg_protocol = "135",XDM_CONST.IP_PROTOCOL_MOBILITY, + msg_protocol = "136",XDM_CONST.IP_PROTOCOL_UDPLITE, + msg_protocol = "137",XDM_CONST.IP_PROTOCOL_MPLS_IN_IP, + msg_protocol = "138",XDM_CONST.IP_PROTOCOL_MANET, + msg_protocol = "139",XDM_CONST.IP_PROTOCOL_HIP, + msg_protocol = "140",XDM_CONST.IP_PROTOCOL_SHIM6, + msg_protocol = "141",XDM_CONST.IP_PROTOCOL_WESP, + msg_protocol = "142",XDM_CONST.IP_PROTOCOL_ROHC, + msg_protocol = "255",XDM_CONST.IP_PROTOCOL_RESERVED, + msg_protocol), + xdm.target.resource.name = msg_resource_name, + xdm.network.http.response_code = if( + msg_status_code = null, null, + msg_status_code = "100", XDM_CONST.HTTP_RSP_CODE_CONTINUE, + msg_status_code = "101", XDM_CONST.HTTP_RSP_CODE_SWITCHING_PROTOCOLS, + msg_status_code = "102", XDM_CONST.HTTP_RSP_CODE_PROCESSING, + msg_status_code = "103", XDM_CONST.HTTP_RSP_CODE_EARLY_HINTS, + msg_status_code = "200", XDM_CONST.HTTP_RSP_CODE_OK, + msg_status_code = "201", XDM_CONST.HTTP_RSP_CODE_CREATED, + msg_status_code = "202", XDM_CONST.HTTP_RSP_CODE_ACCEPTED, + msg_status_code = "203", XDM_CONST.HTTP_RSP_CODE_NON__AUTHORITATIVE_INFORMATION, + msg_status_code = "204", XDM_CONST.HTTP_RSP_CODE_NO_CONTENT, + msg_status_code = "205", XDM_CONST.HTTP_RSP_CODE_RESET_CONTENT, + msg_status_code = "206", XDM_CONST.HTTP_RSP_CODE_PARTIAL_CONTENT, + msg_status_code = "207", XDM_CONST.HTTP_RSP_CODE_MULTI__STATUS, + msg_status_code = "208", XDM_CONST.HTTP_RSP_CODE_ALREADY_REPORTED, + msg_status_code = "226", XDM_CONST.HTTP_RSP_CODE_IM_USED, + msg_status_code = "300", XDM_CONST.HTTP_RSP_CODE_MULTIPLE_CHOICES, + msg_status_code = "301", XDM_CONST.HTTP_RSP_CODE_MOVED_PERMANENTLY, + msg_status_code = "302", XDM_CONST.HTTP_RSP_CODE_FOUND, + msg_status_code = "303", XDM_CONST.HTTP_RSP_CODE_SEE_OTHER, + msg_status_code = "304", XDM_CONST.HTTP_RSP_CODE_NOT_MODIFIED, + msg_status_code = "305", XDM_CONST.HTTP_RSP_CODE_USE_PROXY, + msg_status_code = "307", XDM_CONST.HTTP_RSP_CODE_TEMPORARY_REDIRECT, + msg_status_code = "308", XDM_CONST.HTTP_RSP_CODE_PERMANENT_REDIRECT, + msg_status_code = "400", XDM_CONST.HTTP_RSP_CODE_BAD_REQUEST, + msg_status_code = "401", XDM_CONST.HTTP_RSP_CODE_UNAUTHORIZED, + msg_status_code = "402", XDM_CONST.HTTP_RSP_CODE_PAYMENT_REQUIRED, + msg_status_code = "403", XDM_CONST.HTTP_RSP_CODE_FORBIDDEN, + msg_status_code = "404", XDM_CONST.HTTP_RSP_CODE_NOT_FOUND, + msg_status_code = "405", XDM_CONST.HTTP_RSP_CODE_METHOD_NOT_ALLOWED, + msg_status_code = "406", XDM_CONST.HTTP_RSP_CODE_NOT_ACCEPTABLE, + msg_status_code = "407", XDM_CONST.HTTP_RSP_CODE_PROXY_AUTHENTICATION_REQUIRED, + msg_status_code = "408", XDM_CONST.HTTP_RSP_CODE_REQUEST_TIMEOUT, + msg_status_code = "409", XDM_CONST.HTTP_RSP_CODE_CONFLICT, + msg_status_code = "410", XDM_CONST.HTTP_RSP_CODE_GONE, + msg_status_code = "411", XDM_CONST.HTTP_RSP_CODE_LENGTH_REQUIRED, + msg_status_code = "412", XDM_CONST.HTTP_RSP_CODE_PRECONDITION_FAILED, + msg_status_code = "413", XDM_CONST.HTTP_RSP_CODE_CONTENT_TOO_LARGE, + msg_status_code = "414", XDM_CONST.HTTP_RSP_CODE_URI_TOO_LONG, + msg_status_code = "415", XDM_CONST.HTTP_RSP_CODE_UNSUPPORTED_MEDIA_TYPE, + msg_status_code = "416", XDM_CONST.HTTP_RSP_CODE_RANGE_NOT_SATISFIABLE, + msg_status_code = "417", XDM_CONST.HTTP_RSP_CODE_EXPECTATION_FAILED, + msg_status_code = "421", XDM_CONST.HTTP_RSP_CODE_MISDIRECTED_REQUEST, + msg_status_code = "422", XDM_CONST.HTTP_RSP_CODE_UNPROCESSABLE_CONTENT, + msg_status_code = "423", XDM_CONST.HTTP_RSP_CODE_LOCKED, + msg_status_code = "424", XDM_CONST.HTTP_RSP_CODE_FAILED_DEPENDENCY, + msg_status_code = "425", XDM_CONST.HTTP_RSP_CODE_TOO_EARLY, + msg_status_code = "426", XDM_CONST.HTTP_RSP_CODE_UPGRADE_REQUIRED, + msg_status_code = "428", XDM_CONST.HTTP_RSP_CODE_PRECONDITION_REQUIRED, + msg_status_code = "429", XDM_CONST.HTTP_RSP_CODE_TOO_MANY_REQUESTS, + msg_status_code = "431", XDM_CONST.HTTP_RSP_CODE_REQUEST_HEADER_FIELDS_TOO_LARGE, + msg_status_code = "451", XDM_CONST.HTTP_RSP_CODE_UNAVAILABLE_FOR_LEGAL_REASONS, + msg_status_code = "500", XDM_CONST.HTTP_RSP_CODE_INTERNAL_SERVER_ERROR, + msg_status_code = "501", XDM_CONST.HTTP_RSP_CODE_NOT_IMPLEMENTED, + msg_status_code = "502", XDM_CONST.HTTP_RSP_CODE_BAD_GATEWAY, + msg_status_code = "503", XDM_CONST.HTTP_RSP_CODE_SERVICE_UNAVAILABLE, + msg_status_code = "504", XDM_CONST.HTTP_RSP_CODE_GATEWAY_TIMEOUT, + msg_status_code = "505", XDM_CONST.HTTP_RSP_CODE_HTTP_VERSION_NOT_SUPPORTED, + msg_status_code = "506", XDM_CONST.HTTP_RSP_CODE_VARIANT_ALSO_NEGOTIATES, + msg_status_code = "507", XDM_CONST.HTTP_RSP_CODE_INSUFFICIENT_STORAGE, + msg_status_code = "508", XDM_CONST.HTTP_RSP_CODE_LOOP_DETECTED, + msg_status_code = "511", XDM_CONST.HTTP_RSP_CODE_NETWORK_AUTHENTICATION_REQUIRED, + msg_status_code), + xdm.event.outcome = if( + msg ~= "failed", XDM_CONST.OUTCOME_FAILED, + msg ~= "success", XDM_CONST.OUTCOME_SUCCESS, + msg_status_code IN("200","201","202","203","204","205","207","208","226"), XDM_CONST.OUTCOME_SUCCESS, + msg_status_code IN("4*","5*"),XDM_CONST.OUTCOME_FAILED, + msg_status_code IN("206"), XDM_CONST.OUTCOME_PARTIAL, + XDM_CONST.OUTCOME_UNKNOWN), + xdm.event.outcome_reason = msg_failed_login_reason; + +/* ========================================== + Agent logs mapping + ========================================== */ +filter cefName ~= "Agent" +| alter + trg_os = parsed_cs1 -> os_name, + trg_hostname = arrayindex(regextract(cs1, "^([^\s]+)"),0) + +| alter //XDM mapping + xdm.observer.version = cefDeviceVersion, + xdm.event.type = cefName, + xdm.event.id = id, + xdm.source.host.hostname = shost, + xdm.event.description = msg, + xdm.target.ipv4 = if(is_ipv4(parsed_cs1 -> ip) = TRUE, parsed_cs1 -> ip), + xdm.target.ipv6 = if(is_ipv6(parsed_cs1 -> ip) = TRUE, parsed_cs1 -> ip), + xdm.target.host.os = trg_os, + xdm.target.zone = parsed_cs1 -> Environment, + xdm.target.host.os_family = if( + trg_os ~= "Windows", XDM_CONST.OS_FAMILY_WINDOWS, + trg_os ~= "Mac", XDM_CONST.OS_FAMILY_MACOS, + trg_os ~= "Linux", XDM_CONST.OS_FAMILY_LINUX, + trg_os ~= "Ubuntu", XDM_CONST.OS_FAMILY_UBUNTU), + xdm.target.host.hostname = trg_hostname, + xdm.target.resource.name = trg_hostname, + xdm.target.resource.type = parsed_cs1 -> Role, + xdm.target.application.name = parsed_cs1 -> App, + xdm.event.outcome = if( + msg IN ("Success*","*success*", "*status flag was raised*"), XDM_CONST.OUTCOME_SUCCESS, + msg ~= "[Ff]ail", XDM_CONST.OUTCOME_FAILED, + XDM_CONST.OUTCOME_UNKNOWN), + xdm.alert.severity = cefSeverity; + +/* ========================================== + System logs mapping + ========================================== */ +filter cefName ~= "System" +| alter //XDM mapping + xdm.observer.version = cefDeviceVersion, + xdm.event.type = cefName, + xdm.event.id = id, + xdm.event.log_level = if( + cefSeverity ~= "EMERGENCY" , XDM_CONST.LOG_LEVEL_EMERGENCY, + cefSeverity ~= "ALERT" , XDM_CONST.LOG_LEVEL_ALERT, + cefSeverity ~= "CRITICAL" ,XDM_CONST.LOG_LEVEL_CRITICAL, + cefSeverity ~= "ERROR" ,XDM_CONST.LOG_LEVEL_ERROR, + cefSeverity ~= "WARNING" ,XDM_CONST.LOG_LEVEL_WARNING, + cefSeverity ~= "NOTICE" ,XDM_CONST.LOG_LEVEL_NOTICE, + cefSeverity ~= "INFO" ,XDM_CONST.LOG_LEVEL_INFORMATIONAL, + cefSeverity ~= "DEBUG" ,XDM_CONST.LOG_LEVEL_DEBUG, + cefSeverity), + xdm.event.is_completed = if(cefSeverity ~= "COMPLETE", to_boolean(TRUE), to_boolean(FALSE)), + xdm.source.user_agent = src, + xdm.source.host.hostname = shost, + xdm.event.description = msg; + +/* ========================================== + Network logs mapping + ========================================== */ +filter cefName ~= "Network" +| alter + proto = to_string(proto), + cs3_process_name = if(cs3 IN ("*\*"), arrayindex(regextract(cs3, "[^\\]+$"),0), cs3 IN ("*/*"), arrayindex(regextract(cs3, "[^\/]+$"),0)), + cs14_process_name = if(cs14 IN ("*\*"), arrayindex(regextract(cs14, "[^\\]+$"),0), cs14 IN ("*/*"), arrayindex(regextract(cs14, "[^\/]+$"),0)), + cs15_process_name = if(cs15 IN ("*\*"), arrayindex(regextract(cs15, "[^\\]+$"),0), cs15 IN ("*/*"), arrayindex(regextract(cs15, "[^\/]+$"),0)), + drpoc_process_name = if(drpoc IN ("*\*"), arrayindex(regextract(cs15, "[^\\]+$"),0), drpoc IN ("*/*"), arrayindex(regextract(drpoc, "[^\/]+$"),0)) + +| alter //XDM mapping + xdm.observer.version = cefDeviceVersion, + xdm.event.type = cefName, + xdm.event.id = id, + xdm.source.ipv4 = if(is_ipv4(src) = TRUE, src), + xdm.source.ipv6 = if(is_ipv6(src) = TRUE, src), + xdm.source.host.hostname = shost, + xdm.source.user.username = suser, + xdm.source.identity.username = suser, + xdm.target.ipv4 = if(is_ipv4(dst) = TRUE, dst), + xdm.target.ipv6 = if(is_ipv6(dst) = TRUE, dst), + xdm.target.port = to_integer(dpt), + xdm.target.host.hostname = dhost, + xdm.target.user.username = duser, + xdm.target.identity.username = duser, + xdm.network.ip_protocol = if( + proto = "HOPOPT",XDM_CONST.IP_PROTOCOL_HOPOPT, + proto = "ICMP",XDM_CONST.IP_PROTOCOL_ICMP, + proto = "IGMP",XDM_CONST.IP_PROTOCOL_IGMP, + proto = "GGP",XDM_CONST.IP_PROTOCOL_GGP, + proto = "IP",XDM_CONST.IP_PROTOCOL_IP, + proto = "ST",XDM_CONST.IP_PROTOCOL_ST, + proto = "TCP",XDM_CONST.IP_PROTOCOL_TCP, + proto = "CBT",XDM_CONST.IP_PROTOCOL_CBT, + proto = "EGP",XDM_CONST.IP_PROTOCOL_EGP, + proto = "IGP",XDM_CONST.IP_PROTOCOL_IGP, + proto = "BBN_RCC_MON",XDM_CONST.IP_PROTOCOL_BBN_RCC_MON, + proto = "NVP_II",XDM_CONST.IP_PROTOCOL_NVP_II, + proto = "PUP",XDM_CONST.IP_PROTOCOL_PUP, + proto = "ARGUS",XDM_CONST.IP_PROTOCOL_ARGUS, + proto = "EMCON",XDM_CONST.IP_PROTOCOL_EMCON, + proto = "XNET",XDM_CONST.IP_PROTOCOL_XNET, + proto = "CHAOS",XDM_CONST.IP_PROTOCOL_CHAOS, + proto = "UDP",XDM_CONST.IP_PROTOCOL_UDP, + proto = "MUX",XDM_CONST.IP_PROTOCOL_MUX, + proto = "DCN_MEAS",XDM_CONST.IP_PROTOCOL_DCN_MEAS, + proto = "HMP",XDM_CONST.IP_PROTOCOL_HMP, + proto = "PRM",XDM_CONST.IP_PROTOCOL_PRM, + proto = "XNS_IDP",XDM_CONST.IP_PROTOCOL_XNS_IDP, + proto = "TRUNK_1",XDM_CONST.IP_PROTOCOL_TRUNK_1, + proto = "TRUNK_2",XDM_CONST.IP_PROTOCOL_TRUNK_2, + proto = "LEAF_1",XDM_CONST.IP_PROTOCOL_LEAF_1, + proto = "LEAF_2",XDM_CONST.IP_PROTOCOL_LEAF_2, + proto = "RDP",XDM_CONST.IP_PROTOCOL_RDP, + proto = "IRTP",XDM_CONST.IP_PROTOCOL_IRTP, + proto = "ISO_TP4",XDM_CONST.IP_PROTOCOL_ISO_TP4, + proto = "NETBLT",XDM_CONST.IP_PROTOCOL_NETBLT, + proto = "MFE_NSP",XDM_CONST.IP_PROTOCOL_MFE_NSP, + proto = "MERIT_INP",XDM_CONST.IP_PROTOCOL_MERIT_INP, + proto = "DCCP",XDM_CONST.IP_PROTOCOL_DCCP, + proto = "3PC",XDM_CONST.IP_PROTOCOL_3PC, + proto = "IDPR",XDM_CONST.IP_PROTOCOL_IDPR, + proto = "XTP",XDM_CONST.IP_PROTOCOL_XTP, + proto = "DDP",XDM_CONST.IP_PROTOCOL_DDP, + proto = "IDPR_CMTP",XDM_CONST.IP_PROTOCOL_IDPR_CMTP, + proto = "TP",XDM_CONST.IP_PROTOCOL_TP, + proto = "IL",XDM_CONST.IP_PROTOCOL_IL, + proto = "IPV6",XDM_CONST.IP_PROTOCOL_IPV6, + proto = "SDRP",XDM_CONST.IP_PROTOCOL_SDRP, + proto = "IPV6_ROUTE",XDM_CONST.IP_PROTOCOL_IPV6_ROUTE, + proto = "IPV6_FRAG",XDM_CONST.IP_PROTOCOL_IPV6_FRAG, + proto = "IDRP",XDM_CONST.IP_PROTOCOL_IDRP, + proto = "RSVP",XDM_CONST.IP_PROTOCOL_RSVP, + proto = "GRE",XDM_CONST.IP_PROTOCOL_GRE, + proto = "DSR",XDM_CONST.IP_PROTOCOL_DSR, + proto = "BNA",XDM_CONST.IP_PROTOCOL_BNA, + proto = "ESP",XDM_CONST.IP_PROTOCOL_ESP, + proto = "AH",XDM_CONST.IP_PROTOCOL_AH, + proto = "I_NLSP",XDM_CONST.IP_PROTOCOL_I_NLSP, + proto = "SWIPE",XDM_CONST.IP_PROTOCOL_SWIPE, + proto = "NARP",XDM_CONST.IP_PROTOCOL_NARP, + proto = "MOBILE",XDM_CONST.IP_PROTOCOL_MOBILE, + proto = "TLSP",XDM_CONST.IP_PROTOCOL_TLSP, + proto = "SKIP",XDM_CONST.IP_PROTOCOL_SKIP, + proto = "IPV6_ICMP",XDM_CONST.IP_PROTOCOL_IPV6_ICMP, + proto = "IPV6_NONXT",XDM_CONST.IP_PROTOCOL_IPV6_NONXT, + proto = "IPV6_OPTS",XDM_CONST.IP_PROTOCOL_IPV6_OPTS, + proto = "CFTP",XDM_CONST.IP_PROTOCOL_CFTP, + proto = "SAT_EXPAK",XDM_CONST.IP_PROTOCOL_SAT_EXPAK, + proto = "KRYPTOLAN",XDM_CONST.IP_PROTOCOL_KRYPTOLAN, + proto = "RVD",XDM_CONST.IP_PROTOCOL_RVD, + proto = "IPPC",XDM_CONST.IP_PROTOCOL_IPPC, + proto = "SAT_MON",XDM_CONST.IP_PROTOCOL_SAT_MON, + proto = "VISA",XDM_CONST.IP_PROTOCOL_VISA, + proto = "IPCV",XDM_CONST.IP_PROTOCOL_IPCV, + proto = "CPNX",XDM_CONST.IP_PROTOCOL_CPNX, + proto = "CPHB",XDM_CONST.IP_PROTOCOL_CPHB, + proto = "WSN",XDM_CONST.IP_PROTOCOL_WSN, + proto = "PVP",XDM_CONST.IP_PROTOCOL_PVP, + proto = "BR_SAT_MON",XDM_CONST.IP_PROTOCOL_BR_SAT_MON, + proto = "SUN_ND",XDM_CONST.IP_PROTOCOL_SUN_ND, + proto = "WB_MON",XDM_CONST.IP_PROTOCOL_WB_MON, + proto = "WB_EXPAK",XDM_CONST.IP_PROTOCOL_WB_EXPAK, + proto = "ISO_IP",XDM_CONST.IP_PROTOCOL_ISO_IP, + proto = "VMTP",XDM_CONST.IP_PROTOCOL_VMTP, + proto = "SECURE_VMTP",XDM_CONST.IP_PROTOCOL_SECURE_VMTP, + proto = "VINES",XDM_CONST.IP_PROTOCOL_VINES, + proto = "TTP",XDM_CONST.IP_PROTOCOL_TTP, + proto = "NSFNET_IGP",XDM_CONST.IP_PROTOCOL_NSFNET_IGP, + proto = "DGP",XDM_CONST.IP_PROTOCOL_DGP, + proto = "TCF",XDM_CONST.IP_PROTOCOL_TCF, + proto = "EIGRP",XDM_CONST.IP_PROTOCOL_EIGRP, + proto = "OSPFIGP",XDM_CONST.IP_PROTOCOL_OSPFIGP, + proto = "SPRITE_RPC",XDM_CONST.IP_PROTOCOL_SPRITE_RPC, + proto = "LARP",XDM_CONST.IP_PROTOCOL_LARP, + proto = "MTP",XDM_CONST.IP_PROTOCOL_MTP, + proto = "AX25",XDM_CONST.IP_PROTOCOL_AX25, + proto = "IPIP",XDM_CONST.IP_PROTOCOL_IPIP, + proto = "MICP",XDM_CONST.IP_PROTOCOL_MICP, + proto = "SCC_SP",XDM_CONST.IP_PROTOCOL_SCC_SP, + proto = "ETHERIP",XDM_CONST.IP_PROTOCOL_ETHERIP, + proto = "ENCAP",XDM_CONST.IP_PROTOCOL_ENCAP, + proto = "GMTP",XDM_CONST.IP_PROTOCOL_GMTP, + proto = "IFMP",XDM_CONST.IP_PROTOCOL_IFMP, + proto = "PNNI",XDM_CONST.IP_PROTOCOL_PNNI, + proto = "PIM",XDM_CONST.IP_PROTOCOL_PIM, + proto = "ARIS",XDM_CONST.IP_PROTOCOL_ARIS, + proto = "SCPS",XDM_CONST.IP_PROTOCOL_SCPS, + proto = "QNX",XDM_CONST.IP_PROTOCOL_QNX, + proto = "AN",XDM_CONST.IP_PROTOCOL_AN, + proto = "IPCOMP",XDM_CONST.IP_PROTOCOL_IPCOMP, + proto = "SNP",XDM_CONST.IP_PROTOCOL_SNP, + proto = "COMPAQ_PEER",XDM_CONST.IP_PROTOCOL_COMPAQ_PEER, + proto = "IPX_IN_IP",XDM_CONST.IP_PROTOCOL_IPX_IN_IP, + proto = "VRRP",XDM_CONST.IP_PROTOCOL_VRRP, + proto = "PGM",XDM_CONST.IP_PROTOCOL_PGM, + proto = "L2TP",XDM_CONST.IP_PROTOCOL_L2TP, + proto = "DDX",XDM_CONST.IP_PROTOCOL_DDX, + proto = "IATP",XDM_CONST.IP_PROTOCOL_IATP, + proto = "STP",XDM_CONST.IP_PROTOCOL_STP, + proto = "SRP",XDM_CONST.IP_PROTOCOL_SRP, + proto = "UTI",XDM_CONST.IP_PROTOCOL_UTI, + proto = "SMP",XDM_CONST.IP_PROTOCOL_SMP, + proto = "SM",XDM_CONST.IP_PROTOCOL_SM, + proto = "PTP",XDM_CONST.IP_PROTOCOL_PTP, + proto = "ISIS",XDM_CONST.IP_PROTOCOL_ISIS, + proto = "FIRE",XDM_CONST.IP_PROTOCOL_FIRE, + proto = "CRTP",XDM_CONST.IP_PROTOCOL_CRTP, + proto = "CRUDP",XDM_CONST.IP_PROTOCOL_CRUDP, + proto = "SSCOPMCE",XDM_CONST.IP_PROTOCOL_SSCOPMCE, + proto = "IPLT",XDM_CONST.IP_PROTOCOL_IPLT, + proto = "SPS",XDM_CONST.IP_PROTOCOL_SPS, + proto = "PIPE",XDM_CONST.IP_PROTOCOL_PIPE, + proto = "SCTP",XDM_CONST.IP_PROTOCOL_SCTP, + proto = "FC",XDM_CONST.IP_PROTOCOL_FC, + proto = "RSVP_E2E_IGNORE",XDM_CONST.IP_PROTOCOL_RSVP_E2E_IGNORE, + proto = "MOBILITY",XDM_CONST.IP_PROTOCOL_MOBILITY, + proto = "UDPLITE",XDM_CONST.IP_PROTOCOL_UDPLITE, + proto = "MPLS_IN_IP",XDM_CONST.IP_PROTOCOL_MPLS_IN_IP, + proto = "MANET",XDM_CONST.IP_PROTOCOL_MANET, + proto = "HIP",XDM_CONST.IP_PROTOCOL_HIP, + proto = "SHIM6",XDM_CONST.IP_PROTOCOL_SHIM6, + proto = "WESP",XDM_CONST.IP_PROTOCOL_WESP, + proto = "ROHC",XDM_CONST.IP_PROTOCOL_ROHC, + proto = "RESERVED",XDM_CONST.IP_PROTOCOL_RESERVED, + proto = "0",XDM_CONST.IP_PROTOCOL_HOPOPT, + proto = "1",XDM_CONST.IP_PROTOCOL_ICMP, + proto = "2",XDM_CONST.IP_PROTOCOL_IGMP, + proto = "3",XDM_CONST.IP_PROTOCOL_GGP, + proto = "4",XDM_CONST.IP_PROTOCOL_IP, + proto = "5",XDM_CONST.IP_PROTOCOL_ST, + proto = "6",XDM_CONST.IP_PROTOCOL_TCP, + proto = "7",XDM_CONST.IP_PROTOCOL_CBT, + proto = "8",XDM_CONST.IP_PROTOCOL_EGP, + proto = "9",XDM_CONST.IP_PROTOCOL_IGP, + proto = "10",XDM_CONST.IP_PROTOCOL_BBN_RCC_MON, + proto = "11",XDM_CONST.IP_PROTOCOL_NVP_II, + proto = "12",XDM_CONST.IP_PROTOCOL_PUP, + proto = "13",XDM_CONST.IP_PROTOCOL_ARGUS, + proto = "14",XDM_CONST.IP_PROTOCOL_EMCON, + proto = "15",XDM_CONST.IP_PROTOCOL_XNET, + proto = "16",XDM_CONST.IP_PROTOCOL_CHAOS, + proto = "17",XDM_CONST.IP_PROTOCOL_UDP, + proto = "18",XDM_CONST.IP_PROTOCOL_MUX, + proto = "19",XDM_CONST.IP_PROTOCOL_DCN_MEAS, + proto = "20",XDM_CONST.IP_PROTOCOL_HMP, + proto = "21",XDM_CONST.IP_PROTOCOL_PRM, + proto = "22",XDM_CONST.IP_PROTOCOL_XNS_IDP, + proto = "23",XDM_CONST.IP_PROTOCOL_TRUNK_1, + proto = "24",XDM_CONST.IP_PROTOCOL_TRUNK_2, + proto = "25",XDM_CONST.IP_PROTOCOL_LEAF_1, + proto = "26",XDM_CONST.IP_PROTOCOL_LEAF_2, + proto = "27",XDM_CONST.IP_PROTOCOL_RDP, + proto = "28",XDM_CONST.IP_PROTOCOL_IRTP, + proto = "29",XDM_CONST.IP_PROTOCOL_ISO_TP4, + proto = "30",XDM_CONST.IP_PROTOCOL_NETBLT, + proto = "31",XDM_CONST.IP_PROTOCOL_MFE_NSP, + proto = "32",XDM_CONST.IP_PROTOCOL_MERIT_INP, + proto = "33",XDM_CONST.IP_PROTOCOL_DCCP, + proto = "34",XDM_CONST.IP_PROTOCOL_3PC, + proto = "35",XDM_CONST.IP_PROTOCOL_IDPR, + proto = "36",XDM_CONST.IP_PROTOCOL_XTP, + proto = "37",XDM_CONST.IP_PROTOCOL_DDP, + proto = "38",XDM_CONST.IP_PROTOCOL_IDPR_CMTP, + proto = "39",XDM_CONST.IP_PROTOCOL_TP, + proto = "40",XDM_CONST.IP_PROTOCOL_IL, + proto = "41",XDM_CONST.IP_PROTOCOL_IPV6, + proto = "42",XDM_CONST.IP_PROTOCOL_SDRP, + proto = "43",XDM_CONST.IP_PROTOCOL_IPV6_ROUTE, + proto = "44",XDM_CONST.IP_PROTOCOL_IPV6_FRAG, + proto = "45",XDM_CONST.IP_PROTOCOL_IDRP, + proto = "46",XDM_CONST.IP_PROTOCOL_RSVP, + proto = "47",XDM_CONST.IP_PROTOCOL_GRE, + proto = "48",XDM_CONST.IP_PROTOCOL_DSR, + proto = "49",XDM_CONST.IP_PROTOCOL_BNA, + proto = "50",XDM_CONST.IP_PROTOCOL_ESP, + proto = "51",XDM_CONST.IP_PROTOCOL_AH, + proto = "52",XDM_CONST.IP_PROTOCOL_I_NLSP, + proto = "53",XDM_CONST.IP_PROTOCOL_SWIPE, + proto = "54",XDM_CONST.IP_PROTOCOL_NARP, + proto = "55",XDM_CONST.IP_PROTOCOL_MOBILE, + proto = "56",XDM_CONST.IP_PROTOCOL_TLSP, + proto = "57",XDM_CONST.IP_PROTOCOL_SKIP, + proto = "58",XDM_CONST.IP_PROTOCOL_IPV6_ICMP, + proto = "59",XDM_CONST.IP_PROTOCOL_IPV6_NONXT, + proto = "60",XDM_CONST.IP_PROTOCOL_IPV6_OPTS, + proto = "62",XDM_CONST.IP_PROTOCOL_CFTP, + proto = "64",XDM_CONST.IP_PROTOCOL_SAT_EXPAK, + proto = "65",XDM_CONST.IP_PROTOCOL_KRYPTOLAN, + proto = "66",XDM_CONST.IP_PROTOCOL_RVD, + proto = "67",XDM_CONST.IP_PROTOCOL_IPPC, + proto = "69",XDM_CONST.IP_PROTOCOL_SAT_MON, + proto = "70",XDM_CONST.IP_PROTOCOL_VISA, + proto = "71",XDM_CONST.IP_PROTOCOL_IPCV, + proto = "72",XDM_CONST.IP_PROTOCOL_CPNX, + proto = "73",XDM_CONST.IP_PROTOCOL_CPHB, + proto = "74",XDM_CONST.IP_PROTOCOL_WSN, + proto = "75",XDM_CONST.IP_PROTOCOL_PVP, + proto = "76",XDM_CONST.IP_PROTOCOL_BR_SAT_MON, + proto = "77",XDM_CONST.IP_PROTOCOL_SUN_ND, + proto = "78",XDM_CONST.IP_PROTOCOL_WB_MON, + proto = "79",XDM_CONST.IP_PROTOCOL_WB_EXPAK, + proto = "80",XDM_CONST.IP_PROTOCOL_ISO_IP, + proto = "81",XDM_CONST.IP_PROTOCOL_VMTP, + proto = "82",XDM_CONST.IP_PROTOCOL_SECURE_VMTP, + proto = "83",XDM_CONST.IP_PROTOCOL_VINES, + proto = "84",XDM_CONST.IP_PROTOCOL_TTP, + proto = "85",XDM_CONST.IP_PROTOCOL_NSFNET_IGP, + proto = "86",XDM_CONST.IP_PROTOCOL_DGP, + proto = "87",XDM_CONST.IP_PROTOCOL_TCF, + proto = "88",XDM_CONST.IP_PROTOCOL_EIGRP, + proto = "89",XDM_CONST.IP_PROTOCOL_OSPFIGP, + proto = "90",XDM_CONST.IP_PROTOCOL_SPRITE_RPC, + proto = "91",XDM_CONST.IP_PROTOCOL_LARP, + proto = "92",XDM_CONST.IP_PROTOCOL_MTP, + proto = "93",XDM_CONST.IP_PROTOCOL_AX25, + proto = "94",XDM_CONST.IP_PROTOCOL_IPIP, + proto = "95",XDM_CONST.IP_PROTOCOL_MICP, + proto = "96",XDM_CONST.IP_PROTOCOL_SCC_SP, + proto = "97",XDM_CONST.IP_PROTOCOL_ETHERIP, + proto = "98",XDM_CONST.IP_PROTOCOL_ENCAP, + proto = "100",XDM_CONST.IP_PROTOCOL_GMTP, + proto = "101",XDM_CONST.IP_PROTOCOL_IFMP, + proto = "102",XDM_CONST.IP_PROTOCOL_PNNI, + proto = "103",XDM_CONST.IP_PROTOCOL_PIM, + proto = "104",XDM_CONST.IP_PROTOCOL_ARIS, + proto = "105",XDM_CONST.IP_PROTOCOL_SCPS, + proto = "106",XDM_CONST.IP_PROTOCOL_QNX, + proto = "107",XDM_CONST.IP_PROTOCOL_AN, + proto = "108",XDM_CONST.IP_PROTOCOL_IPCOMP, + proto = "109",XDM_CONST.IP_PROTOCOL_SNP, + proto = "110",XDM_CONST.IP_PROTOCOL_COMPAQ_PEER, + proto = "111",XDM_CONST.IP_PROTOCOL_IPX_IN_IP, + proto = "112",XDM_CONST.IP_PROTOCOL_VRRP, + proto = "113",XDM_CONST.IP_PROTOCOL_PGM, + proto = "115",XDM_CONST.IP_PROTOCOL_L2TP, + proto = "116",XDM_CONST.IP_PROTOCOL_DDX, + proto = "117",XDM_CONST.IP_PROTOCOL_IATP, + proto = "118",XDM_CONST.IP_PROTOCOL_STP, + proto = "119",XDM_CONST.IP_PROTOCOL_SRP, + proto = "120",XDM_CONST.IP_PROTOCOL_UTI, + proto = "121",XDM_CONST.IP_PROTOCOL_SMP, + proto = "122",XDM_CONST.IP_PROTOCOL_SM, + proto = "123",XDM_CONST.IP_PROTOCOL_PTP, + proto = "124",XDM_CONST.IP_PROTOCOL_ISIS, + proto = "125",XDM_CONST.IP_PROTOCOL_FIRE, + proto = "126",XDM_CONST.IP_PROTOCOL_CRTP, + proto = "127",XDM_CONST.IP_PROTOCOL_CRUDP, + proto = "128",XDM_CONST.IP_PROTOCOL_SSCOPMCE, + proto = "129",XDM_CONST.IP_PROTOCOL_IPLT, + proto = "130",XDM_CONST.IP_PROTOCOL_SPS, + proto = "131",XDM_CONST.IP_PROTOCOL_PIPE, + proto = "132",XDM_CONST.IP_PROTOCOL_SCTP, + proto = "133",XDM_CONST.IP_PROTOCOL_FC, + proto = "134",XDM_CONST.IP_PROTOCOL_RSVP_E2E_IGNORE, + proto = "135",XDM_CONST.IP_PROTOCOL_MOBILITY, + proto = "136",XDM_CONST.IP_PROTOCOL_UDPLITE, + proto = "137",XDM_CONST.IP_PROTOCOL_MPLS_IN_IP, + proto = "138",XDM_CONST.IP_PROTOCOL_MANET, + proto = "139",XDM_CONST.IP_PROTOCOL_HIP, + proto = "140",XDM_CONST.IP_PROTOCOL_SHIM6, + proto = "141",XDM_CONST.IP_PROTOCOL_WESP, + proto = "142",XDM_CONST.IP_PROTOCOL_ROHC, + proto = "255",XDM_CONST.IP_PROTOCOL_RESERVED, + proto), + xdm.source.process.name = coalesce(cs3,cs14), + xdm.source.user.identifier = cs11, + xdm.source.identity.identifier = cs11, + xdm.event.outcome_reason = cs6, + xdm.network.rule = cs7, + xdm.target.user.identifier = cs12, + xdm.target.identity.identifier = cs12, + xdm.source.process.executable.filename = coalesce(cs3_process_name, cs14_process_name), + xdm.source.process.executable.path = coalesce(cs13, cs14), + xdm.target.process.executable.filename = cs15_process_name, + xdm.target.process.executable.path = coalesce(cs15, drpoc_process_name), + xdm.target.application.name = cs16, + xdm.observer.action = act, + xdm.event.outcome = if( + cs1 ~= "SUCCESS", XDM_CONST.OUTCOME_SUCCESS, + cs1 ~= "FAIL", XDM_CONST.OUTCOME_FAILED, + XDM_CONST.OUTCOME_UNKNOWN + ); + +/* ========================================== + Label logs mapping + ========================================== */ +filter cefName ~= "Label" +| alter //XDM mapping + xdm.observer.version = cefDeviceVersion, + xdm.event.type = cefName, + xdm.alert.severity = cefSeverity, + xdm.event.id = id, + xdm.event.description = msg; + +/* ========================================== + Incidents logs mapping + ========================================== */ +filter cefName NOT IN ("System*", "Audit*", "Agent*", "Network*", "Label*") +| alter //extract fields + cs5_app = arrayindex(regextract(cs5, "App\:\s([^,]+)"),0), + cs5_os = arrayindex(regextract(cs5, "OS\:\s([^,]+)"),0), + cs5_env = arrayindex(regextract(cs5, "Environment\:\s([^,]+)"),0) + +| alter //XDM mapping + xdm.event.type = cefDeviceEventClassId, + xdm.observer.version = cefDeviceVersion, + xdm.event.description = cefName, + xdm.alert.severity = if( + to_string(cefSeverity) = "8", "High", + to_string(cefSeverity) = "5", "Medium", + to_string(cefSeverity) = "3", "Low", + cefSeverity), + xdm.observer.action = act, + xdm.target.ipv4 = if(is_ipv4(dvc) = TRUE, dvc), + xdm.target.ipv6 = if(is_ipv6(dvc) = TRUE, dvc), + xdm.target.host.hostname = dvchost, + xdm.event.id = cs1, + xdm.alert.source_url = cs2, + xdm.event.tags = split(cs3, ", "), + xdm.target.host.device_id = cs4, + xdm.target.application.name = cs5_app, + xdm.target.host.os = cs5_os, + xdm.target.host.os_family = if( + cs5_os ~= "Windows", XDM_CONST.OS_FAMILY_WINDOWS, + cs5_os ~= "Mac", XDM_CONST.OS_FAMILY_MACOS, + cs5_os ~= "Linux", XDM_CONST.OS_FAMILY_LINUX, + cs5_os ~= "Ubuntu", XDM_CONST.OS_FAMILY_UBUNTU), + xdm.target.zone = cs5_env; \ No newline at end of file diff --git a/Packs/GuardiCore/ModelingRules/GuardiCore_2_11/GuardiCore_2_11.yml b/Packs/GuardiCore/ModelingRules/GuardiCore_2_11/GuardiCore_2_11.yml new file mode 100644 index 000000000000..d61dc489551a --- /dev/null +++ b/Packs/GuardiCore/ModelingRules/GuardiCore_2_11/GuardiCore_2_11.yml @@ -0,0 +1,8 @@ +fromversion: 8.15.0 +id: Akamai_GuardiCore_ModelingRule +name: Akamai GuardiCore Modeling Rule +rules: '' +schema: '' +tags: '' +supportedModules: +- xsiam diff --git a/Packs/GuardiCore/ModelingRules/GuardiCore_2_11/GuardiCore_2_11_schema.json b/Packs/GuardiCore/ModelingRules/GuardiCore_2_11/GuardiCore_2_11_schema.json new file mode 100644 index 000000000000..9d9ecc148b11 --- /dev/null +++ b/Packs/GuardiCore/ModelingRules/GuardiCore_2_11/GuardiCore_2_11_schema.json @@ -0,0 +1,132 @@ +{ + "akamai_guardicore_raw": { + "cefName": { + "type": "string", + "is_array": false + }, + "cefDeviceVersion": { + "type": "string", + "is_array": false + }, + "cefDeviceEventClassId": { + "type": "string", + "is_array": false + }, + "cefSeverity": { + "type": "string", + "is_array": false + }, + "suser": { + "type": "string", + "is_array": false + }, + "msg": { + "type": "string", + "is_array": false + }, + "act": { + "type": "string", + "is_array": false + }, + "src": { + "type": "string", + "is_array": false + }, + "id": { + "type": "string", + "is_array": false + }, + "shost": { + "type": "string", + "is_array": false + }, + "dst": { + "type": "string", + "is_array": false + }, + "dpt": { + "type": "int", + "is_array": false + }, + "dhost": { + "type": "string", + "is_array": false + }, + "duser": { + "type": "string", + "is_array": false + }, + "proto": { + "type": "string", + "is_array": false + }, + "dvc": { + "type": "string", + "is_array": false + }, + "dvchost": { + "type": "string", + "is_array": false + }, + "cs1": { + "type": "string", + "is_array": false + }, + "cs2": { + "type": "string", + "is_array": false + }, + "cs3": { + "type": "string", + "is_array": false + }, + "cs4": { + "type": "string", + "is_array": false + }, + "cs5": { + "type": "string", + "is_array": false + }, + "cs6": { + "type": "string", + "is_array": false + }, + "cs7": { + "type": "string", + "is_array": false + }, + "cs11": { + "type": "string", + "is_array": false + }, + "cs12": { + "type": "string", + "is_array": false + }, + "cs13": { + "type": "string", + "is_array": false + }, + "cs14": { + "type": "string", + "is_array": false + }, + "cs15": { + "type": "string", + "is_array": false + }, + "cs16": { + "type": "string", + "is_array": false + }, + "drpoc": { + "type": "string", + "is_array": false + }, + "parsed_cs1": { + "type": "string", + "is_array": false + } + } +} \ No newline at end of file diff --git a/Packs/GuardiCore/ReleaseNotes/2_0_26.md b/Packs/GuardiCore/ReleaseNotes/2_0_26.md new file mode 100644 index 000000000000..50321e94155b --- /dev/null +++ b/Packs/GuardiCore/ReleaseNotes/2_0_26.md @@ -0,0 +1,7 @@ + +#### Modeling Rules + +##### New: Akamai GuardiCore Modeling Rule + +- New: Added a new modeling rule version that maps the `xdm.*.identity.*` fields alongside the existing `xdm.*.user.*` fields. +<~XSIAM> (Available from Cortex XSIAM 2.11). diff --git a/Packs/GuardiCore/pack_metadata.json b/Packs/GuardiCore/pack_metadata.json index 351e5f854bd0..871a7dabc79a 100644 --- a/Packs/GuardiCore/pack_metadata.json +++ b/Packs/GuardiCore/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Akamai GuardiCore", "description": "Data center breach detection", "support": "xsoar", - "currentVersion": "2.0.25", + "currentVersion": "2.0.26", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/Silverfort/ModelingRules/Silverfort/Silverfort.yml b/Packs/Silverfort/ModelingRules/Silverfort/Silverfort.yml index 054a72680a71..33ec650f7249 100644 --- a/Packs/Silverfort/ModelingRules/Silverfort/Silverfort.yml +++ b/Packs/Silverfort/ModelingRules/Silverfort/Silverfort.yml @@ -1,4 +1,5 @@ fromversion: 8.12.0 +toversion: 8.14.0 id: Silverfort_Admin_Console_ModelingRule name: Silverfort Admin Console Modeling Rule rules: '' diff --git a/Packs/Silverfort/ModelingRules/Silverfort_2_11/Silverfort_2_11.xif b/Packs/Silverfort/ModelingRules/Silverfort_2_11/Silverfort_2_11.xif new file mode 100644 index 000000000000..d02bda171e64 --- /dev/null +++ b/Packs/Silverfort/ModelingRules/Silverfort_2_11/Silverfort_2_11.xif @@ -0,0 +1,72 @@ +//Rule for mapping event type "Authentication" of Silverfort Admin Console +[RULE: silverfort_admin_console_authentication_fields] +alter + src_user = arrayindex(regextract(suser,"(\S+)\@"),0), //suser comes sometimes as UPN + coordinates = if(cs11 != "n/a", split(cs11, ",")), //The coordinates comes as , + outcome_reason = arrayindex(regextract(cs2, "\((.+)\)"), 0), //The format of 'cs2' is 'Denied (Bad Password)', we're extracting the outcome reason. + risks = if(cs7 != "n/a", replace(cs7, "_", " ")) //Comes with underscore instead of space delimiter +| alter + latitude = if(cs11 != "n/a", to_float(arrayindex(coordinates, 0))), + longitude = if(cs11 != "n/a", to_float(arrayindex(coordinates, 1))) + +//Mapping to XDM fields +| alter + xdm.source.user.username = coalesce(src_user,suser), + xdm.source.identity.username = coalesce(src_user,suser), + xdm.source.user.upn = if(src_user != null, suser, concat(suser, "@", sntdom)), //In some cases suser comes as UPN, and in others as username, the UPN can then be derived as suser@sntdom. + xdm.source.identity.upn = if(src_user != null, suser, concat(suser, "@", sntdom)), //In some cases suser comes as UPN, and in others as username, the UPN can then be derived as suser@sntdom. + xdm.source.user.domain = sntdom, + xdm.source.identity.domain = sntdom, + xdm.source.host.hostname = if(shost = "n/a", null, shost), + xdm.source.ipv4 = if(is_ipv4(src) = TRUE, src), + xdm.source.ipv6 = if(is_ipv6(src) = TRUE, src), + xdm.target.host.hostname = if(is_ipv4(dhost) = FALSE AND is_ipv6(dhost) = FALSE, dhost), //dhost sometimes represents IP address and sometimes hostname. + xdm.target.resource.name = if(destinationServiceName != "", destinationServiceName, dhost), + xdm.target.ipv4 = if(is_ipv4(dhost) = TRUE, dhost), + xdm.target.ipv6 = if(is_ipv6(dhost) = TRUE, dhost), + xdm.target.domain = if(dntdom != "", dntdom), + xdm.event.description = if(msg != "", msg), + xdm.alert.severity = cs1, + xdm.event.outcome = if(cs2 contains "Allowed", XDM_CONST.OUTCOME_SUCCESS, cs2 contains "Denied", XDM_CONST.OUTCOME_FAILED, XDM_CONST.OUTCOME_UNKNOWN), + xdm.observer.action = if(cs3 != "n/a",cs3), + xdm.alert.risks = split(risks ,","), + xdm.network.rule = if(cs8 != "n/a", replace(cs8, "_", " ")), + xdm.auth.auth_method = app, + xdm.source.location.country = if(cs9 != "n/a", cs9), + xdm.source.location.city = if(cs10 != "n/a", cs10), + xdm.source.location.latitude = latitude, + xdm.source.location.longitude = longitude, + xdm.event.type = "authentication", + xdm.event.original_event_type = cefdeviceeventclassid, + xdm.event.operation = XDM_CONST.OPERATION_TYPE_AUTH_LOGIN, //MFA is a different cefdeviceeventclassid "MFA", we currently don't support this event class. + xdm.event.tags = arraycreate(XDM_CONST.EVENT_TAG_AUTHENTICATION); + + +//For authentication story - should be only for SSO events. +[RULE: silverfort_admin_console_authentication_story_fields] +alter + xdm.source.port = to_integer(0), + xdm.source.user.user_type = if(suser ~= "\$$" OR suser ~= "^(http|host|cifs|krbtgt|mssql|nfs)\/" OR suser ~= "\/",XDM_CONST.USER_TYPE_MACHINE_ACCOUNT, XDM_CONST.USER_TYPE_REGULAR), + xdm.source.identity.user_type = if(suser ~= "\$$" OR suser ~= "^(http|host|cifs|krbtgt|mssql|nfs)\/" OR suser ~= "\/",XDM_CONST.USER_TYPE_MACHINE_ACCOUNT, XDM_CONST.USER_TYPE_REGULAR), + xdm.target.port = to_integer(0), + xdm.logon.type = XDM_CONST.LOGON_TYPE_INTERACTIVE, + xdm.network.ip_protocol = XDM_CONST.IP_PROTOCOL_TCP, + xdm.auth.service = "IDP", + xdm.event.outcome_reason = if( + outcome_reason IN("*Bad password*", "*Bad username*", "*Bad credentials*", "*Expired password*"), "bad_credentials", + outcome_reason IN("*Account disabled, expired or locked out*", "*Account disabled*"), "account_expired_or_disabled", + outcome_reason IN("*Locked account*"), "account_locked", + outcome_reason IN("*Expired ticket*", "*The client trust failed or is not implemented*", "*The ticket and authenticator do not match*", "*Bad server*", "*cannot accommodate requested option*", "*Clock skew is too great*", "*TGT has been revoked*", "*KDC has no support for PADATA type*", "*Requested start time is later than end time*"), "failed_login", + outcome_reason IN("*Outside authorized hours*", "*Unauthorized workstation*", "Denied (Conditional access applied*", "*Changing password is required*"), "auth_policy_access_violation", + "NOT_SPECIFIED"); + +[MODEL: dataset = silverfort_admin_console_raw] + +filter cefdeviceeventclassid = "Authentication" AND app ~= "SSO|SAML|OIDC" +| call silverfort_admin_console_authentication_fields +| call silverfort_admin_console_authentication_story_fields; + +filter cefdeviceeventclassid = "Authentication" AND app NOT IN("*SSO*","*SAML*", "*OIDC*") +| call silverfort_admin_console_authentication_fields +| alter + xdm.event.outcome_reason = if(cs5 != "n/a", cs5, outcome_reason); \ No newline at end of file diff --git a/Packs/Silverfort/ModelingRules/Silverfort_2_11/Silverfort_2_11.yml b/Packs/Silverfort/ModelingRules/Silverfort_2_11/Silverfort_2_11.yml new file mode 100644 index 000000000000..f2ebb1e158ad --- /dev/null +++ b/Packs/Silverfort/ModelingRules/Silverfort_2_11/Silverfort_2_11.yml @@ -0,0 +1,8 @@ +fromversion: 8.15.0 +id: Silverfort_Admin_Console_ModelingRule +name: Silverfort Admin Console Modeling Rule +rules: '' +schema: '' +tags: '' +supportedModules: +- xsiam diff --git a/Packs/Silverfort/ModelingRules/Silverfort_2_11/Silverfort_2_11_schema.json b/Packs/Silverfort/ModelingRules/Silverfort_2_11/Silverfort_2_11_schema.json new file mode 100644 index 000000000000..48f7ed314fe1 --- /dev/null +++ b/Packs/Silverfort/ModelingRules/Silverfort_2_11/Silverfort_2_11_schema.json @@ -0,0 +1,88 @@ +{ + "silverfort_admin_console_raw": { + "rt": { + "type": "datetime", + "is_array": false + }, + "cefdeviceeventclassid": { + "type": "string", + "is_array": false + }, + "cefseverity": { + "type": "string", + "is_array": false + }, + "msg": { + "type": "string", + "is_array": false + }, + "app": { + "type": "string", + "is_array": false + }, + "suser": { + "type": "string", + "is_array": false + }, + "sntdom": { + "type": "string", + "is_array": false + }, + "shost": { + "type": "string", + "is_array": false + }, + "src": { + "type": "string", + "is_array": false + }, + "cs1": { + "type": "string", + "is_array": false + }, + "cs2": { + "type": "string", + "is_array": false + }, + "cs3": { + "type": "string", + "is_array": false + }, + "cs5": { + "type": "string", + "is_array": false + }, + "cs7": { + "type": "string", + "is_array": false + }, + "cs8": { + "type": "string", + "is_array": false + }, + "cs9": { + "type": "string", + "is_array": false + }, + "cs10": { + "type": "string", + "is_array": false + }, + "cs11": { + "type": "string", + "is_array": false + }, + "destinationservicename": { + "type": "string", + "is_array": false + }, + "dhost": { + "type": "string", + "is_array": false + }, + "dntdom": { + "type": "string", + "is_array": false + } + } +} \ No newline at end of file diff --git a/Packs/Silverfort/ReleaseNotes/2_0_41.md b/Packs/Silverfort/ReleaseNotes/2_0_41.md new file mode 100644 index 000000000000..2ea47d45b7ff --- /dev/null +++ b/Packs/Silverfort/ReleaseNotes/2_0_41.md @@ -0,0 +1,7 @@ + +#### Modeling Rules + +##### New: Silverfort Admin Console Modeling Rule + +- New: Added a new modeling rule version that maps the `xdm.*.identity.*` fields alongside the existing `xdm.*.user.*` fields. +<~XSIAM> (Available from Cortex XSIAM 2.11). diff --git a/Packs/Silverfort/pack_metadata.json b/Packs/Silverfort/pack_metadata.json index e3ad3de7869d..09e1c4c24036 100644 --- a/Packs/Silverfort/pack_metadata.json +++ b/Packs/Silverfort/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Silverfort", "description": "Silverfort protects organizations from data breaches by delivering strong authentication across entire corporate networks and cloud environments, without requiring any modifications to endpoints or servers. Using patent-pending technology, Silverfort's agentless approach enables multi-factor authentication and AI-driven adaptive authentication even for systems that don’t support it today, including proprietary systems, critical infrastructure, shared folders, IoT devices, and more. Use Silverfort integration to get & update Silverfort risk severity. This integration was integrated and tested with Silverfort version 2.12.", "support": "partner", - "currentVersion": "2.0.40", + "currentVersion": "2.0.41", "author": "Silverfort", "url": "https://support.silverfort.com/", "email": "ecosystem@silverfort.com", From 345ca625a88492bbec24fd97d467b202a6dae1d1 Mon Sep 17 00:00:00 2001 From: Content Bot <55035720+content-bot@users.noreply.github.com> Date: Wed, 19 Aug 2026 12:23:54 +0300 Subject: [PATCH 015/419] Auto Updated Docker PR from 2026-08-18 GitLab Pipeline ID 12005646 [Success] (#45559) * Updated Docker Images. * Updated Release Notes. --------- Co-authored-by: content-bot Co-authored-by: Adi Bamberger Edri <72088126+BEAdi@users.noreply.github.com> --- Packs/Base/ReleaseNotes/1_42_21.md | 7 + .../Scripts/SanePdfReport/SanePdfReport.yml | 2 +- Packs/Base/pack_metadata.json | 2 +- .../ReleaseNotes/1_4_16.md | 39 ++++ .../AddUserToIncidentTeam.yml | 2 +- .../CaseMgmtAnalystTools.yml | 2 +- .../CaseMgmtDisplayLabels.yml | 2 +- .../CaseMgmtIncidentTypesByRole.yml | 2 +- .../CaseMgmtIncidentTypesDisplay.yml | 2 +- .../CaseMgmtResponseProcess.yml | 2 +- .../CloseLinkedIncidentsPostProcessing.yml | 2 +- .../CompleteTaskOnTimerBreach.yml | 2 +- .../TimersOnOwnerChange.yml | 2 +- .../CaseManagement-Generic/pack_metadata.json | 2 +- .../ReleaseNotes/2_1_10.md | 15 ++ .../Scripts/XMetrics/XMetrics.yml | 2 +- .../Scripts/XMetricsTotal/XMetricsTotal.yml | 2 +- .../Scripts/XMetricsYear/XMetricsYear.yml | 2 +- .../pack_metadata.json | 2 +- .../ReleaseNotes/1_5_8.md | 155 +++++++++++++ .../Scripts/BatchData/BatchData.yml | 2 +- .../Scripts/CompareList/CompareList.yml | 2 +- .../ConvertUTCEpochTimeToTimeStamp.yml | 2 +- .../CreateArrayWithDuplicates.yml | 2 +- .../CreateEDLInstance/CreateEDLInstance.yml | 2 +- .../CreateFileFromPathObject.yml | 2 +- .../DateTimeToADTime/DateTimeToADTime.yml | 2 +- .../DateTimeToLDAPTime/DateTimeToLDAPTime.yml | 2 +- .../Scripts/Defang/Defang.yml | 2 +- .../DeleteExpiredIndicatorWithExlusion.yml | 2 +- .../DeleteIncidentsByQuery.yml | 2 +- .../DeleteIndicators/DeleteIndicators.yml | 2 +- .../DisplayIndicatorReputationContent.yml | 2 +- .../DisplayTaggedWarroomEntries.yml | 2 +- .../FindPlaybookCustomDependencies.yml | 2 +- .../Scripts/GetFields/GetFields.yml | 2 +- .../GetFilePathPreProcessing.yml | 2 +- .../GetIndexOfArrayValue.yml | 2 +- .../GetIndicatorCustomFieldsByQuery.yml | 2 +- .../GetListDatawithKeyword.yml | 2 +- .../IPCalcCheckSubnetCollision.yml | 2 +- .../IPCalcReturnAddressBinary.yml | 2 +- .../IPCalcReturnAddressIANAAllocation.yml | 2 +- .../IPCalcReturnSubnetAddresses.yml | 2 +- .../IPCalcReturnSubnetBroadcastAddress.yml | 2 +- .../IPCalcReturnSubnetNetwork.yml | 2 +- .../InvertEveryTwoItems.yml | 2 +- .../Scripts/MapRegex/MapRegex.yml | 2 +- .../Scripts/MaxList/MaxList.yml | 2 +- .../Scripts/MinList/MinList.yml | 2 +- .../RandomElementFromList.yml | 2 +- .../RandomPhotoNasa/RandomPhotoNasa.yml | 2 +- .../RedactIndicator/RedactIndicator.yml | 2 +- .../RemoveEmptyEvidence.yml | 2 +- .../RetrievePlaybookDependencies.yml | 2 +- .../Scripts/SSLVerifier/SSLVerifier.yml | 2 +- .../StripAccentMarksFromString.yml | 2 +- .../isArrayItemInList/isArrayItemInList.yml | 2 +- .../CommunityCommonScripts/pack_metadata.json | 2 +- Packs/GitHub/Integrations/GitHub/GitHub.yml | 2 +- Packs/GitHub/ReleaseNotes/2_3_3.md | 7 + Packs/GitHub/pack_metadata.json | 2 +- Packs/HealthCheck/ReleaseNotes/3_1_5.md | 203 ++++++++++++++++++ .../GetAutomationsCount.yml | 2 +- .../GetContentPackStatus.yml | 2 +- .../GetCustomAutomations.yml | 2 +- .../GetCustomPlaybooks/GetCustomPlaybooks.yml | 2 +- .../GetDeprecatedAutomations.yml | 2 +- .../GetDeprecatedIntegrations.yml | 2 +- .../GetDeprecatedPlaybooks.yml | 2 +- .../GetDetachedAutomations.yml | 2 +- .../GetDetachedPlaybooks.yml | 2 +- .../GetDiskSpaceStatus/GetDiskSpaceStatus.yml | 2 +- .../GetDockerContainersCount.yml | 2 +- .../GetInvHealthStatus/GetInvHealthStatus.yml | 2 +- .../GetPlaybooksCount/GetPlaybooksCount.yml | 2 +- .../GetPlaybooksHealthStatus.yml | 2 +- .../GetSystemHealthStatus.yml | 2 +- .../GetWorkersCount/GetWorkersCount.yml | 2 +- .../HealthCheckAPIvalidation.yml | 2 +- .../HealthCheckAnalyzeLargeInvestigations.yml | 2 +- .../Scripts/HealthCheckCPU/HealthCheckCPU.yml | 2 +- .../HealthCheckContainersStatus.yml | 2 +- .../HealthCheckDiskUsage.yml | 2 +- .../HealthCheckDiskUsageLine.yml | 2 +- .../HealthCheckDockerLog.yml | 2 +- .../HealthCheckFields/HealthCheckFields.yml | 2 +- .../HealthCheckFileSystem.yml | 2 +- ...kGetLargestInputsAndOutputsInIncidents.yml | 2 +- .../HealthCheckIncidentsCreatedDaily.yml | 2 +- .../HealthCheckIncidentsCreatedMonthly.yml | 2 +- .../HealthCheckIncidentsCreatedWeekly.yml | 2 +- .../HealthCheckInstalledPacks.yml | 2 +- .../HealthCheckIntegrations.yml | 2 +- .../HealthCheckLicenseData.yml | 2 +- .../HealthCheckMemory/HealthCheckMemory.yml | 2 +- .../HealthCheckNumberOfDroppedIncidents.yml | 2 +- .../HealthCheckNumberOfEngines.yml | 2 +- .../HealthCheckNumberOfLargeIOIncidents.yml | 2 +- .../HealthCheckNumberOfLargeIncidents.yml | 2 +- .../HealthCheckNumberOfPartitions.yml | 2 +- .../HealthCheckOutdatedPacks.yml | 2 +- .../HealthCheckPacksInstalled.yml | 2 +- .../HealthCheckPanicLog.yml | 2 +- .../HealthCheckPlaybookAnalysis.yml | 2 +- .../HealthCheckReadConf.yml | 2 +- .../HealthCheckReadTemeletryLog.yml | 2 +- .../HealthCheckReadVC/HealthCheckReadVC.yml | 2 +- .../HealthCheckServerConfiguration.yml | 2 +- .../HealthCheckServerLog.yml | 2 +- .../HealthCheckSystemDiagnostics.yml | 2 +- .../HealthCheckUnpack/HealthCheckUnpack.yml | 2 +- .../HealthCheckWorkers/HealthCheckWorkers.yml | 2 +- Packs/HealthCheck/pack_metadata.json | 2 +- ...rosoftDefenderAdvancedThreatProtection.yml | 2 +- .../ReleaseNotes/1_20_44.md | 7 + .../pack_metadata.json | 2 +- Packs/Whois/Integrations/Whois/Whois.yml | 2 +- Packs/Whois/ReleaseNotes/1_5_44.md | 7 + Packs/Whois/pack_metadata.json | 2 +- 120 files changed, 552 insertions(+), 112 deletions(-) create mode 100644 Packs/Base/ReleaseNotes/1_42_21.md create mode 100644 Packs/CaseManagement-Generic/ReleaseNotes/1_4_16.md create mode 100644 Packs/CommunityCommonDashboards/ReleaseNotes/2_1_10.md create mode 100644 Packs/CommunityCommonScripts/ReleaseNotes/1_5_8.md create mode 100644 Packs/GitHub/ReleaseNotes/2_3_3.md create mode 100644 Packs/HealthCheck/ReleaseNotes/3_1_5.md create mode 100644 Packs/MicrosoftDefenderAdvancedThreatProtection/ReleaseNotes/1_20_44.md create mode 100644 Packs/Whois/ReleaseNotes/1_5_44.md diff --git a/Packs/Base/ReleaseNotes/1_42_21.md b/Packs/Base/ReleaseNotes/1_42_21.md new file mode 100644 index 000000000000..042002d92b72 --- /dev/null +++ b/Packs/Base/ReleaseNotes/1_42_21.md @@ -0,0 +1,7 @@ + +#### Scripts + +##### SanePdfReports + +- Updated the Docker image to: *demisto/sane-pdf-reports:1.0.0.11473180*. + diff --git a/Packs/Base/Scripts/SanePdfReport/SanePdfReport.yml b/Packs/Base/Scripts/SanePdfReport/SanePdfReport.yml index 4ebb6868c8e8..4a37f7232361 100644 --- a/Packs/Base/Scripts/SanePdfReport/SanePdfReport.yml +++ b/Packs/Base/Scripts/SanePdfReport/SanePdfReport.yml @@ -51,7 +51,7 @@ tags: - pdf timeout: '0' type: python -dockerimage: demisto/sane-pdf-reports:1.0.0.10737051 +dockerimage: demisto/sane-pdf-reports:1.0.0.11473180 runas: DBotWeakRole tests: - No Test diff --git a/Packs/Base/pack_metadata.json b/Packs/Base/pack_metadata.json index ecdc445a6726..d8773b2ceda8 100644 --- a/Packs/Base/pack_metadata.json +++ b/Packs/Base/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Base", "description": "The base pack for Cortex XSOAR.", "support": "xsoar", - "currentVersion": "1.42.20", + "currentVersion": "1.42.21", "author": "Cortex XSOAR", "serverMinVersion": "6.0.0", "url": "https://www.paloaltonetworks.com/cortex", diff --git a/Packs/CaseManagement-Generic/ReleaseNotes/1_4_16.md b/Packs/CaseManagement-Generic/ReleaseNotes/1_4_16.md new file mode 100644 index 000000000000..dbba86b627ae --- /dev/null +++ b/Packs/CaseManagement-Generic/ReleaseNotes/1_4_16.md @@ -0,0 +1,39 @@ + +#### Scripts + +##### CloseLinkedIncidentsPostProcessing + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### AddUserToIncidentTeam + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### TimersOnOwnerChange + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### CaseMgmtIncidentTypesDisplay + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### CaseMgmtDisplayLabels + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### CaseMgmtAnalystTools + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### CompleteTaskOnTimerBreach + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### CaseMgmtIncidentTypesByRole + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### CaseMgmtResponseProcess + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + diff --git a/Packs/CaseManagement-Generic/Scripts/AddUserToIncidentTeam/AddUserToIncidentTeam.yml b/Packs/CaseManagement-Generic/Scripts/AddUserToIncidentTeam/AddUserToIncidentTeam.yml index 3b5d3f570bbf..70cce50ec390 100644 --- a/Packs/CaseManagement-Generic/Scripts/AddUserToIncidentTeam/AddUserToIncidentTeam.yml +++ b/Packs/CaseManagement-Generic/Scripts/AddUserToIncidentTeam/AddUserToIncidentTeam.yml @@ -9,7 +9,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: '' -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: AddUserToIncidentTeam runas: DBotWeakRole diff --git a/Packs/CaseManagement-Generic/Scripts/CaseMgmtAnalystTools/CaseMgmtAnalystTools.yml b/Packs/CaseManagement-Generic/Scripts/CaseMgmtAnalystTools/CaseMgmtAnalystTools.yml index 81fc8723f8bc..9ecc71980e28 100644 --- a/Packs/CaseManagement-Generic/Scripts/CaseMgmtAnalystTools/CaseMgmtAnalystTools.yml +++ b/Packs/CaseManagement-Generic/Scripts/CaseMgmtAnalystTools/CaseMgmtAnalystTools.yml @@ -5,7 +5,7 @@ comment: 'Dynamic display script to display a list of useful Analyst Tools on an commonfields: id: CaseMgmtAnalystTools version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: CaseMgmtAnalystTools runas: DBotWeakRole diff --git a/Packs/CaseManagement-Generic/Scripts/CaseMgmtDisplayLabels/CaseMgmtDisplayLabels.yml b/Packs/CaseManagement-Generic/Scripts/CaseMgmtDisplayLabels/CaseMgmtDisplayLabels.yml index 251345cfb6fe..0bb6b52ca5b5 100644 --- a/Packs/CaseManagement-Generic/Scripts/CaseMgmtDisplayLabels/CaseMgmtDisplayLabels.yml +++ b/Packs/CaseManagement-Generic/Scripts/CaseMgmtDisplayLabels/CaseMgmtDisplayLabels.yml @@ -2,7 +2,7 @@ comment: 'Dynamic section that will display the Labels for an Incident in a mark commonfields: id: CaseMgmtDisplayLabels version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: CaseMgmtDisplayLabels runas: DBotWeakRole diff --git a/Packs/CaseManagement-Generic/Scripts/CaseMgmtIncidentTypesByRole/CaseMgmtIncidentTypesByRole.yml b/Packs/CaseManagement-Generic/Scripts/CaseMgmtIncidentTypesByRole/CaseMgmtIncidentTypesByRole.yml index d63895c063b6..6f1efe7c4e9e 100644 --- a/Packs/CaseManagement-Generic/Scripts/CaseMgmtIncidentTypesByRole/CaseMgmtIncidentTypesByRole.yml +++ b/Packs/CaseManagement-Generic/Scripts/CaseMgmtIncidentTypesByRole/CaseMgmtIncidentTypesByRole.yml @@ -2,7 +2,7 @@ comment: "Restricts the Incident Types a user can create manually, based on thei commonfields: id: CaseMgmtIncidentTypesByRole version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: CaseMgmtIncidentTypesByRole runas: DBotWeakRole diff --git a/Packs/CaseManagement-Generic/Scripts/CaseMgmtIncidentTypesDisplay/CaseMgmtIncidentTypesDisplay.yml b/Packs/CaseManagement-Generic/Scripts/CaseMgmtIncidentTypesDisplay/CaseMgmtIncidentTypesDisplay.yml index 13b9555cb341..5947c1861beb 100644 --- a/Packs/CaseManagement-Generic/Scripts/CaseMgmtIncidentTypesDisplay/CaseMgmtIncidentTypesDisplay.yml +++ b/Packs/CaseManagement-Generic/Scripts/CaseMgmtIncidentTypesDisplay/CaseMgmtIncidentTypesDisplay.yml @@ -2,7 +2,7 @@ comment: "Restricts the Incident Types a user can create manually based on an XS commonfields: id: CaseMgmtIncidentTypesDisplay version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: CaseMgmtIncidentTypesDisplay runas: DBotWeakRole diff --git a/Packs/CaseManagement-Generic/Scripts/CaseMgmtResponseProcess/CaseMgmtResponseProcess.yml b/Packs/CaseManagement-Generic/Scripts/CaseMgmtResponseProcess/CaseMgmtResponseProcess.yml index 1b84f25c6316..41313753e0d4 100644 --- a/Packs/CaseManagement-Generic/Scripts/CaseMgmtResponseProcess/CaseMgmtResponseProcess.yml +++ b/Packs/CaseManagement-Generic/Scripts/CaseMgmtResponseProcess/CaseMgmtResponseProcess.yml @@ -2,7 +2,7 @@ comment: Dynamic display script to display a response process on an Incident lay commonfields: id: CaseMgmtResponseProcess version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: CaseMgmtResponseProcess runas: DBotWeakRole diff --git a/Packs/CaseManagement-Generic/Scripts/CloseLinkedIncidentsPostProcessing/CloseLinkedIncidentsPostProcessing.yml b/Packs/CaseManagement-Generic/Scripts/CloseLinkedIncidentsPostProcessing/CloseLinkedIncidentsPostProcessing.yml index 3c1466e307b0..ddb21d3c3972 100644 --- a/Packs/CaseManagement-Generic/Scripts/CloseLinkedIncidentsPostProcessing/CloseLinkedIncidentsPostProcessing.yml +++ b/Packs/CaseManagement-Generic/Scripts/CloseLinkedIncidentsPostProcessing/CloseLinkedIncidentsPostProcessing.yml @@ -2,7 +2,7 @@ comment: 'Post Processing Script that will close linked Incidents when the Incid commonfields: id: CloseLinkedIncidentsPostProcessing version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: CloseLinkedIncidentsPostProcessing runas: DBotWeakRole diff --git a/Packs/CaseManagement-Generic/Scripts/CompleteTaskOnTimerBreach/CompleteTaskOnTimerBreach.yml b/Packs/CaseManagement-Generic/Scripts/CompleteTaskOnTimerBreach/CompleteTaskOnTimerBreach.yml index 8e1626296bff..f8b1e773c40e 100644 --- a/Packs/CaseManagement-Generic/Scripts/CompleteTaskOnTimerBreach/CompleteTaskOnTimerBreach.yml +++ b/Packs/CaseManagement-Generic/Scripts/CompleteTaskOnTimerBreach/CompleteTaskOnTimerBreach.yml @@ -5,7 +5,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: '' -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: CompleteTaskOnTimerBreach runas: DBotWeakRole diff --git a/Packs/CaseManagement-Generic/Scripts/TimersOnOwnerChange/TimersOnOwnerChange.yml b/Packs/CaseManagement-Generic/Scripts/TimersOnOwnerChange/TimersOnOwnerChange.yml index 4b093392aa4a..c6995bc41053 100644 --- a/Packs/CaseManagement-Generic/Scripts/TimersOnOwnerChange/TimersOnOwnerChange.yml +++ b/Packs/CaseManagement-Generic/Scripts/TimersOnOwnerChange/TimersOnOwnerChange.yml @@ -9,7 +9,7 @@ comment: |- commonfields: id: TimersOnOwnerChange version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: TimersOnOwnerChange runas: DBotWeakRole diff --git a/Packs/CaseManagement-Generic/pack_metadata.json b/Packs/CaseManagement-Generic/pack_metadata.json index 926d8627fbb1..10108aa4bb2b 100644 --- a/Packs/CaseManagement-Generic/pack_metadata.json +++ b/Packs/CaseManagement-Generic/pack_metadata.json @@ -2,7 +2,7 @@ "name": "CaseManagement-Generic", "description": "Case Management - Generic\n\nBuilt by the Cortex Customer Success Team to provide quick deployment of Case Management with XSOAR", "support": "community", - "currentVersion": "1.4.15", + "currentVersion": "1.4.16", "author": "Cortex XSOAR Customer Success", "url": "", "email": "", diff --git a/Packs/CommunityCommonDashboards/ReleaseNotes/2_1_10.md b/Packs/CommunityCommonDashboards/ReleaseNotes/2_1_10.md new file mode 100644 index 000000000000..c130e9b61a01 --- /dev/null +++ b/Packs/CommunityCommonDashboards/ReleaseNotes/2_1_10.md @@ -0,0 +1,15 @@ + +#### Scripts + +##### XMetricsYear + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### XMetricsTotal + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### XMetrics + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + diff --git a/Packs/CommunityCommonDashboards/Scripts/XMetrics/XMetrics.yml b/Packs/CommunityCommonDashboards/Scripts/XMetrics/XMetrics.yml index 49aa6c41c1d8..17ff19c4dee0 100644 --- a/Packs/CommunityCommonDashboards/Scripts/XMetrics/XMetrics.yml +++ b/Packs/CommunityCommonDashboards/Scripts/XMetrics/XMetrics.yml @@ -13,7 +13,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: '' -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true engineinfo: {} name: XMetrics diff --git a/Packs/CommunityCommonDashboards/Scripts/XMetricsTotal/XMetricsTotal.yml b/Packs/CommunityCommonDashboards/Scripts/XMetricsTotal/XMetricsTotal.yml index 427a66ecff33..508a20219a69 100644 --- a/Packs/CommunityCommonDashboards/Scripts/XMetricsTotal/XMetricsTotal.yml +++ b/Packs/CommunityCommonDashboards/Scripts/XMetricsTotal/XMetricsTotal.yml @@ -13,7 +13,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: '' -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true engineinfo: {} name: XMetricsTotal diff --git a/Packs/CommunityCommonDashboards/Scripts/XMetricsYear/XMetricsYear.yml b/Packs/CommunityCommonDashboards/Scripts/XMetricsYear/XMetricsYear.yml index 12f7e8fd8c14..3294c1d7cffa 100644 --- a/Packs/CommunityCommonDashboards/Scripts/XMetricsYear/XMetricsYear.yml +++ b/Packs/CommunityCommonDashboards/Scripts/XMetricsYear/XMetricsYear.yml @@ -8,7 +8,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: '' -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true engineinfo: {} name: XMetricsYear diff --git a/Packs/CommunityCommonDashboards/pack_metadata.json b/Packs/CommunityCommonDashboards/pack_metadata.json index ae4f352cce77..e4c876439b27 100644 --- a/Packs/CommunityCommonDashboards/pack_metadata.json +++ b/Packs/CommunityCommonDashboards/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Community Common Dashboards", "description": "A pack that contains community dashboards", "support": "community", - "currentVersion": "2.1.9", + "currentVersion": "2.1.10", "author": "Randy Uhrlaub", "url": "", "email": "", diff --git a/Packs/CommunityCommonScripts/ReleaseNotes/1_5_8.md b/Packs/CommunityCommonScripts/ReleaseNotes/1_5_8.md new file mode 100644 index 000000000000..d383baeac49e --- /dev/null +++ b/Packs/CommunityCommonScripts/ReleaseNotes/1_5_8.md @@ -0,0 +1,155 @@ + +#### Scripts + +##### RemoveEmptyEvidence + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### GetListDatawithKeyword + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### FindPlaybookCustomDependencies + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### GetIndicatorCustomFieldsByQuery + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### DateTimeToLDAPTime + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### MaxList + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### redactindicator + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### RetrievePlaybookDependencies + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### DisplayTaggedWarroomEntries + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### IPCalcReturnSubnetBroadcastAddress + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### IPCalcReturnAddressBinary + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### GetFields + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### RandomElementFromList + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### RandomPhotoNasa + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### DeleteIncidentsByQuery + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### DeleteIndicators + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### CreateArrayWithDuplicates + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### IPCalcReturnSubnetNetwork + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### isArrayItemInList + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### MinList + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### delete_expired_indicator_with_exlusion + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### InvertEveryTwoItems + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### StripAccentMarksFromString + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### Defang + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### DisplayIndicatorReputationContent + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### SSLVerifier + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### CreateEDLInstance + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### MapRegex + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### IPCalcReturnAddressIANAAllocation + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### CompareList + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### IPCalcReturnSubnetAddresses + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### ConvertUTCEpochTimeToTimeStamp + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### CreateFileFromPathObject + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### DateTimeToADTime + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### IPCalcCheckSubnetCollision + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### GetIndexOfArrayValue + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### GetFilePathPreProcessing + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### BatchData + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + diff --git a/Packs/CommunityCommonScripts/Scripts/BatchData/BatchData.yml b/Packs/CommunityCommonScripts/Scripts/BatchData/BatchData.yml index fee389a15337..21d9f00b0ace 100644 --- a/Packs/CommunityCommonScripts/Scripts/BatchData/BatchData.yml +++ b/Packs/CommunityCommonScripts/Scripts/BatchData/BatchData.yml @@ -15,7 +15,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: '' -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: BatchData runas: DBotWeakRole diff --git a/Packs/CommunityCommonScripts/Scripts/CompareList/CompareList.yml b/Packs/CommunityCommonScripts/Scripts/CompareList/CompareList.yml index ae270cf171d1..9df0780cc33a 100644 --- a/Packs/CommunityCommonScripts/Scripts/CompareList/CompareList.yml +++ b/Packs/CommunityCommonScripts/Scripts/CompareList/CompareList.yml @@ -8,7 +8,7 @@ args: commonfields: id: CompareList version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 comment: Compares two lists. enabled: true name: CompareList diff --git a/Packs/CommunityCommonScripts/Scripts/ConvertUTCEpochTimeToTimeStamp/ConvertUTCEpochTimeToTimeStamp.yml b/Packs/CommunityCommonScripts/Scripts/ConvertUTCEpochTimeToTimeStamp/ConvertUTCEpochTimeToTimeStamp.yml index ed5a0dde6e01..a368adaee0aa 100644 --- a/Packs/CommunityCommonScripts/Scripts/ConvertUTCEpochTimeToTimeStamp/ConvertUTCEpochTimeToTimeStamp.yml +++ b/Packs/CommunityCommonScripts/Scripts/ConvertUTCEpochTimeToTimeStamp/ConvertUTCEpochTimeToTimeStamp.yml @@ -17,7 +17,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: '' -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: ConvertUTCEpochTimeToTimeStamp runas: DBotWeakRole diff --git a/Packs/CommunityCommonScripts/Scripts/CreateArrayWithDuplicates/CreateArrayWithDuplicates.yml b/Packs/CommunityCommonScripts/Scripts/CreateArrayWithDuplicates/CreateArrayWithDuplicates.yml index 3d152784708e..6bac7b10cb37 100644 --- a/Packs/CommunityCommonScripts/Scripts/CreateArrayWithDuplicates/CreateArrayWithDuplicates.yml +++ b/Packs/CommunityCommonScripts/Scripts/CreateArrayWithDuplicates/CreateArrayWithDuplicates.yml @@ -21,7 +21,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: '' -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: CreateArrayWithDuplicates runas: DBotWeakRole diff --git a/Packs/CommunityCommonScripts/Scripts/CreateEDLInstance/CreateEDLInstance.yml b/Packs/CommunityCommonScripts/Scripts/CreateEDLInstance/CreateEDLInstance.yml index 7d14724f7841..acc4b55c25a6 100644 --- a/Packs/CommunityCommonScripts/Scripts/CreateEDLInstance/CreateEDLInstance.yml +++ b/Packs/CommunityCommonScripts/Scripts/CreateEDLInstance/CreateEDLInstance.yml @@ -15,7 +15,7 @@ comment: Use this automation to create an EDL instance on XSOAR. commonfields: id: CreateEDLInstance version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: CreateEDLInstance runas: DBotWeakRole diff --git a/Packs/CommunityCommonScripts/Scripts/CreateFileFromPathObject/CreateFileFromPathObject.yml b/Packs/CommunityCommonScripts/Scripts/CreateFileFromPathObject/CreateFileFromPathObject.yml index 6e26a3505996..3490a85d30d1 100644 --- a/Packs/CommunityCommonScripts/Scripts/CreateFileFromPathObject/CreateFileFromPathObject.yml +++ b/Packs/CommunityCommonScripts/Scripts/CreateFileFromPathObject/CreateFileFromPathObject.yml @@ -10,7 +10,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: '' -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: CreateFileFromPathObject runas: DBotWeakRole diff --git a/Packs/CommunityCommonScripts/Scripts/DateTimeToADTime/DateTimeToADTime.yml b/Packs/CommunityCommonScripts/Scripts/DateTimeToADTime/DateTimeToADTime.yml index 45045771b0aa..d3ca371cc31d 100644 --- a/Packs/CommunityCommonScripts/Scripts/DateTimeToADTime/DateTimeToADTime.yml +++ b/Packs/CommunityCommonScripts/Scripts/DateTimeToADTime/DateTimeToADTime.yml @@ -7,7 +7,7 @@ comment: Converts unix time to AD Integer8 time. This is used in many AD date fi commonfields: id: DateTimeToADTime version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: DateTimeToADTime runas: DBotWeakRole diff --git a/Packs/CommunityCommonScripts/Scripts/DateTimeToLDAPTime/DateTimeToLDAPTime.yml b/Packs/CommunityCommonScripts/Scripts/DateTimeToLDAPTime/DateTimeToLDAPTime.yml index 08140c00dbef..d391142324e7 100644 --- a/Packs/CommunityCommonScripts/Scripts/DateTimeToLDAPTime/DateTimeToLDAPTime.yml +++ b/Packs/CommunityCommonScripts/Scripts/DateTimeToLDAPTime/DateTimeToLDAPTime.yml @@ -10,7 +10,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: '' -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true engineinfo: {} name: DateTimeToLDAPTime diff --git a/Packs/CommunityCommonScripts/Scripts/Defang/Defang.yml b/Packs/CommunityCommonScripts/Scripts/Defang/Defang.yml index a78da36e61f3..39cd9d29995f 100644 --- a/Packs/CommunityCommonScripts/Scripts/Defang/Defang.yml +++ b/Packs/CommunityCommonScripts/Scripts/Defang/Defang.yml @@ -38,7 +38,7 @@ comment: Defangs IP, Mail and URL address to prevent them from being recognized. commonfields: id: Defang version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: Defang runas: DBotWeakRole diff --git a/Packs/CommunityCommonScripts/Scripts/DeleteExpiredIndicatorWithExlusion/DeleteExpiredIndicatorWithExlusion.yml b/Packs/CommunityCommonScripts/Scripts/DeleteExpiredIndicatorWithExlusion/DeleteExpiredIndicatorWithExlusion.yml index 261cbb1c539d..18407b589275 100644 --- a/Packs/CommunityCommonScripts/Scripts/DeleteExpiredIndicatorWithExlusion/DeleteExpiredIndicatorWithExlusion.yml +++ b/Packs/CommunityCommonScripts/Scripts/DeleteExpiredIndicatorWithExlusion/DeleteExpiredIndicatorWithExlusion.yml @@ -4,7 +4,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: '' -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 comment: deletes expired indicators. enabled: true name: delete_expired_indicator_with_exlusion diff --git a/Packs/CommunityCommonScripts/Scripts/DeleteIncidentsByQuery/DeleteIncidentsByQuery.yml b/Packs/CommunityCommonScripts/Scripts/DeleteIncidentsByQuery/DeleteIncidentsByQuery.yml index 2493c5b418f9..2aae40aaec14 100644 --- a/Packs/CommunityCommonScripts/Scripts/DeleteIncidentsByQuery/DeleteIncidentsByQuery.yml +++ b/Packs/CommunityCommonScripts/Scripts/DeleteIncidentsByQuery/DeleteIncidentsByQuery.yml @@ -13,7 +13,7 @@ contentitemexportablefields: fromServerVersion: "" dependson: must: [] -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: DeleteIncidentsByQuery runas: DBotWeakRole diff --git a/Packs/CommunityCommonScripts/Scripts/DeleteIndicators/DeleteIndicators.yml b/Packs/CommunityCommonScripts/Scripts/DeleteIndicators/DeleteIndicators.yml index a9e1f53aec88..cb50c8a96d58 100644 --- a/Packs/CommunityCommonScripts/Scripts/DeleteIndicators/DeleteIndicators.yml +++ b/Packs/CommunityCommonScripts/Scripts/DeleteIndicators/DeleteIndicators.yml @@ -18,7 +18,7 @@ comment: Delete indicators based on query, values, or IDs. commonfields: id: 'DeleteIndicators' version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true engineinfo: {} name: DeleteIndicators diff --git a/Packs/CommunityCommonScripts/Scripts/DisplayIndicatorReputationContent/DisplayIndicatorReputationContent.yml b/Packs/CommunityCommonScripts/Scripts/DisplayIndicatorReputationContent/DisplayIndicatorReputationContent.yml index 15a9f29459ef..7596a31ad983 100644 --- a/Packs/CommunityCommonScripts/Scripts/DisplayIndicatorReputationContent/DisplayIndicatorReputationContent.yml +++ b/Packs/CommunityCommonScripts/Scripts/DisplayIndicatorReputationContent/DisplayIndicatorReputationContent.yml @@ -1,7 +1,7 @@ commonfields: id: DisplayIndicatorReputationContent version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: DisplayIndicatorReputationContent runas: DBotWeakRole diff --git a/Packs/CommunityCommonScripts/Scripts/DisplayTaggedWarroomEntries/DisplayTaggedWarroomEntries.yml b/Packs/CommunityCommonScripts/Scripts/DisplayTaggedWarroomEntries/DisplayTaggedWarroomEntries.yml index d05f6d72fa5e..8fcb3b15952e 100644 --- a/Packs/CommunityCommonScripts/Scripts/DisplayTaggedWarroomEntries/DisplayTaggedWarroomEntries.yml +++ b/Packs/CommunityCommonScripts/Scripts/DisplayTaggedWarroomEntries/DisplayTaggedWarroomEntries.yml @@ -5,7 +5,7 @@ args: commonfields: id: DisplayTaggedWarroomEntries version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true comment: Display warroom entries in a dynamic section which are tagged with 'report'. name: DisplayTaggedWarroomEntries diff --git a/Packs/CommunityCommonScripts/Scripts/FindPlaybookCustomDependencies/FindPlaybookCustomDependencies.yml b/Packs/CommunityCommonScripts/Scripts/FindPlaybookCustomDependencies/FindPlaybookCustomDependencies.yml index 2c7007ccf20c..baa47e6567a0 100644 --- a/Packs/CommunityCommonScripts/Scripts/FindPlaybookCustomDependencies/FindPlaybookCustomDependencies.yml +++ b/Packs/CommunityCommonScripts/Scripts/FindPlaybookCustomDependencies/FindPlaybookCustomDependencies.yml @@ -14,7 +14,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: '' -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true engineinfo: {} name: FindPlaybookCustomDependencies diff --git a/Packs/CommunityCommonScripts/Scripts/GetFields/GetFields.yml b/Packs/CommunityCommonScripts/Scripts/GetFields/GetFields.yml index 790a8a43ba78..ac0ad8b1f5bc 100644 --- a/Packs/CommunityCommonScripts/Scripts/GetFields/GetFields.yml +++ b/Packs/CommunityCommonScripts/Scripts/GetFields/GetFields.yml @@ -22,7 +22,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: '' -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: GetFields runas: DBotWeakRole diff --git a/Packs/CommunityCommonScripts/Scripts/GetFilePathPreProcessing/GetFilePathPreProcessing.yml b/Packs/CommunityCommonScripts/Scripts/GetFilePathPreProcessing/GetFilePathPreProcessing.yml index 59688c4883f5..8c91b10a1055 100644 --- a/Packs/CommunityCommonScripts/Scripts/GetFilePathPreProcessing/GetFilePathPreProcessing.yml +++ b/Packs/CommunityCommonScripts/Scripts/GetFilePathPreProcessing/GetFilePathPreProcessing.yml @@ -9,7 +9,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: '' -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: GetFilePathPreProcessing runas: DBotWeakRole diff --git a/Packs/CommunityCommonScripts/Scripts/GetIndexOfArrayValue/GetIndexOfArrayValue.yml b/Packs/CommunityCommonScripts/Scripts/GetIndexOfArrayValue/GetIndexOfArrayValue.yml index 14235df8a77d..0b4ba2887ddc 100644 --- a/Packs/CommunityCommonScripts/Scripts/GetIndexOfArrayValue/GetIndexOfArrayValue.yml +++ b/Packs/CommunityCommonScripts/Scripts/GetIndexOfArrayValue/GetIndexOfArrayValue.yml @@ -15,7 +15,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: "" -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: GetIndexOfArrayValue runas: DBotWeakRole diff --git a/Packs/CommunityCommonScripts/Scripts/GetIndicatorCustomFieldsByQuery/GetIndicatorCustomFieldsByQuery.yml b/Packs/CommunityCommonScripts/Scripts/GetIndicatorCustomFieldsByQuery/GetIndicatorCustomFieldsByQuery.yml index 1ab0146a6def..2670b0b548d2 100644 --- a/Packs/CommunityCommonScripts/Scripts/GetIndicatorCustomFieldsByQuery/GetIndicatorCustomFieldsByQuery.yml +++ b/Packs/CommunityCommonScripts/Scripts/GetIndicatorCustomFieldsByQuery/GetIndicatorCustomFieldsByQuery.yml @@ -16,7 +16,7 @@ outputs: scripttarget: 0 subtype: python3 runonce: false -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 runas: DBotWeakRole fromversion: 6.9.0 tests: diff --git a/Packs/CommunityCommonScripts/Scripts/GetListDatawithKeyword/GetListDatawithKeyword.yml b/Packs/CommunityCommonScripts/Scripts/GetListDatawithKeyword/GetListDatawithKeyword.yml index 4e7c2ce27498..65792452076e 100644 --- a/Packs/CommunityCommonScripts/Scripts/GetListDatawithKeyword/GetListDatawithKeyword.yml +++ b/Packs/CommunityCommonScripts/Scripts/GetListDatawithKeyword/GetListDatawithKeyword.yml @@ -28,7 +28,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: "" -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: GetListDatawithKeyword runas: DBotWeakRole diff --git a/Packs/CommunityCommonScripts/Scripts/IPCalcCheckSubnetCollision/IPCalcCheckSubnetCollision.yml b/Packs/CommunityCommonScripts/Scripts/IPCalcCheckSubnetCollision/IPCalcCheckSubnetCollision.yml index b56bfcd7689e..347719a0b9b2 100644 --- a/Packs/CommunityCommonScripts/Scripts/IPCalcCheckSubnetCollision/IPCalcCheckSubnetCollision.yml +++ b/Packs/CommunityCommonScripts/Scripts/IPCalcCheckSubnetCollision/IPCalcCheckSubnetCollision.yml @@ -24,7 +24,7 @@ script: '-' subtype: python3 timeout: '0' type: python -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 tests: - No tests fromversion: 6.0.0 diff --git a/Packs/CommunityCommonScripts/Scripts/IPCalcReturnAddressBinary/IPCalcReturnAddressBinary.yml b/Packs/CommunityCommonScripts/Scripts/IPCalcReturnAddressBinary/IPCalcReturnAddressBinary.yml index f750081f764b..043b134926b5 100644 --- a/Packs/CommunityCommonScripts/Scripts/IPCalcReturnAddressBinary/IPCalcReturnAddressBinary.yml +++ b/Packs/CommunityCommonScripts/Scripts/IPCalcReturnAddressBinary/IPCalcReturnAddressBinary.yml @@ -18,7 +18,7 @@ script: '-' subtype: python3 timeout: '0' type: python -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 tests: - No tests fromversion: 6.0.0 diff --git a/Packs/CommunityCommonScripts/Scripts/IPCalcReturnAddressIANAAllocation/IPCalcReturnAddressIANAAllocation.yml b/Packs/CommunityCommonScripts/Scripts/IPCalcReturnAddressIANAAllocation/IPCalcReturnAddressIANAAllocation.yml index e2211c14fe09..a243f330ceb0 100644 --- a/Packs/CommunityCommonScripts/Scripts/IPCalcReturnAddressIANAAllocation/IPCalcReturnAddressIANAAllocation.yml +++ b/Packs/CommunityCommonScripts/Scripts/IPCalcReturnAddressIANAAllocation/IPCalcReturnAddressIANAAllocation.yml @@ -18,7 +18,7 @@ script: '-' subtype: python3 timeout: '0' type: python -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 tests: - No tests fromversion: 6.0.0 diff --git a/Packs/CommunityCommonScripts/Scripts/IPCalcReturnSubnetAddresses/IPCalcReturnSubnetAddresses.yml b/Packs/CommunityCommonScripts/Scripts/IPCalcReturnSubnetAddresses/IPCalcReturnSubnetAddresses.yml index 331dbdfe3475..9e20348f1096 100644 --- a/Packs/CommunityCommonScripts/Scripts/IPCalcReturnSubnetAddresses/IPCalcReturnSubnetAddresses.yml +++ b/Packs/CommunityCommonScripts/Scripts/IPCalcReturnSubnetAddresses/IPCalcReturnSubnetAddresses.yml @@ -15,7 +15,7 @@ script: '-' subtype: python3 timeout: '0' type: python -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 tests: - No tests fromversion: 6.0.0 diff --git a/Packs/CommunityCommonScripts/Scripts/IPCalcReturnSubnetBroadcastAddress/IPCalcReturnSubnetBroadcastAddress.yml b/Packs/CommunityCommonScripts/Scripts/IPCalcReturnSubnetBroadcastAddress/IPCalcReturnSubnetBroadcastAddress.yml index cbb8d3c706d2..b13ac2ee2f19 100644 --- a/Packs/CommunityCommonScripts/Scripts/IPCalcReturnSubnetBroadcastAddress/IPCalcReturnSubnetBroadcastAddress.yml +++ b/Packs/CommunityCommonScripts/Scripts/IPCalcReturnSubnetBroadcastAddress/IPCalcReturnSubnetBroadcastAddress.yml @@ -15,7 +15,7 @@ script: '-' subtype: python3 timeout: '0' type: python -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 tests: - No tests fromversion: 6.0.0 diff --git a/Packs/CommunityCommonScripts/Scripts/IPCalcReturnSubnetNetwork/IPCalcReturnSubnetNetwork.yml b/Packs/CommunityCommonScripts/Scripts/IPCalcReturnSubnetNetwork/IPCalcReturnSubnetNetwork.yml index 2977f43e3a59..db2ea2a1fc1f 100644 --- a/Packs/CommunityCommonScripts/Scripts/IPCalcReturnSubnetNetwork/IPCalcReturnSubnetNetwork.yml +++ b/Packs/CommunityCommonScripts/Scripts/IPCalcReturnSubnetNetwork/IPCalcReturnSubnetNetwork.yml @@ -15,7 +15,7 @@ script: '-' subtype: python3 timeout: '0' type: python -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 tests: - No tests fromversion: 6.0.0 diff --git a/Packs/CommunityCommonScripts/Scripts/InvertEveryTwoItems/InvertEveryTwoItems.yml b/Packs/CommunityCommonScripts/Scripts/InvertEveryTwoItems/InvertEveryTwoItems.yml index 1cefb7f5a771..edb26cd208e5 100644 --- a/Packs/CommunityCommonScripts/Scripts/InvertEveryTwoItems/InvertEveryTwoItems.yml +++ b/Packs/CommunityCommonScripts/Scripts/InvertEveryTwoItems/InvertEveryTwoItems.yml @@ -9,7 +9,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: '' -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: InvertEveryTwoItems runas: DBotWeakRole diff --git a/Packs/CommunityCommonScripts/Scripts/MapRegex/MapRegex.yml b/Packs/CommunityCommonScripts/Scripts/MapRegex/MapRegex.yml index 416f8c1adeec..e1d604f84743 100644 --- a/Packs/CommunityCommonScripts/Scripts/MapRegex/MapRegex.yml +++ b/Packs/CommunityCommonScripts/Scripts/MapRegex/MapRegex.yml @@ -8,7 +8,7 @@ comment: "This transformer will take in a value and transform it based on multip commonfields: id: MapRegex version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: MapRegex runas: DBotWeakRole diff --git a/Packs/CommunityCommonScripts/Scripts/MaxList/MaxList.yml b/Packs/CommunityCommonScripts/Scripts/MaxList/MaxList.yml index 651973dfdd3d..69c1661b910d 100644 --- a/Packs/CommunityCommonScripts/Scripts/MaxList/MaxList.yml +++ b/Packs/CommunityCommonScripts/Scripts/MaxList/MaxList.yml @@ -8,7 +8,7 @@ comment: "Gets the maximum value from list\ne.g. [\"25\", \"10\", \"25\"] => \" commonfields: id: MaxList version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: MaxList runas: DBotWeakRole diff --git a/Packs/CommunityCommonScripts/Scripts/MinList/MinList.yml b/Packs/CommunityCommonScripts/Scripts/MinList/MinList.yml index 5f3f9ba143ea..4591b344673a 100644 --- a/Packs/CommunityCommonScripts/Scripts/MinList/MinList.yml +++ b/Packs/CommunityCommonScripts/Scripts/MinList/MinList.yml @@ -8,7 +8,7 @@ comment: "Gets the minimum value from list\ne.g. [\"25\", \"10\", \"25\"] => \" commonfields: id: MinList version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: MinList runas: DBotWeakRole diff --git a/Packs/CommunityCommonScripts/Scripts/RandomElementFromList/RandomElementFromList.yml b/Packs/CommunityCommonScripts/Scripts/RandomElementFromList/RandomElementFromList.yml index 61e611cef4c0..b4f5d18b910f 100644 --- a/Packs/CommunityCommonScripts/Scripts/RandomElementFromList/RandomElementFromList.yml +++ b/Packs/CommunityCommonScripts/Scripts/RandomElementFromList/RandomElementFromList.yml @@ -11,7 +11,7 @@ comment: randomly select elements from a list in Python. commonfields: id: RandomElementFromList version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: RandomElementFromList runas: DBotWeakRole diff --git a/Packs/CommunityCommonScripts/Scripts/RandomPhotoNasa/RandomPhotoNasa.yml b/Packs/CommunityCommonScripts/Scripts/RandomPhotoNasa/RandomPhotoNasa.yml index 5e8ca4ef2bcf..ce502562133d 100644 --- a/Packs/CommunityCommonScripts/Scripts/RandomPhotoNasa/RandomPhotoNasa.yml +++ b/Packs/CommunityCommonScripts/Scripts/RandomPhotoNasa/RandomPhotoNasa.yml @@ -5,7 +5,7 @@ args: commonfields: id: RandomPhotoNasa version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: RandomPhotoNasa runas: DBotWeakRole diff --git a/Packs/CommunityCommonScripts/Scripts/RedactIndicator/RedactIndicator.yml b/Packs/CommunityCommonScripts/Scripts/RedactIndicator/RedactIndicator.yml index 9ff0409fdeda..3e773b587538 100644 --- a/Packs/CommunityCommonScripts/Scripts/RedactIndicator/RedactIndicator.yml +++ b/Packs/CommunityCommonScripts/Scripts/RedactIndicator/RedactIndicator.yml @@ -14,7 +14,7 @@ name: redactindicator script: '' subtype: python3 type: python -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 runas: DBotWeakRole fromversion: 6.0.0 tests: diff --git a/Packs/CommunityCommonScripts/Scripts/RemoveEmptyEvidence/RemoveEmptyEvidence.yml b/Packs/CommunityCommonScripts/Scripts/RemoveEmptyEvidence/RemoveEmptyEvidence.yml index 4b12e3e8be1e..3ed9be5ae8bd 100644 --- a/Packs/CommunityCommonScripts/Scripts/RemoveEmptyEvidence/RemoveEmptyEvidence.yml +++ b/Packs/CommunityCommonScripts/Scripts/RemoveEmptyEvidence/RemoveEmptyEvidence.yml @@ -11,7 +11,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: "" -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: RemoveEmptyEvidence runas: DBotWeakRole diff --git a/Packs/CommunityCommonScripts/Scripts/RetrievePlaybookDependencies/RetrievePlaybookDependencies.yml b/Packs/CommunityCommonScripts/Scripts/RetrievePlaybookDependencies/RetrievePlaybookDependencies.yml index 602859b05683..7b5e9d397bc2 100644 --- a/Packs/CommunityCommonScripts/Scripts/RetrievePlaybookDependencies/RetrievePlaybookDependencies.yml +++ b/Packs/CommunityCommonScripts/Scripts/RetrievePlaybookDependencies/RetrievePlaybookDependencies.yml @@ -46,7 +46,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: "" -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: RetrievePlaybookDependencies outputs: diff --git a/Packs/CommunityCommonScripts/Scripts/SSLVerifier/SSLVerifier.yml b/Packs/CommunityCommonScripts/Scripts/SSLVerifier/SSLVerifier.yml index a122d37035d9..d96b005751a1 100644 --- a/Packs/CommunityCommonScripts/Scripts/SSLVerifier/SSLVerifier.yml +++ b/Packs/CommunityCommonScripts/Scripts/SSLVerifier/SSLVerifier.yml @@ -30,7 +30,7 @@ outputs: type: string scripttarget: 0 subtype: python3 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 runas: DBotWeakRole fromversion: 5.0.0 tests: diff --git a/Packs/CommunityCommonScripts/Scripts/StripAccentMarksFromString/StripAccentMarksFromString.yml b/Packs/CommunityCommonScripts/Scripts/StripAccentMarksFromString/StripAccentMarksFromString.yml index afe15db3467e..3d5a75c27a12 100644 --- a/Packs/CommunityCommonScripts/Scripts/StripAccentMarksFromString/StripAccentMarksFromString.yml +++ b/Packs/CommunityCommonScripts/Scripts/StripAccentMarksFromString/StripAccentMarksFromString.yml @@ -9,7 +9,7 @@ comment: |- commonfields: id: StripAccentMarksFromString version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: StripAccentMarksFromString runas: DBotWeakRole diff --git a/Packs/CommunityCommonScripts/Scripts/isArrayItemInList/isArrayItemInList.yml b/Packs/CommunityCommonScripts/Scripts/isArrayItemInList/isArrayItemInList.yml index 4601ce854b47..08b857082ac2 100644 --- a/Packs/CommunityCommonScripts/Scripts/isArrayItemInList/isArrayItemInList.yml +++ b/Packs/CommunityCommonScripts/Scripts/isArrayItemInList/isArrayItemInList.yml @@ -17,7 +17,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: '' -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: isArrayItemInList runas: DBotWeakRole diff --git a/Packs/CommunityCommonScripts/pack_metadata.json b/Packs/CommunityCommonScripts/pack_metadata.json index c50db41834e2..1e0a9910195b 100644 --- a/Packs/CommunityCommonScripts/pack_metadata.json +++ b/Packs/CommunityCommonScripts/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Community Common Scripts", "description": "A pack that contains community scripts", "support": "community", - "currentVersion": "1.5.7", + "currentVersion": "1.5.8", "author": "", "url": "https://live.paloaltonetworks.com/t5/cortex-xsoar-discussions/bd-p/Cortex_XSOAR_Discussions", "email": "", diff --git a/Packs/GitHub/Integrations/GitHub/GitHub.yml b/Packs/GitHub/Integrations/GitHub/GitHub.yml index 664802258c1f..401c32dd4deb 100644 --- a/Packs/GitHub/Integrations/GitHub/GitHub.yml +++ b/Packs/GitHub/Integrations/GitHub/GitHub.yml @@ -7557,7 +7557,7 @@ script: required: true description: Deletes a GitHub Actions artifact. name: github-delete-actions-artifact - dockerimage: demisto/auth-utils:1.0.0.7837600 + dockerimage: demisto/auth-utils:1.0.0.11671917 isfetch: true runonce: false script: '-' diff --git a/Packs/GitHub/ReleaseNotes/2_3_3.md b/Packs/GitHub/ReleaseNotes/2_3_3.md new file mode 100644 index 000000000000..7860f985a697 --- /dev/null +++ b/Packs/GitHub/ReleaseNotes/2_3_3.md @@ -0,0 +1,7 @@ + +#### Integrations + +##### GitHub + +- Updated the Docker image to: *demisto/auth-utils:1.0.0.11671917*. + diff --git a/Packs/GitHub/pack_metadata.json b/Packs/GitHub/pack_metadata.json index 4e5b546faf14..a6a6ed0509b7 100644 --- a/Packs/GitHub/pack_metadata.json +++ b/Packs/GitHub/pack_metadata.json @@ -2,7 +2,7 @@ "name": "GitHub", "description": "Manage GitHub issues and pull requests directly from Cortex XSOAR", "support": "xsoar", - "currentVersion": "2.3.2", + "currentVersion": "2.3.3", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/HealthCheck/ReleaseNotes/3_1_5.md b/Packs/HealthCheck/ReleaseNotes/3_1_5.md new file mode 100644 index 000000000000..fff469c648bd --- /dev/null +++ b/Packs/HealthCheck/ReleaseNotes/3_1_5.md @@ -0,0 +1,203 @@ + +#### Scripts + +##### HealthCheckFileSystem + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### getSystemHealthStatus + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### HealthCheckNumberOfLargeIOIncidents + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### HealthCheckAPIvalidation + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### getPlaybooksCount + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### getDockerContainersCount + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### getWorkersCount + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### getDeprecatedAutomations + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### HealthCheckSystemDiagnostics + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### HealthCheckLicenseData + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### getDeprecatedPlaybooks + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### HealthCheckFields + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### HealthCheckWorkers + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### getPlaybooksHealthStatus + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### getDeprecatedIntegrations + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### HealthCheckDiskUsage + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### HealthCheckContainersStatus + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### HealthCheckDiskUsageLine + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### HealthCheckInstalledPacks + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### HealthCheckIncidentsCreatedDaily + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### HealthCheckServerConfiguration + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### getCustomPlaybooks + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### getDiskSpaceStatus + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### HealthCheckPlaybookAnalysis + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### getInvHealthStatus + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### HealthCheckDockerLog + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### HealthCheckOutdatedPacks + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### getCustomAutomations + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### HealthCheckUnpack + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### getAutomationsCount + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### HealthCheckPanicLog + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### HealthCheckNumberOfDroppedIncidents + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### HealthCheckNumberOfPartitions + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### HealthCheckMemory + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### HealthCheckReadVC + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### HealthCheckCPU + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### HealthCheckReadConf + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### HealthCheckNumberOfLargeIncidents + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### HealthCheckNumberOfEngines + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### HealthCheckIncidentsCreatedWeekly + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### HealthCheckPacksInstalled + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### HealthCheckAnalyzeLargeInvestigations + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### getDetachedAutomations + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### getDetachedPlaybooks + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### HealthCheckServerLog + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### HealthCheckReadTemeletryLog + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### HealthCheckGetLargestInputsAndOutputsInIncidents + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### HealthCheckIncidentsCreatedMonthly + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### HealthCheckIntegrations + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + +##### getContentPackStatus + +- Updated the Docker image to: *demisto/python3:3.12.13.11879924*. + diff --git a/Packs/HealthCheck/Scripts/GetAutomationsCount/GetAutomationsCount.yml b/Packs/HealthCheck/Scripts/GetAutomationsCount/GetAutomationsCount.yml index 78308411755c..0e8fc1e25130 100644 --- a/Packs/HealthCheck/Scripts/GetAutomationsCount/GetAutomationsCount.yml +++ b/Packs/HealthCheck/Scripts/GetAutomationsCount/GetAutomationsCount.yml @@ -5,7 +5,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: '' -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true engineinfo: {} name: getAutomationsCount diff --git a/Packs/HealthCheck/Scripts/GetContentPackStatus/GetContentPackStatus.yml b/Packs/HealthCheck/Scripts/GetContentPackStatus/GetContentPackStatus.yml index 9d5d9ddfdc03..544d95236cec 100644 --- a/Packs/HealthCheck/Scripts/GetContentPackStatus/GetContentPackStatus.yml +++ b/Packs/HealthCheck/Scripts/GetContentPackStatus/GetContentPackStatus.yml @@ -5,7 +5,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: '' -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true engineinfo: {} name: getContentPackStatus diff --git a/Packs/HealthCheck/Scripts/GetCustomAutomations/GetCustomAutomations.yml b/Packs/HealthCheck/Scripts/GetCustomAutomations/GetCustomAutomations.yml index 24f5fbb31c4c..9a2ef7fd2a1b 100644 --- a/Packs/HealthCheck/Scripts/GetCustomAutomations/GetCustomAutomations.yml +++ b/Packs/HealthCheck/Scripts/GetCustomAutomations/GetCustomAutomations.yml @@ -5,7 +5,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: '' -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true engineinfo: {} name: getCustomAutomations diff --git a/Packs/HealthCheck/Scripts/GetCustomPlaybooks/GetCustomPlaybooks.yml b/Packs/HealthCheck/Scripts/GetCustomPlaybooks/GetCustomPlaybooks.yml index 0aa9191970fc..96f9cb1ec460 100644 --- a/Packs/HealthCheck/Scripts/GetCustomPlaybooks/GetCustomPlaybooks.yml +++ b/Packs/HealthCheck/Scripts/GetCustomPlaybooks/GetCustomPlaybooks.yml @@ -5,7 +5,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: '' -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true engineinfo: {} name: getCustomPlaybooks diff --git a/Packs/HealthCheck/Scripts/GetDeprecatedAutomations/GetDeprecatedAutomations.yml b/Packs/HealthCheck/Scripts/GetDeprecatedAutomations/GetDeprecatedAutomations.yml index e86dbc0b645a..9f9781277990 100644 --- a/Packs/HealthCheck/Scripts/GetDeprecatedAutomations/GetDeprecatedAutomations.yml +++ b/Packs/HealthCheck/Scripts/GetDeprecatedAutomations/GetDeprecatedAutomations.yml @@ -5,7 +5,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: '' -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true engineinfo: {} name: getDeprecatedAutomations diff --git a/Packs/HealthCheck/Scripts/GetDeprecatedIntegrations/GetDeprecatedIntegrations.yml b/Packs/HealthCheck/Scripts/GetDeprecatedIntegrations/GetDeprecatedIntegrations.yml index 442119c1254c..2063bcc9cb4e 100644 --- a/Packs/HealthCheck/Scripts/GetDeprecatedIntegrations/GetDeprecatedIntegrations.yml +++ b/Packs/HealthCheck/Scripts/GetDeprecatedIntegrations/GetDeprecatedIntegrations.yml @@ -5,7 +5,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: '' -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true engineinfo: {} name: getDeprecatedIntegrations diff --git a/Packs/HealthCheck/Scripts/GetDeprecatedPlaybooks/GetDeprecatedPlaybooks.yml b/Packs/HealthCheck/Scripts/GetDeprecatedPlaybooks/GetDeprecatedPlaybooks.yml index ca750b3607d2..c1d3eb58b6a2 100644 --- a/Packs/HealthCheck/Scripts/GetDeprecatedPlaybooks/GetDeprecatedPlaybooks.yml +++ b/Packs/HealthCheck/Scripts/GetDeprecatedPlaybooks/GetDeprecatedPlaybooks.yml @@ -5,7 +5,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: '' -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true engineinfo: {} name: getDeprecatedPlaybooks diff --git a/Packs/HealthCheck/Scripts/GetDetachedAutomations/GetDetachedAutomations.yml b/Packs/HealthCheck/Scripts/GetDetachedAutomations/GetDetachedAutomations.yml index 5319e3f8df43..facab0cf800a 100644 --- a/Packs/HealthCheck/Scripts/GetDetachedAutomations/GetDetachedAutomations.yml +++ b/Packs/HealthCheck/Scripts/GetDetachedAutomations/GetDetachedAutomations.yml @@ -5,7 +5,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: '' -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true engineinfo: {} name: getDetachedAutomations diff --git a/Packs/HealthCheck/Scripts/GetDetachedPlaybooks/GetDetachedPlaybooks.yml b/Packs/HealthCheck/Scripts/GetDetachedPlaybooks/GetDetachedPlaybooks.yml index ca415c98da22..b4d96aaf764a 100644 --- a/Packs/HealthCheck/Scripts/GetDetachedPlaybooks/GetDetachedPlaybooks.yml +++ b/Packs/HealthCheck/Scripts/GetDetachedPlaybooks/GetDetachedPlaybooks.yml @@ -5,7 +5,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: '' -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true engineinfo: {} name: getDetachedPlaybooks diff --git a/Packs/HealthCheck/Scripts/GetDiskSpaceStatus/GetDiskSpaceStatus.yml b/Packs/HealthCheck/Scripts/GetDiskSpaceStatus/GetDiskSpaceStatus.yml index 3686973ed346..898fc791196d 100644 --- a/Packs/HealthCheck/Scripts/GetDiskSpaceStatus/GetDiskSpaceStatus.yml +++ b/Packs/HealthCheck/Scripts/GetDiskSpaceStatus/GetDiskSpaceStatus.yml @@ -5,7 +5,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: '' -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true engineinfo: {} name: getDiskSpaceStatus diff --git a/Packs/HealthCheck/Scripts/GetDockerContainersCount/GetDockerContainersCount.yml b/Packs/HealthCheck/Scripts/GetDockerContainersCount/GetDockerContainersCount.yml index c010b0826239..26ac4be44b81 100644 --- a/Packs/HealthCheck/Scripts/GetDockerContainersCount/GetDockerContainersCount.yml +++ b/Packs/HealthCheck/Scripts/GetDockerContainersCount/GetDockerContainersCount.yml @@ -5,7 +5,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: '' -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true engineinfo: {} name: getDockerContainersCount diff --git a/Packs/HealthCheck/Scripts/GetInvHealthStatus/GetInvHealthStatus.yml b/Packs/HealthCheck/Scripts/GetInvHealthStatus/GetInvHealthStatus.yml index 85dbb8057360..7392a9e53f9c 100644 --- a/Packs/HealthCheck/Scripts/GetInvHealthStatus/GetInvHealthStatus.yml +++ b/Packs/HealthCheck/Scripts/GetInvHealthStatus/GetInvHealthStatus.yml @@ -5,7 +5,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: '' -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true engineinfo: {} name: getInvHealthStatus diff --git a/Packs/HealthCheck/Scripts/GetPlaybooksCount/GetPlaybooksCount.yml b/Packs/HealthCheck/Scripts/GetPlaybooksCount/GetPlaybooksCount.yml index c131af009c62..a278c880af15 100644 --- a/Packs/HealthCheck/Scripts/GetPlaybooksCount/GetPlaybooksCount.yml +++ b/Packs/HealthCheck/Scripts/GetPlaybooksCount/GetPlaybooksCount.yml @@ -5,7 +5,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: '' -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true engineinfo: {} name: getPlaybooksCount diff --git a/Packs/HealthCheck/Scripts/GetPlaybooksHealthStatus/GetPlaybooksHealthStatus.yml b/Packs/HealthCheck/Scripts/GetPlaybooksHealthStatus/GetPlaybooksHealthStatus.yml index bba07a6d0a70..bde7a95edbee 100644 --- a/Packs/HealthCheck/Scripts/GetPlaybooksHealthStatus/GetPlaybooksHealthStatus.yml +++ b/Packs/HealthCheck/Scripts/GetPlaybooksHealthStatus/GetPlaybooksHealthStatus.yml @@ -5,7 +5,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: '' -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true engineinfo: {} name: getPlaybooksHealthStatus diff --git a/Packs/HealthCheck/Scripts/GetSystemHealthStatus/GetSystemHealthStatus.yml b/Packs/HealthCheck/Scripts/GetSystemHealthStatus/GetSystemHealthStatus.yml index 832d6a7cb2f0..222a50283eb0 100644 --- a/Packs/HealthCheck/Scripts/GetSystemHealthStatus/GetSystemHealthStatus.yml +++ b/Packs/HealthCheck/Scripts/GetSystemHealthStatus/GetSystemHealthStatus.yml @@ -5,7 +5,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: '' -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true engineinfo: {} name: getSystemHealthStatus diff --git a/Packs/HealthCheck/Scripts/GetWorkersCount/GetWorkersCount.yml b/Packs/HealthCheck/Scripts/GetWorkersCount/GetWorkersCount.yml index 4ed35d32fd63..a1d7341eb0b2 100644 --- a/Packs/HealthCheck/Scripts/GetWorkersCount/GetWorkersCount.yml +++ b/Packs/HealthCheck/Scripts/GetWorkersCount/GetWorkersCount.yml @@ -5,7 +5,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: '' -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true engineinfo: {} name: getWorkersCount diff --git a/Packs/HealthCheck/Scripts/HealthCheckAPIvalidation/HealthCheckAPIvalidation.yml b/Packs/HealthCheck/Scripts/HealthCheckAPIvalidation/HealthCheckAPIvalidation.yml index 046ad424d59b..df236a29ee6d 100644 --- a/Packs/HealthCheck/Scripts/HealthCheckAPIvalidation/HealthCheckAPIvalidation.yml +++ b/Packs/HealthCheck/Scripts/HealthCheckAPIvalidation/HealthCheckAPIvalidation.yml @@ -4,7 +4,7 @@ comment: |- commonfields: id: HealthCheckAPIvalidation version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: HealthCheckAPIvalidation runas: DBotWeakRole diff --git a/Packs/HealthCheck/Scripts/HealthCheckAnalyzeLargeInvestigations/HealthCheckAnalyzeLargeInvestigations.yml b/Packs/HealthCheck/Scripts/HealthCheckAnalyzeLargeInvestigations/HealthCheckAnalyzeLargeInvestigations.yml index ec426fb282cb..944be9b14418 100644 --- a/Packs/HealthCheck/Scripts/HealthCheckAnalyzeLargeInvestigations/HealthCheckAnalyzeLargeInvestigations.yml +++ b/Packs/HealthCheck/Scripts/HealthCheckAnalyzeLargeInvestigations/HealthCheckAnalyzeLargeInvestigations.yml @@ -17,7 +17,7 @@ name: HealthCheckAnalyzeLargeInvestigations script: '' subtype: python3 type: python -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 runas: DBotWeakRole tests: - No tests (auto formatted) diff --git a/Packs/HealthCheck/Scripts/HealthCheckCPU/HealthCheckCPU.yml b/Packs/HealthCheck/Scripts/HealthCheckCPU/HealthCheckCPU.yml index 3da13e080570..b6bfc2f64ded 100644 --- a/Packs/HealthCheck/Scripts/HealthCheckCPU/HealthCheckCPU.yml +++ b/Packs/HealthCheck/Scripts/HealthCheckCPU/HealthCheckCPU.yml @@ -10,7 +10,7 @@ comment: Present or parse CPU usage stats. commonfields: id: HealthCheckCPU version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: HealthCheckCPU runas: DBotWeakRole diff --git a/Packs/HealthCheck/Scripts/HealthCheckContainersStatus/HealthCheckContainersStatus.yml b/Packs/HealthCheck/Scripts/HealthCheckContainersStatus/HealthCheckContainersStatus.yml index 80e2fc7dcca1..ce372cd1df31 100644 --- a/Packs/HealthCheck/Scripts/HealthCheckContainersStatus/HealthCheckContainersStatus.yml +++ b/Packs/HealthCheck/Scripts/HealthCheckContainersStatus/HealthCheckContainersStatus.yml @@ -2,7 +2,7 @@ comment: Containers status. commonfields: id: HealthCheckContainersStatus version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: HealthCheckContainersStatus outputs: diff --git a/Packs/HealthCheck/Scripts/HealthCheckDiskUsage/HealthCheckDiskUsage.yml b/Packs/HealthCheck/Scripts/HealthCheckDiskUsage/HealthCheckDiskUsage.yml index bb57dde34561..6031b25a69c7 100644 --- a/Packs/HealthCheck/Scripts/HealthCheckDiskUsage/HealthCheckDiskUsage.yml +++ b/Packs/HealthCheck/Scripts/HealthCheckDiskUsage/HealthCheckDiskUsage.yml @@ -10,7 +10,7 @@ comment: Present or parse Disk usage stats. commonfields: id: HealthCheckDiskUsage version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: HealthCheckDiskUsage runas: DBotWeakRole diff --git a/Packs/HealthCheck/Scripts/HealthCheckDiskUsageLine/HealthCheckDiskUsageLine.yml b/Packs/HealthCheck/Scripts/HealthCheckDiskUsageLine/HealthCheckDiskUsageLine.yml index 25faebe2b47c..330152c1d2df 100644 --- a/Packs/HealthCheck/Scripts/HealthCheckDiskUsageLine/HealthCheckDiskUsageLine.yml +++ b/Packs/HealthCheck/Scripts/HealthCheckDiskUsageLine/HealthCheckDiskUsageLine.yml @@ -2,7 +2,7 @@ comment: Present Disk usage stats line widget. commonfields: id: HealthCheckDiskUsageLine version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: HealthCheckDiskUsageLine runas: DBotWeakRole diff --git a/Packs/HealthCheck/Scripts/HealthCheckDockerLog/HealthCheckDockerLog.yml b/Packs/HealthCheck/Scripts/HealthCheckDockerLog/HealthCheckDockerLog.yml index 3e2a9c887ae3..3c197510007f 100644 --- a/Packs/HealthCheck/Scripts/HealthCheckDockerLog/HealthCheckDockerLog.yml +++ b/Packs/HealthCheck/Scripts/HealthCheckDockerLog/HealthCheckDockerLog.yml @@ -7,7 +7,7 @@ comment: Read Docker log file. commonfields: id: HealthCheckDockerLog version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: HealthCheckDockerLog runas: DBotWeakRole diff --git a/Packs/HealthCheck/Scripts/HealthCheckFields/HealthCheckFields.yml b/Packs/HealthCheck/Scripts/HealthCheckFields/HealthCheckFields.yml index 1e3ef42e98eb..930531fe0f67 100644 --- a/Packs/HealthCheck/Scripts/HealthCheckFields/HealthCheckFields.yml +++ b/Packs/HealthCheck/Scripts/HealthCheckFields/HealthCheckFields.yml @@ -2,7 +2,7 @@ comment: Parsing custom fields to detect indexed fields for risky field types. commonfields: id: HealthCheckFields version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: HealthCheckFields runas: DBotWeakRole diff --git a/Packs/HealthCheck/Scripts/HealthCheckFileSystem/HealthCheckFileSystem.yml b/Packs/HealthCheck/Scripts/HealthCheckFileSystem/HealthCheckFileSystem.yml index 7143652ccb51..4aa85350111f 100644 --- a/Packs/HealthCheck/Scripts/HealthCheckFileSystem/HealthCheckFileSystem.yml +++ b/Packs/HealthCheck/Scripts/HealthCheckFileSystem/HealthCheckFileSystem.yml @@ -10,7 +10,7 @@ comment: read and parse filesystem.log commonfields: id: HealthCheckFileSystem version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: HealthCheckFileSystem runas: DBotWeakRole diff --git a/Packs/HealthCheck/Scripts/HealthCheckGetLargestInputsAndOutputsInIncidents/HealthCheckGetLargestInputsAndOutputsInIncidents.yml b/Packs/HealthCheck/Scripts/HealthCheckGetLargestInputsAndOutputsInIncidents/HealthCheckGetLargestInputsAndOutputsInIncidents.yml index d1bc771dd071..9a3fd4048814 100644 --- a/Packs/HealthCheck/Scripts/HealthCheckGetLargestInputsAndOutputsInIncidents/HealthCheckGetLargestInputsAndOutputsInIncidents.yml +++ b/Packs/HealthCheck/Scripts/HealthCheckGetLargestInputsAndOutputsInIncidents/HealthCheckGetLargestInputsAndOutputsInIncidents.yml @@ -13,7 +13,7 @@ comment: Returns inputs and outputs larger than 1 MB from all Cortex XSOAR inves commonfields: id: HealthCheckGetLargestInputsAndOutputsInIncidents version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: HealthCheckGetLargestInputsAndOutputsInIncidents runas: DBotWeakRole diff --git a/Packs/HealthCheck/Scripts/HealthCheckIncidentsCreatedDaily/HealthCheckIncidentsCreatedDaily.yml b/Packs/HealthCheck/Scripts/HealthCheckIncidentsCreatedDaily/HealthCheckIncidentsCreatedDaily.yml index 2805f417b914..c6c4187e7d6f 100644 --- a/Packs/HealthCheck/Scripts/HealthCheckIncidentsCreatedDaily/HealthCheckIncidentsCreatedDaily.yml +++ b/Packs/HealthCheck/Scripts/HealthCheckIncidentsCreatedDaily/HealthCheckIncidentsCreatedDaily.yml @@ -2,7 +2,7 @@ comment: Trend graph for incidents created per day. commonfields: id: HealthCheckIncidentsCreatedDaily version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: HealthCheckIncidentsCreatedDaily runas: DBotWeakRole diff --git a/Packs/HealthCheck/Scripts/HealthCheckIncidentsCreatedMonthly/HealthCheckIncidentsCreatedMonthly.yml b/Packs/HealthCheck/Scripts/HealthCheckIncidentsCreatedMonthly/HealthCheckIncidentsCreatedMonthly.yml index aee20ff7aa60..afa3240e8cd4 100644 --- a/Packs/HealthCheck/Scripts/HealthCheckIncidentsCreatedMonthly/HealthCheckIncidentsCreatedMonthly.yml +++ b/Packs/HealthCheck/Scripts/HealthCheckIncidentsCreatedMonthly/HealthCheckIncidentsCreatedMonthly.yml @@ -2,7 +2,7 @@ comment: Trend graph for incidents created per month. commonfields: id: HealthCheckIncidentsCreatedMonthly version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: HealthCheckIncidentsCreatedMonthly runas: DBotWeakRole diff --git a/Packs/HealthCheck/Scripts/HealthCheckIncidentsCreatedWeekly/HealthCheckIncidentsCreatedWeekly.yml b/Packs/HealthCheck/Scripts/HealthCheckIncidentsCreatedWeekly/HealthCheckIncidentsCreatedWeekly.yml index ec5c56d5462f..85698f516d03 100644 --- a/Packs/HealthCheck/Scripts/HealthCheckIncidentsCreatedWeekly/HealthCheckIncidentsCreatedWeekly.yml +++ b/Packs/HealthCheck/Scripts/HealthCheckIncidentsCreatedWeekly/HealthCheckIncidentsCreatedWeekly.yml @@ -2,7 +2,7 @@ comment: Trend graph for incident creation. commonfields: id: HealthCheckIncidentsCreatedWeekly version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: HealthCheckIncidentsCreatedWeekly runas: DBotWeakRole diff --git a/Packs/HealthCheck/Scripts/HealthCheckInstalledPacks/HealthCheckInstalledPacks.yml b/Packs/HealthCheck/Scripts/HealthCheckInstalledPacks/HealthCheckInstalledPacks.yml index 615ab9f698f4..601bb6203073 100644 --- a/Packs/HealthCheck/Scripts/HealthCheckInstalledPacks/HealthCheckInstalledPacks.yml +++ b/Packs/HealthCheck/Scripts/HealthCheckInstalledPacks/HealthCheckInstalledPacks.yml @@ -2,7 +2,7 @@ comment: "Read the installedpacks.json. \n\nCount and get packs names." commonfields: id: HealthCheckInstalledPacks version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: HealthCheckInstalledPacks outputs: diff --git a/Packs/HealthCheck/Scripts/HealthCheckIntegrations/HealthCheckIntegrations.yml b/Packs/HealthCheck/Scripts/HealthCheckIntegrations/HealthCheckIntegrations.yml index d9e1748ad4fe..a5277fd282c6 100644 --- a/Packs/HealthCheck/Scripts/HealthCheckIntegrations/HealthCheckIntegrations.yml +++ b/Packs/HealthCheck/Scripts/HealthCheckIntegrations/HealthCheckIntegrations.yml @@ -2,7 +2,7 @@ comment: Collect integrations name and count number of engines. commonfields: id: HealthCheckIntegrations version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: HealthCheckIntegrations runas: DBotWeakRole diff --git a/Packs/HealthCheck/Scripts/HealthCheckLicenseData/HealthCheckLicenseData.yml b/Packs/HealthCheck/Scripts/HealthCheckLicenseData/HealthCheckLicenseData.yml index 143b1cbf2226..2ba408f11da5 100644 --- a/Packs/HealthCheck/Scripts/HealthCheckLicenseData/HealthCheckLicenseData.yml +++ b/Packs/HealthCheck/Scripts/HealthCheckLicenseData/HealthCheckLicenseData.yml @@ -7,7 +7,7 @@ comment: Read the license_data.log file extracted from the log bundle. commonfields: id: HealthCheckLicenseData version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: HealthCheckLicenseData outputs: diff --git a/Packs/HealthCheck/Scripts/HealthCheckMemory/HealthCheckMemory.yml b/Packs/HealthCheck/Scripts/HealthCheckMemory/HealthCheckMemory.yml index d4995fc9f46f..6b449368ae3e 100644 --- a/Packs/HealthCheck/Scripts/HealthCheckMemory/HealthCheckMemory.yml +++ b/Packs/HealthCheck/Scripts/HealthCheckMemory/HealthCheckMemory.yml @@ -10,7 +10,7 @@ comment: Present or analyze memory usage. commonfields: id: HealthCheckMemory version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: HealthCheckMemory runas: DBotWeakRole diff --git a/Packs/HealthCheck/Scripts/HealthCheckNumberOfDroppedIncidents/HealthCheckNumberOfDroppedIncidents.yml b/Packs/HealthCheck/Scripts/HealthCheckNumberOfDroppedIncidents/HealthCheckNumberOfDroppedIncidents.yml index 261bb1aff62f..ca9991f83e83 100644 --- a/Packs/HealthCheck/Scripts/HealthCheckNumberOfDroppedIncidents/HealthCheckNumberOfDroppedIncidents.yml +++ b/Packs/HealthCheck/Scripts/HealthCheckNumberOfDroppedIncidents/HealthCheckNumberOfDroppedIncidents.yml @@ -12,7 +12,7 @@ comment: Number of dropped incidents. commonfields: id: HealthCheckNumberOfDroppedIncidents version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: HealthCheckNumberOfDroppedIncidents outputs: diff --git a/Packs/HealthCheck/Scripts/HealthCheckNumberOfEngines/HealthCheckNumberOfEngines.yml b/Packs/HealthCheck/Scripts/HealthCheckNumberOfEngines/HealthCheckNumberOfEngines.yml index 2e839cfe3e61..58b02e915ee2 100644 --- a/Packs/HealthCheck/Scripts/HealthCheckNumberOfEngines/HealthCheckNumberOfEngines.yml +++ b/Packs/HealthCheck/Scripts/HealthCheckNumberOfEngines/HealthCheckNumberOfEngines.yml @@ -2,7 +2,7 @@ comment: Presenting Number of engines. commonfields: id: HealthCheckNumberOfEngines version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: HealthCheckNumberOfEngines runas: DBotWeakRole diff --git a/Packs/HealthCheck/Scripts/HealthCheckNumberOfLargeIOIncidents/HealthCheckNumberOfLargeIOIncidents.yml b/Packs/HealthCheck/Scripts/HealthCheckNumberOfLargeIOIncidents/HealthCheckNumberOfLargeIOIncidents.yml index a70819cb22fb..3d831316d884 100644 --- a/Packs/HealthCheck/Scripts/HealthCheckNumberOfLargeIOIncidents/HealthCheckNumberOfLargeIOIncidents.yml +++ b/Packs/HealthCheck/Scripts/HealthCheckNumberOfLargeIOIncidents/HealthCheckNumberOfLargeIOIncidents.yml @@ -2,7 +2,7 @@ comment: Widget Script to present the number of incidents with large input and o commonfields: id: HealthCheckNumberOfLargeIOIncidents version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: HealthCheckNumberOfLargeIOIncidents runas: DBotWeakRole diff --git a/Packs/HealthCheck/Scripts/HealthCheckNumberOfLargeIncidents/HealthCheckNumberOfLargeIncidents.yml b/Packs/HealthCheck/Scripts/HealthCheckNumberOfLargeIncidents/HealthCheckNumberOfLargeIncidents.yml index 1f18408b88c4..4d4b8182fd78 100644 --- a/Packs/HealthCheck/Scripts/HealthCheckNumberOfLargeIncidents/HealthCheckNumberOfLargeIncidents.yml +++ b/Packs/HealthCheck/Scripts/HealthCheckNumberOfLargeIncidents/HealthCheckNumberOfLargeIncidents.yml @@ -2,7 +2,7 @@ comment: Widget Script to present the number of large incidents. commonfields: id: HealthCheckNumberOfLargeIncidents version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: HealthCheckNumberOfLargeIncidents runas: DBotWeakRole diff --git a/Packs/HealthCheck/Scripts/HealthCheckNumberOfPartitions/HealthCheckNumberOfPartitions.yml b/Packs/HealthCheck/Scripts/HealthCheckNumberOfPartitions/HealthCheckNumberOfPartitions.yml index cbdde4ffdb7c..87d77d50f650 100644 --- a/Packs/HealthCheck/Scripts/HealthCheckNumberOfPartitions/HealthCheckNumberOfPartitions.yml +++ b/Packs/HealthCheck/Scripts/HealthCheckNumberOfPartitions/HealthCheckNumberOfPartitions.yml @@ -2,7 +2,7 @@ comment: Widget Script to present the number of BoltDB partitions. commonfields: id: HealthCheckNumberOfPartitions version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: HealthCheckNumberOfPartitions runas: DBotWeakRole diff --git a/Packs/HealthCheck/Scripts/HealthCheckOutdatedPacks/HealthCheckOutdatedPacks.yml b/Packs/HealthCheck/Scripts/HealthCheckOutdatedPacks/HealthCheckOutdatedPacks.yml index 44dff9c4e563..9c9a4b6ecd3f 100644 --- a/Packs/HealthCheck/Scripts/HealthCheckOutdatedPacks/HealthCheckOutdatedPacks.yml +++ b/Packs/HealthCheck/Scripts/HealthCheckOutdatedPacks/HealthCheckOutdatedPacks.yml @@ -2,7 +2,7 @@ comment: Presenting Outdated Packs. commonfields: id: HealthCheckOutdatedPacks version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: HealthCheckOutdatedPacks runas: DBotWeakRole diff --git a/Packs/HealthCheck/Scripts/HealthCheckPacksInstalled/HealthCheckPacksInstalled.yml b/Packs/HealthCheck/Scripts/HealthCheckPacksInstalled/HealthCheckPacksInstalled.yml index 84997a8fc16d..d446a07259d2 100644 --- a/Packs/HealthCheck/Scripts/HealthCheckPacksInstalled/HealthCheckPacksInstalled.yml +++ b/Packs/HealthCheck/Scripts/HealthCheckPacksInstalled/HealthCheckPacksInstalled.yml @@ -2,7 +2,7 @@ comment: Presenting numbers of packs installed. commonfields: id: HealthCheckPacksInstalled version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: HealthCheckPacksInstalled runas: DBotWeakRole diff --git a/Packs/HealthCheck/Scripts/HealthCheckPanicLog/HealthCheckPanicLog.yml b/Packs/HealthCheck/Scripts/HealthCheckPanicLog/HealthCheckPanicLog.yml index 9a95ad690a64..e9cac359be00 100644 --- a/Packs/HealthCheck/Scripts/HealthCheckPanicLog/HealthCheckPanicLog.yml +++ b/Packs/HealthCheck/Scripts/HealthCheckPanicLog/HealthCheckPanicLog.yml @@ -6,7 +6,7 @@ comment: Read panic log file line by line and display warnings, fatal errors and commonfields: id: HealthCheckPanicLog version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: HealthCheckPanicLog runas: DBotWeakRole diff --git a/Packs/HealthCheck/Scripts/HealthCheckPlaybookAnalysis/HealthCheckPlaybookAnalysis.yml b/Packs/HealthCheck/Scripts/HealthCheckPlaybookAnalysis/HealthCheckPlaybookAnalysis.yml index cd267600faa2..4b9b83d6e4f7 100644 --- a/Packs/HealthCheck/Scripts/HealthCheckPlaybookAnalysis/HealthCheckPlaybookAnalysis.yml +++ b/Packs/HealthCheck/Scripts/HealthCheckPlaybookAnalysis/HealthCheckPlaybookAnalysis.yml @@ -7,7 +7,7 @@ comment: Parsing playbooks. commonfields: id: HealthCheckPlaybookAnalysis version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: HealthCheckPlaybookAnalysis runas: DBotWeakRole diff --git a/Packs/HealthCheck/Scripts/HealthCheckReadConf/HealthCheckReadConf.yml b/Packs/HealthCheck/Scripts/HealthCheckReadConf/HealthCheckReadConf.yml index 126aa81ad02e..471331f3674e 100644 --- a/Packs/HealthCheck/Scripts/HealthCheckReadConf/HealthCheckReadConf.yml +++ b/Packs/HealthCheck/Scripts/HealthCheckReadConf/HealthCheckReadConf.yml @@ -7,7 +7,7 @@ comment: Read the license_data.log file extracted from the log bundle. commonfields: id: HealthCheckReadConf version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: HealthCheckReadConf outputs: diff --git a/Packs/HealthCheck/Scripts/HealthCheckReadTemeletryLog/HealthCheckReadTemeletryLog.yml b/Packs/HealthCheck/Scripts/HealthCheckReadTemeletryLog/HealthCheckReadTemeletryLog.yml index 65021c96546e..2a21d9f7c38d 100644 --- a/Packs/HealthCheck/Scripts/HealthCheckReadTemeletryLog/HealthCheckReadTemeletryLog.yml +++ b/Packs/HealthCheck/Scripts/HealthCheckReadTemeletryLog/HealthCheckReadTemeletryLog.yml @@ -5,7 +5,7 @@ comment: Read Telemtry log. commonfields: id: HealthCheckReadTemeletryLog version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: HealthCheckReadTemeletryLog runas: DBotWeakRole diff --git a/Packs/HealthCheck/Scripts/HealthCheckReadVC/HealthCheckReadVC.yml b/Packs/HealthCheck/Scripts/HealthCheckReadVC/HealthCheckReadVC.yml index 21b4b57c2fd2..7a3c3267163b 100644 --- a/Packs/HealthCheck/Scripts/HealthCheckReadVC/HealthCheckReadVC.yml +++ b/Packs/HealthCheck/Scripts/HealthCheckReadVC/HealthCheckReadVC.yml @@ -7,7 +7,7 @@ comment: Read the version_control.log file extracted from the log bundle. commonfields: id: HealthCheckReadVC version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: HealthCheckReadVC outputs: diff --git a/Packs/HealthCheck/Scripts/HealthCheckServerConfiguration/HealthCheckServerConfiguration.yml b/Packs/HealthCheck/Scripts/HealthCheckServerConfiguration/HealthCheckServerConfiguration.yml index 99c6e816d35f..6afe978210b2 100644 --- a/Packs/HealthCheck/Scripts/HealthCheckServerConfiguration/HealthCheckServerConfiguration.yml +++ b/Packs/HealthCheck/Scripts/HealthCheckServerConfiguration/HealthCheckServerConfiguration.yml @@ -2,7 +2,7 @@ comment: Collect server configurations and save that into a table field. commonfields: id: HealthCheckServerConfiguration version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: HealthCheckServerConfiguration outputs: diff --git a/Packs/HealthCheck/Scripts/HealthCheckServerLog/HealthCheckServerLog.yml b/Packs/HealthCheck/Scripts/HealthCheckServerLog/HealthCheckServerLog.yml index f028c868c172..91eebdf15f19 100644 --- a/Packs/HealthCheck/Scripts/HealthCheckServerLog/HealthCheckServerLog.yml +++ b/Packs/HealthCheck/Scripts/HealthCheckServerLog/HealthCheckServerLog.yml @@ -6,7 +6,7 @@ comment: Read server log file line by line and display warnings, fatal errors an commonfields: id: HealthCheckServerLog version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: HealthCheckServerLog runas: DBotWeakRole diff --git a/Packs/HealthCheck/Scripts/HealthCheckSystemDiagnostics/HealthCheckSystemDiagnostics.yml b/Packs/HealthCheck/Scripts/HealthCheckSystemDiagnostics/HealthCheckSystemDiagnostics.yml index 156bb7b47b13..305ae965e6e2 100644 --- a/Packs/HealthCheck/Scripts/HealthCheckSystemDiagnostics/HealthCheckSystemDiagnostics.yml +++ b/Packs/HealthCheck/Scripts/HealthCheckSystemDiagnostics/HealthCheckSystemDiagnostics.yml @@ -2,7 +2,7 @@ comment: Collect data from System Diagnostics tool. commonfields: id: HealthCheckSystemDiagnostics version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: HealthCheckSystemDiagnostics runas: DBotWeakRole diff --git a/Packs/HealthCheck/Scripts/HealthCheckUnpack/HealthCheckUnpack.yml b/Packs/HealthCheck/Scripts/HealthCheckUnpack/HealthCheckUnpack.yml index 814fd2fc6bce..45de5adeb84f 100644 --- a/Packs/HealthCheck/Scripts/HealthCheckUnpack/HealthCheckUnpack.yml +++ b/Packs/HealthCheck/Scripts/HealthCheckUnpack/HealthCheckUnpack.yml @@ -6,7 +6,7 @@ comment: "Extract files from log bundle - supports tar.gz & tar \n\nhandle unsup commonfields: id: HealthCheckUnpack version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: HealthCheckUnpack outputs: diff --git a/Packs/HealthCheck/Scripts/HealthCheckWorkers/HealthCheckWorkers.yml b/Packs/HealthCheck/Scripts/HealthCheckWorkers/HealthCheckWorkers.yml index 4c35693da546..53cc9362ed5f 100644 --- a/Packs/HealthCheck/Scripts/HealthCheckWorkers/HealthCheckWorkers.yml +++ b/Packs/HealthCheck/Scripts/HealthCheckWorkers/HealthCheckWorkers.yml @@ -10,7 +10,7 @@ comment: Present or analyze workers usage. commonfields: id: HealthCheckWorkers version: -1 -dockerimage: demisto/python3:3.12.13.8428455 +dockerimage: demisto/python3:3.12.13.11879924 enabled: true name: HealthCheckWorkers outputs: diff --git a/Packs/HealthCheck/pack_metadata.json b/Packs/HealthCheck/pack_metadata.json index 221b40101a28..2fa33bbe43b3 100644 --- a/Packs/HealthCheck/pack_metadata.json +++ b/Packs/HealthCheck/pack_metadata.json @@ -2,7 +2,7 @@ "name": "System Diagnostics and Health Check", "description": "CS Health Check", "support": "community", - "currentVersion": "3.1.4", + "currentVersion": "3.1.5", "author": "Cortex XSOAR Customer Success", "url": "https://live.paloaltonetworks.com/t5/cortex-xsoar-discussions/bd-p/Cortex_XSOAR_Discussions", "email": "", diff --git a/Packs/MicrosoftDefenderAdvancedThreatProtection/Integrations/MicrosoftDefenderAdvancedThreatProtection/MicrosoftDefenderAdvancedThreatProtection.yml b/Packs/MicrosoftDefenderAdvancedThreatProtection/Integrations/MicrosoftDefenderAdvancedThreatProtection/MicrosoftDefenderAdvancedThreatProtection.yml index 4ab9a0274c7f..2f10fc133c11 100644 --- a/Packs/MicrosoftDefenderAdvancedThreatProtection/Integrations/MicrosoftDefenderAdvancedThreatProtection/MicrosoftDefenderAdvancedThreatProtection.yml +++ b/Packs/MicrosoftDefenderAdvancedThreatProtection/Integrations/MicrosoftDefenderAdvancedThreatProtection/MicrosoftDefenderAdvancedThreatProtection.yml @@ -5926,7 +5926,7 @@ script: - contextPath: MicrosoftATP.PublicVulnerability.UpdatedOn description: The date and time when this vulnerability was last updated. type: String - dockerimage: demisto/crypto:1.0.0.7704170 + dockerimage: demisto/crypto:1.0.0.11658507 isfetch: true runonce: false script: '-' diff --git a/Packs/MicrosoftDefenderAdvancedThreatProtection/ReleaseNotes/1_20_44.md b/Packs/MicrosoftDefenderAdvancedThreatProtection/ReleaseNotes/1_20_44.md new file mode 100644 index 000000000000..0a070fcc0cd2 --- /dev/null +++ b/Packs/MicrosoftDefenderAdvancedThreatProtection/ReleaseNotes/1_20_44.md @@ -0,0 +1,7 @@ + +#### Integrations + +##### Microsoft Defender for Endpoint + +- Updated the Docker image to: *demisto/crypto:1.0.0.11658507*. + diff --git a/Packs/MicrosoftDefenderAdvancedThreatProtection/pack_metadata.json b/Packs/MicrosoftDefenderAdvancedThreatProtection/pack_metadata.json index afc38b1c7178..791c26483ae2 100644 --- a/Packs/MicrosoftDefenderAdvancedThreatProtection/pack_metadata.json +++ b/Packs/MicrosoftDefenderAdvancedThreatProtection/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Microsoft Defender for Endpoint", "description": "Microsoft Defender for Endpoint (previously Microsoft Defender Advanced Threat Protection (ATP)) is a unified platform for preventative protection, post-breach detection, automated investigation, and response.", "support": "xsoar", - "currentVersion": "1.20.43", + "currentVersion": "1.20.44", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/Whois/Integrations/Whois/Whois.yml b/Packs/Whois/Integrations/Whois/Whois.yml index 779b49805c2a..9c25cc0d0f4d 100644 --- a/Packs/Whois/Integrations/Whois/Whois.yml +++ b/Packs/Whois/Integrations/Whois/Whois.yml @@ -1451,7 +1451,7 @@ script: - contextPath: DBotScore.Reliability description: Reliability of the source providing the intelligence data. type: String - dockerimage: demisto/ippysocks-py3:1.0.0.9067966 + dockerimage: demisto/ippysocks-py3:1.0.0.11195141 runonce: false script: '-' subtype: python3 diff --git a/Packs/Whois/ReleaseNotes/1_5_44.md b/Packs/Whois/ReleaseNotes/1_5_44.md new file mode 100644 index 000000000000..51e31b79b784 --- /dev/null +++ b/Packs/Whois/ReleaseNotes/1_5_44.md @@ -0,0 +1,7 @@ + +#### Integrations + +##### Whois + +- Updated the Docker image to: *demisto/ippysocks-py3:1.0.0.11195141*. + diff --git a/Packs/Whois/pack_metadata.json b/Packs/Whois/pack_metadata.json index 820d01b340e5..5685d3350836 100644 --- a/Packs/Whois/pack_metadata.json +++ b/Packs/Whois/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Whois", "description": "This Content Pack helps you run Whois commands as playbook tasks or real-time actions within Cortex XSOAR to obtain valuable domain metadata.", "support": "xsoar", - "currentVersion": "1.5.43", + "currentVersion": "1.5.44", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 225d61beeb4000a3236c8bf39e2db3892cab446d Mon Sep 17 00:00:00 2001 From: Content Bot <55035720+content-bot@users.noreply.github.com> Date: Wed, 19 Aug 2026 12:30:45 +0300 Subject: [PATCH 016/419] [AUD Isolation] MicrosoftGraphUser - from 2026-08-18 (#45560) * Updated Docker Images for MicrosoftGraphUser. * Updated Release Notes. * add ignore --------- Co-authored-by: content-bot Co-authored-by: Adi --- Packs/MicrosoftGraphUser/.secrets-ignore | 4 +++- .../Integrations/MicrosoftGraphUser/MicrosoftGraphUser.yml | 2 +- Packs/MicrosoftGraphUser/ReleaseNotes/1_7_8.md | 7 +++++++ Packs/MicrosoftGraphUser/pack_metadata.json | 2 +- 4 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 Packs/MicrosoftGraphUser/ReleaseNotes/1_7_8.md diff --git a/Packs/MicrosoftGraphUser/.secrets-ignore b/Packs/MicrosoftGraphUser/.secrets-ignore index 2f3f3002d995..b4a99570907d 100644 --- a/Packs/MicrosoftGraphUser/.secrets-ignore +++ b/Packs/MicrosoftGraphUser/.secrets-ignore @@ -11,4 +11,6 @@ MSGraphUserDirectReports.Reports.@Odata.Type MSGraphUserManager.Manager.@Odata.Type test2@test2.com https://portal.azure.com -https://adnotifications.windowsazure.com \ No newline at end of file +https://adnotifications.windowsazure.com +MSGraphUserGroups.Groups.@Odata.Type +MSGraphUserAuthMethods.Methods.@Odata.Type \ No newline at end of file diff --git a/Packs/MicrosoftGraphUser/Integrations/MicrosoftGraphUser/MicrosoftGraphUser.yml b/Packs/MicrosoftGraphUser/Integrations/MicrosoftGraphUser/MicrosoftGraphUser.yml index de702fa66b25..9f1519267b12 100644 --- a/Packs/MicrosoftGraphUser/Integrations/MicrosoftGraphUser/MicrosoftGraphUser.yml +++ b/Packs/MicrosoftGraphUser/Integrations/MicrosoftGraphUser/MicrosoftGraphUser.yml @@ -1355,7 +1355,7 @@ script: - contextPath: MSGraphUser.MFAAccessToken.AccessToken description: The access token value. type: String - dockerimage: demisto/crypto:1.0.0.6932158 + dockerimage: demisto/crypto:1.0.0.11658507 runonce: false script: '-' subtype: python3 diff --git a/Packs/MicrosoftGraphUser/ReleaseNotes/1_7_8.md b/Packs/MicrosoftGraphUser/ReleaseNotes/1_7_8.md new file mode 100644 index 000000000000..69b224b72743 --- /dev/null +++ b/Packs/MicrosoftGraphUser/ReleaseNotes/1_7_8.md @@ -0,0 +1,7 @@ + +#### Integrations + +##### Entra ID Users + +- Updated the Docker image to: *demisto/crypto:1.0.0.11658507*. + diff --git a/Packs/MicrosoftGraphUser/pack_metadata.json b/Packs/MicrosoftGraphUser/pack_metadata.json index 21a04ec9d3b5..734eeaa4b3fb 100644 --- a/Packs/MicrosoftGraphUser/pack_metadata.json +++ b/Packs/MicrosoftGraphUser/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Microsoft Graph User", "description": "Use the Microsoft Graph integration to connect to and interact with user objects on Microsoft Platforms.", "support": "xsoar", - "currentVersion": "1.7.7", + "currentVersion": "1.7.8", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 4ea59755c17629c905dee927aa13a7f38cf0d5c9 Mon Sep 17 00:00:00 2001 From: dtroushinsky Date: Wed, 19 Aug 2026 12:54:07 +0300 Subject: [PATCH 017/419] Orca Event Collector: fix event pagination and cursor handling, add _ENTRY_STATUS field (#45415) * Orca Event Collector: fix pagination and cursor wedge, add _ENTRY_STATUS field * fix validations * Update Packs/Orca/ReleaseNotes/3_1_0.md Co-authored-by: Marketplace AI reviewer * address review: safe_parse_datetime helper, traceback logging, bracketed log prefixes, info-level fetch summary, default first_fetch to 1 minute * address review comments * fix docker image release note entry --------- Co-authored-by: Marketplace AI reviewer --- .../OrcaEventCollector/OrcaEventCollector.py | 505 +++++++++-- .../OrcaEventCollector/OrcaEventCollector.yml | 28 +- .../OrcaEventCollector_test.py | 846 +++++++++++++++--- Packs/Orca/ReleaseNotes/3_1_0.md | 11 + Packs/Orca/pack_metadata.json | 12 +- 5 files changed, 1160 insertions(+), 242 deletions(-) create mode 100644 Packs/Orca/ReleaseNotes/3_1_0.md diff --git a/Packs/Orca/Integrations/OrcaEventCollector/OrcaEventCollector.py b/Packs/Orca/Integrations/OrcaEventCollector/OrcaEventCollector.py index cb3c1d7ec40f..01022b6ba6eb 100644 --- a/Packs/Orca/Integrations/OrcaEventCollector/OrcaEventCollector.py +++ b/Packs/Orca/Integrations/OrcaEventCollector/OrcaEventCollector.py @@ -12,6 +12,10 @@ DATE_FORMAT = "%Y-%m-%dT%H:%M:%SZ" # ISO8601 format with UTC, default in XSOAR VENDOR = "orca" PRODUCT = "security" +DEFAULT_PAGE_SIZE = 100 # Serving Layer API default page size (SQL LIMIT) +TEST_MODULE_LIMIT = 1 # Minimal page size for the connectivity test +DEFAULT_GET_EVENTS_LIMIT = 1000 # Fallback cap for the manual get-events command +DEFAULT_GET_EVENTS_START = "1 minute" # Fallback lower bound for the manual get-events command """ CLIENT CLASS """ @@ -20,28 +24,31 @@ class Client(BaseClient): def __init__(self, server_url: str, headers: dict, proxy: bool = False, verify: bool = False): super().__init__(base_url=server_url, verify=verify, proxy=proxy, headers=headers) - def get_alerts_request(self, max_fetch: int, last_fetch: str, next_page_token: Optional[str]) -> dict: - """Retrieve information about alerts using the new Serving Layer API. + def get_alerts_request(self, page_size: int, start_index: int, last_fetch: str, end_time: str) -> dict: + """Retrieve a single page of alerts using the Serving Layer API. + + The Serving Layer API uses offset-based pagination: ``start_at_index`` is a plain + 0-based SQL OFFSET (not a cursor/token) and ``limit`` maps to SQL LIMIT. The caller + is responsible for advancing ``start_index`` between pages and detecting the end of + results (a page returning fewer rows than ``page_size`` or an empty ``data`` array). + + Events are filtered and ordered by ``LastUpdated`` (the sync timestamp), which is + monotonic under Orca's eventual consistency - unlike ``CreatedAt``. The window is + two-sided: ``LastUpdated >= last_fetch AND LastUpdated < end_time``. The ``end_time`` + upper bound is fixed at the start of the run so events synced mid-run are not + half-fetched (they are picked up whole on the next run). ``gte``/``lt`` operators are + used without ``value_type`` for second-level precision (per Orca guidance). + Args: - max_fetch: int - Limit number of returned records. - last_fetch: str - The date and time of the last fetch. - **MUST be a valid ISO 8601 string (e.g., "2023-10-27T10:00:00Z" or "2023-10-27T10:00:00+00:00").** + page_size: int - Maximum number of records to return in this page (SQL LIMIT). + start_index: int - 0-based offset for this page (SQL OFFSET). + last_fetch: str - Inclusive lower bound for ``LastUpdated`` (ISO 8601). + **MUST be a valid ISO 8601 string (e.g., "2023-10-27T10:00:00Z").** The API is very strict about this format. - next_page_token: Optional[str] - The token for the next page, used as start_at_index. + end_time: str - Exclusive upper bound for ``LastUpdated`` (ISO 8601), fixed at run start. Returns: - A dictionary with the alerts details. + A dictionary with the alerts details (keys: ``status``, ``data``, ``from_cache``). """ - - start_index = 0 - if next_page_token: - try: - start_index = int(next_page_token) - except ValueError: - demisto.info( - f"Invalid next_page_token (expected integer for start_at_index): {next_page_token}. Defaulting to 0." - ) - start_index = 0 - payload = { "query": { "models": ["Alert"], @@ -51,18 +58,23 @@ def get_alerts_request(self, max_fetch: int, last_fetch: str, next_page_token: O "operator": "and", "values": [ { - "key": "CreatedAt", + "key": "LastUpdated", "values": [last_fetch], "type": "datetime", - "operator": "date_gte", - "value_type": "days", - } + "operator": "gte", + }, + { + "key": "LastUpdated", + "values": [end_time], + "type": "datetime", + "operator": "lt", + }, ], }, }, - "limit": max_fetch, + "limit": page_size, "start_at_index": start_index, - "order_by[]": ["CreatedAt"], + "order_by[]": ["LastUpdated"], "select": [ "AlertId", "AlertType", @@ -77,12 +89,13 @@ def get_alerts_request(self, max_fetch: int, last_fetch: str, next_page_token: O "Source", "Status", "CreatedAt", + "LastUpdated", "LastSeen", "Labels", ], } - demisto.debug(f"In get_alerts (Serving Layer API) request payload: {json.dumps(payload)}") + demisto.debug(f"[Client] get_alerts (Serving Layer API) request payload: {json.dumps(payload)}") return self._http_request(method="POST", url_suffix="/serving-layer/query", json_data=payload) @@ -90,11 +103,33 @@ def get_alerts_request(self, max_fetch: int, last_fetch: str, next_page_token: O """ HELPER FUNCTIONS """ +def safe_parse_datetime(raw_value: Optional[str], field_name: str = "timestamp", context: str = "") -> Optional[datetime]: + """Parse ``raw_value`` with ``arg_to_datetime``, returning ``None`` if missing/unparseable. + + ``arg_to_datetime`` raises on unparseable input; this wrapper catches that and logs the full + traceback so callers never crash on a single bad timestamp. + """ + if not raw_value: + return None + try: + return arg_to_datetime(arg=raw_value) + except Exception as e: + demisto.debug( + f"[safe_parse_datetime] arg_to_datetime failed parsing '{field_name}'{f' for {context}' if context else ''} " + f"with value '{raw_value}'. Error: {e}\n{traceback.format_exc()}" + ) + return None + + def add_time_key_to_alerts(alerts: List[Dict[str, Any]]) -> List[Dict[str, Any]]: """ Adds the _time key to the alerts with improved logging and clarity. This function mutates the 'alerts' list in place and also returns it. + ``_time`` is set from the alert's ``LastUpdated`` (the sync timestamp), so updated alerts + re-land in XSIAM at their update time. If ``LastUpdated`` is missing/unparseable, we fall + back to ``CreatedAt``, and finally to the current time. + Args: alerts: A list of alert dictionaries to process. @@ -109,29 +144,65 @@ def add_time_key_to_alerts(alerts: List[Dict[str, Any]]) -> List[Dict[str, Any]] for alert in alerts: alert_data = alert.get("data", {}) - create_time_str = alert_data.get("CreatedAt", {}).get("value") alert_id = alert_data.get("AlertId", {}).get("value") or alert.get("id", "UNKNOWN_ID") - create_time = None - if create_time_str: - try: - create_time = arg_to_datetime(arg=create_time_str) - except Exception as e: - demisto.error( - f"arg_to_datetime failed unexpectedly while parsing for AlertId: {alert_id} " - f"with value '{create_time_str}', setting fallback time {now_utc}. Error: {e}" - ) - create_time = now_utc - - if create_time: - alert["_time"] = create_time.strftime(DATE_FORMAT) + last_updated_str = alert_data.get("LastUpdated", {}).get("value") + create_time_str = alert_data.get("CreatedAt", {}).get("value") + + # Prefer LastUpdated (sync time); fall back to CreatedAt if it is missing/unparseable. + event_time = None + for field_name, raw_value in (("LastUpdated", last_updated_str), ("CreatedAt", create_time_str)): + event_time = safe_parse_datetime(raw_value, field_name, f"AlertId: {alert_id}") + if event_time: + break + + if event_time: + alert["_time"] = event_time.strftime(DATE_FORMAT) else: demisto.info( - f"Could not parse or find 'CreatedAt' value for AlertId: {alert_id}. " - f"Raw 'CreatedAt' value was: '{create_time_str}'. Setting '_time' to {fallback_time_str}." + f"[add_time_key_to_alerts] Could not parse or find 'LastUpdated'/'CreatedAt' value for AlertId: {alert_id}. " + f"Raw values were LastUpdated='{last_updated_str}', CreatedAt='{create_time_str}'. " + f"Setting '_time' to {fallback_time_str}." ) alert["_time"] = fallback_time_str - demisto.debug(f"Processed AlertId: {alert_id}, final _time: {alert.get('_time')}") + demisto.debug(f"[add_time_key_to_alerts] Processed AlertId: {alert_id}, final _time: {alert.get('_time')}") + + return alerts + + +def add_entry_status_to_alerts(alerts: List[Dict[str, Any]]) -> List[Dict[str, Any]]: + """ + Adds the ``_ENTRY_STATUS`` key to each alert, classifying whether it is new or updated. + This function mutates the 'alerts' list in place and also returns it. + + Logic: + - "new" when ``LastUpdated`` == ``CreatedAt`` (never modified since creation), + or when either timestamp is missing/unparseable (safe default). + - "updated" when ``LastUpdated`` > ``CreatedAt`` (modified after creation). + + Args: + alerts: A list of alert dictionaries to process. + + Returns: + The mutated list of alerts, now including the '_ENTRY_STATUS' key. + """ + if not alerts: + return alerts + + for alert in alerts: + alert_data = alert.get("data", {}) + alert_id = alert_data.get("AlertId", {}).get("value") or alert.get("id", "UNKNOWN_ID") + created_time = safe_parse_datetime(alert_data.get("CreatedAt", {}).get("value"), "CreatedAt", f"AlertId: {alert_id}") + last_updated_time = safe_parse_datetime( + alert_data.get("LastUpdated", {}).get("value"), "LastUpdated", f"AlertId: {alert_id}" + ) + + if created_time and last_updated_time and last_updated_time > created_time: + alert["_ENTRY_STATUS"] = "updated" + else: + alert["_ENTRY_STATUS"] = "new" + + demisto.debug(f"[add_entry_status_to_alerts] Processed AlertId: {alert_id}, _ENTRY_STATUS: {alert.get('_ENTRY_STATUS')}") return alerts @@ -139,17 +210,17 @@ def add_time_key_to_alerts(alerts: List[Dict[str, Any]]) -> List[Dict[str, Any]] """ COMMAND FUNCTIONS """ -def orca_test_module(client: Client, last_fetch: str, max_fetch: int) -> str: +def orca_test_module(client: Client, last_fetch: str, end_time: str) -> str: """Test the connection to Orca Security. Args: client: client - An Orca client. - last_fetch: str - The time and date of the last fetch alert - max_fetch: int - The maximum number of events per fetch + last_fetch: str - The time and date of the last fetch alert. + end_time: str - The exclusive upper bound for the fetch window (run start). Returns: 'ok' if the connection was successful, else throws exception. """ try: - client.get_alerts_request(max_fetch, last_fetch, None) + client.get_alerts_request(TEST_MODULE_LIMIT, 0, last_fetch, end_time) return "ok" except DemistoException as e: if "Error in API call [404] - Not Found" in e.message: @@ -158,32 +229,293 @@ def orca_test_module(client: Client, last_fetch: str, max_fetch: int) -> str: raise Exception(e.message) -def get_alerts(client: Client, max_fetch: int, last_fetch: str, next_page_token: str = None) -> tuple: - """Retrieve information about alerts. +def get_alerts( + client: Client, + max_fetch: int, + last_fetch: str, + end_time: str, + start_offset: int = 0, + page_size: int = DEFAULT_PAGE_SIZE, +) -> list: + """Retrieve alerts, paginating through all available pages for the given window. + + The Serving Layer API is offset-based: there is no next-page token. We start at + ``start_at_index`` = ``start_offset`` and, after each page, advance the offset by the number + of rows actually returned (not blindly by ``page_size``). Pagination stops when a page returns + fewer rows than ``page_size`` (or an empty ``data`` array) - the normal end-of-results + signal - or when we reach ``max_fetch`` total events for this run. + + ``start_offset`` lets the caller resume mid-second: when a single ``LastUpdated`` second holds + more events than ``max_fetch``, one run cannot consume the whole second, so the cursor timestamp + cannot advance. To avoid wedging the collector on that second WITHOUT exceeding ``max_fetch``, + the caller persists how many boundary-second events were already consumed (``lastRunOffset``) + and passes it here so the next run continues where the previous one stopped. + + The fetch window is two-sided on ``LastUpdated``: ``>= last_fetch AND < end_time``. + Args: client: client - An Orca client. - max_fetch: int - The maximum number of events per fetch - last_fetch: str - The time and date of the last fetch alert - next_page_token: str - The token to the next page. + max_fetch: int - The maximum number of events to collect in this run (across all pages). + last_fetch: str - Inclusive lower bound for ``LastUpdated``. + end_time: str - Exclusive upper bound for ``LastUpdated`` (fixed at run start). + start_offset: int - SQL OFFSET to start from (resume point within the boundary second). + page_size: int - The maximum number of events to request per page. Returns: - - list of alerts - - next_page_token if exist + A list of alerts (at most ``max_fetch`` items). """ - response = client.get_alerts_request(max_fetch, last_fetch, next_page_token) - next_page_token = response.get("next_page_token", None) - alerts = response.get("data", []) - demisto.debug(f"Get Alerts Response {next_page_token=} , {len(alerts)=}\n {alerts=}") - return alerts, next_page_token + alerts: list = [] + start_index = start_offset + pages_fetched = 0 + + while len(alerts) < max_fetch: + # Don't request more than we still need for this run. + current_page_size = min(page_size, max_fetch - len(alerts)) + response = client.get_alerts_request(current_page_size, start_index, last_fetch, end_time) + page = response.get("data", []) + demisto.debug(f"[get_alerts] page: {start_index=} , {current_page_size=} , returned={len(page)}") + + if not page: + # Empty page - no more results. + break + + pages_fetched += 1 + alerts.extend(page) + # Advance the SQL OFFSET by the number of rows actually returned. + start_index += len(page) + + if len(page) < current_page_size: + # Short page - this was the last page of results. + break + + # Summary line: confirms pagination is looping (vs the old single-page behavior). + demisto.info(f"[get_alerts] summary: fetched {len(alerts)} event(s) across {pages_fetched} page(s) from {start_offset=}") + # If we stopped because we hit max_fetch (rather than exhausting the window), a backlog + # remains for the next run. This is the key signal to watch during the tenant catch-up: + # it means the window still has more events than max_fetch could carry this cycle. + if len(alerts) >= max_fetch: + demisto.info( + f"[get_alerts] reached max_fetch cap ({max_fetch}); more events remain in the window " + f"[LastUpdated >= {last_fetch} AND < {end_time}]. They will be collected on the next run." + ) + return alerts + + +def normalize_last_updated(raw_value: Optional[str]) -> Optional[str]: + """Normalize a ``LastUpdated`` string to ``DATE_FORMAT`` (``...Z``). + + The API returns ``+00:00`` offsets while the persisted cursor uses ``...Z``; both + boundary comparisons (dedup_alerts, get_boundary_ids) must normalize both sides so + the same instant compares equal. Returns ``None`` if missing/unparseable. + """ + parsed = safe_parse_datetime(raw_value, "LastUpdated") + return parsed.strftime(DATE_FORMAT) if parsed else None + + +def add_one_second(cursor: str) -> str: + """Return ``cursor`` advanced by one second, in ``DATE_FORMAT`` (``cursor`` if unparseable). + + Steps the cursor past a drained boundary second so the inclusive lower bound does not + re-read it. Safe because every event at that second was already fetched via the offset walk. + """ + parsed = safe_parse_datetime(cursor, "cursor") + if not parsed: + return cursor + return (parsed + timedelta(seconds=1)).strftime(DATE_FORMAT) + + +def dedup_alerts(alerts: List[Dict[str, Any]], seen_ids: List[str], boundary_time: Optional[str]) -> List[Dict[str, Any]]: + """Remove alerts already returned at the previous window's upper boundary. + + Because the lower bound is inclusive (``LastUpdated >= last_fetch``), any alert whose + ``LastUpdated`` equals the previous run's boundary second would be re-fetched. We drop + exactly those alerts whose ``AlertId`` was already emitted at that boundary second. + + Timestamps are normalized via :func:`normalize_last_updated` before comparison so that + the API's ``+00:00`` form matches the persisted ``...Z`` cursor. + + Args: + alerts: Alerts fetched this run (ordered by ``LastUpdated`` ascending). + seen_ids: AlertIds emitted at ``boundary_time`` on the previous run. + boundary_time: The previous run's boundary ``LastUpdated`` value (== this run's ``last_fetch``). + Returns: + The alerts list with boundary-second duplicates removed. + """ + if not alerts or not seen_ids or not boundary_time: + return alerts + + normalized_boundary = normalize_last_updated(boundary_time) + seen = set(seen_ids) + deduped = [ + alert + for alert in alerts + if not ( + normalize_last_updated(alert.get("data", {}).get("LastUpdated", {}).get("value")) == normalized_boundary + and alert.get("data", {}).get("AlertId", {}).get("value") in seen + ) + ] + demisto.debug(f"[dedup_alerts] removed {len(alerts) - len(deduped)} boundary duplicate(s) at {normalized_boundary}") + return deduped + + +def get_boundary_ids(alerts: List[Dict[str, Any]], boundary_time: str) -> List[str]: + """Collect AlertIds whose ``LastUpdated`` equals the given boundary second. + + These IDs are persisted so the next run can skip them (see :func:`dedup_alerts`). + Timestamps are normalized via :func:`normalize_last_updated` before comparison so that + the API's ``+00:00`` form matches the persisted ``...Z`` cursor - without this the list + comes back empty and the cursor stalls on the boundary second. + + Args: + alerts: Alerts emitted this run. + boundary_time: The newest ``LastUpdated`` value (this run's boundary). + Returns: + A list of AlertIds sharing ``boundary_time`` as their ``LastUpdated``. + """ + normalized_boundary = normalize_last_updated(boundary_time) + return [ + alert_id + for alert in alerts + if normalize_last_updated(alert.get("data", {}).get("LastUpdated", {}).get("value")) == normalized_boundary + and (alert_id := alert.get("data", {}).get("AlertId", {}).get("value")) + ] """ MAIN FUNCTION """ +def fetch_events( + client: Client, + start_time: str, + last_run_ids: list, + last_run_offset: int, + max_fetch: int, + end_time: str, +) -> None: + """Scheduled fetch: pull alerts, dedup, push to XSIAM, and advance the persisted cursor. + + ``start_time`` is the persisted cursor (inclusive lower bound on ``LastUpdated``) from the + previous run's ``lastRun``. + """ + # Explicit fetch window for this run (lower inclusive -> upper exclusive), for diagnostics. + demisto.debug(f"[Fetch Events] Fetch window: LastUpdated >= {start_time} AND < {end_time} ({max_fetch=} {last_run_offset=})") + alerts = get_alerts(client, max_fetch, start_time, end_time, start_offset=last_run_offset) + # Capture the RAW page size and newest timestamp BEFORE dedup: the wedge guard must key + # off these, since dedup can empty a full page and hide the "full page, same second" signal. + raw_fetched_count = len(alerts) + newest_before_dedup = alerts[-1].get("data", {}).get("LastUpdated", {}).get("value") if alerts else None + + # Drop alerts already emitted at the previous run's boundary second (inclusive lower bound). + alerts = dedup_alerts(alerts, last_run_ids, start_time) + + if alerts: + alerts = add_time_key_to_alerts(alerts) + alerts = add_entry_status_to_alerts(alerts) + # Distribution of new vs updated: proves the LastUpdated cursor now captures updates. + updated_count = sum(1 for alert in alerts if alert.get("_ENTRY_STATUS") == "updated") + demisto.debug( + f"[Fetch Events] Entry status distribution: new={len(alerts) - updated_count}, " + f"updated={updated_count}, total={len(alerts)}" + ) + demisto.debug(f"[Fetch Events] before send_events_to_xsiam {VENDOR=} {PRODUCT=} {alerts=}") + send_events_to_xsiam(alerts, VENDOR, PRODUCT) + demisto.debug(f"[Fetch Events] after send_events_to_xsiam {VENDOR=} {PRODUCT=} {alerts=}") + + # Advance the cursor using the newest RAW timestamp (dedup may have emptied the list). + new_last_fetch = normalize_last_updated(newest_before_dedup) or start_time + page_was_full = raw_fetched_count == max_fetch + same_second = new_last_fetch == normalize_last_updated(start_time) + + if raw_fetched_count == 0 and last_run_offset > 0: + # Drained-second terminator: an empty page while resuming at a non-zero offset proves + # the boundary second is fully consumed. Step the cursor +1s and clear the offset so + # the inclusive lower bound does not re-read it forever (infinite duplicate loop). + new_last_fetch = add_one_second(start_time) + new_last_run_offset = 0 + new_last_run_ids: list[str] = [] + demisto.info( + f"[Fetch Events] Boundary second {start_time} fully drained (empty page at offset " + f"{last_run_offset}); stepping cursor to {new_last_fetch} and resetting offset." + ) + elif page_was_full and same_second: + # Wedge guard: a full raw page still on the same second means that second holds more + # than max_fetch events. Keep the timestamp but advance an in-second offset so the + # next run reads the next slice. + new_last_run_offset = last_run_offset + raw_fetched_count + # Same second: accumulate (union) ids so earlier slices aren't lost when the offset resets. + current_ids = get_boundary_ids(alerts, new_last_fetch) if alerts else [] + new_last_run_ids = list(set(last_run_ids + current_ids)) + demisto.info( + f"[Fetch Events] Boundary second {new_last_fetch} not fully drained; advancing lastRunOffset " + f"to {new_last_run_offset} (max_fetch={max_fetch})" + ) + else: + # Normal path: page not full or crossed into a newer second. Reset the offset. + new_last_run_offset = 0 + current_ids = get_boundary_ids(alerts, new_last_fetch) if alerts else [] + if same_second: + # Offset reset while still on the same second: union so accumulated ids survive the reset. + new_last_run_ids = list(set(last_run_ids + current_ids)) + else: + # Second advanced: only the new second's ids matter. + new_last_run_ids = current_ids if alerts else last_run_ids + + current_last_run = { + "lastRun": new_last_fetch, + "lastRunIds": new_last_run_ids, + "lastRunOffset": new_last_run_offset, + } + + demisto.setLastRun(current_last_run) + demisto.debug( + f"[Fetch Events] Persisted lastRun={new_last_fetch} with {len(new_last_run_ids)} boundary id(s), " + f"lastRunOffset={new_last_run_offset}" + ) + demisto.debug(f"[Fetch Events] {current_last_run=}") + + +def get_events_command(client: Client, args: dict) -> None: + """Manual debug command: pull alerts for an explicit window and optionally push them. + + Driven entirely by its own ``start_time`` / ``end_time`` / ``limit`` arguments - it does NOT read + or write the persisted ``lastRun`` cursor, so it is safe to run on demand without disrupting the + scheduled fetch. When an argument is omitted, a sensible default window/cap is used. + """ + start = safe_parse_datetime(args.get("start_time") or DEFAULT_GET_EVENTS_START, "start_time") + start_time = start.strftime(DATE_FORMAT) if start else "" + end = safe_parse_datetime(args.get("end_time"), "end_time") + end_time = end.strftime(DATE_FORMAT) if end else datetime.now(timezone.utc).strftime(DATE_FORMAT) + limit = arg_to_number(args.get("limit")) or DEFAULT_GET_EVENTS_LIMIT + should_push_events = argToBoolean(args.get("should_push_events", False)) + + demisto.debug(f"[Get Events] Fetch window: LastUpdated >= {start_time} AND < {end_time} ({limit=})") + alerts = get_alerts(client, limit, start_time, end_time) + + # Normalize before returning so the CommandResults outputs carry the parsed events (_time / _ENTRY_STATUS). + if alerts: + alerts = add_time_key_to_alerts(alerts) + alerts = add_entry_status_to_alerts(alerts) + + return_results( + CommandResults( + readable_output=tableToMarkdown(t=alerts, name=f"{VENDOR} - {PRODUCT} events", removeNull=True), + outputs_prefix=f"{VENDOR.capitalize()}.Events", + outputs=alerts, + raw_response=alerts, + ) + ) + + if should_push_events and alerts: + demisto.debug(f"[Get Events] before send_events_to_xsiam {VENDOR=} {PRODUCT=} count={len(alerts)}") + send_events_to_xsiam(alerts, VENDOR, PRODUCT) + demisto.debug(f"[Get Events] after send_events_to_xsiam {VENDOR=} {PRODUCT=} count={len(alerts)}") + + def main() -> None: command = demisto.command() api_token = demisto.params().get("credentials", {}).get("password") server_url = f"{demisto.params().get('server_url')}/api" - first_fetch = demisto.params().get("first_fetch") or "3 days" + # Event Collectors default to now - 1 minute when no first_fetch is configured. + first_fetch = demisto.params().get("first_fetch") or "1 minute" max_fetch = arg_to_number(demisto.params().get("max_fetch")) or 1000 verify_certificate = not demisto.params().get("insecure", False) proxy = demisto.params().get("proxy", False) @@ -191,8 +523,10 @@ def main() -> None: # How much time before the first fetch to retrieve events first_fetch_time = arg_to_datetime(arg=first_fetch, arg_name="First fetch time", required=True) first_fetch_time = first_fetch_time.strftime(DATE_FORMAT) if first_fetch_time else "" - demisto.debug(f"{first_fetch_time=}") - demisto.info(f"Orca Security. Command being called is {command}") + # Fixed exclusive upper bound for this run, so events synced mid-run aren't half-fetched. + end_time = datetime.now(timezone.utc).strftime(DATE_FORMAT) + demisto.debug(f"[Main] {first_fetch_time=} {end_time=}") + demisto.info(f"[Main] Orca Security. Command being called is {command}") try: headers: dict = {"Authorization": f"Token {api_token}"} @@ -200,47 +534,24 @@ def main() -> None: last_run = demisto.getLastRun() if not last_run: - demisto.debug(f"first run {last_run=}") + demisto.debug(f"[Fetch Events] first run {last_run=}") last_fetch = first_fetch_time + last_run_ids: list = [] + last_run_offset = 0 else: last_fetch = last_run.get("lastRun") - demisto.debug(f"Isn't the first run {last_fetch}") - next_page_token = last_run.get("next_page_token") + last_run_ids = last_run.get("lastRunIds", []) + # In-second resume point: how many events at the boundary second were already consumed. + # Non-zero only when a single LastUpdated second holds more events than max_fetch. + last_run_offset = last_run.get("lastRunOffset", 0) + demisto.debug(f"[Fetch Events] Isn't the first run {last_fetch=} {last_run_ids=} {last_run_offset=}") if command == "test-module": - return_results(orca_test_module(client, last_fetch, 3)) - elif command in ("fetch-events", "orca-security-get-events"): - alerts, next_page_token = get_alerts(client, max_fetch, last_fetch, next_page_token) - - if command == "fetch-events": - should_push_events = True - - else: # command == 'orca-security-get-events' - should_push_events = argToBoolean(demisto.args().get("should_push_events", False)) - return_results( - CommandResults( - readable_output=tableToMarkdown(t=alerts, name=f"{VENDOR} - {PRODUCT} events", removeNull=True), - raw_response=alerts, - ) - ) - - if should_push_events and alerts: - alerts = add_time_key_to_alerts(alerts) - demisto.debug(f"before send_events_to_xsiam {VENDOR=} {PRODUCT=} {alerts=}") - send_events_to_xsiam(alerts, VENDOR, PRODUCT) - demisto.debug(f"after send_events_to_xsiam {VENDOR=} {PRODUCT=} {alerts=}") - - current_last_run = {"next_page_token": next_page_token} - if next_page_token: - current_last_run["lastRun"] = last_fetch - else: - last_updated_str = alerts[-1].get("data", {}).get("CreatedAt", {}).get("value") if alerts else None - last_updated = arg_to_datetime(arg=last_updated_str) - current_last_run["lastRun"] = last_updated.strftime(DATE_FORMAT) if last_updated else last_fetch - - demisto.setLastRun(current_last_run) - demisto.debug(f"{current_last_run=}") - + return_results(orca_test_module(client, last_fetch, end_time)) + elif command == "fetch-events": + fetch_events(client, last_fetch, last_run_ids, last_run_offset, max_fetch, end_time) + elif command == "orca-security-get-events": + get_events_command(client, demisto.args()) else: raise NotImplementedError("This command is not implemented yet.") diff --git a/Packs/Orca/Integrations/OrcaEventCollector/OrcaEventCollector.yml b/Packs/Orca/Integrations/OrcaEventCollector/OrcaEventCollector.yml index 6815edf13fe2..0e7567bfa9ab 100644 --- a/Packs/Orca/Integrations/OrcaEventCollector/OrcaEventCollector.yml +++ b/Packs/Orca/Integrations/OrcaEventCollector/OrcaEventCollector.yml @@ -24,7 +24,7 @@ configuration: type: 9 section: Connect - name: first_fetch - defaultvalue: 3 days + defaultvalue: 1 minute display: First fetch time (