OpenCTI

Manages OpenCTI platform. Compatible with OpenCTI 4.X API and OpenCTI 5.X API versions.

Data Enrichment & Threat Intelligence · OpenCTI

Details

IDOpenCTI
ProviderFiligran
CategoryData Enrichment & Threat Intelligence
From Version5.0.0
Docker Imagedemisto/vendors-sdk:1.0.0.10120494
Supported ModulesAgentix XSIAM

README

Manages indicators from OpenCTI.
This integration was tested with version 5.12.17 of OpenCTI.

Configure OpenCTI on Cortex XSOAR

  1. Navigate to Settings > Integrations > Servers & Services.
  2. Search for OpenCTI.
  3. Click Add instance to create and configure a new integration instance.

    Parameter Required
    Base URL True
    API Key (leave empty. Fill in the API key in the password field.) False
    Trust any certificate (not secure) False
    Use system proxy settings False
  4. Click Test to validate the URLs, token, and connection.

Commands

You can execute these commands from the Cortex XSOAR CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.

opencti-get-indicators


Get indicators in OpenCTI.

Base Command

opencti-get-indicators

Input

Argument Name Description Required
search The indicator’s value to filter by, can be partial value. Optional
created_by The ID of the entity that created the indicator (use opencti-organization-list to find or create). Optional
creator The ID of the indicator creator. Optional
created_after Created after date filter. Format: YYYY-MM-DDThh:mm:ss.sssZ. Optional
created_before Created before date filter. Format: YYYY-MM-DDThh:mm:ss.sssZ. Optional
valid_until_after Valid until after date filter. Format: YYYY-MM-DDThh:mm:ss.sssZ. Optional
valid_until_before Valid until before date filter. Format: YYYY-MM-DDThh:mm:ss.sssZ. Optional
valid_from_after Valid from after date filter. Format: YYYY-MM-DDThh:mm:ss.sssZ. Optional
valid_from_before Valid from before date filter. Format: YYYY-MM-DDThh:mm:ss.sssZ. Optional
indicator_types The types of the indicator. Use opencti-indicator-types-list to find all indicator types in OpenCTI. Optional
label_id The label ID for the indicator (use opencti-label-list to find or create). Optional
limit The maximum number of indicators to return. Maximum value is 500. Default is 50. Optional
last_run_id The last ID from the previous call, from which to begin pagination for this call. You can find this value at the OpenCTI.Indicators.LastRunID context path. Optional
additional_filters List of filters to apply. Format: [{key: str, operator: str, values: list[str], mode: str}, …]. Optional
all_results When the argument is set to true, the limit argument is ignored. Possible values are: true, false. Default is false. Optional

Context Output

Path Type Description
OpenCTI.Indicators.IndicatorList.id string Unique ID of the indicator.
OpenCTI.Indicators.IndicatorList.name string Name of the indicator.
OpenCTI.Indicators.IndicatorList.description string Description of the indicator.
OpenCTI.Indicators.IndicatorList.pattern string The pattern associated with the indicator.
OpenCTI.Indicators.IndicatorList.validFrom string The valid-from date of the indicator.
OpenCTI.Indicators.IndicatorList.validUntil string The valid-until date of the indicator.
OpenCTI.Indicators.IndicatorList.score number Score of the indicator.
OpenCTI.Indicators.IndicatorList.confidence number Confidence of the indicator.
OpenCTI.Indicators.IndicatorList.createdBy string Name of the entity that created the indicator.
OpenCTI.Indicators.IndicatorList.creators list Name of the indicator creators.
OpenCTI.Indicators.IndicatorList.labels list Labels associated with the indicator.
OpenCTI.Indicators.IndicatorList.indicatorTypes list Types of the indicator.
OpenCTI.Indicators.IndicatorList.created string Creation date of the indicator.
OpenCTI.Indicators.IndicatorList.updatedAt string Last update date of the indicator.
OpenCTI.Indicators.LastRunID string The last ID of the previous fetch for pagination.

opencti-indicator-delete


Delete indicator.

Base Command

opencti-indicator-delete

Input

Argument Name Description Required
id Indicator ID. Required

Context Output

There is no context output for this command.

Command Example

!opencti-indicator-delete id=74faf2e8-bbab-4a1a-a548-58db202c5e57

Human Readable Output

Indicator deleted.

opencti-indicator-field-update


Update the indicator field. The fields that can be updated are: score, description.

Base Command

opencti-indicator-field-update

Input

Argument Name Description Required
id Indicator ID. Required
field Indicator field to update. Possible values are: score, description. Required
value Value of the field to update. Required

Context Output

Path Type Description
OpenCTI.Indicator.id String Updated indicator ID.

Command Example

!opencti-indicator-field-update field=score id=81d63245-9ba3-495d-8e78-03b037d71e01 value=100

Context Example

{
    "OpenCTI": {
        "Indicator": {
            "id": "81d63245-9ba3-495d-8e78-03b037d71e01"
        }
    }
}

Human Readable Output

Indicator 81d63245-9ba3-495d-8e78-03b037d71e01 updated successfully.

opencti-indicator-create


Create new indicator.

Base Command

opencti-indicator-create

Input

Argument Name Description Required
type The indicator type to create. Out-of-the-box indicator types supported in XSOAR are: Account, Domain, Email, File-MD5, File-SHA1, File-SHA256, Host, IP, IPV6, Registry Key, and URL. Possible values are: Account, Domain, Email, File-MD5, File-SHA1, File-SHA256, Host, IP, IPv6, Registry Key, URL. Required
created_by Organization ID. Use opencti-organization-list to find all organization IDs in OpenCTI, or use opencti-organization-create to create a new organization ID. Optional
marking_id Indicator marking definition ID. Use opencti-marking-definition-list to find all marking definition IDs in OpenCTI. Optional
label_id Indicator label ID. Use opencti-label-list to find all label IDs in OpenCTI, or use opencti-label-create to create a new label. Optional
external_references_id External references URL. Use opencti-external-reference-create to create a new external reference. Optional
description Indicator description. Optional
score Indicator score. Values range is 0 - 100. Default value is 50. Optional
value Indicator value. Optional

Context Output

Path Type Description
OpenCTI.Indicator.id String New indicator ID.

Command Example

!opencti-indicator-create type=Domain created_by=0c7cb378-64c3-4809-b423-986ac7cecf91 description=test value="TestDomainDocs.com" score=70 label_id=fa57f98e-f2f5-45fd-97f2-bf2c53119044 marking_id=9128e411-c759-4af0-aeb0-b65f12082648

Context Example

{
    "OpenCTI": {
        "Indicator": {
            "id": "7ed5946a-81a2-4490-8be8-06d3633a41fb",
            "type": "Domain",
            "value": "TestDomainDocs.com"
        }
    }
}

Human Readable Output

Indicator created successfully. New Indicator id: 7ed5946a-81a2-4490-8be8-06d3633a41fb

opencti-indicator-field-add


Add a field to the indicator. Fields that can be added are marking definition and label.

Base Command

opencti-indicator-field-add

Input

Argument Name Description Required
id Indicator ID. Required
field Indicator field to add. Possible values are: marking, label. Required
value Value of the field to add. Enter label ID or marking definition ID. Use opencti-label-list to find all label IDs in OpenCTI, or use opencti-label-create to create a new label. Use opencti-marking-definition-list to find all marking definition IDs in OpenCTI. Required

Context Output

There is no context output for this command.

Command Example

!opencti-indicator-field-add id=33bd535b-fa1c-41e2-a6f9-80d82dd29a9b field=label value=07cfae2d-6cc9-42c5-9fd0-32eff8142404

Human Readable Output

Added label successfully.

opencti-indicator-field-remove


Remove indicator field value. Fields which values can be removed are marking definition and label.

Base Command

opencti-indicator-field-remove

Input

Argument Name Description Required
id Indicator ID. Required
field Indicator field to update. Possible values are: marking, label. Required
value Value of the field to remove. Enter label ID or marking definition ID. Use opencti-label-list to find all label IDs in OpenCTI or opencti-marking-definition-list to find all marking definition IDs in OpenCTI. Required

opencti-indicator-create


Create a new indicator in OpenCTI.

Base Command

opencti-indicator-create

Input

Argument Name Description Required
name Name of the indicator. Required
indicator Value of the indicator. Required
main_observable_type Main observable type for the indicator. Possible values are: Account, Domain, Email, File-MD5, File-SHA1, File-SHA256, IP, IPv6, Registry Key, URL. Required
indicator_types The types of the indicator. Use opencti-indicator-types-list to find all indicator types in OpenCTI. Optional
description The description of the indicator. Optional
confidence Confidence level for the indicator, value between 0 and 100. Default is 50. Optional
score The score of the indicator, value between 0 and 100. Default is 50. Optional
valid_from The valid-from date for the indicator in the format YYYY-MM-DDThh:mm:ss.sssZ. Optional
valid_until The valid-until date for the indicator in the format YYYY-MM-DDThh:mm:ss.sssZ. Optional
created_by The ID of the entity that created the indicator (use opencti-organization-list to find or create). Optional
label_id The label ID for the indicator (use opencti-label-list to find or create). Optional
marking_id The marking ID for the indicator (use opencti-marking-definition-list to find). Optional
external_references_id External references ID for the indicator (use opencti-external-reference-create to create). Optional
create_observables Create OpenCTI observable related with the OpenCTI indicator created. Possible values are: true, false. Default is false. Optional

Context Output

Path Type Description
OpenCTI.Indicator.id string New Indicator ID.
                },
                {
                    "id": "11ddff08-8933-46d7-ab22-31f49496499f",
                    "name": "ExampleOrganization"
                }
            ]
        },
        {
            "organizationsLastRun": "YXJyYXljb25uZWN0aW9uOjI="
        }
    ]
} }

#### Human Readable Output

>### Organizations
>|Name|Id|
>|---|---|
>| Test_Organization | 1e12fe87-db3e-4838-8391-6910547bf60d |
>| ExampleOrganization | 11ddff08-8933-46d7-ab22-31f49496499f |


### opencti-organization-create
***
Create a new organization.


#### Base Command

`opencti-organization-create`
#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| name | Name of the organization to create. | Required | 
| description | Description of the organization. | Optional | 
| reliability | Reliability of the organization. Possible values are: A, B, C, D, E, F. | Optional | 


#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| OpenCTI.Organization.id | String | New organization ID. | 


#### Command Example
```!opencti-organization-create name=ExampleOrganization description="create organization" reliability="C"```

#### Context Example
```json
{
    "OpenCTI": {
        "Organization": {
            "id": "11ddff08-8933-46d7-ab22-31f49496499f"
        }
    }
}

Human Readable Output

Organization ExampleOrganization was created successfully with id: 11ddff08-8933-46d7-ab22-31f49496499f.

opencti-label-list


Get list of all labels.

Base Command

opencti-label-list

Input

Argument Name Description Required
limit The maximum number of labels to return per fetch. Default is 50. Optional
last_run_id The last ID from the previous call, from which to begin pagination for this call. You can find this value at the OpenCTI.Labels.labelsLastRun context path. Optional

Context Output

Path Type Description
OpenCTI.Labels.LabelsList.id String Label ID.
OpenCTI.Labels.LabelsList.value String Label name.
OpenCTI.Labels.labelsLastRun String The last ID of the previous fetch to use for pagination.

Command Example

!opencti-label-list limit=2

Context Example

{
    "OpenCTI": {
        "Labels": {
            "LabelsList": [
                {
                    "id": "7ba41668-1594-4a09-9be5-3640f2c2d253",
                    "value": "demisto_lablel"
                },
                {
                    "id": "fa57f98e-f2f5-45fd-97f2-bf2c53119044",
                    "value": "devdemisto"
                }
            ],
            "labelsLastRun": "YXJyYXljb25uZWN0aW9uOjI="
        }
    }
}

Human Readable Output

Labels

Value Id
demisto_lablel 7ba41668-1594-4a09-9be5-3640f2c2d253
devdemisto fa57f98e-f2f5-45fd-97f2-bf2c53119044

opencti-label-create


Create a new label.

Base Command

opencti-label-create

Input

Argument Name Description Required
name Name of the new label to create. Required

Context Output

Path Type Description
OpenCTI.Label.id String New label ID.

Command Example

!opencti-label-create name=docsTest

Context Example

{
    "OpenCTI": {
        "Label": {
            "id": "beb5159a-e162-4352-b7d7-6e355db7f057"
        }
    }
}

Human Readable Output

Label docsTest was created successfully with id: beb5159a-e162-4352-b7d7-6e355db7f057.

opencti-external-reference-create


Create external reference.

Base Command

opencti-external-reference-create

Input

Argument Name Description Required
url External references URL. Required
source_name External references source name. Required

Context Output

Path Type Description
OpenCTI.externalReference.id String New external reference ID.

Command Example

!opencti-external-reference-create source_name=source_name url=www.url.com

Context Example

{
    "OpenCTI": {
        "externalReference": {
            "id": "8339d023-ada2-4b32-8a29-0a3897fc096d"
        }
    }
}

Human Readable Output

Reference source_name was created successfully with id: 8339d023-ada2-4b32-8a29-0a3897fc096d.

opencti-marking-definition-list


Get a list of all marking definitions.

Base Command

opencti-marking-definition-list

Input

Argument Name Description Required
limit The maximum number of marking definitions to return per fetch. Default is 50. Optional
last_run_id The last ID from the previous call, from which to begin pagination for this call. You can find this value at the OpenCTI.MarkingDefinitions.markingsLastRun context path. Optional

Context Output

Path Type Description
OpenCTI.MarkingDefinitions.MarkingDefinitionsList.id String Marking definition ID.
OpenCTI.MarkingDefinitions.MarkingDefinitionsList.value String Marking definition name.
OpenCTI.MarkingDefinitions.markingsLastRun String The last ID of the previous fetch to use for pagination.

Command Example

!opencti-marking-definition-list limit=2

Context Example

{
    "OpenCTI": {
        "MarkingDefinitions": {
            "MarkingDefinitionsList": [
                {
                    "id": "dc911977-796a-4d96-95e4-615bd1c41263",
                    "value": "TLP:GREEN"
                },
                {
                    "id": "9128e411-c759-4af0-aeb0-b65f12082648",
                    "value": "TLP:AMBER"
                }
            ],
            "markingsLastRun": "YXJyYXljb25uZWN0aW9uOjI="
        }
    }
}

Human Readable Output

Markings

Value Id
TLP:GREEN dc911977-796a-4d96-95e4-615bd1c41263
TLP:AMBER 9128e411-c759-4af0-aeb0-b65f12082648

opencti-relationship-create


Create new relationship.

Base Command

opencti-relationship-create

Input

Argument Name Description Required
from_id Source entity ID for the relationship. Required
to_id Target entity ID for the relationship. Required
relationship_type Type of relationship to create. Possible values are: uses, targets, indicates, mitigates, attributed-to, located-at, related-to, derived-from, member-of, variant-of, part-of, communicates-with, compromises, delivers, owns, authored-by, impersonates, controls, hosts, investigates. Default is related-to. Optional
description Description of the relationship. Optional
confidence Confidence Number. Values range is 0 - 100. Optional

Context Output

Path Type Description
OpenCTI.Relationship.id unknown New Relationship ID.
OpenCTI.Relationship.relationshipType unknown New Relationship Type.

opencti-incident-delete


Delete incident.

Base Command

opencti-incident-delete

Input

Argument Name Description Required
id Incident ID. Required

Context Output

There is no context output for this command.

opencti-incident-create


Create new incident.

Base Command

opencti-incident-create

Input

Argument Name Description Required
name Incident name. Required
incident_type Incident Type name. Use opencti-incident-types-list to find all incident types in OpenCTI. Optional
confidence Incident Confidence Number. Values range is 0 - 100. Default value is 50. Optional
severity Incident severity. Possible values are: low, medium, high, critical. Optional
description Incident description. Optional
source Incident Source. Optional
objective Incident objective. Optional
created_by Organization ID. Use opencti-organization-list to find all organization IDs in OpenCTI, or use opencti-organization-create to create a new organization ID. Optional
first_seen Incident First seen. YYYY-MM-DDThh:mm:ss.sssZ. Optional
last_seen Incident Last seen. YYYY-MM-DDThh:mm:ss.sssZ. Optional
label_id Incident label ID. Use opencti-label-list to find all label IDs in OpenCTI, or use opencti-label-create to create a new label. Optional
marking_id Observable marking definition ID. Use opencti-marking-definition-list to find all marking definition IDs in OpenCTI. Optional
external_references_id External references URL. Use opencti-external-reference-create to create a new external reference. Optional

Context Output

Path Type Description
OpenCTI.Incident.id String New Incident ID.

opencti-observable-field-add


Add a field to the observable. Fields that can be added are marking definition and label.

Base Command

opencti-observable-field-add

Input

Argument Name Description Required
id Observable ID. Required
field Observable field to add. Possible values are: marking, label. Required
value Value of the field to add. Enter label ID or marking definition ID. Use opencti-label-list to find all label IDs in OpenCTI, or use opencti-label-create to create a new label. Use opencti-marking-definition-list to find all marking definition IDs in OpenCTI. Required

Context Output

There is no context output for this command.

opencti-indicator-update


Update a indicator in OpenCTI.

Base Command

opencti-indicator-update

Input

Argument Name Description Required
id ID of the indicator. Required
name Name of the indicator. Optional
indicator_types The types of the indicator. Use opencti-indicator-types-list to find all indicator types in OpenCTI. Optional
description The description of the indicator. Optional
confidence Confidence level for the indicator, value between 0 and 100. Default is 50. Default is 50. Optional
score The score of the indicator, value between 0 and 100. Default is 50. Default is 50. Optional
valid_from The valid-from date for the indicator in the format YYYY-MM-DDThh:mm:ss.sssZ. Optional
valid_until The valid-until date for the indicator in the format YYYY-MM-DDThh:mm:ss.sssZ. Optional
label_id The label ID for the indicator (use opencti-label-list to find or create). Optional
marking_id The marking ID for the indicator (use opencti-marking-definition-list to find). Optional
external_references_id External references ID for the indicator (use opencti-external-reference-create to create). Optional

Context Output

Path Type Description
OpenCTI.Indicator.id string New Indicator ID.
OpenCTI.Indicator.name string Name of the updated indicator.
OpenCTI.Indicator.validFrom string The valid-from date of the updated indicator.
OpenCTI.Indicator.validUntil string The valid-until date of the updated indicator.

opencti-relationship-list


Get a list of all relationships in OpenCTI.

Base Command

opencti-relationship-list

Input

Argument Name Description Required
from_id The relationship from entity ID. Required
limit The maximum number of relationships to return per fetch. Default value is 50. Maximum value is 200. Default is 50. Optional
last_run_id The last ID from the previous call, from which to begin pagination for this call. You can find this value at the OpenCTI.Relationships.relationshipsLastRun context path. Optional

Context Output

Path Type Description
OpenCTI.Relationships.RelationshipsList.id String Relationship ID.
OpenCTI.Relationships.RelationshipsList.relationshipType String Relationship type.
OpenCTI.Relationships.RelationshipsList.fromId String Relationship from entity ID.
OpenCTI.Relationships.RelationshipsList.toId String Relationship to entity ID.
OpenCTI.Relationships.RelationshipsList.toEntityType String Relationship to entity type.
OpenCTI.Relationships.relationshipsLastRun String The last ID of the previous fetch to use for pagination.

opencti-observable-create


Create new observable.

Base Command

opencti-observable-create

Input

Argument Name Description Required
type The observable type to create. Out-of-the-box observable types supported in XSOAR are: Account, Domain, Email, File-MD5, File-SHA1, File-SHA256, Host, IP, IPV6, Registry Key, and URL. Possible values are: Account, Domain, Email, File-MD5, File-SHA1, File-SHA256, Host, IP, IPv6, Registry Key, URL. Required
created_by Organization ID. Use opencti-organization-list to find all organization IDs in OpenCTI, or use opencti-organization-create to create a new organization ID. Optional
marking_id Observable marking definition ID. Use opencti-marking-definition-list to find all marking definition IDs in OpenCTI. Optional
label_id Observable label ID. Use opencti-label-list to find all label IDs in OpenCTI, or use opencti-label-create to create a new label. Optional
external_references_id External references URL. Use opencti-external-reference-create to create a new external reference. Optional
description Observable description. Optional
score Observable score. Values range is 0 - 100. Default value is 50. Optional
value Observable value. Optional
create_indicator Create OpenCTI indicator related with the OpenCTI observable created. Possible values are: true, false. Default is false. Optional

Context Output

Path Type Description
OpenCTI.Observable.id String New observable ID.
OpenCTI.Observable.value String New observable value.
OpenCTI.Observable.type String New observable type.

opencti-get-observables


Gets observables from OpenCTI.

Base Command

opencti-get-observables

Input

Argument Name Description Required
limit The maximum number of observables to return. Default value is 50. Maximum value is 500. Optional
score_start Score minimum value to filter by. Values range is 0-100. . Optional
score_end Score maximum value to filter by. Values range is 0-100. . Optional
score A specific score. Values range is 0-100 or Unknown. Optional
observable_types The observable types to fetch. Out-of-the-box observable types supported in Cortex XSOAR are: Account, Domain, Email, File, Host, IP, IPv6, Registry Key, and URL. Possible values are: ALL, Account, Domain, Email, File, Host, IP, IPv6, Registry Key, URL. Default is ALL. Optional
last_run_id The last ID from the previous call, from which to begin pagination for this call. You can find this value at the OpenCTI.ObservablesList.LastRunID context path. Optional
search The observable’s value to filter by. Can be a partial value. Optional
additional_filters List of filters to apply. Format: [{key: str, operator: str, values: list[str], mode: str}, …]. Optional
all_results When the argument is set to true, the limit argument is ignored. Possible values are: true, false. Default is false. Optional

Context Output

Path Type Description
OpenCTI.Observables.ObservablesList.type String Observable type.
OpenCTI.Observables.ObservablesList.value String Observable value.
OpenCTI.Observables.ObservablesList.id String Observable ID.
OpenCTI.Observables.ObservablesList.createdBy Unknown The creator of the observable.
OpenCTI.Observables.ObservablesList.score Number Observable score.
OpenCTI.Observables.ObservablesList.description String Observable description.
OpenCTI.Observables.ObservablesList.labels Unknown Observable labels.
OpenCTI.Observables.ObservablesList.marking Unknown Observable marking definitions.
OpenCTI.Observables.ObservablesList.externalReferences Unknown Observable external references.
OpenCTI.Observables.LastRunID String The last ID of the previous fetch to use for pagination.

opencti-relationship-delete


Delete relationship.

Base Command

opencti-relationship-delete

Input

Argument Name Description Required
id Relationship ID. Required

Context Output

There is no context output for this command.

opencti-observable-delete


Delete observable.

Base Command

opencti-observable-delete

Input

Argument Name Description Required
id Observable ID. Required

Context Output

There is no context output for this command.

opencti-observable-field-remove


Remove observable field value. Fields which values can be removed are marking definition and label.

Base Command

opencti-observable-field-remove

Input

Argument Name Description Required
id Observable ID. Required
field Observable field to update. Possible values are: marking, label. Required
value Value of the field to remove. Enter label ID or marking definition ID. Use opencti-label-list to find all label IDs in OpenCTI or opencti-marking-definition-list to find all marking definition IDs in OpenCTI. Required

Context Output

There is no context output for this command.

opencti-observable-field-update


Update the observable field. The fields that can be updated are: score, description.

Base Command

opencti-observable-field-update

Input

Argument Name Description Required
id Observable ID. Required
field Observable field to update. Possible values are: score, description. Required
value Value of the field to update. Required

Context Output

Path Type Description
OpenCTI.Observable.id String Updated observable ID.

opencti-indicator-types-list


Get a list of all indicator types.

Base Command

opencti-indicator-types-list

Input

| Argument Name | Description | Required |
| — | — | — |

Context Output

Path Type Description
OpenCTI.IndicatorTypes.IndicatorTypesList.id unknown Indicator type ID.
OpenCTI.IndicatorTypes.IndicatorTypesList.name unknown Indicator type name.
OpenCTI.IndicatorTypes.IndicatorTypesList.description unknown Indicator type description.

opencti-incident-types-list


Get a list of all incident types.

Base Command

opencti-incident-types-list

Input

| Argument Name | Description | Required |
| — | — | — |

Context Output

Path Type Description
OpenCTI.IncidentTypes.IncidentTypesList.id unknown Incident type ID.
OpenCTI.IncidentTypes.IncidentTypesList.name unknown Incident type name.
OpenCTI.IncidentTypes.IncidentTypesList.description unknown Incident type description.

opencti-get-incidents


Get incidents in OpenCTI.

Base Command

opencti-get-incidents

Input

Argument Name Description Required
search The incident’s value to filter by. Can be a partial value. Optional
created_by The ID of the entity that created the incident (use opencti-organization-list to find or create). Optional
creator The ID of the incident creator. Optional
created_after Created after date filter. Format: YYYY-MM-DDThh:mm:ss.sssZ. Optional
created_before Created before date filter. Format: YYYY-MM-DDThh:mm:ss.sssZ. Optional
incident_types The types of the incident. Use opencti-incident-types-list to find all incident types in OpenCTI. Optional
label_id The label ID for the incident (use opencti-label-list to find or create). Optional
limit The maximum number of incidents to return. Maximum value is 500. Default is 50. Optional
last_run_id The last ID from the previous call, from which to begin pagination for this call. You can find this value at the OpenCTI.Incidents.LastRunID context path. Optional
additional_filters List of filters to apply. Format: [{key: str, operator: str, values: list[str], mode: str}, …]. Optional
all_results When the argument is set to true, the limit argument is ignored. Possible values are: true, false. Default is false. Optional

Context Output

Path Type Description
OpenCTI.Incidents.IncidentList.id string Unique ID of the incident.
OpenCTI.Incidents.IncidentList.name string Name of the incident.
OpenCTI.Incidents.IncidentList.description string Description of the incident.
OpenCTI.Incidents.IncidentList.source string The source of the incident.
OpenCTI.Incidents.IncidentList.severity string The severity of the incident.
OpenCTI.Incidents.IncidentList.objective string The objective date of the incident.
OpenCTI.Incidents.IncidentList.confidence number Confidence of the incident.
OpenCTI.Incidents.IncidentList.createdBy string Name of the entity that created the incident.
OpenCTI.Incidents.IncidentList.creators list Name of the incident creators.
OpenCTI.Incidents.IncidentList.labels list Labels associated with the incident.
OpenCTI.Incidents.IncidentList.incidentTypes list Types of the incident.
OpenCTI.Incidents.IncidentList.created string Creation date of the incident.
OpenCTI.Incidents.IncidentList.updatedAt string Last update date of the incident.
OpenCTI.Incidents.LastRunID string The last ID of the previous fetch for pagination.

Configuration parameters

  • base_url — Base URL (required)
  • credentials — API Key (leave empty. Fill in the API key in the password field.)
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings
  • redirect_std_out — Redirect stdout

Commands (25)

  • opencti-external-reference-create

    Create external reference.

  • opencti-get-incidents

    Get incidents in OpenCTI.

  • opencti-get-indicators

    Get indicators in OpenCTI.

  • opencti-get-observables

    Gets observables from OpenCTI.

  • opencti-incident-create

    Create new incident.

  • opencti-incident-delete

    Delete incident.

  • opencti-incident-types-list

    Get a list of all incident types.

  • opencti-indicator-create

    Create a new indicator in OpenCTI.

  • opencti-indicator-field-add

    Add a field to the indicator. Fields that can be added are marking definition and label.

  • opencti-indicator-field-remove

    Remove indicator field value. Fields whose values can be removed are marking definition and label.

  • opencti-indicator-types-list

    Get a list of all indicator types.

  • opencti-indicator-update

    Update a indicator in OpenCTI.

  • opencti-label-create

    Create a new label.

  • opencti-label-list

    Get list of all labels.

  • opencti-marking-definition-list

    Get a list of all marking definitions.

  • opencti-observable-create

    Create new observable.

  • opencti-observable-delete

    Delete observable.

  • opencti-observable-field-add

    Add a field to the observable. Fields that can be added are marking definition and label.

  • opencti-observable-field-remove

    Remove observable field value. Fields which values can be removed are marking definition and label.

  • opencti-observable-field-update

    Update the observable field. The fields that can be updated are: score, description.

  • opencti-organization-create

    Create a new organization.

  • opencti-organization-list

    Get a list of all organizations in OpenCTI.

  • opencti-relationship-create

    Create new relationship.

  • opencti-relationship-delete

    Delete relationship.

  • opencti-relationship-list

    Get a list of all relationships in OpenCTI.

import pytest
from CommonServerPython import CommandResults
from OpenCTI import *
from pycti import (
    ExternalReference,
    Incident,
    Indicator,
    Label,
    MarkingDefinition,
    StixCoreRelationship,
    StixCyberObservable,
    StixDomainObject,
)
from test_data.data import (
    RESPONSE_DATA_EMPTY,
    RESPONSE_DATA_INCIDENTS,
    RESPONSE_DATA_INDICATORS,
    RESPONSE_DATA_OBSERVABLES,
)


class Client:
    temp = ""
    query = None
    incident = Incident
    indicator = Indicator
    stix_domain_object = StixDomainObject
    stix_cyber_observable = StixCyberObservable
    stix_core_relationship = StixCoreRelationship
    identity = Identity
    label = Label
    marking_definition = MarkingDefinition
    external_reference = ExternalReference


def test_get_observables(mocker):
    """Tests get_observables function
    Given
        The following observable types: 'registry key', 'account' that were chosen by the user and other additional_filters
    When
        - `fetch_observables_command` or `get_observables_command` are calling the get_observables function
    Then
        - convert the result to observables list
        - validate the length of the observables list
        - validate the new_last_id that is saved into the integration context is the same as the ID returned by the
            command.
    """
    client = Client
    mocker.patch.object(client.stix_cyber_observable, "list", return_value=RESPONSE_DATA_OBSERVABLES)
    observables = get_observables(
        client,
        observable_types=["registry key", "account"],
        limit=10,
        additional_filters=[{"key": "score", "values": ["0", "50"], "operator": "AND"}],
    )
    assert len(observables) == 2


@pytest.mark.parametrize(
    "response_mock, value, expected_length, expected_value",
    [
        (
            [
                {
                    "created_at": "2022-10-24T18:16:52.678Z",
                    "entity_type": "IPv4-Addr",
                    "id": "id",
                    "observable_value": "8.8.8.8",
                    "spec_version": "2.1",
                    "standard_id": "standard_id",
                    "updated_at": "2022-10-24T18:16:52.678Z",
                    "value": "8.8.8.8",
                    "x_opencti_score": 50,
                }
            ],
            "8.8.8.8",
            1,
            "8.8.8.8",
        )
    ],
)
def test_get_observables_value_argument(mocker, response_mock, value, expected_length, expected_value):
    """Tests get_observables function
    Given
        A value to filter by
    When
        - calling get_observables
    Then
        - Ensure that only the result with the same given value is returned.
    """
    client = Client
    mocker.patch.object(client.stix_cyber_observable, "list", return_value=response_mock)
    observables = get_observables(client, ["ALL"], search=value)
    assert len(observables) == expected_length
    assert observables[0].get("value") == expected_value


def test_get_observables_command(mocker):
    """Tests get_observables_command function
    Given
        The following observable types: 'registry key', 'account' that were chosen by the user and 'limit': 2
    When
        - Calling `get_observables_command`
    Then
        - convert the result to human readable table
        - validate the readable_output, raw_response.
    """
    client = Client
    args = {"observable_types": "registry key,account", "limit": 2}
    mocker.patch.object(client.stix_cyber_observable, "list", return_value=RESPONSE_DATA_OBSERVABLES)
    results: CommandResults = get_observables_command(client, args)
    assert len(results.raw_response) == 2
    assert "Observables" in results.readable_output


def test_get_observables_command_no_parameters(mocker):
    """Test get_observables_command function where there is no parameters to filter by
    Given
        No parameters to filter by
    When
        Calling the `get_observables_command`
    Then
        Return all observables
    """
    client = Client
    mocker.patch.object(client.stix_cyber_observable, "list", return_value=RESPONSE_DATA_OBSERVABLES)
    all_observables = get_observables_command(client, args={"observable_types": "ALL"})
    default_observables = get_observables_command(client, {})
    assert len(all_observables.raw_response) == len(default_observables.raw_response)


def test_get_observables_command_with_just_score_end(mocker):
    """Test get_observables_command function where there is just score_end parameter
    Given
        Filter score_end = 50
    When
        Calling the `get_observables_command`
    Then
        Return all observables with score = 0 until score = 50
    """
    client = Client
    mocker.patch.object(client.stix_cyber_observable, "list", return_value=RESPONSE_DATA_OBSERVABLES)
    observables_with_end = get_observables_command(client, args={"score_end": 50})
    observables_with_end_start = get_observables_command(client, args={"score_end": 50, "score_start": 0})
    assert len(observables_with_end.raw_response) == len(observables_with_end_start.raw_response)


def test_get_observables_command_with_just_score_start(mocker):
    """Test get_observables_command function where there is just score_end parameter
    Given
        Filter score_start = 50
    When
        Calling the `get_observables_command`
    Then
        Return all observables with score = 50 until score = 100
    """
    client = Client
    mocker.patch.object(client.stix_cyber_observable, "list", return_value=RESPONSE_DATA_OBSERVABLES)
    observables_with_end = get_observables_command(client, args={"score_start": 50})
    observables_with_end_start = get_observables_command(client, args={"score_start": 50, "score_end": 100})
    assert len(observables_with_end.raw_response) == len(observables_with_end_start.raw_response)


def test_get_observables_command_with_score(mocker):
    """Tests get_observables_command function with a specified score
    Given
        The following observable types: 'registry key', 'account' that were chosen by the user and a specified 'score': 50
    When
        - Calling `get_observables_command`
    Then
        - Verify that the result includes observables with a score of 50.
    """
    client = Client
    args = {"observable_types": "registry key,account", "score": "50"}
    mocker.patch.object(client.stix_cyber_observable, "list", return_value=RESPONSE_DATA_OBSERVABLES)
    results: CommandResults = get_observables_command(client, args)
    assert len(results.raw_response) == 2
    for observable in results.raw_response:
        assert observable.get("x_opencti_score") == 50


def test_get_observables_command_with_no_data_to_return(mocker):
    """Tests get_observables_command function with no data to return
    Given
        The following observable types: 'registry key', 'account' that were chosen by the user.
    When
        - Calling `get_observables_command`
    Then
        - validate the response to have a "No observables" string
    """
    client = Client
    args = {"observable_types": ["registry key", "account"]}
    mocker.patch.object(client.stix_cyber_observable, "list", return_value=RESPONSE_DATA_EMPTY)
    results: CommandResults = get_observables_command(client, args)
    assert "No observables" in results.readable_output


def test_observable_delete_command(mocker):
    """Tests observable_delete_command function
    Given
        id of observable to delete
    When
        - Calling `observable_delete_command`
    Then
        - validate the response to have a "Observable deleted." string
    """
    client = Client
    args = {"id": "123456"}
    mocker.patch.object(client.stix_cyber_observable, "delete", return_value="Observable deleted")
    results: CommandResults = observable_delete_command(client, args)
    assert "Observable deleted" in results.readable_output


@pytest.mark.parametrize(argnames="field, value", argvalues=[("score", "50"), ("description", "new description")])
def test_observable_field_update_command(mocker, field, value):
    """Tests observable_field_update_command function
    Given
        id of observable to update
        field to update
        value to update
    When
        - Calling `observable_field_update_command`
    Then
        - validate the response to have a "Observable deleted." string and context as expected
    """
    client = Client
    args = {"id": "123456", "field": field, "value": value}
    mocker.patch.object(client.stix_cyber_observable, "update_field", return_value={"id": "123456"})
    results: CommandResults = observable_field_update_command(client, args)
    assert "updated successfully" in results.readable_output
    assert results.outputs == {"id": "123456"}


def test_observable_create_command(mocker):
    """Tests observable_create_command function
    Given
        type of observable to create
        score to create
        data to create
    When
        - Calling `observable_create_command`
    Then
        - validate the readable_output, context
    """
    client = Client
    args = {"score": "20", "type": "Domain", "value": "devtest.com"}
    mocker.patch.object(
        client.stix_cyber_observable, "create", return_value={"id": "123456", "value": "devtest.com", "type": "Domain"}
    )
    results: CommandResults = observable_create_command(client, args)
    assert "Observable created successfully" in results.readable_output
    assert results.outputs == {"id": "123456", "value": "devtest.com", "type": "Domain"}


@pytest.mark.parametrize(
    argnames="field, value, function_name",
    argvalues=[("marking", "TLP:RED", "add_marking_definition"), ("label", "new-label", "add_label")],
)
def test_observable_field_add_command(mocker, field, value, function_name):
    """Tests observable_field_add_command function
    Given
        id of observable to add
        field to add
        value to add
    When
        - Calling `observable_field_add_command`
    Then
        - validate the response to have a "added successfully." string at human readable
    """
    client = Client
    args = {"id": "123456", "field": field, "value": value}
    mocker.patch.object(client.label, "create", return_value={"id": "123456"})
    mocker.patch.object(client.marking_definition, "create", return_value={"id": "123456"})
    mocker.patch.object(client.stix_cyber_observable, function_name, return_value=True)

    results: CommandResults = observable_field_add_command(client, args)
    assert "successfully" in results.readable_output


@pytest.mark.parametrize(
    argnames="field, value, function_name",
    argvalues=[("marking", "TLP:RED", "remove_marking_definition"), ("label", "new-label", "remove_label")],
)
def test_observable_field_remove_command(mocker, field, value, function_name):
    """Tests observable_field_remove_command function
    Given
        id of observable to remove
        field to remove
        value to remove
    When
        - Calling `observable_field_remove_command`
    Then
        - validate the response to have a "removed successfully." string at human readable
    """
    client = Client
    args = {"id": "123456", "field": field, "value": value}

    mocker.patch.object(client.label, "create", return_value={"id": "123456"})
    mocker.patch.object(client.marking_definition, "create", return_value={"id": "123456"})
    mocker.patch.object(client.stix_cyber_observable, function_name, return_value=True)

    results: CommandResults = observable_field_remove_command(client, args)
    assert "successfully" in results.readable_output


def test_organization_list_command(mocker):
    """Tests organization_list_command function
    Given

    When
        - Calling `organization_list_command`
    Then
        - validate the readable_output, context
    """
    client = Client
    mocker.patch.object(
        client.identity,
        "list",
        return_value={"entities": [{"id": "1", "name": "test organization"}], "pagination": {"endCursor": "XYZ123"}},
    )
    results: CommandResults = organization_list_command(client, {})
    assert "Organizations" in results.readable_output
    assert results.outputs.get("OpenCTI.Organizations.OrganizationsList(val.id === obj.id)") == [
        {"id": "1", "name": "test organization"}
    ]


def test_organization_create_command(mocker):
    """Tests organization_create_command function
    Given
        - name: organization name to create
    When
        - Calling `organization_create_command`
    Then
        - validate the readable_output, context
    """
    client = Client
    args = {
        "name": "Test Organization",
    }
    mocker.patch.object(client.identity, "create", return_value={"id": "1"})
    results: CommandResults = organization_create_command(client, args)
    assert "was created successfully" in results.readable_output
    assert results.outputs == {"id": "1"}


def test_label_list_command(mocker):
    """Tests label_list_command function
    Given

    When
        - Calling `label_list_command`
    Then
        - validate the readable_output, context
    """
    client = Client
    mocker.patch.object(
        client.label,
        "list",
        return_value={"entities": [{"id": "1", "value": "test-label"}], "pagination": {"endCursor": "XYZ123"}},
    )
    results: CommandResults = label_list_command(client, {})
    assert "Labels" in results.readable_output
    assert results.outputs.get("OpenCTI.Labels.LabelsList(val.id === obj.id)") == [{"id": "1", "value": "test-label"}]


def test_label_create_command(mocker):
    """Tests label_create_command function
    Given
        - name: label name to create
    When
        - Calling `label_create_command`
    Then
        - validate the readable_output, context
    """
    client = Client
    args = {
        "name": "test-label-1",
    }
    mocker.patch.object(client.label, "create", return_value={"id": "1"})
    results: CommandResults = label_create_command(client, args)
    assert "was created successfully" in results.readable_output
    assert results.outputs == {"id": "1"}


def test_external_reference_create_command(mocker):
    """Tests external_reference_create_command function
    Given
        - source_name: name of external reference source
        - url: url of external reference
    When
        - Calling `external_reference_create_command`
    Then
        - validate the readable_output, context
    """
    client = Client
    args = {"source_name": "test-label-1", "url": "testurl.com"}
    mocker.patch.object(client.external_reference, "create", return_value={"id": "1"})
    results: CommandResults = external_reference_create_command(client, args)
    assert "was created successfully" in results.readable_output
    assert results.outputs == {"id": "1"}


def test_marking_list_command(mocker):
    """Tests marking_list_command function
    Given

    When
        - Calling `marking_list_command`
    Then
        - validate the readable_output, context
    """
    client = Client
    mocker.patch.object(
        client.marking_definition,
        "list",
        return_value={"entities": [{"id": "1", "definition": "TLP:RED"}], "pagination": {"endCursor": "XYZ123"}},
    )
    results: CommandResults = marking_list_command(client, {})
    assert "Markings" in results.readable_output
    assert results.outputs.get("OpenCTI.MarkingDefinitions.MarkingDefinitionsList(val.id === obj.id)") == [
        {"id": "1", "value": "TLP:RED"}
    ]


def test_incident_create_command(mocker):
    """Tests incident_create_command function
    Given
        type of incident to create
        name of incident to create
        confidence of incident to create
        description of incident to create
    When
        - Calling `incident_create_command`
    Then
        - validate the readable_output, context
    """
    client = Client
    args = {
        "incident_type": "Lorem",
        "name": "Lorem ipsum dolor",
        "confidence": "100",
        "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
    }
    mocker.patch.object(client.incident, "create", return_value={"id": "123456"})
    results: CommandResults = incident_create_command(client, args)
    assert "Incident created successfully" in results.readable_output
    assert results.outputs == {"id": "123456"}


def test_incident_create_command_exception(mocker, capfd):
    """Tests incident_create_command function
    Given
        type of incident to create
        name of incident to create
        confidence of incident to create
        description of incident to create
    When
        - Calling `incident_create_command`
    Then
        - Ensure a DemistoException is raised with the correct error message.
    """
    client = Client
    args = {
        "incident_type": "Lorem",
        "name": "Lorem ipsum dolor",
        "confidence": "100",
        "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
    }
    mocker.patch.object(client.incident, "create", side_effect=Exception("Test exception"))
    with pytest.raises(DemistoException, match="Can't create incident."):
        incident_create_command(client, args)
    captured = capfd.readouterr()
    assert captured.out.strip() == "Test exception"


def test_incident_create_command_exception_data_not_returned(mocker):
    """Tests incident_create_command function
    Given
        type of incident to create
        name of incident to create
        confidence of incident to create
        description of incident to create
    When
        - Calling `incident_create_command`
    Then
        - Ensure a DemistoException is raised with the correct error message.
    """
    client = Client
    args = {
        "incident_type": "Lorem",
        "name": "Lorem ipsum dolor",
        "confidence": "100",
        "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
    }
    mocker.patch.object(client.incident, "create", return_value={})
    with pytest.raises(DemistoException, match="Can't create incident."):
        incident_create_command(client, args)


def test_incident_delete_command(mocker):
    """Tests incident_delete_command function
    Given
        id of incident to delete
    When
        - Calling `incident_delete_command`
    Then
        - validate the response to have a "Incident deleted." string
    """
    client = Client
    args = {"id": "123456"}
    mocker.patch.object(client.stix_domain_object, "delete", return_value="Incident deleted")
    results: CommandResults = incident_delete_command(client, args)
    assert "Incident deleted" in results.readable_output


def test_incident_delete_command_exception(mocker, capfd):
    """Tests incident_delete_command function
    Given
        id of incident to delete
    When
        - Calling `incident_delete_command`
    Then
        - Ensure a DemistoException is raised with the correct error message.
    """
    client = Client
    args = {"id": "123456"}
    mocker.patch.object(client.stix_domain_object, "delete", side_effect=Exception("Test exception"))
    with pytest.raises(DemistoException, match="Can't delete incident."):
        incident_delete_command(client, args)
    captured = capfd.readouterr()
    assert captured.out.strip() == "Test exception"


def test_get_incidents(mocker):
    """Tests get_incidents function
    Given
        The following incident types: 'registry key', 'account' that were chosen by the user.
    When
        - `get_incidents_command` is calling the get_incidents function
    Then
        - convert the result to incidents list
        - validate the length of the incidents list
        - validate the new_last_id that is saved into the integration context is the same as the ID returned by the
            command.
    """
    client = Client
    mocker.patch.object(client.incident, "list", return_value=RESPONSE_DATA_INCIDENTS)
    incidents = get_incidents(
        client,
        incident_types=["incident_type_1", "incident_type_2"],
        limit=10,
        additional_filters=[{"key": "score", "values": ["0", "50"], "operator": "AND"}],
    )
    assert len(incidents) == 2


def test_get_incidents_exception(mocker, capfd):
    """Tests get_incidents function
    Given
        The following incident types: 'registry key', 'account' that were chosen by the user.
    When
        - `get_incidents_command` is calling the get_incidents function
    Then
         Ensure a DemistoException is raised with the correct error message.
    """
    client = Client
    mocker.patch.object(client.incident, "list", side_effect=Exception("Test exception"))
    with pytest.raises(DemistoException, match="Failed to retrieve incidents."):
        get_incidents(client, incident_types=["incident_type_1", "incident_type_2"], limit=10)
    captured = capfd.readouterr()
    assert captured.out.strip() == "Test exception"


def test_get_incidents_command(mocker):
    """Tests get_incidents_command function
    Given
        The following incident types: 'compromised' that were chosen by the user and 'limit': 2
    When
        - Calling `get_incidents_command`
    Then
        - convert the result to human readable table
        - validate the readable_output, raw_response.
    """
    client = Client
    args = {"incident_types": "compromised", "limit": 2}
    mocker.patch.object(client.incident, "list", return_value=RESPONSE_DATA_INCIDENTS)
    results: CommandResults = get_incidents_command(client, args)
    assert len(results.raw_response) == 2
    assert "Incidents" in results.readable_output
    assert RESPONSE_DATA_INCIDENTS.get("pagination", {}).get("endCursor") == results.outputs.get(
        "OpenCTI.Incidents(val.lastRunID)"
    ).get("lastRunID")


def test_get_incidents_command_with_no_data_to_return(mocker):
    """Tests get_incidents_command function with no data to return
    Given
        The following incident types: 'compromised' that were chosen by the user.
    When
        - Calling `get_incidents_command`
    Then
        - validate the response to have a "No incidents" string
    """
    client = Client
    args = {"incident_types": "compromised"}
    mocker.patch.object(client.incident, "list", return_value=RESPONSE_DATA_EMPTY)
    results: CommandResults = get_incidents_command(client, args)
    assert "No incidents" in results.readable_output


def test_incident_types_list_command(mocker):
    """Tests incident_types_list_command function
    Given

    When
        - Calling `incident_types_list_command`
    Then
        - validate the readable_output, context
    """
    client = Client
    mocker.patch.object(
        client,
        "query",
        return_value={
            "data": {
                "vocabularies": {
                    "edges": [
                        {"node": {"id": "1", "name": "Phishing", "description": "Phishing incident type"}},
                    ]
                }
            }
        },
    )
    results: CommandResults = incident_types_list_command(client, {})
    assert "Incident Types" in results.readable_output
    assert results.outputs.get("OpenCTI.IncidentTypes.IncidentTypesList(val.id === obj.id)") == [
        {"id": "1", "name": "Phishing", "description": "Phishing incident type"}
    ]


def test_incident_types_list_command_with_no_data_to_return(mocker):
    """Tests incident_types_list_command function
    Given

    When
        - Calling `incident_types_list_command`
    Then
        - validate the response to have a "No observables" string
    """
    client = Client
    mocker.patch.object(client, "query", return_value={"data": {"vocabularies": {"edges": []}}})
    results: CommandResults = incident_types_list_command(client, {})
    assert "No incident types" in results.readable_output


def test_incident_types_list_command_exception(mocker, capfd):
    """Tests incident_types_list_command function
    Given

    When
        - Calling `incident_types_list_command`
    Then
        - Ensure a DemistoException is raised with the correct error message.
    """
    client = Client
    mocker.patch.object(client, "query", side_effect=Exception("Test exception"))
    with pytest.raises(DemistoException, match="Can't list incident types."):
        incident_types_list_command(client, {})
    captured = capfd.readouterr()
    assert captured.out.strip() == "Test exception"


def test_relationship_create_command(mocker):
    """Tests relationship_create_command function
    Given
        from_id entity
        to_id entity
        relationship_type
    When
        - Calling `relationship_create_command`
    Then
        - validate the readable_output, context
    """
    client = Client
    args = {"from_id": "123456", "to_id": "123457", "relationship_type": "related-to"}
    mocker.patch.object(client.stix_core_relationship, "create", return_value={"id": "123456", "relationship_type": "related-to"})
    results: CommandResults = relationship_create_command(client, args)
    assert "Relationship created successfully" in results.readable_output
    assert results.outputs == {"id": "123456", "relationshipType": "related-to"}


def test_relationship_delete_command(mocker):
    """Tests relationship_delete_command function
    Given
        id of relationship to delete
    When
        - Calling `relationship_delete_command`
    Then
        - validate the response to have a "Relationship deleted." string
    """
    client = Client
    args = {"id": "123456"}
    mocker.patch.object(client.stix_core_relationship, "delete", return_value="Relationship deleted")
    results: CommandResults = relationship_delete_command(client, args)
    assert "Relationship deleted" in results.readable_output


def test_relationship_delete_command_exception(mocker, capfd):
    """Tests relationship_delete_command function
    Given
        id of relationship to delete
    When
        - Calling `relationship_delete_command`
    Then
        - Ensure a DemistoException is raised with the correct error message.
    """
    client = Client
    args = {"id": "123456"}
    mocker.patch.object(client.stix_core_relationship, "delete", side_effect=Exception("Test exception"))
    with pytest.raises(DemistoException, match="Can't delete relationship."):
        relationship_delete_command(client, args)
    captured = capfd.readouterr()
    assert captured.out.strip() == "Test exception"


def test_relationship_list_command(mocker):
    """Tests relationship_list_command function
    Given

    When
        - Calling `relationship_list_command`
    Then
        - validate the readable_output, context
    """
    client = Client
    mocker.patch.object(
        client.stix_core_relationship,
        "list",
        return_value={
            "entities": [
                {
                    "id": "4acaed3c-5683-4caa-b87d-28ba32c72056",
                    "relationship_type": "related-to",
                    "from": {"id": "17282d6a-2da1-491a-b1ad-13b29bead0c8"},
                    "to": {"id": "a4ff07c2-3ea8-42fc-b227-947e74a3a551", "entity_type": "IPv4-Addr"},
                }
            ],
            "pagination": {"endCursor": "XYZ123"},
        },
    )
    results: CommandResults = relationship_list_command(client, {"from_id": "17282d6a-2da1-491a-b1ad-13b29bead0c8"})
    assert "Relationships" in results.readable_output
    assert results.outputs.get("OpenCTI.Relationships.RelationshipsList(val.id === obj.id)") == [
        {
            "id": "4acaed3c-5683-4caa-b87d-28ba32c72056",
            "relationshipType": "related-to",
            "fromId": "17282d6a-2da1-491a-b1ad-13b29bead0c8",
            "toId": "a4ff07c2-3ea8-42fc-b227-947e74a3a551",
            "toEntityType": "IPv4-Addr",
        }
    ]


def test_relationship_create_command_with_no_data_to_return(mocker):
    """Tests relationship_create_command function
    Given
        from_id entity
        to_id entity
        relationship_type
    When
        - Calling `relationship_create_command`
    Then
        - Ensure a DemistoException is raised with the correct error message.
    """
    client = Client
    args = {"from_id": "123456", "to_id": "123457", "relationship_type": "related-to"}
    mocker.patch.object(client.stix_core_relationship, "create", return_value={})
    with pytest.raises(DemistoException, match="Can't create relationship."):
        relationship_create_command(client, args)


def test_relationship_create_command_exception(mocker, capfd):
    """Tests relationship_create_command function
    Given
        from_id entity
        to_id entity
        relationship_type
    When
        - Calling `relationship_create_command`
    Then
        - Ensure a DemistoException is raised with the correct error message.
    """
    client = Client
    args = {"from_id": "123456", "to_id": "123457", "relationship_type": "related-to"}
    mocker.patch.object(client.stix_core_relationship, "create", side_effect=Exception("Test exception"))
    with pytest.raises(DemistoException, match="Can't create relationship."):
        relationship_create_command(client, args)
    captured = capfd.readouterr()
    assert captured.out.strip() == "Test exception"


def test_indicator_create_command(mocker):
    """Tests indicator_create_command function
    Given
        name of indicator to create
        indicator value to create
        main_observable_type of indicator to create
    When
        - Calling `indicator_create_command`
    Then
        - validate the readable_output, context
    """
    client = Client
    args = {"name": "Lorem ipsum dolor", "indicator": "192.168.1.1", "main_observable_type": "ip"}
    mocker.patch.object(client.indicator, "create", return_value={"id": "123456"})
    results: CommandResults = indicator_create_command(client, args)
    assert "Indicator created successfully" in results.readable_output
    assert results.outputs == {"id": "123456"}


def test_indicator_create_command_exception(mocker, capfd):
    """Tests indicator_create_command function
    Given
        name of indicator to create
        indicator value to create
        main_observable_type of indicator to create
    When
        - Calling `indicator_create_command`
    Then
        - Ensure a DemistoException is raised with the correct error message.
    """
    client = Client
    args = {"name": "Lorem ipsum dolor", "indicator": "192.168.1.1", "main_observable_type": "ip"}
    mocker.patch.object(client.indicator, "create", side_effect=Exception("Test exception"))
    with pytest.raises(DemistoException, match="Can't create indicator."):
        indicator_create_command(client, args)
    captured = capfd.readouterr()
    assert captured.out.strip() == "Test exception"


def test_indicator_create_command_exception_data_not_returned(mocker):
    """Tests indicator_create_command function
    Given
        name of indicator to create
        indicator value to create
        main_observable_type of indicator to create
    When
        - Calling `indicator_create_command`
    Then
        - Ensure a DemistoException is raised with the correct error message.
    """
    client = Client
    args = {"name": "Lorem ipsum dolor", "indicator": "192.168.1.1", "main_observable_type": "ip"}
    mocker.patch.object(client.indicator, "create", return_value={})
    with pytest.raises(DemistoException, match="Can't create indicator."):
        indicator_create_command(client, args)


def test_indicator_update_command(mocker):
    """Tests indicator_update_command function
    Given
        id of indicator to update
        description to update
        valid_until to update
    When
        - Calling `indicator_update_command`
    Then
        - validate the readable_output, context
    """
    client = Client
    args = {"id": "123456", "description": "Lorem ipsum dolor", "valid_until": "2023-12-31T23:59:59.000Z"}
    mocker.patch.object(
        client,
        "query",
        return_value={
            "data": {
                "indicatorFieldPatch": {
                    "id": "123456",
                    "name": "Lorem ipsum dolor",
                    "valid_from": "2023-01-01T00:00:00.000Z",
                    "valid_until": "2023-12-31T23:59:59.000Z",
                }
            }
        },
    )
    results: CommandResults = indicator_update_command(client, args)
    assert "Indicator updated successfully" in results.readable_output
    assert results.outputs == {
        "id": "123456",
        "name": "Lorem ipsum dolor",
        "validFrom": "2023-01-01T00:00:00.000Z",
        "validUntil": "2023-12-31T23:59:59.000Z",
    }


def test_indicator_update_command_exception(mocker, capfd):
    """Tests indicator_update_command function
    Given
        id of indicator to update
        description to update
        valid_until to update
    When
        - Calling `indicator_update_command`
    Then
        - Ensure a DemistoException is raised with the correct error message.
    """
    client = Client
    args = {"id": "123456", "description": "Lorem ipsum dolor", "valid_until": "2023-12-31T23:59:59.000Z"}
    mocker.patch.object(client, "query", side_effect=Exception("Test exception"))
    with pytest.raises(DemistoException, match="Can't update indicator."):
        indicator_update_command(client, args)
    captured = capfd.readouterr()
    assert captured.out.strip() == "Test exception"


def test_indicator_update_command_exception_data_not_returned(mocker):
    """Tests indicator_update_command function
    Given
        id of indicator to update
        description to update
        valid_until to update
    When
        - Calling `indicator_update_command`
    Then
        - Ensure a DemistoException is raised with the correct error message.
    """
    client = Client
    args = {"id": "123456", "description": "Lorem ipsum dolor", "valid_until": "2023-12-31T23:59:59.000Z"}
    mocker.patch.object(client, "query", return_value={"data": {"indicatorFieldPatch": {}}})
    with pytest.raises(DemistoException, match="Can't update indicator."):
        indicator_update_command(client, args)


@pytest.mark.parametrize(
    argnames="field, value, function_name,",
    argvalues=[("marking", "TLP:RED", "add_marking_definition"), ("label", "new-label", "add_label")],
)
def test_indicator_field_add_command(mocker, field, value, function_name):
    """Tests indicator_field_add_command function
    Given
        id of indicator to add
        field to add
        value to add
    When
        - Calling `indicator_field_add_command`
    Then
        - validate the response to have a "added successfully." string at human readable
    """
    client = Client
    args = {"id": "123456", "field": field, "value": value}
    mocker.patch.object(client.stix_domain_object, function_name, return_value=True)
    results: CommandResults = indicator_field_add_command(client, args)
    assert f"Added {field} successfully." in results.readable_output


@pytest.mark.parametrize(
    argnames="field, value, function_name,",
    argvalues=[("marking", "TLP:RED", "add_marking_definition"), ("label", "new-label", "add_label")],
)
def test_indicator_field_add_command_field_not_added(mocker, field, value, function_name):
    """Tests indicator_field_add_command function
    Given
        id of indicator to add
        field to add
        value to add
    When
        - Calling `indicator_field_add_command`
    Then
        - validate the response to have a "added successfully." string at human readable
    """
    client = Client
    args = {"id": "123456", "field": field, "value": value}
    mocker.patch.object(client.stix_domain_object, function_name, return_value=False)
    with pytest.raises(DemistoException, match=f"Can't add {field}."):
        indicator_field_add_command(client, args)


@pytest.mark.parametrize(
    argnames="field, value, function_name",
    argvalues=[("marking", "TLP:RED", "remove_marking_definition"), ("label", "new-label", "remove_label")],
)
def test_indicator_field_remove_command(mocker, field, value, function_name):
    """Tests indicator_field_remove_command function
    Given
        id of indicator to remove
        field to remove
        value to remove
    When
        - Calling `indicator_field_remove_command`
    Then
        - validate the response to have a "removed successfully." string at human readable
    """
    client = Client
    args = {"id": "123456", "field": field, "value": value}
    mocker.patch.object(client.stix_domain_object, function_name, return_value=True)
    results: CommandResults = indicator_field_remove_command(client, args)
    assert f"{field}: {value} was removed successfully from indicator: 123456." in results.readable_output


@pytest.mark.parametrize(
    argnames="field, value, function_name",
    argvalues=[("marking", "TLP:RED", "remove_marking_definition"), ("label", "new-label", "remove_label")],
)
def test_indicator_field_remove_command_field_not_removed(mocker, field, value, function_name):
    """Tests indicator_field_remove_command function
    Given
        id of indicator to remove
        field to remove
        value to remove
    When
        - Calling `indicator_field_remove_command`
    Then
        - validate the response to have a "removed successfully." string at human readable
    """
    client = Client
    args = {"id": "123456", "field": field, "value": value}
    mocker.patch.object(client.stix_domain_object, function_name, return_value=False)
    with pytest.raises(DemistoException, match=f"Can't remove {field}."):
        indicator_field_remove_command(client, args)


@pytest.mark.parametrize(
    argnames="field, value, function_name",
    argvalues=[("marking", "TLP:RED", "remove_marking_definition"), ("label", "new-label", "remove_label")],
)
def test_indicator_field_remove_command_exception(mocker, capfd, field, value, function_name):
    """Tests indicator_field_remove_command function
    Given
        id of indicator to remove
        field to remove
        value to remove
    When
        - Calling `indicator_field_remove_command`
    Then
        - validate the response to have a "removed successfully." string at human readable
    """
    client = Client
    args = {"id": "123456", "field": field, "value": value}
    mocker.patch.object(client.stix_domain_object, function_name, side_effect=Exception("Test exception"))
    with pytest.raises(DemistoException, match=f"Can't remove {field} from indicator."):
        indicator_field_remove_command(client, args)
    captured = capfd.readouterr()
    assert captured.out.strip() == "Test exception"


def test_get_indicators(mocker):
    """Tests get_indicators function
    Given
        The following indicator types: 'registry key', 'account' that were chosen by the user.
    When
        - `get_indicators_command` is calling the get_indicators function
    Then
        - convert the result to indicators list
        - validate the length of the indicators list
        - validate the new_last_id that is saved into the integration context is the same as the ID returned by the
            command.
    """
    client = Client
    mocker.patch.object(client.indicator, "list", return_value=RESPONSE_DATA_INDICATORS)
    indicators = get_indicators(
        client,
        indicator_types=["indicator_type_1", "indicator_type_2"],
        limit=10,
        additional_filters=[{"key": "score", "values": ["0", "50"], "operator": "AND"}],
    )
    assert len(indicators) == 2


def test_get_indicators_exception(mocker, capfd):
    """Tests get_indicators function
    Given
        The following indicator types: 'registry key', 'account' that were chosen by the user.
    When
        - `get_indicators_command` is calling the get_indicators function
    Then
         Ensure a DemistoException is raised with the correct error message.
    """
    client = Client
    mocker.patch.object(client.indicator, "list", side_effect=Exception("Test exception"))
    with pytest.raises(DemistoException, match="Failed to retrieve indicators."):
        get_indicators(client, indicator_types=["indicator_type_1", "indicator_type_2"], limit=10)
    captured = capfd.readouterr()
    assert captured.out.strip() == "Test exception"


def test_get_indicators_command(mocker):
    """Tests get_indicators_command function
    Given
        The following indicator types: 'compromised' that were chosen by the user and 'limit': 2
    When
        - Calling `get_indicators_command`
    Then
        - convert the result to human readable table
        - validate the readable_output, raw_response.
    """
    client = Client
    args = {"indicator_types": "compromised", "limit": 2}
    mocker.patch.object(client.indicator, "list", return_value=RESPONSE_DATA_INDICATORS)
    results: CommandResults = get_indicators_command(client, args)
    assert len(results.raw_response) == 2
    assert "Indicators" in results.readable_output
    assert RESPONSE_DATA_INDICATORS.get("pagination", {}).get("endCursor") == results.outputs.get(
        "OpenCTI.Indicators(val.lastRunID)"
    ).get("lastRunID")


def test_get_indicators_command_with_no_data_to_return(mocker):
    """Tests get_indicators_command function with no data to return
    Given
        The following indicator types: 'compromised' that were chosen by the user.
    When
        - Calling `get_indicators_command`
    Then
        - validate the response to have a "No indicators" string
    """
    client = Client
    args = {"indicator_types": "compromised"}
    mocker.patch.object(client.indicator, "list", return_value=RESPONSE_DATA_EMPTY)
    results: CommandResults = get_indicators_command(client, args)
    assert "No indicators" in results.readable_output


def test_indicator_types_list_command(mocker):
    """Tests indicator_types_list_command function
    Given

    When
        - Calling `indicator_types_list_command`
    Then
        - validate the readable_output, context
    """
    client = Client
    mocker.patch.object(
        client,
        "query",
        return_value={
            "data": {
                "vocabularies": {
                    "edges": [
                        {"node": {"id": "1", "name": "compromised", "description": "compromised"}},
                    ]
                }
            }
        },
    )
    results: CommandResults = indicator_types_list_command(client, {})
    assert "Indicator Types" in results.readable_output
    assert results.outputs.get("OpenCTI.IndicatorTypes.IndicatorTypesList(val.id === obj.id)") == [
        {"id": "1", "name": "compromised", "description": "compromised"}
    ]


def test_indicator_types_list_command_with_no_data_to_return(mocker):
    """Tests indicator_types_list_command function
    Given

    When
        - Calling `indicator_types_list_command`
    Then
        - validate the response to have a "No observables" string
    """
    client = Client
    mocker.patch.object(client, "query", return_value={"data": {"vocabularies": {"edges": []}}})
    results: CommandResults = indicator_types_list_command(client, {})
    assert "No indicator types" in results.readable_output


def test_indicator_types_list_command_exception(mocker, capfd):
    """Tests indicator_types_list_command function
    Given

    When
        - Calling `indicator_types_list_command`
    Then
        - Ensure a DemistoException is raised with the correct error message.
    """
    client = Client
    mocker.patch.object(client, "query", side_effect=Exception("Test exception"))
    with pytest.raises(DemistoException, match="Can't list indicator types."):
        indicator_types_list_command(client, {})
    captured = capfd.readouterr()
    assert captured.out.strip() == "Test exception"