FileCreateAndUploadV2
Creates a file (using the given data input or entry ID) and uploads it to the current investigation War Room.
python · Common Scripts
Details
| ID | FileCreateAndUploadV2 |
|---|---|
| Language | python |
| From Version | 6.0.0 |
| Docker Image | demisto/python3:3.12.13.10404775 |
| Tags | Utility |
README
Creates a file (using the given data input or entry ID) and uploads it to the current investigation War Room.
Script Data
| Name | Description |
|---|---|
| Script Type | python3 |
| Tags | Utility |
| Cortex XSOAR Version | 6.0.0 |
Inputs
| Argument Name | Description |
|---|---|
| filename | The name of the file to be created. |
| data | Input data to write to the file. |
| entryId | Entry ID contents to write in the file. |
| data_encoding | Encoding type of the input data or contents. |
Outputs
| Path | Description | Type |
|---|---|---|
| File.Size | The size of the file. | Number |
| File.SHA1 | The SHA1 hash of the file. | String |
| File.SHA256 | The SHA256 hash of the file. | String |
| File.SHA512 | The SHA512 hash of the file. | String |
| File.Name | The name of the file. | String |
| File.SSDeep | The SSDeep hash of the file. | String |
| File.EntryID | The entry ID of the file. | String |
| File.Info | File information. | String |
| File.Type | The file type. | String |
| File.MD5 | The MD5 hash of the file. | String |
| File.Extension | The file extension. | String |
Script Examples
Example command
!FileCreateAndUploadV2 filename=test.txt data=test
Context Example
{
"File": {
"EntryID": "919@35961d68-3216-49b9-870a-2f09e5dac489",
"Extension": "txt",
"Info": "text/plain; charset=utf-8",
"MD5": "098f6bcd4621d373cade4e832627b4f6",
"Name": "test.txt",
"SHA1": "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3",
"SHA256": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
"SHA512": "ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a8ff",
"SSDeep": "3:Hn:Hn",
"Size": 4,
"Type": "ASCII text, with no line terminators"
}
}
Limitation
Using the entryID argument to copy the contents of an existing file from different incidents is only available from XSOAR version 6.12.0 onwards.
import json import sys from pathlib import Path import demistomock as demisto import pytest from CommonServerPython import DemistoException from FileCreateAndUploadV2 import ( EntryType, decode_data, get_data_entry, get_data_from_file, main, ) from pytest_mock import MockerFixture def side_effect_sys_exit(code): pass def test_main(mocker): mocker.patch.object(sys, "exit", side_effect=side_effect_sys_exit) with open("./test_data/test-1.json") as f: test_list = json.load(f) for eval in test_list: mocker.patch.object( demisto, "args", return_value={ "filename": eval["filename"], "data": eval.get("data"), "data_encoding": eval.get("data_encoding"), "entryId": eval.get("entryId"), }, ) mocker.patch.object(demisto, "results") main() assert demisto.results.call_count == 1 results = demisto.results.call_args[0][0] assert (eval["ok"] and results["Type"] == 3) or ((not eval["ok"]) and results["Type"] != 3) def test_main_with_entry_id(mocker): """ Given an entry ID as an argument, When the main function is called, Then it should fetch the entry metadata, get the data associated with the entry, decode the data, and return the result. """ mocker.patch.object( demisto, "args", return_value={ "filename": "test.txt", "data": "test_file_data", "data_encoding": "raw_encoding", "entryId": "1234", }, ) mock_file_data = b"test_file_data" mock_get_entry_metadata = mocker.patch( "FileCreateAndUploadV2.get_entry_metadata", return_value={"Type": EntryType.FILE, "ID": "1234"} ) mock_get_data_entry = mocker.patch("FileCreateAndUploadV2.get_data_entry", return_value=mock_file_data) mock_decode_data = mocker.patch("FileCreateAndUploadV2.decode_data", return_value=mock_file_data) mocker.patch.object(demisto, "results") main() results = demisto.results.call_args[0][0] assert results["File"] == "test.txt" assert results["ContentsFormat"] == "text" mock_get_entry_metadata.assert_called_once_with("1234") mock_get_data_entry.assert_called_once_with(mock_get_entry_metadata.return_value) mock_decode_data.assert_called_once_with(mock_get_data_entry.return_value, "raw_encoding") def test_main_without_entry_id(mocker: MockerFixture) -> None: """Given valid arguments without an entry_id, When the main function is called, Then it should not raise any exceptions. """ mocker.patch.object( demisto, "args", return_value={ "filename": "test_file", "data": "test_data", "data_encoding": "raw", }, ) mocker.patch("FileCreateAndUploadV2.decode_data", return_value=b"test_data") mocker.patch.object(demisto, "results") main() results = demisto.results.call_args[0][0] assert results["File"] == "test_file" assert results["ContentsFormat"] == "text" def test_get_data_from_file(mocker: MockerFixture) -> None: """Given a valid entry_id, When the get_data_from_file function is called, Then it should return the data read from the file. """ mocker.patch.object(Path, "read_bytes", return_value=b"test_data") mocker.patch.object(demisto, "getFilePath", return_value={"path": "test_path"}) assert get_data_from_file("test_entry_id") == b"test_data" def test_get_data_from_file_exception(mocker: MockerFixture) -> None: """Given an invalid entry_id, When the get_data_from_file function is called, Then it should raise a DemistoException. """ mocker.patch.object(Path, "read_bytes", side_effect=Exception("Error")) mocker.patch.object(demisto, "getFilePath", return_value={"path": "test_path"}) with pytest.raises(DemistoException, match="There was a problem opening or reading the file.\nError is: Error"): get_data_from_file("test_entry_id") def test_decode_data_base64() -> None: """Given a base64 encoded data, When the decode_data function is called with data_encoding as 'base64', Then it should return the decoded data. """ assert decode_data(b"dGVzdF9kYXRh", "base64") == b"test_data" def test_decode_data_raw() -> None: """Given a raw data, When the decode_data function is called with data_encoding as 'raw', Then it should return the same data. """ assert decode_data(b"test_data", "raw") == b"test_data" def test_decode_data_invalid() -> None: """Given a data, When the decode_data function is called with an invalid data_encoding, Then it should raise a ValueError. """ with pytest.raises(ValueError, match="Invalid data encoding value: invalid, must be either `base64` or `raw`"): decode_data(b"test_data", "invalid") @pytest.mark.parametrize( "entry_type", [ pytest.param(EntryType.FILE, id="entry file type"), pytest.param(EntryType.IMAGE, id="entry image type"), pytest.param(EntryType.ENTRY_INFO_FILE, id="entry info file type"), pytest.param(EntryType.VIDEO_FILE, id="entry video file type"), ], ) def test_get_data_entry_with_various_file_types(mocker: MockerFixture, entry_type: int) -> None: """ Given a dictionary with entry metadata, When the entry type is one of the file types (FILE, IMAGE, ENTRY_INFO_FILE, VIDEO_FILE), Then the function should return the data from the file associated with the entry ID. """ mock_get_data_from_file = mocker.patch("FileCreateAndUploadV2.get_data_from_file", return_value=b"test file data") entry_metadata = {"Type": entry_type, "ID": "1234"} result = get_data_entry(entry_metadata) assert result == b"test file data" mock_get_data_from_file.assert_called_once_with("1234") def test_get_data_entry_no_file_type(mocker: MockerFixture) -> None: """ Given a dictionary with entry metadata, When the entry type is not FILE, IMAGE, ENTRY_INFO_FILE, or VIDEO_FILE, Then the function should return the contents from the entry metadata. """ mock_get_data_from_file = mocker.patch("FileCreateAndUploadV2.get_data_from_file") entry_metadata = {"Type": 0, "ID": "1234", "Contents": "other data"} result = get_data_entry(entry_metadata) assert result == "other data" mock_get_data_from_file.assert_not_called()