Azure Storage Container
Create and Manage Azure Storage Container services.
IT Services · Azure Storage Container
Details
| ID | Azure Storage Container |
|---|---|
| Provider | Microsoft |
| Category | IT Services |
| From Version | 6.0.0 |
| Docker Image | demisto/python3:3.12.13.10116658 |
| Supported Modules | Agentix XSIAM |
README
Azure Storage Container
Create and Manage Azure Storage Container services.
This integration was integrated and tested with version “2020-10-02” of Azure Storage Container
Configure Azure Storage Container in Cortex
| Parameter | Required |
|---|---|
| Storage account name | True |
| Account SAS Token | False |
| Use Azure Managed Identities | False |
| Azure Managed Identities Client ID | False |
| Shared Key | False |
| Use system proxy settings | False |
| Trust any certificate (not secure) | False |
## Shared Access Signatures Information (SAS)
- The required SAS token for this integration should be taken at the storage account level and not at container level.
Shared Access Signatures (SAS) Permissions
In order to use the integration use-cases,
please make sure your SAS token contains the following permissions:
- ‘Blob’ and ‘File’ service.
- ‘Service’, ‘Container’ and ‘Object’ resource types.
- ‘Read’, ‘Write’, ‘Delete’, ‘List’, ‘Create’, ‘Add’, ‘Update’ and ‘Immutable storage’ permissions.
- ‘Blob versioning permissions’
Shared Key Permissions
To set the AllowSharedKeyAccess property for an Azure Storage account, a user needs to have the permissions to create and manage storage accounts.
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-container-list
List Containers under the specified storage account.
Base Command
azure-storage-container-list
Input
| Argument Name | Description | Required |
|---|---|---|
| limit | Number of Containers to retrieve. Default is 50. Default is 50. | Optional |
| prefix | Filters the results to return only Containers whose names begin with the specified prefix. | Optional |
| page | Page number. Default is 1. Default is 1. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| AzureStorageContainer.Container.name | String | Container name. |
Command Example
!azure-storage-container-list prefix="xs"
Context Example
{
"AzureStorageContainer": {
"Container": {
"name": "xsoar"
}
}
}
Human Readable Output
Containers List
Current page size: 50
Showing page 1 out others that may exist
Name xsoar
azure-storage-container-create
Create a new Container under the specified account.
Base Command
azure-storage-container-create
Input
| Argument Name | Description | Required |
|---|---|---|
| container_name | The name of the Container to create. Rules for naming containers can be found here: https://docs.microsoft.com/en-us/rest/api/storageservices/naming-and-referencing-containers–blobs–and-metadata . |
Required |
Context Output
There is no context output for this command.
Command Example
!azure-storage-container-create container_name="xsoar"
Human Readable Output
Container xsoar successfully created.
azure-storage-container-property-get
Retrieve properties for the specified Container.
Base Command
azure-storage-container-property-get
Input
| Argument Name | Description | Required |
|---|---|---|
| container_name | The name of the Container. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| AzureStorageContainer.Container.Property.last_modified | Date | Last modified time of the container. |
| AzureStorageContainer.Container.Property.etag | String | The entity tag for the container. |
| AzureStorageContainer.Container.Property.lease_status | String | The lease status of the container. |
| AzureStorageContainer.Container.Property.lease_state | String | The lease state of the container. |
| AzureStorageContainer.Container.Property.has_immutability_policy | String | Indicates whether the container has an immutability policy set on it. |
| AzureStorageContainer.Container.Property.has_legal_hold | String | Indicates whether the container has a legal hold. |
| AzureStorageContainer.Container.name | String | Container name. |
Command Example
!azure-storage-container-property-get container_name="xsoar"
Context Example
{
"AzureStorageContainer": {
"Container": {
"Property": {
"content_length": "0",
"date": "2021-11-28T12:43:05",
"default_encryption_scope": "$account-encryption-key",
"deny_encryption_scope_override": "false",
"etag": "\"0x8D9B26C9BBF026C\"",
"has_immutability_policy": "false",
"has_legal_hold": "false",
"immutable_storage_with_versioning_enabled": "false",
"last_modified": "2021-11-28T12:42:58",
"lease_state": "available",
"lease_status": "unlocked",
"request_id": "00a9c6bf-f01e-007a-5255-e448bd000000",
"server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
"version": "2020-10-02"
},
"name": "xsoar"
}
}
}
Human Readable Output
Container xsoar Properties
Last Modified Etag Lease Status Lease State Has Immutability Policy Has Legal Hold 2021-11-28T12:42:58 “0x8D9B26C9BBF026C” unlocked available false false
azure-storage-container-delete
Marks the specified Container for deletion. The Container and any Blobs contained within it, will be deleted during garbage collection.
Base Command
azure-storage-container-delete
Input
| Argument Name | Description | Required |
|---|---|---|
| container_name | The name of the Container to delete. | Required |
Context Output
There is no context output for this command.
Command Example
!azure-storage-container-delete container_name="xsoar"
Human Readable Output
Container xsoar successfully deleted.
azure-storage-container-blob-list
List Blobs under the specified container.
Base Command
azure-storage-container-blob-list
Input
| Argument Name | Description | Required |
|---|---|---|
| container_name | The name of the Container. | Required |
| limit | Number of blobs to retrieve. Default is 50. Default is 50. | Optional |
| prefix | Filters the results to return only blobs whose names begin with the specified prefix. | Optional |
| page | Page number. Default is 1. Default is 1. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| AzureStorageContainer.Container.Blob.name | String | Blob name. |
| AzureStorageContainer.Container.name | String | Container name. |
Command Example
!azure-storage-container-blob-list container_name="xsoar"
Context Example
{
"AzureStorageContainer": {
"Container": {
"Blob": [
{
"name": "xsoar.txt"
}
],
"name": "xsoar"
}
}
}
Human Readable Output
xsoar Container Blobs List
Current page size: 50
Showing page 1 out others that may exist
Name xsoar.txt
azure-storage-container-blob-create
Create a new Blob under the specified Container.
Base Command
azure-storage-container-blob-create
Input
| Argument Name | Description | Required |
|---|---|---|
| container_name | The name of the Blob Container. | Required |
| file_entry_id | The entry ID of the file to upload as a new blob. Available from XSOAR war room while the context data contains file output. | Required |
| blob_name | The name of the Blob to create. Default is XSOAR file name. | Optional |
Context Output
There is no context output for this command.
Command Example
!azure-storage-container-blob-create container_name="xsoar" file_entry_id="16488@b5e40781-86c8-4799-8f10-ace443e93234" blob_name="xsoar.txt"
Human Readable Output
Blob successfully created.
azure-storage-container-blob-update
Update the content of an existing Blob.
Base Command
azure-storage-container-blob-update
Input
| Argument Name | Description | Required |
|---|---|---|
| container_name | The name of the Blob Container. | Required |
| file_entry_id | The entry ID of the file to upload as a new blob. Available from XSOAR war room while the context data contains file output. | Required |
| blob_name | The name of the Blob to update. | Required |
Context Output
There is no context output for this command.
Command Example
!azure-storage-container-blob-update container_name="xsoar" file_entry_id="16488@b5e40781-86c8-4799-8f10-ace443e93234" blob_name="xsoar.txt"
Human Readable Output
Blob xsoar.txt successfully updated.
azure-storage-container-blob-get
Retrieve Blob from Container.
Base Command
azure-storage-container-blob-get
Input
| Argument Name | Description | Required |
|---|---|---|
| container_name | The name of the Blob Container. | Required |
| blob_name | The name of the Blob to retrieve. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| File.Size | String | 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 | Unknown | The MD5 hash of the file. |
| File.Extension | String | The file extension. |
Command Example
!azure-storage-container-blob-get container_name="xsoar" blob_name="xsoar.txt"
Context Example
{
"File": {
"EntryID": "16508@b5e40781-86c8-4799-8f10-ace443e93234",
"Extension": "txt",
"Info": "text/plain; charset=utf-8",
"MD5": "950eb0708854a661313dd150a643af8b",
"Name": "xsoar.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-container-blob-tag-get
Retrieve the tags of the specified Blob.
Base Command
azure-storage-container-blob-tag-get
Input
| Argument Name | Description | Required |
|---|---|---|
| container_name | The name of the Blob Container. | Required |
| blob_name | The name of the blob. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| AzureStorageContainer.Container.Blob.Tag.Key | String | Tag key. |
| AzureStorageContainer.Container.Blob.Tag.Value | String | Tag value. |
| AzureStorageContainer.Container.Blob.name | String | Blob name. |
| AzureStorageContainer.Container.name | String | Container name. |
Command Example
!azure-storage-container-blob-tag-get container_name="xsoar" blob_name="xsoar.txt"
Context Example
{
"AzureStorageContainer": {
"Container": {
"Blob": {
"Tag": [
{
"Key": "tag-name-1",
"Value": "tag-value-1"
}
],
"name": "xsoar.txt"
},
"name": "xsoar"
}
}
}
Human Readable Output
Blob xsoar.txt Tags
Key Value tag-name-1 tag-value-1
azure-storage-container-blob-tag-set
Sets the tags for the specified Blob. The command replace the entire tags of the Blob and can be used to remove tags.
Base Command
azure-storage-container-blob-tag-set
Input
| Argument Name | Description | Required |
|---|---|---|
| container_name | The name of the Blob Container. | Required |
| blob_name | The name of the blob. | Required |
| tags | Tags fields in JSON format: {“tag-name-1”: “tag-value-1”, “tag-name-2”: “tag-value-2”}. The tags fields may contain at most 10 tags. | Required |
Context Output
There is no context output for this command.
Command Example
!azure-storage-container-blob-tag-set container_name="xsoar" blob_name="xsoar.txt" tags=`{ "tag-name-1": "tag-value-1" }`
Human Readable Output
xsoar.txt Tags successfully updated.
azure-storage-container-blob-delete
Marks the specified Blob for deletion. The Blob will be deleted during garbage collection.
Base Command
azure-storage-container-blob-delete
Input
| Argument Name | Description | Required |
|---|---|---|
| container_name | The name of the Blob Container. | Required |
| blob_name | The name of the Blob to delete. | Required |
Context Output
There is no context output for this command.
Command Example
!azure-storage-container-blob-delete container_name="xsoar" blob_name="xsoar.txt"
Human Readable Output
Blob xsoar.txt successfully deleted.
azure-storage-container-blob-property-get
Retrieve Blob properties.
Base Command
azure-storage-container-blob-property-get
Input
| Argument Name | Description | Required |
|---|---|---|
| container_name | The name of the Blob Container. | Required |
| blob_name | The name of the blob. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| AzureStorageContainer.Container.Blob.Property.last_modified | Date | Last modified time of the blob. |
| AzureStorageContainer.Container.Blob.Property.etag | String | The entity tag for the blob. |
| AzureStorageContainer.Container.Blob.Property.lease_status | String | The lease status of the blob. |
| AzureStorageContainer.Container.Blob.Property.lease_state | String | The lease state of the blob. |
| AzureStorageContainer.Container.Blob.Property.blob_type | String | The blob type. |
| AzureStorageContainer.Container.Blob.Property.content_length | Number | The size of the blob in bytes. |
| AzureStorageContainer.Container.Blob.Property.content_type | String | The content type specified for the blob. If no content type was specified, the default content type is application/octet-stream. |
| AzureStorageContainer.Container.Blob.Property.content-md5 | String | The MD5 hash of the blob content. |
| AzureStorageContainer.Container.Blob.Property.creation_time | Date | The date at which the blob was created. |
| AzureStorageContainer.Container.Blob.name | String | Blob name. |
Command Example
!azure-storage-container-blob-property-get container_name="xsoar" blob_name="xsoar.txt"
Context Example
{
"AzureStorageContainer": {
"Container": {
"Blob": {
"Property": {
"accept_ranges": "bytes",
"access_tier": "Hot",
"access_tier_inferred": "true",
"blob_type": "BlockBlob",
"content_length": "11",
"content_md5": "lQ6wcIhUpmExPdFQpkOviw==",
"content_type": "application/octet-stream",
"creation_time": "2021-11-28T12:43:09",
"date": "2021-11-28T12:43:24",
"etag": "\"0x8D9B26CA6AD74B3\"",
"last_modified": "2021-11-28T12:43:17",
"lease_state": "available",
"lease_status": "unlocked",
"request_id": "8f64c941-501e-0097-4255-e403f0000000",
"server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
"server_encrypted": "true",
"version": "2020-10-02"
},
"name": "xsoar.txt"
},
"name": "xsoar"
}
}
}
Human Readable Output
Blob xsoar.txt Properties
Creation Time Last Modified Content Length Content Type Etag 2021-11-28T12:43:09 2021-11-28T12:43:17 11 application/octet-stream “0x8D9B26CA6AD74B3”
azure-storage-container-blob-property-set
Set Blob properties.
Base Command
azure-storage-container-blob-property-set
Input
| Argument Name | Description | Required |
|---|---|---|
| container_name | The name of the Blob Container. | Required |
| blob_name | The name of the blob. | Required |
| content_type | Blob content type. Indicates the media type of the blob. | Optional |
| content_md5 | Blob MD5 hash value. Can be used by the client to check for content integrity. | Optional |
| content_encoding | Blob content encoding. Used to specify the compression algorithm of the blob content. | Optional |
| content_language | Blob content language. Describes the human languages of the blob content. | Optional |
| content_disposition | Blob content disposition. Conveys additional information about how to process the response payload, and also can be used to attach additional metadata. | Optional |
| cache_control | Modifies the cache control string for the blob. Indicates directives for caching in both requests and responses. | Optional |
| request_id | Request ID generated by the client and recorded in the analytics logs when storage analytics logging is enabled. | Optional |
| lease_id | Required if the blob has an active lease. | Optional |
Context Output
There is no context output for this command.
Command Example
!azure-storage-container-blob-property-set container_name="xsoar" blob_name="xsoar.txt" content_type="text/plain"
Human Readable Output
Blob xsoar.txt properties successfully updated.
azure-storage-container-sas-create
Retrieve Blob properties.
Base Command
azure-storage-container-sas-create
Input
| Argument Name | Description | Required |
|---|---|---|
| container_name | The name of the Blob Container. | Required |
| expiry_time | Expiry time for sas token(hours). | Required |
| signed_resources | specifies which resources are accessible via the shared access signature. Options available c(container), b(blob), bv(blob version),bs(blob snapshot),d(directory) | Required |
| signed_permissions | The permissions that are associated with the shared access signature. The user is restricted to operations that are allowed by the permissions. Possible permission: r = Read, a=access, c=create, w=write. Also must follow the this order “racwdxltmeop”Example: r,c,a,w,rac, racw. | Required |
| signed_ip | specifies a public IP address or a range of public IP addresses from which to accept requests. | Required |
| account_key | The account key to create the SAS token with. |
Command Example
!azure-storage-container-sas-create account_key="TestAccountKey" expiry_time="1" signed_resources="test signed_permissions="test signed_ip="127.0.0.1"
azure-storage-container-block-public-access
Block public access to a container..
Base Command
azure-storage-container-block-public-access
Input
| Argument Name | Description | Required |
|---|---|---|
| container_name | The name of the Blob Container. | Required |
Context Output
There is no context output for this command.
Command Example
!azure-storage-container-block-public-access container_name="xsoar"
Human Readable Output
xsoar.txt Public access to container ‘{container_name}’ has been successfully blocked.
Configuration parameters
credentials— Storage account nameuse_managed_identities— Use Azure Managed Identitiesmanaged_identities_client_id—proxy— Use system proxy settingsinsecure— Trust any certificate (not secure)key— Account keyshared_key—
Commands (15)
-
azure-storage-container-blob-createCreate a new Blob under the specified Container.
-
azure-storage-container-blob-deleteMarks the specified Blob for deletion. The Blob will be deleted during garbage collection.
-
azure-storage-container-blob-getRetrieve Blob from Container.
-
azure-storage-container-blob-listList Blobs under the specified container.
-
azure-storage-container-blob-property-getRetrieve Blob properties.
-
azure-storage-container-blob-property-setSet Blob properties.
-
azure-storage-container-blob-tag-getRetrieve the tags of the specified Blob.
-
azure-storage-container-blob-tag-setSets the tags for the specified Blob. The command replace the entire tags of the Blob and can be used to remove tags.
-
azure-storage-container-blob-updateUpdate the content of an existing Blob.
-
azure-storage-container-block-public-accessBlock public access to a container.
-
azure-storage-container-createCreate a new Container under the specified account.
-
azure-storage-container-deleteMarks the specified Container for deletion. The Container and any Blobs contained within it, will be deleted during garbage collection.
-
azure-storage-container-listList Containers under the specified storage account.
-
azure-storage-container-property-getRetrieve properties for the specified Container.
-
azure-storage-container-sas-createcreate SAS token for container.
import defusedxml.ElementTree as defused_ET import pytest from CommonServerPython import * ACCOUNT_NAME = "test" BASE_URL = f"https://{ACCOUNT_NAME}.blob.core.windows.net/" SAS_TOKEN = "XXXX" API_VERSION = "2020-10-02" SHARED_KEY = "XXXX" def load_mock_response(file_name: str, file_type: str = "json"): """ 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_type (str): Mock file type. """ file_path = f"test_data/{file_name}" if file_type == "xml": top = defused_ET.parse(file_path) return ET.tostring(top.getroot(), encoding="utf8").decode("utf-8") else: with open(f"test_data/{file_name}", encoding="utf-8") as mock_file: return mock_file.read() def test_azure_storage_list_containers_command(requests_mock): """ Scenario: List Containers. Given: - User has provided valid credentials. When: - azure-storage-container-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 AzureStorageContainer import Client, list_containers_command mock_response = load_mock_response("containers.xml", "xml") url = f"{BASE_URL}?{SAS_TOKEN}&maxresults=50&comp=list" 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_containers_command(client, {}) assert len(result.outputs) == 2 assert result.outputs_prefix == "AzureStorageContainer.Container" assert result.outputs[0].get("name") == "xsoar" assert result.outputs[1].get("name") == "test" def test_azure_storage_create_container_command(requests_mock): """ Scenario: Create Container. Given: - User has provided valid credentials. When: - azure-storage-container-create called. Then: - Ensure that the output is empty (None). - Ensure readable output message content. - Ensure validation of the container name. """ from AzureStorageContainer import Client, create_container_command container_name = "test" url = f"{BASE_URL}{container_name}?{SAS_TOKEN}&restype=container" 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_container_command(client, {"container_name": container_name}) assert result.outputs is None assert result.outputs_prefix is None assert result.readable_output == f"Container {container_name} successfully created." invalid_container_name = "test--1" with pytest.raises(Exception): create_container_command(client, {"container_name": invalid_container_name}) def test_azure_storage_create_blob_command_content_length_header(mocker): """ Given: - User has provided valid credentials. When: - azure-storage-container-blob-create called. Then: - Ensure the content length header is being sent with the correct file size. """ from AzureStorageContainer import Client, create_blob_command def mock_file(_id): return { "path": "test_data/blob.txt", "name": "blob.txt", } client = Client( server_url=BASE_URL, verify=False, proxy=False, account_sas_token=SAS_TOKEN, storage_account_name=ACCOUNT_NAME, api_version=API_VERSION, ) mocker.patch.object(demisto, "getFilePath", side_effect=mock_file) http_mocker = mocker.patch.object(client.ms_client, "http_request", return_value="worked") create_blob_command(client, {"container_name": "container-test", "file_entry_id": "1"}) assert http_mocker.call_args.kwargs.get("headers", {}) == {"x-ms-blob-type": "BlockBlob"} def test_azure_storage_get_container_properties_command(requests_mock): """ Scenario: Retrieve properties for the specified Container. Given: - User has provided valid credentials. When: - azure-storage-container-property-get 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 AzureStorageContainer import Client, get_container_properties_command container_name = "test" url = f"{BASE_URL}{container_name}?{SAS_TOKEN}&restype=container" headers_response = json.loads(load_mock_response("container_properties.json")) requests_mock.get(url, headers=headers_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 = get_container_properties_command(client, {"container_name": container_name}) assert len(result.outputs) == 2 assert len(result.outputs.get("Property")) == 14 assert result.outputs_prefix == "AzureStorageContainer.Container" assert result.outputs.get("Property").get("lease_status") == "unlocked" assert result.outputs.get("name") == container_name def test_azure_storage_delete_container_command(requests_mock): """ Scenario: Delete Container. Given: - User has provided valid credentials. When: - azure-storage-container-delete called. Then: - Ensure that the output is empty (None). - Ensure readable output message content. """ from AzureStorageContainer import Client, delete_container_command container_name = "test" url = f"{BASE_URL}{container_name}?{SAS_TOKEN}&restype=container" 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_container_command(client, {"container_name": container_name}) assert result.outputs is None assert result.outputs_prefix is None assert result.readable_output == f"Container {container_name} successfully deleted." def test_azure_storage_list_blobs_command(requests_mock): """ Scenario: List Blobs under the specified container. Given: - User has provided valid credentials. When: - azure-storage-container-blob-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 AzureStorageContainer import Client, list_blobs_command container_name = "test" url = f"{BASE_URL}{container_name}?{SAS_TOKEN}&container_name={container_name}&maxresults=50&restype=container&comp=list" response = load_mock_response("blobs.xml", "xml") requests_mock.get(url, text=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_blobs_command(client, {"container_name": container_name}) assert len(result.outputs) == 2 assert len(result.outputs.get("Blob")) == 2 assert result.outputs_prefix == "AzureStorageContainer.Container" assert result.outputs.get("Blob")[0].get("name") == "xsoar.txt" assert result.outputs.get("Blob")[1].get("name") == "test.pdf" assert result.outputs.get("name") == container_name def test_azure_storage_get_blob_command(requests_mock): """ Scenario: Retrieve Blob from Container. Given: - User has provided valid credentials. When: - azure-storage-container-blob-get called. Then: - Ensure XSOAR File output. """ from AzureStorageContainer import Client, get_blob_command container_name = "test" blob_name = "blob.txt" url = f"{BASE_URL}{container_name}/{blob_name}?{SAS_TOKEN}" with open("test_data/blob.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_blob_command(client, {"container_name": container_name, "blob_name": blob_name}) assert result["ContentsFormat"] == "text" assert result["Type"] == EntryType.FILE assert result["File"] == blob_name assert len(result) == 5 def test_azure_storage_get_blob_tags_command(requests_mock): """ Scenario: Retrieve the tags of the specified Blob. Given: - User has provided valid credentials. When: - azure-storage-container-blob-tag-get 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 AzureStorageContainer import Client, get_blob_tags_command container_name = "test" blob_name = "blob.txt" url = f"{BASE_URL}{container_name}/{blob_name}?{SAS_TOKEN}&comp=tags" mock_response = load_mock_response("tags.xml", "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 = get_blob_tags_command(client, {"container_name": container_name, "blob_name": blob_name}) assert len(result.outputs) == 2 assert len(result.outputs.get("Blob")) == 2 assert len(result.outputs.get("Blob").get("Tag")) == 1 assert result.outputs_prefix == "AzureStorageContainer.Container" assert result.outputs.get("Blob").get("Tag")[0].get("Key") == "Name" assert result.outputs.get("Blob").get("Tag")[0].get("Value") == "Azure" def test_azure_storage_block_public_access_command(mocker, requests_mock): """ Scenario: Block public access for the specified container. Given: - User has provided valid credentials. When: - azure-storage-container-block-public-access called. Then: - Ensure readable output message content. """ from AzureStorageContainer import Client, block_public_access_command params = {"shared_key": {"password": SHARED_KEY}, "credentials": {"identifier": ACCOUNT_NAME}} mocker.patch.object(demisto, "params", return_value=params) container_name = "test" url = f"https://{ACCOUNT_NAME}.blob.core.windows.net/{container_name}?restype=container&comp=acl" requests_mock.put(url, status_code=200, 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 = block_public_access_command(client, {"container_name": container_name}) expected_response = f"Public access to container '{container_name}' has been successfully blocked" assert result.readable_output == expected_response # Test for invalid shared key with pytest.raises(ValueError, match="Incorrect shared key provided"): # Here we need to set params to have an invalid key invalid_shared_key_params = {"shared_key": {"password": "invalid-key"}, "credentials": {"identifier": ACCOUNT_NAME}} mocker.patch.object(demisto, "params", return_value=invalid_shared_key_params) block_public_access_command(client, {"container_name": container_name}) # Test for missing shared key with pytest.raises(KeyError, match="The 'shared_key' parameter must be provided."): missing_shared_key_params = {"shared_key": {"password": ""}, "credentials": {"identifier": ACCOUNT_NAME}} mocker.patch.object(demisto, "params", return_value=missing_shared_key_params) block_public_access_command(client, {"container_name": container_name}) def test_azure_storage_set_blob_tags_command(requests_mock): """ Scenario: Set the tags for the specified Blob. Given: - User has provided valid credentials. When: - azure-storage-container-blob-tag-set called. Then: - Ensure that the output is empty (None). - Ensure readable output message content. """ from AzureStorageContainer import Client, set_blob_tags_command container_name = "test" blob_name = "blob.txt" url = f"{BASE_URL}{container_name}/{blob_name}?{SAS_TOKEN}&comp=tags" 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 = set_blob_tags_command(client, {"container_name": container_name, "blob_name": blob_name, "tags": "{}"}) assert result.outputs is None assert result.outputs_prefix is None assert result.readable_output == f"{blob_name} Tags successfully updated." def test_azure_storage_delete_blob_command(requests_mock): """ Scenario: Delete Blob from Container. Given: - User has provided valid credentials. When: - azure-storage-container-blob-delete called. Then: - Ensure that the output is empty (None). - Ensure readable output message content. """ from AzureStorageContainer import Client, delete_blob_command container_name = "test" blob_name = "blob.txt" url = f"{BASE_URL}{container_name}/{blob_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_blob_command(client, {"container_name": container_name, "blob_name": blob_name}) assert result.outputs is None assert result.outputs_prefix is None assert result.readable_output == f"Blob {blob_name} successfully deleted." def test_azure_storage_get_blob_properties_command(requests_mock): """ Scenario: Retrieve Blob properties. Given: - User has provided valid credentials. When: - azure-storage-container-blob-property-get 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 AzureStorageContainer import Client, get_blob_properties_command container_name = "test" blob_name = "blob.txt" url = f"{BASE_URL}{container_name}/{blob_name}?{SAS_TOKEN}" headers_response = json.loads(load_mock_response("blob_properties.json")) requests_mock.head(url, headers=headers_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 = get_blob_properties_command(client, {"container_name": container_name, "blob_name": blob_name}) assert len(result.outputs) == 2 assert len(result.outputs.get("Blob")) == 2 assert len(result.outputs.get("Blob").get("Property")) == 18 assert result.outputs_prefix == "AzureStorageContainer.Container" assert result.outputs.get("Blob").get("Property").get("blob_type") == "BlockBlob" assert result.outputs.get("Blob").get("name") == blob_name assert result.outputs.get("name") == container_name def test_azure_storage_set_blob_properties_command(requests_mock): """ Scenario: Set Blob properties. Given: - User has provided valid credentials. When: - azure-storage-container-blob-property-set called. Then: - Ensure that the output is empty (None). - Ensure readable output message content. """ from AzureStorageContainer import Client, set_blob_properties_command container_name = "test" blob_name = "blob.txt" url = f"{BASE_URL}{container_name}/{blob_name}?{SAS_TOKEN}&comp=properties" 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 = set_blob_properties_command(client, {"container_name": container_name, "blob_name": blob_name}) assert result.outputs is None assert result.outputs_prefix is None assert result.readable_output == f"Blob {blob_name} properties successfully updated." def test_create_set_tags_request_body(): """ Scenario: Create valid request body for set blob tags. Given: - User has provided valid credentials. When: - azure-storage-container-blob-tag-set called. Then: - Ensure command request body. """ from AzureStorageContainer import create_set_tags_request_body tags = {"tag-name-1": "tag-value-1", "tag-name-2": "tag-value-2-yehuda"} result = create_set_tags_request_body(tags) expected = ( "<Tags><TagSet><Tag><Key>tag-name-1</Key><Value>tag-value-1</Value></Tag><Tag><Key>tag-name-2</Key>" "<Value>tag-value-2-yehuda</Value></Tag></TagSet></Tags>" ) assert result == expected def test_generate_sas_signature(): from AzureStorageContainer import generate_sas_signature assert ( generate_sas_signature( "test", "test", "test", "test", "test", "test", "test", "test", ) == "sp=test&st=test&se=test&sip=test&spr=https&sv=test&sr=test&sig=pyUQ25%2BIijJ2TstI5Q6Sre3jJWI0b4qwvRg2LtD9uhc%3D" ) # noqa def test_generate_sas_signature_no_key(mocker): """ Given: - User hasn't provided an account key to create the SAS token. When: - azure-storage-container-sas-create called. Then: - Ensure command raises an exception. """ from AzureStorageContainer import Client, generate_sas_token_command mocker.patch.object(demisto, "params", return_value={}) client = Client( server_url=BASE_URL, verify=False, proxy=False, account_sas_token=SAS_TOKEN, storage_account_name=ACCOUNT_NAME, api_version=API_VERSION, ) with pytest.raises(DemistoException): generate_sas_token_command(client, {"signed_permissions": "c"}) def test_check_valid_permission(): from AzureStorageContainer import check_valid_permission assert check_valid_permission("cr", "c") assert not check_valid_permission("cr", "crw") @pytest.mark.parametrize(argnames="client_id", argvalues=["test_client_id", None]) def test_test_module_command_with_managed_identities(mocker, requests_mock, client_id): """ Given: - Managed Identities client id for authentication. When: - Calling test_module. Then: - Ensure the output are as expected. """ import re import AzureStorageContainer import demistomock as demisto from AzureStorageContainer import MANAGED_IDENTITIES_TOKEN_URL, main mock_token = {"access_token": "test_token", "expires_in": "86400"} get_mock = requests_mock.get(MANAGED_IDENTITIES_TOKEN_URL, json=mock_token) requests_mock.get(re.compile("blob.core.windows.net/.*")) params = { "managed_identities_client_id": {"password": client_id}, "use_managed_identities": "True", "credentials": {"identifier": "test_storage_account_name"}, } mocker.patch.object(demisto, "params", return_value=params) mocker.patch.object(demisto, "command", return_value="test-module") mocker.patch.object(AzureStorageContainer, "return_results", return_value=params) main() assert "ok" in AzureStorageContainer.return_results.call_args[0][0] qs = get_mock.last_request.qs assert (client_id and qs["client_id"] == [client_id]) or "client_id" not in qs def test_put_blob_request_uses_basename(mocker): """ Given: - A file entry with a name containing directory path components and no explicit file_name. When: - Calling put_blob_request. Then: - Verify that only the basename of the file name is used as the blob name. """ import os import demistomock as demisto from AzureStorageContainer import Client mocker.patch.object( demisto, "getFilePath", return_value={"path": "/tmp/testfile", "name": "/tmp/evil/../../../etc/passwd"}, ) mocker.patch.object(os, "remove") mock_copy = mocker.patch("shutil.copy") mocker.patch("builtins.open", mocker.mock_open(read_data=b"data")) client = Client( server_url=BASE_URL, verify=False, proxy=False, account_sas_token=SAS_TOKEN, storage_account_name=ACCOUNT_NAME, api_version=API_VERSION, ) mocker.patch.object(client.ms_client, "http_request", return_value=mocker.MagicMock(status_code=201)) client.put_blob_request(container_name="test-container", file_entry_id="entry1") # Verify shutil.copy was called with the sanitized basename only copy_call_args = mock_copy.call_args[0] assert copy_call_args[1] == "passwd" assert os.path.basename(copy_call_args[1]) == copy_call_args[1]