Azure Storage FileShare

Create and Manage Azure FileShare Files and Directories.

IT Services · Azure Storage FileShare

Details

IDAzure Storage FileShare
ProviderMicrosoft
CategoryIT Services
From Version6.0.0
Docker Imagedemisto/python3:3.12.13.10116658
Supported ModulesAgentix XSIAM

README

Azure Storage FileShare

Create and Manage Azure FileShare Files and Directories.
This integration was integrated and tested with version “2020-10-02” of Azure Storage FileShare

Configure Azure Storage FileShare in Cortex

Parameter Required
Storage account name True
Account SAS Token True
Use system proxy settings False
Trust any certificate (not secure) False

Shared Access Signatures (SAS) Permissions

In order to use the integration use-cases,
please make sure your SAS token contains the following permissions:

  1. ‘File’ and ‘Blob’ services.
  2. ‘Service’, ‘Container’ and ‘Object’ resource types.
  3. ‘Read’, ‘Write’, ‘Delete’, ‘List’, ‘Create’, ‘Add’, ‘Update’ and ‘Immutable storage’ permissions.
  4. ‘Blob versioning permissions’

Commands

You can execute these commands from the 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.

azure-storage-fileshare-create


Create a new Azure file share under the specified account.

Base Command

azure-storage-fileshare-create

Input

Argument Name Description Required
share_name The name of the new Share to create. Rules for naming shares can be found here: https://docs.microsoft.com/en-us/rest/api/storageservices/naming-and-referencing-shares–directories–files–and-metadata. Required

Context Output

There is no context output for this command.

Command Example

!azure-storage-fileshare-create share_name="test-xsoar"

Human Readable Output

Share test-xsoar successfully created.

azure-storage-fileshare-delete


Delete file share under the specified account.

Base Command

azure-storage-fileshare-delete

Input

Argument Name Description Required
share_name The name of the Share to delete. Required

Context Output

There is no context output for this command.

Command Example

!azure-storage-fileshare-delete share_name="test-xsoar"

Human Readable Output

Share test-xsoar successfully deleted.

azure-storage-fileshare-list


list Azure file shares under the specified account.

Base Command

azure-storage-fileshare-list

Input

Argument Name Description Required
limit Number of shares to retrieve. Default is 50. Default is 50. Optional
prefix Filters the results to return only shares whose name begins with the specified prefix. Optional
page Page number. Default is 1. Default is 1. Optional

Context Output

Path Type Description
AzureStorageFileShare.Share.Name String Share name.

Command Example

!azure-storage-fileshare-list prefix="test-xsoar" limit="1"

Context Example

{
    "AzureStorageFileShare": {
        "Share": {
            "Name": "test-xsoar"
        }
    }
}

Human Readable Output

Shares List

Current page size: 1
Showing page 1 out others that may exist

Name
test-xsoar

azure-storage-fileshare-content-list


List files and directories under the specified share or directory.

Base Command

azure-storage-fileshare-content-list

Input

Argument Name Description Required
prefix Filters the results to return only files and directories whose name begins with the specified prefix. Optional
limit Number of directories and files to retrieve. Default is 50. Default is 50. Optional
share_name The name of the Share in which the directories ans files are located. Required
directory_path The path to the parent directory of the directories and files to retrieve. A path name is composed of one or more directory name components separated by the forward-slash (/) character. If the parent directory path is omitted, the directory will be referred to the first level of the specified share. Optional
page Page number. Default is 1. Default is 1. Optional

Context Output

Path Type Description
AzureStorageFileShare.Share.Name String Share name.
AzureStorageFileShare.Share.Content.Path String Directory path..
AzureStorageFileShare.Share.Content.DirectoryId String Directory ID.
AzureStorageFileShare.Share.Content.File.FileId String File ID.
AzureStorageFileShare.Share.Content.File.Name String File name.
AzureStorageFileShare.Share.Content.File.Property.Content-Length String File size in bytes.
AzureStorageFileShare.Share.Content.File.Property.CreationTime Date File creation time.
AzureStorageFileShare.Share.Content.File.Property.LastAccessTime Date File last access time.
AzureStorageFileShare.Share.Content.File.Property.LastWriteTime Date File last write time.
AzureStorageFileShare.Share.Content.File.Property.ChangeTime Date File change time.
AzureStorageFileShare.Share.Content.File.Property.Last-Modified Date File last modified time.
AzureStorageFileShare.Share.Content.Directory.FileId String Directory ID.
AzureStorageFileShare.Share.Content.Directory.Name String Directory name.
AzureStorageFileShare.Share.Content.Directory.Property.CreationTime Date File creation time.
AzureStorageFileShare.Share.Content.Directory.Property.LastAccessTime Date File last access time.
AzureStorageFileShare.Share.Content.Directory.Property.LastWriteTime Date File last write time.
AzureStorageFileShare.Share.Content.Directory.Property.ChangeTime Date File change time.
AzureStorageFileShare.Share.Content.Directory.Property.Last-Modified Date File last modified time.

Command Example

!azure-storage-fileshare-content-list limit="50" share_name="myfileshare" directory_path="mydirectorytest" page="1"

Context Example

{
    "AzureStorageFileShare": {
        "Share": {
            "Content": {
                "Directory": [
                    {
                        "FileId": "13835084443561230336",
                        "Name": "tttttt",
                        "Property": {
                            "ChangeTime": "2021-08-12T07:11:50",
                            "CreationTime": "2021-08-12T07:11:50",
                            "Last-Modified": "2021-08-12T07:11:50",
                            "LastAccessTime": "2021-08-12T07:11:50",
                            "LastWriteTime": "2021-08-12T07:11:50"
                        }
                    },
                    {
                        "FileId": "16140971433240035328",
                        "Name": "yehuda123",
                        "Property": {
                            "ChangeTime": "2021-08-06T13:44:04",
                            "CreationTime": "2021-08-06T13:44:04",
                            "Last-Modified": "2021-08-06T13:44:04",
                            "LastAccessTime": "2021-08-06T13:44:04",
                            "LastWriteTime": "2021-08-06T13:44:04"
                        }
                    }
                ],
                "DirectoryId": "11529285414812647424",
                "File": [
                    {
                        "FileId": "13835137220119363584",
                        "Name": "testepoccreation.txt",
                        "Property": {
                            "ChangeTime": "2021-08-12T05:26:11",
                            "Content-Length": "11",
                            "CreationTime": "2021-08-12T05:26:11",
                            "Last-Modified": "2021-08-15T09:39:17",
                            "LastAccessTime": "2021-08-12T05:26:11",
                            "LastWriteTime": "2021-08-12T05:26:11"
                        }
                    },
                    {
                        "FileId": "13835060254305419264",
                        "Name": "testsasss.txt",
                        "Property": {
                            "ChangeTime": "2021-08-15T09:44:16",
                            "Content-Length": "11",
                            "CreationTime": "2021-08-15T09:44:16",
                            "Last-Modified": "2021-08-15T09:44:16",
                            "LastAccessTime": "2021-08-15T09:44:16",
                            "LastWriteTime": "2021-08-15T09:44:16"
                        }
                    }
                ],
                "Path": "mydirectorytest"
            },
            "Name": "myfileshare"
        }
    }
}

Human Readable Output

Directories and Files List:
Current page size: 50
Showing page 1 out others that may exist

Directories

Name File Id
tttttt 13835084443561230336
yehuda123 16140971433240035328

Files

Name File Id
testepoccreation.txt 13835137220119363584
testsasss.txt 13835060254305419264

azure-storage-fileshare-directory-create


Create a new directory under the specified share or parent directory.

Base Command

azure-storage-fileshare-directory-create

Input

Argument Name Description Required
share_name The name of the Share in which the new directory will be created. Required
directory_name The name of the new directory. Required
directory_path The path to the parent directory where the new directory will be created. A path name is composed of one or more directory name components separated by the forward-slash (/) character. If the parent directory path is omitted, the directory will be referred to the first level of the specified share. Optional

Context Output

There is no context output for this command.

Command Example

!azure-storage-fileshare-directory-create share_name="test-xsoar" directory_name="xsoar-directory"

Human Readable Output

xsoar-directory Directory successfully created in test-xsoar.

azure-storage-fileshare-directory-delete


Delete the specified empty directory. Note that the directory must be empty before it can be deleted.

Base Command

azure-storage-fileshare-directory-delete

Input

Argument Name Description Required
share_name The name of the Share in which the directory is located. Required
directory_name The name of the directory to delete. Required
directory_path The path to the parent directory of the directory to delete. A path name is composed of one or more directory name components separated by the forward-slash (/) character. If the parent directory path is omitted, the directory will be referred to the first level of the specified share. Optional

Context Output

There is no context output for this command.

Command Example

!azure-storage-fileshare-directory-delete share_name="test-xsoar" directory_name="xsoar-directory"

Human Readable Output

xsoar-directory Directory successfully deleted from test-xsoar.

azure-storage-fileshare-file-create


Creates a new file in Share.

Base Command

azure-storage-fileshare-file-create

Input

Argument Name Description Required
share_name The name of the Share in which the new file will be created. Required
file_entry_id The entry ID of the file to upload as a new file. Available from XSOAR war room while the context data contains file output. Required
directory_path The path to the parent directory where the new file will be created. A path name is composed of one or more directory name components separated by the forward-slash (/) character. If the parent directory path is omitted, the directory will be created within first level of the specified share. Optional
file_name The name of the new file to create. Default is XSOAR file name. The file suffix should be specified. for example: test.txt. Optional

Context Output

There is no context output for this command.

Command Example

!azure-storage-fileshare-file-create share_name="test-xsoar" directory_path="xsoar-directory" file_name="AzureStorage.txt" file_entry_id="16488@b5e40781-86c8-4799-8f10-ace443e93234"

Human Readable Output

File successfully created in test-xsoar.

azure-storage-fileshare-file-get


Retrieve file from Share.

Base Command

azure-storage-fileshare-file-get

Input

Argument Name Description Required
share_name The name of the Share in which the file is located. Required
file_name The name of the file to retrieve. The file suffix should be specified. for example: test.txt. Required
directory_path The path to the parent directory of the file to retrieve. A path name is composed of one or more directory name components separated by the forward-slash (/) character. If the parent directory path is omitted, the directory will be referred to the first level of the specified share. Optional

Context Output

Path Type Description
File.Size Number The size of the file.
File.SHA1 String The SHA1 hash of the file.
File.SHA256 String The SHA256 hash of the file.
File.Name String The name of the file.
File.SSDeep String The SSDeep hash of the file.
File.EntryID String The entry ID of the file.
File.Info String File information.
File.Type String The file type.
File.MD5 String The MD5 hash of the file.
File.Extension String The file extension.

Command Example

!azure-storage-fileshare-file-get share_name="test-xsoar" file_name="AzureStorage.txt" directory_path="xsoar-directory"

Context Example

{
    "File": {
        "EntryID": "16572@b5e40781-86c8-4799-8f10-ace443e93234",
        "Extension": "txt",
        "Info": "text/plain; charset=utf-8",
        "MD5": "950eb0708854a661313dd150a643af8b",
        "Name": "AzureStorage.txt",
        "SHA1": "2f82d9a13f948a1ced93f9da85323d45fb2eedf8",
        "SHA256": "150296c0c1a1ca044fc132010b6049342c460f4a68386ab24de9b6a167e54765",
        "SHA512": "6d9deaacce47943767d19c8de846c9e57692543c90b4f45c3abbe4123380bd1665dc4bd9b4d0a99d09d3a0f8c67da842826181834223362f1c75f5f9e6c358ef",
        "SSDeep": "3:h8Kpl:Rpl",
        "Size": 11,
        "Type": "ASCII text, with no line terminators"
    }
}

Human Readable Output

azure-storage-fileshare-file-delete


Delete file from Share.

Base Command

azure-storage-fileshare-file-delete

Input

Argument Name Description Required
share_name The name of the Share in which the file is located. Required
file_name The name of the file to delete. The file suffix should be specified. for example: test.txt. Required
directory_path The path to the parent directory of the file to delete. A path name is composed of one or more directory name components separated by the forward-slash (/) character. If the parent directory path is omitted, the directory will be referred to the first level of the specified share. Optional

Context Output

There is no context output for this command.

Command Example

!azure-storage-fileshare-file-delete share_name="test-xsoar" file_name="AzureStorage.txt" directory_path="xsoar-directory"

Human Readable Output

File AzureStorage.txt successfully deleted from test-xsoar.

Configuration parameters

  • credentials — Storage account name (required)
  • proxy — Use system proxy settings
  • insecure — Trust any certificate (not secure)

Commands (9)

  • azure-storage-fileshare-content-list

    List files and directories under the specified share or directory.

  • azure-storage-fileshare-create

    Create a new Azure file share under the specified account.

  • azure-storage-fileshare-delete

    Delete file share under the specified account.

  • azure-storage-fileshare-directory-create

    Create a new directory under the specified share or parent directory.

  • azure-storage-fileshare-directory-delete

    Delete the specified empty directory. Note that the directory must be empty before it can be deleted.

  • azure-storage-fileshare-file-create

    Creates a new file in Share.

  • azure-storage-fileshare-file-delete

    Delete file from Share.

  • azure-storage-fileshare-file-get

    Retrieve file from Share.

  • azure-storage-fileshare-list

    list Azure file shares under the specified account.

import defusedxml.ElementTree as defused_ET
import pytest
from CommonServerPython import *

ACCOUNT_NAME = "test"
BASE_URL = f"https://{ACCOUNT_NAME}.file.core.windows.net/"
SAS_TOKEN = "XXXX"
API_VERSION = "2020-10-02"


def load_xml_mock_response(file_name: str) -> str:
    """
    Load one of the mock responses to be used for assertion.
    Args:
        file_name (str): Name of the mock response XML file to return.
    """
    file_path = f"test_data/{file_name}"

    top = defused_ET.parse(file_path)
    return ET.tostring(top.getroot(), encoding="utf8").decode("utf-8")


def test_azure_storage_create_share_command(requests_mock):
    """
    Scenario: Create new Share.
    Given:
     - User has provided valid credentials.
    When:
     - azure-storage-fileshare-create called.
    Then:
     - Ensure that the output is empty (None).
     - Ensure readable output message content.
     - Ensure validation of the share name.
    """
    from AzureStorageFileShare import Client, create_share_command

    share_name = "test"
    url = f"{BASE_URL}{share_name}?{SAS_TOKEN}&restype=share"

    requests_mock.put(url, text="")

    client = Client(
        server_url=BASE_URL,
        verify=False,
        proxy=False,
        account_sas_token=SAS_TOKEN,
        storage_account_name=ACCOUNT_NAME,
        api_version=API_VERSION,
    )
    result = create_share_command(client, {"share_name": share_name})

    assert result.outputs is None
    assert result.outputs_prefix is None
    assert result.readable_output == f"Share {share_name} successfully created."

    invalid_share_name = "test--1"

    with pytest.raises(Exception):
        create_share_command(client, {"share_name": invalid_share_name})


def test_azure_storage_delete_share_command(requests_mock):
    """
    Scenario: Delete Share.
    Given:
     - User has provided valid credentials.
    When:
     - azure-storage-fileshare-delete called.
    Then:
     - Ensure that the output is empty (None).
     - Ensure readable output message content.
    """
    from AzureStorageFileShare import Client, delete_share_command

    share_name = "test"
    url = f"{BASE_URL}{share_name}?{SAS_TOKEN}&restype=share"

    requests_mock.delete(url, text="")

    client = Client(
        server_url=BASE_URL,
        verify=False,
        proxy=False,
        account_sas_token=SAS_TOKEN,
        storage_account_name=ACCOUNT_NAME,
        api_version=API_VERSION,
    )
    result = delete_share_command(client, {"share_name": share_name})

    assert result.outputs is None
    assert result.outputs_prefix is None
    assert result.readable_output == f"Share {share_name} successfully deleted."


def test_azure_storage_list_shares_command(requests_mock):
    """
    Scenario: List Shares.
    Given:
     - User has provided valid credentials.
    When:
     - azure-storage-fileshare-list called.
    Then:
     - Ensure number of items is correct.
     - Ensure outputs prefix is correct.
     - Ensure a sample value from the API matches what is generated in the context.
    """
    from AzureStorageFileShare import Client, list_shares_command

    url = f"{BASE_URL}?{SAS_TOKEN}&comp=list&maxresults=50"
    mock_response = load_xml_mock_response("shares.xml")
    requests_mock.get(url, text=mock_response)

    client = Client(
        server_url=BASE_URL,
        verify=False,
        proxy=False,
        account_sas_token=SAS_TOKEN,
        storage_account_name=ACCOUNT_NAME,
        api_version=API_VERSION,
    )
    result = list_shares_command(client, {})

    assert len(result.outputs) == 2
    assert result.outputs_prefix == "AzureStorageFileShare.Share"
    assert result.outputs[0].get("Name") == "my-file-share"
    assert result.outputs[1].get("Name") == "my-share"


def test_azure_storage_list_directories_and_files_command(requests_mock):
    """
    Scenario: List directories and files.
    Given:
     - User has provided valid credentials.
    When:
     - azure-storage-fileshare-content-list called.
    Then:
     - Ensure number of items is correct.
     - Ensure outputs prefix is correct.
     - Ensure a sample value from the API matches what is generated in the context.
    """
    from AzureStorageFileShare import Client, list_directories_and_files_command

    share_name = "test"
    url = f"{BASE_URL}{share_name}?{SAS_TOKEN}&restype=directory&comp=list&include=Timestamps&maxresults=50"
    mock_response = load_xml_mock_response("files.xml")
    requests_mock.get(url, text=mock_response)

    client = Client(
        server_url=BASE_URL,
        verify=False,
        proxy=False,
        account_sas_token=SAS_TOKEN,
        storage_account_name=ACCOUNT_NAME,
        api_version=API_VERSION,
    )
    result = list_directories_and_files_command(client, {"share_name": share_name})

    assert len(result.outputs) == 2
    assert len(result.outputs.get("Content")) == 4
    assert len(result.outputs.get("Content").get("Directory")) == 1
    assert len(result.outputs.get("Content").get("File")) == 1
    assert result.outputs_prefix == "AzureStorageFileShare.Share"
    assert result.outputs.get("Content")["File"][0].get("Name") == "AzureStorage_image.png"
    assert result.outputs.get("Name") == share_name


def test_azure_storage_create_directory_command(requests_mock):
    """
    Scenario: Create directory.
    Given:
     - User has provided valid credentials.
    When:
     - azure-storage-fileshare-directory-create called.
    Then:
     - Ensure that the output is empty (None).
     - Ensure readable output message content.
     - Ensure validation of the directory name.
    """
    from AzureStorageFileShare import Client, create_directory_command

    share_name = "test"
    directory_name = "test_new_directory"
    url = f"{BASE_URL}{share_name}/{directory_name}?{SAS_TOKEN}&restype=directory"

    requests_mock.put(url, text="")

    client = Client(
        server_url=BASE_URL,
        verify=False,
        proxy=False,
        account_sas_token=SAS_TOKEN,
        storage_account_name=ACCOUNT_NAME,
        api_version=API_VERSION,
    )
    result = create_directory_command(client, {"share_name": share_name, "directory_name": directory_name})

    assert result.outputs is None
    assert result.outputs_prefix is None
    assert result.readable_output == f"{directory_name} Directory successfully created in {share_name}."

    invalid_directory_name = "test<1"

    with pytest.raises(Exception):
        create_directory_command(client, {"share_name": share_name, "directory_name": invalid_directory_name})


def test_azure_storage_delete_directory_command(requests_mock):
    """
    Scenario: Delete directory.
    Given:
     - User has provided valid credentials.
    When:
     - azure-storage-fileshare-directory-delete called.
    Then:
     - Ensure that the output is empty (None).
     - Ensure readable output message content.
    """
    from AzureStorageFileShare import Client, delete_directory_command

    share_name = "test"
    directory_name = "test_new_directory"
    url = f"{BASE_URL}{share_name}/{directory_name}?{SAS_TOKEN}&restype=directory"

    requests_mock.delete(url, text="")

    client = Client(
        server_url=BASE_URL,
        verify=False,
        proxy=False,
        account_sas_token=SAS_TOKEN,
        storage_account_name=ACCOUNT_NAME,
        api_version=API_VERSION,
    )
    result = delete_directory_command(client, {"share_name": share_name, "directory_name": directory_name})

    assert result.outputs is None
    assert result.outputs_prefix is None
    assert result.readable_output == f"{directory_name} Directory successfully deleted from {share_name}."


def test_azure_storage_get_file_command(requests_mock):
    """
    Scenario: Get file.
    Given:
     - User has provided valid credentials.
    When:
     - azure-storage-fileshare-file-get called.
    Then:
     - Ensure XSOAR File output.
    """
    from AzureStorageFileShare import Client, get_file_command

    share_name = "test"
    file_name = "test_file.txt"
    url = f"{BASE_URL}{share_name}/{file_name}?{SAS_TOKEN}"

    with open("test_data/test_file.txt", "rb") as text_file_mock:
        requests_mock.get(url, content=text_file_mock.read())

    client = Client(
        server_url=BASE_URL,
        verify=False,
        proxy=False,
        account_sas_token=SAS_TOKEN,
        storage_account_name=ACCOUNT_NAME,
        api_version=API_VERSION,
    )
    result = get_file_command(client, {"share_name": share_name, "file_name": file_name})

    assert result["ContentsFormat"] == "text"
    assert result["Type"] == EntryType.FILE
    assert result["File"] == file_name
    assert len(result) == 5


def test_azure_storage_delete_file_command(requests_mock):
    """
    Scenario: Delete file
    Given:
     - User has provided valid credentials.
    When:
     - azure-storage-fileshare-file-delete called.
    Then:
     - Ensure that the output is empty (None).
     - Ensure readable output message content.
    """
    from AzureStorageFileShare import Client, delete_file_command

    share_name = "test"
    file_name = "test_file.txt"
    url = f"{BASE_URL}{share_name}/{file_name}?{SAS_TOKEN}"

    requests_mock.delete(url, text="")

    client = Client(
        server_url=BASE_URL,
        verify=False,
        proxy=False,
        account_sas_token=SAS_TOKEN,
        storage_account_name=ACCOUNT_NAME,
        api_version=API_VERSION,
    )
    result = delete_file_command(client, {"share_name": share_name, "file_name": file_name})

    assert result.outputs is None
    assert result.outputs_prefix is None
    assert result.readable_output == f"File {file_name} successfully deleted from {share_name}."


def test_validate_characters():
    """
    Test validate_characters function.
    Scenarios:
        - Send valid string to function.
        - Send invalid string to function.
    Then:
     - Ensure that the output is correct (True / False).

    """
    from AzureStorageFileShare import validate_characters

    valida_string = "my-valid-test"
    invalid_string = "my-invalid|test"

    assert validate_characters(valida_string, '"\/:|<>*?')
    assert not validate_characters(invalid_string, '"\/:|<>*?')


def test_create_file_command(requests_mock, mocker):
    """
    Scenario: Create a file in Share from War room file Entry ID.
    Given:
     - User has provided valid credentials.
    When:
     - azure-storage-fileshare-file-create called.
    Then:
     - Ensure that the output is empty (None).
     - Ensure readable output message content.
    """
    mocker.patch("shutil.copy")
    mocker.patch("shutil.rmtree")
    mocker.patch.object(demisto, "getFilePath", return_value={"path": "my_local_path", "name": "my_file_name"})

    mock_read = mocker.mock_open(read_data="XSOAR-TEST")
    mocker.patch("AzureStorageFileShare.open", mock_read)

    from AzureStorageFileShare import Client, create_file_command

    share_name = "test"
    file_entry_id = "12345"
    directory_path = "xsoar/path"
    file_name = "test_file.txt"

    command_arguments = {
        "share_name": share_name,
        "file_entry_id": file_entry_id,
        "directory_path": directory_path,
        "file_name": file_name,
    }
    url = f"{BASE_URL}{share_name}/{directory_path}/{file_name}?{SAS_TOKEN}"

    requests_mock.put(url, text="", status_code=201)
    url = f"{BASE_URL}{share_name}/{directory_path}/{file_name}?{SAS_TOKEN}&comp=range"

    requests_mock.put(url, text="", status_code=201)

    client = Client(
        server_url=BASE_URL,
        verify=False,
        proxy=False,
        account_sas_token=SAS_TOKEN,
        storage_account_name=ACCOUNT_NAME,
        api_version=API_VERSION,
    )
    result = create_file_command(client, command_arguments)

    assert result.outputs is None
    assert result.outputs_prefix is None
    assert result.readable_output == f"File successfully created in {share_name}."