SearchIndicatorRelationshipsAgentix

This automation outputs the indicator relationships to context according to the provided query, using the entities, entityTypes, and relationships arguments. All arguments will use the AND operator. For example, using the following arguments entities=8.8.8.8 entities_types=Domain will provide only relationships that the 8.8.8.8 indicator has with indicators of type domain.

python · Base

Details

IDSearchIndicatorRelationshipsAgentix
Languagepython
From Version6.6.0
Docker Imagedemisto/python3:3.12.13.10116658
import json


def util_load_json(path):
    with open(path, encoding="utf-8") as f:
        return json.loads(f.read())


def test_get_relationships_no_parameters_returns_empty_list():
    """
    Given: No parameters are provided to get_relationships function
    When: Calling get_relationships()
    Then: An empty list should be returned
    """
    from SearchIndicatorRelationshipsAgentix import get_relationships

    result = get_relationships({})

    assert result == []


def test_get_relationships_with_entities_only(mocker):
    """
    Given: A list of entities is provided to get_relationships function
    When: Calling get_relationships with entities parameter
    Then: SearchIndicatorRelationships command should be executed and relationships returned
    """
    from SearchIndicatorRelationshipsAgentix import get_relationships

    mock_execute_command = mocker.patch("SearchIndicatorRelationshipsAgentix.demisto.executeCommand")
    mock_get = mocker.patch("SearchIndicatorRelationshipsAgentix.demisto.get")

    mock_execute_command.return_value = [{"Contents": {"Relationships": [{"id": "rel1", "type": "related-to"}]}}]
    mock_get.return_value = {"Relationships": [{"id": "rel1", "type": "related-to"}]}

    result = get_relationships({"entities": ["example.com"]})

    mock_execute_command.assert_called_once_with(
        "SearchIndicatorRelationships", {"entities": ["example.com"], "limit": 20, "verbose": "false", "revoked": "false"}
    )
    assert result == [{"id": "rel1", "type": "related-to"}]


def test_get_relationships_with_entities_types_calls_filter_function(mocker):
    """
    Given: Entities and entity types are provided to get_relationships function
    When: Calling get_relationships with entities and related_entity_types parameters
    Then: The filter_relationships_by_entity_types function should be called with correct parameters
    """
    from SearchIndicatorRelationshipsAgentix import get_relationships

    mock_filter = mocker.patch("SearchIndicatorRelationshipsAgentix.filter_relationships_by_entity_types")
    mock_filter.return_value = [{"id": "filtered_rel", "type": "indicates"}]

    result = get_relationships({"entities": ["malware.exe"], "related_entity_types": ["File"], "limit": 10})

    mock_filter.assert_called_once_with(["malware.exe"], ["File"], [], 10, "false", "false")
    assert result == [{"id": "filtered_rel", "type": "indicates"}]


def test_filter_relationships_by_entity_types_single_page_results(mocker):
    """
    Given: A single page of relationships with matching entity types
    When: Calling filter_relationships_by_entity_types function
    Then: Only relationships matching the specified entity types should be returned
    """
    from SearchIndicatorRelationshipsAgentix import filter_relationships_by_entity_types

    mock_execute_command = mocker.patch("SearchIndicatorRelationshipsAgentix.demisto.executeCommand")
    mock_get = mocker.patch("SearchIndicatorRelationshipsAgentix.demisto.get")

    mock_execute_command.return_value = [
        {
            "Contents": {
                "Relationships": [
                    {
                        "EntityAType": "File",
                        "EntityBType": "Domain",
                        "EntityA": "test.exe",
                        "EntityB": "example.com",
                        "id": "rel1",
                    },
                    {"EntityAType": "File", "EntityBType": "IP", "EntityA": "test.exe", "EntityB": "1.2.3.4", "id": "rel2"},
                ]
            }
        }
    ]

    mock_get.side_effect = [
        {
            "Relationships": [
                {"EntityAType": "File", "EntityBType": "Domain", "EntityA": "test.exe", "EntityB": "example.com", "id": "rel1"},
                {"EntityAType": "File", "EntityBType": "IP", "EntityA": "test.exe", "EntityB": "1.2.3.4", "id": "rel2"},
            ],
            "RelationshipsPagination": [],
        }
    ]

    result = filter_relationships_by_entity_types(["test.exe"], ["Domain"], [], 10)

    assert len(result) == 1
    assert result[0]["EntityAType"] == "File"
    assert result[0]["id"] == "rel1"


def test_filter_relationships_by_entity_types_multiple_pages(mocker):
    """
    Given: Multiple pages of relationships with pagination tokens
    When: Calling filter_relationships_by_entity_types function
    Then: All pages should be fetched and matching relationships returned
    """
    from SearchIndicatorRelationshipsAgentix import filter_relationships_by_entity_types

    mock_execute_command = mocker.patch("SearchIndicatorRelationshipsAgentix.demisto.executeCommand")
    mock_get = mocker.patch("SearchIndicatorRelationshipsAgentix.demisto.get")

    mock_execute_command.side_effect = [
        [
            {
                "Contents": {
                    "Relationships": [
                        {
                            "EntityAType": "File",
                            "EntityBType": "File",
                            "EntityA": "test.exe",
                            "EntityB": "test2.exe",
                            "id": "rel1",
                        }
                    ],
                    "RelationshipsPagination": ["token1"],
                }
            }
        ],
        [
            {
                "Contents": {
                    "Relationships": [
                        {
                            "EntityAType": "File",
                            "EntityBType": "File",
                            "EntityA": "test.exe",
                            "EntityB": "test2.exe",
                            "id": "rel2",
                        }
                    ],
                    "RelationshipsPagination": [],
                }
            }
        ],
    ]

    mock_get.side_effect = [
        {
            "Relationships": [
                {"EntityAType": "File", "EntityBType": "File", "EntityA": "test.exe", "EntityB": "test2.exe", "id": "rel1"}
            ],
            "RelationshipsPagination": ["token1"],
        },
        {
            "Relationships": [
                {"EntityAType": "File", "EntityBType": "File", "EntityA": "test.exe", "EntityB": "test2.exe", "id": "rel2"}
            ],
            "RelationshipsPagination": [],
        },
    ]

    result = filter_relationships_by_entity_types(["test.exe"], ["File"], [], 10)

    assert len(result) == 2
    assert mock_execute_command.call_count == 2


def test_filter_relationships_by_entity_types_limit_reached_early(mocker):
    """
    Given: More relationships available than the specified limit
    When: Calling filter_relationships_by_entity_types function with a limit
    Then: Only the number of relationships up to the limit should be returned
    """
    from SearchIndicatorRelationshipsAgentix import filter_relationships_by_entity_types

    mock_execute_command = mocker.patch("SearchIndicatorRelationshipsAgentix.demisto.executeCommand")
    mock_get = mocker.patch("SearchIndicatorRelationshipsAgentix.demisto.get")

    mock_execute_command.return_value = [
        {
            "Contents": {
                "Relationships": [
                    {
                        "EntityAType": "File",
                        "EntityBType": "Domain",
                        "EntityA": "test.exe",
                        "EntityB": "example.com",
                        "id": "rel1",
                    },
                    {
                        "EntityAType": "File",
                        "EntityBType": "Domain",
                        "EntityA": "test.exe",
                        "EntityB": "example1.com",
                        "id": "rel2",
                    },
                    {
                        "EntityAType": "File",
                        "EntityBType": "Domain",
                        "EntityA": "test.exe",
                        "EntityB": "example2.com",
                        "id": "rel3",
                    },
                ]
            }
        }
    ]

    mock_get.return_value = {
        "Relationships": [
            {"EntityAType": "File", "EntityBType": "Domain", "EntityA": "test.exe", "EntityB": "example.com", "id": "rel1"},
            {"EntityAType": "File", "EntityBType": "Domain", "EntityA": "test.exe", "EntityB": "example1.com", "id": "rel2"},
            {"EntityAType": "File", "EntityBType": "Domain", "EntityA": "test.exe", "EntityB": "example2.com", "id": "rel3"},
        ],
        "RelationshipsPagination": ["token1"],
    }

    result = filter_relationships_by_entity_types(["test.exe"], ["Domain"], [], 2)

    assert len(result) == 2


def test_filter_relationships_by_entity_types_no_matching_types(mocker):
    """
    Given: Relationships exist but none match the specified entity types
    When: Calling filter_relationships_by_entity_types function
    Then: An empty list should be returned
    """
    from SearchIndicatorRelationshipsAgentix import filter_relationships_by_entity_types

    mock_execute_command = mocker.patch("SearchIndicatorRelationshipsAgentix.demisto.executeCommand")
    mock_get = mocker.patch("SearchIndicatorRelationshipsAgentix.demisto.get")

    mock_execute_command.return_value = [
        {
            "Contents": {
                "Relationships": [
                    {"EntityAType": "IP", "EntityBType": "Domain", "EntityA": "1.2.3.4", "EntityB": "example.com", "id": "rel1"},
                    {
                        "EntityAType": "URL",
                        "EntityBType": "Domain",
                        "EntityA": "http://example.com",
                        "EntityB": "example.com",
                        "id": "rel2",
                    },
                ]
            }
        }
    ]

    mock_get.return_value = {
        "Relationships": [
            {"EntityAType": "IP", "EntityBType": "Domain", "EntityA": "1.2.3.4", "EntityB": "example.com", "id": "rel1"},
            {
                "EntityAType": "URL",
                "EntityBType": "Domain",
                "EntityA": "http://example.com",
                "EntityB": "example.com",
                "id": "rel2",
            },
        ],
        "RelationshipsPagination": [],
    }

    result = filter_relationships_by_entity_types(["test.exe"], ["File"], [], 10)

    assert len(result) == 0


def test_filter_relationships_by_entity_types_empty_response(mocker):
    """
    Given: An empty response from the SearchIndicatorRelationships command
    When: Calling filter_relationships_by_entity_types function
    Then: An empty list should be returned
    """
    from SearchIndicatorRelationshipsAgentix import filter_relationships_by_entity_types

    mock_execute_command = mocker.patch("SearchIndicatorRelationshipsAgentix.demisto.executeCommand")

    mock_execute_command.return_value = []

    result = filter_relationships_by_entity_types(["test.exe"], ["File"], [], 10)

    assert result == []


def test_filter_relationships_by_entity_types_domain_relates_to(mocker):
    """
    Given: A relationship exists where google.com relates to example.com
    When: Calling filter_relationships_by_entity_types function with domain entities
    Then: The relationship should be returned
    """
    from SearchIndicatorRelationshipsAgentix import filter_relationships_by_entity_types

    mock_execute_command = mocker.patch("SearchIndicatorRelationshipsAgentix.demisto.executeCommand")
    mock_get = mocker.patch("SearchIndicatorRelationshipsAgentix.demisto.get")

    mock_execute_command.return_value = [
        {
            "Contents": {
                "Relationships": [
                    {
                        "EntityAType": "Domain",
                        "EntityBType": "Domain",
                        "EntityA": "google.com",
                        "EntityB": "example.com",
                        "Relationship": "relates-to",
                        "id": "rel1",
                    }
                ]
            }
        }
    ]

    mock_get.return_value = {
        "Relationships": [
            {
                "EntityAType": "Domain",
                "EntityBType": "Domain",
                "EntityA": "google.com",
                "EntityB": "example.com",
                "Relationship": "relates-to",
                "id": "rel1",
            }
        ],
        "RelationshipsPagination": [],
    }

    result = filter_relationships_by_entity_types(["google.com", "example.com"], ["Domain"], ["relates-to"], 10)

    assert len(result) == 1
    assert result[0]["EntityA"] == "google.com"
    assert result[0]["EntityB"] == "example.com"
    assert result[0]["Relationship"] == "relates-to"
    assert result[0]["EntityAType"] == "Domain"
    assert result[0]["EntityBType"] == "Domain"


def test_filter_relationships_by_entity_types_domain_not_matching_type(mocker):
    """
    Given: A relationship exists where google.com relates to 8.8.8.8 (IP)
    When: Calling filter_relationships_by_entity_types function with google.com and DOMAIN type
    Then: No relationships should be returned
    """
    from SearchIndicatorRelationshipsAgentix import filter_relationships_by_entity_types

    mock_execute_command = mocker.patch("SearchIndicatorRelationshipsAgentix.demisto.executeCommand")
    mock_get = mocker.patch("SearchIndicatorRelationshipsAgentix.demisto.get")

    mock_execute_command.return_value = [
        {
            "Contents": {
                "Relationships": [
                    {
                        "EntityAType": "Domain",
                        "EntityBType": "IP",
                        "EntityA": "google.com",
                        "EntityB": "8.8.8.8",
                        "Relationship": "relates-to",
                        "id": "rel1",
                    }
                ]
            }
        }
    ]

    mock_get.return_value = {
        "Relationships": [
            {
                "EntityAType": "Domain",
                "EntityBType": "IP",
                "EntityA": "google.com",
                "EntityB": "8.8.8.8",
                "Relationship": "relates-to",
                "id": "rel1",
            }
        ],
        "RelationshipsPagination": [],
    }

    result = filter_relationships_by_entity_types(["google.com"], ["Domain"], ["relates-to"], 10)

    assert len(result) == 0