ExtractEmailV2

Verifies that an email address is valid and only returns the address if it is valid.

python · Common Scripts

Details

IDExtractEmailV2
Languagepython
From Version5.5.0
Docker Imagedemisto/python3:3.12.13.10116658
Tagsindicator-format

README

Verifies that an email address is valid and only returns the address if it is valid.

Script Data


Name Description
Script Type python3
Tags indicator-format
Cortex XSOAR Version 5.5.0

Inputs


Argument Name Description
input The Emails to process.

Outputs


There are no outputs for this script.

import demistomock as demisto
import pytest
from ExtractEmailFormatting import check_tld, extract_email, extract_email_from_url_query, main, refang_email
from pytest_mock import MockFixture

defang_data = [
    ("xsoar@test[.]com", "xsoar@test.com"),  # disable-secrets-detection
    ("xsoar[@]test[.]com", "xsoar@test.com"),  # disable-secrets-detection
    ("xsoar[@]test.com", "xsoar@test.com"),  # disable-secrets-detection
]


@pytest.mark.parametrize("address,valid", defang_data)
def test_check_defanging(address, valid):
    assert refang_email(address) == valid


tld_data = [
    ("Xsoar@test.org.de", True),  # disable-secrets-detection
    ("xsoar@test.net.bla", True),  # disable-secrets-detection
    ("Xsoar@test.uk.png", False),  # disable-secrets-detection
    ("Xsoar@test.eml", False),  # disable-secrets-detection
    ("Xsoar@test.new.docx", False),  # disable-secrets-detection
    ("entry@id.com.gif", False),  # disable-secrets-detection
    ("randomName@randomDomain.com", True),  # disable-secrets-detection
    ("Xsoar@xsoar.xlsx", False),  # disable-secrets-detection
]


@pytest.mark.parametrize("address,valid", tld_data)
def test_check_tld(address, valid):
    assert check_tld(address) is valid


@pytest.mark.parametrize(
    "input,output",
    [  # noqa: E501 disable-secrets-detection # no processing needed
        ("\\u003ctest@test.com", "test@test.com"),
        ('"test@test.com"', "test@test.com"),
        ("<test@test.com>", "test@test.com"),
        ("test", ""),
        ("co/ed/trn/update?a=b&email=user@test6.net", "user@test6.net"),
        ("https://example.com/?marketing.comunicacion@example.com=ABA=123&a=456/", "marketing.comunicacion@example.com"),
        ("//example.com?marketing.comunicacion@example.com", "marketing.comunicacion@example.com"),  # disable-secrets-detection
        # Regression tests: valid emails with special characters should not be treated as URL queries
        ("user+tag@example.com", "user+tag@example.com"),  # Email with + (valid character)
        ("user=name@example.com", "user=name@example.com"),  # Email with = in local part (valid but rare)
        ("simple@example.com", "simple@example.com"),  # Simple valid email without special chars
    ],
)  # noqa: E124
def test_extract_email(input, output):
    assert extract_email(input) == output


@pytest.mark.parametrize(
    "input,output",
    [  # noqa: E501 disable-secrets-detection # no processing needed
        ("co/ed/trn/update?a=b&email=user@test6.net", "user@test6.net"),
        ("co/ed/trn/update?", ""),
        ("marketing.comunicacion@example.com=ABA=123", "marketing.comunicacion@example.com"),
        ("//example.com?marketing.comunicacion@example.com", "marketing.comunicacion@example.com"),  # disable-secrets-detection
        ("//example.com?marketing.comunicacion@example.com=", "marketing.comunicacion@example.com"),  # disable-secrets-detection
    ],
)  # noqa: E124
def test_extract_email_from_url_query(input, output):
    assert extract_email_from_url_query(input) == output


ARGS = {
    "input": "Xsoar@test.org.de,Xsoar@test.eml, "  # disable-secrets-detection
    "Xsoar@test.uk, "  # disable-secrets-detection
    "Xsoar@xsoar.xlsx,Xsoar@xsoar.co.il"  # disable-secrets-detection
}

EXPECTED_RESULTS = [
    ["xsoar@test.org.de"],  # disable-secrets-detection
    [],
    ["xsoar@test.uk"],  # disable-secrets-detection
    [],
    ["xsoar@xsoar.co.il"],  # disable-secrets-detection
]


def test_main(mocker):
    """Verifies that all valid addresses get returned.
    Given
    - Email addresses that were auto-extracted by the Email regex.
    When
    - Auto extracting an email address or using the extractIndicator script.
    Then
    - Return all valid addresses
    """
    mocker.patch.object(demisto, "args", return_value=ARGS)
    mocker.patch.object(demisto, "results")
    main()
    results = [email_address["Contents"] for email_address in demisto.results.call_args[0][0]]
    assert results == EXPECTED_RESULTS


def test_main_invalid_emails(mocker):
    """Verifies that no input returns an empty string.
    Given
    - Empty string as an input to the formatter.
    When
    - An empty string is passed to formatter by the user.
    Then
    - Return an empty string
    """
    mocker.patch.object(demisto, "args", return_value={"input": ""})
    mocker.patch.object(demisto, "results")
    main()
    assert demisto.results.call_args[0][0] == ""


def test_main_raise_error(mocker: MockFixture):
    """
    Given:
        - Exception during the automation
    When:
        - Running the automation
    Then:
        - Ensure the return_error is called with the correct error message.
    """
    return_error_mock = mocker.patch("ExtractEmailFormatting.return_error")
    mocker.patch("ExtractEmailFormatting.argToList", side_effect=Exception("Test Exception"))

    main()

    assert return_error_mock.call_count == 1
    assert "Error: \nTest Exception" in return_error_mock.call_args[0][0]