From cd6adf5cb3af17ed96cb4e8735e3a6d3f8c9c482 Mon Sep 17 00:00:00 2001 From: Gal Nakash Date: Wed, 3 Jan 2024 18:10:48 +0200 Subject: [PATCH] GoogleDrive: Get Parents API Implement get parents api to get the tree of folders in google drive for a file Signed-off-by: Gal Nakash --- .../Integrations/GoogleDrive/GoogleDrive.py | 47 ++++++++++++++++++- .../Integrations/GoogleDrive/GoogleDrive.yml | 25 ++++++++++ .../GoogleDrive/GoogleDrive_test.py | 30 ++++++++++++ .../Integrations/GoogleDrive/README.md | 23 +++++++++ .../test_data/get_parents_list.txt | 14 ++++++ Packs/GoogleDrive/ReleaseNotes/1_3_0.md | 7 +++ Packs/GoogleDrive/pack_metadata.json | 2 +- 7 files changed, 145 insertions(+), 3 deletions(-) create mode 100644 Packs/GoogleDrive/Integrations/GoogleDrive/test_data/get_parents_list.txt create mode 100644 Packs/GoogleDrive/ReleaseNotes/1_3_0.md diff --git a/Packs/GoogleDrive/Integrations/GoogleDrive/GoogleDrive.py b/Packs/GoogleDrive/Integrations/GoogleDrive/GoogleDrive.py index b5726830dc9c..851476f23ee1 100644 --- a/Packs/GoogleDrive/Integrations/GoogleDrive/GoogleDrive.py +++ b/Packs/GoogleDrive/Integrations/GoogleDrive/GoogleDrive.py @@ -134,7 +134,8 @@ 'FILE_PERMISSION_UPDATE': 'drive/v3/files/{}/permissions/{}', 'FILE_PERMISSION_DELETE': 'drive/v3/files/{}/permissions/{}', 'FILE_MODIFY_LABEL': 'drive/v3/files/{}/modifyLabels', - 'FILE_GET_LABELS': 'drive/v3/files/{}/listLabels' + 'FILE_GET_LABELS': 'drive/v3/files/{}/listLabels', + 'FILE_GET_PARENTS': 'drive/v2/files/{}/parents' } OUTPUT_PREFIX: dict[str, str] = { @@ -158,7 +159,8 @@ 'GOOGLE_DRIVE_FILE_PERMISSION_HEADER': 'GoogleDrive.FilePermission', 'FILE_PERMISSION': 'FilePermission', - 'LABELS': 'GoogleDrive.Labels' + 'LABELS': 'GoogleDrive.Labels', + 'PARENTS': 'GoogleDrive.File.Parents' } @@ -1056,6 +1058,46 @@ def file_get_command(client: 'GSuiteClient', args: dict[str, str]) -> CommandRes return handle_response_single_file(response, args) +@logger +def file_get_parents(client: 'GSuiteClient', args: dict[str, str]) -> CommandResults: + """ + google-drive-get-file-parents + Query a single file in Google Drive to retrieve its parents. + + :param client: Client object. + :param args: Command arguments. + + :return: Command Result. + """ + # Specific file + is_root = False + parents = [] + file_id = args.get('file_id') + while not is_root: + modify_label_request_res = prepare_file_modify_labels_request( + client, args, scopes=COMMAND_SCOPES['FILES']) + http_request_params = modify_label_request_res['http_request_params'] + http_request_params['fileId'] = file_id + url_suffix = URL_SUFFIX['FILE_GET_PARENTS'].format(file_id) + response = client.http_request(url_suffix=url_suffix, method='GET', params=http_request_params) + + for parent in response.get('items', []): + is_root = parent.get('isRoot', False) + parents.append(parent.get('id', '')) + file_id = parent.get('id', '') + break + + outputs: dict = { + OUTPUT_PREFIX['PARENTS']: parents + } + + return CommandResults( + outputs=outputs, + readable_output=f"Parents of file {args.get('file_id')} are {parents}", + raw_response=response, + ) + + def handle_response_files_list(response: dict[str, Any]) -> CommandResults: outputs_context = [] readable_output = '' @@ -1897,6 +1939,7 @@ def main() -> None: # pragma: no cover 'google-drive-file-modify-label': modify_label_command, 'google-drive-get-labels': get_labels_command, 'google-drive-get-file-labels': get_file_labels_command, + 'google-drive-file-get-parents': file_get_parents, } command = demisto.command() diff --git a/Packs/GoogleDrive/Integrations/GoogleDrive/GoogleDrive.yml b/Packs/GoogleDrive/Integrations/GoogleDrive/GoogleDrive.yml index efb7c0daac8e..d20361deb969 100644 --- a/Packs/GoogleDrive/Integrations/GoogleDrive/GoogleDrive.yml +++ b/Packs/GoogleDrive/Integrations/GoogleDrive/GoogleDrive.yml @@ -3076,6 +3076,31 @@ script: - contextPath: GoogleDrive.File.File.mimeType description: The MIME type of the copied file. type: String + - name: google-drive-file-get-parents + description: Get parents of a Google Drive file. + arguments: + - name: file_id + description: ID of the requested file. Can be retrieved using the `google-drive-files-list` command. + - name: user_id + description: The user's primary email address. + - auto: PREDEFINED + defaultValue: "false" + description: 'Whether both My Drive and shared drive items should be included in the results.' + name: include_items_from_all_drives + predefined: + - "true" + - "false" + - auto: PREDEFINED + description: Whether the requesting application supports both My Drives and shared drives. + name: supports_all_drives + defaultValue: "False" + predefined: + - "True" + - "False" + outputs: + - contextPath: GoogleDrive.File.Parents + description: The IDs of the parent folders which contain the file. + type: String dockerimage: demisto/googleapi-python3:1.0.0.83805 isfetch: true runonce: false diff --git a/Packs/GoogleDrive/Integrations/GoogleDrive/GoogleDrive_test.py b/Packs/GoogleDrive/Integrations/GoogleDrive/GoogleDrive_test.py index 00ed7c560428..5c7487ec449d 100644 --- a/Packs/GoogleDrive/Integrations/GoogleDrive/GoogleDrive_test.py +++ b/Packs/GoogleDrive/Integrations/GoogleDrive/GoogleDrive_test.py @@ -1084,3 +1084,33 @@ def raise_error(): 'user_id': 'test_user_id', } ) + + @patch(MOCKER_HTTP_METHOD) + def test_drive_get_file_parents_success(self, mocker_http_request, gsuite_client): + """ + Scenario: For file_get_parents command successful run. + + Given: + - Command args. + + When: + - Calling google-drive-get-file-parents command with the parameters provided. + + Then: + - Ensure command's raw_response, outputs should be as expected. + """ + from GoogleDrive import file_get_parents + + with open('test_data/get_parents_list.txt', encoding='utf-8') as data: + mock_response = json.load(data) + mocker_http_request.return_value = mock_response + + args = { + 'use_domain_admin_access': True, + 'file_id': 'test', + 'user_id': 'test' + } + result = file_get_parents(gsuite_client, args) + + assert len(result.outputs.get('GoogleDrive.File.Parents')) == 1 + assert result.raw_response == mock_response diff --git a/Packs/GoogleDrive/Integrations/GoogleDrive/README.md b/Packs/GoogleDrive/Integrations/GoogleDrive/README.md index ae03eb9c3d94..01c0022ca634 100644 --- a/Packs/GoogleDrive/Integrations/GoogleDrive/README.md +++ b/Packs/GoogleDrive/Integrations/GoogleDrive/README.md @@ -1357,3 +1357,26 @@ Make a copy of a Google Drive file. >|---|---|---|---| >| 1JBZfuJcRpnpv5wS5-RBxT5OGjfKMP1cCmqOBHCe7GPw | drive#file | application/vnd.google-apps.spreadsheet | New Copy | +### google-drive-file-get-parents + +*** +Get parents of a Google Drive file. + +#### Base Command + +`google-drive-file-get-parents` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| file_id | ID of the requested file. Can be retrieved using the `google-drive-files-list` command. | Optional | +| user_id | The user's primary email address. | Optional | +| include_items_from_all_drives | Whether both My Drive and shared drive items should be included in the results. Possible values are: true, false. Default is false. | Optional | +| supports_all_drives | Whether the requesting application supports both My Drives and shared drives. Possible values are: True, False. Default is False. | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| GoogleDrive.File.Parents | String | The IDs of the parent folders which contain the file. | diff --git a/Packs/GoogleDrive/Integrations/GoogleDrive/test_data/get_parents_list.txt b/Packs/GoogleDrive/Integrations/GoogleDrive/test_data/get_parents_list.txt new file mode 100644 index 000000000000..5a9f645f0a3a --- /dev/null +++ b/Packs/GoogleDrive/Integrations/GoogleDrive/test_data/get_parents_list.txt @@ -0,0 +1,14 @@ +{ + "kind": "drive#parentList", + "etag": "\"B6Ts0uRGIRS5cehymN8hytHFo-M\"", + "selfLink": "https://www.googleapis.com/drive/v2/files/1OKPUTs6C2PmFvAj1co7qcz2kTk9xZPsOhPjMEwPmlM8/parents", + "items": [ + { + "selfLink": "https://www.googleapis.com/drive/v2/files/1OKPUTs6C2PmFvAj1co7qcz2kTk9xZPsOhPjMEwPmlM8/parents/1FlYv4F2x0JK_fudwEsNvNVjyUV3L89IB", + "id": "1FlYv4F2x0JK_fudwEsNvNVjyUV3L89IB", + "isRoot": true, + "kind": "drive#parentReference", + "parentLink": "https://www.googleapis.com/drive/v2/files/1FlYv4F2x0JK_fudwEsNvNVjyUV3L89IB" + } + ] +} diff --git a/Packs/GoogleDrive/ReleaseNotes/1_3_0.md b/Packs/GoogleDrive/ReleaseNotes/1_3_0.md new file mode 100644 index 000000000000..8f522df3d80b --- /dev/null +++ b/Packs/GoogleDrive/ReleaseNotes/1_3_0.md @@ -0,0 +1,7 @@ + +#### Integrations + +##### Google Drive + +- Added the **google-drive-file-get-parents** command. +- Updated the Docker image to: *demisto/googleapi-python3:1.0.0.83805*. diff --git a/Packs/GoogleDrive/pack_metadata.json b/Packs/GoogleDrive/pack_metadata.json index 08ef8e136899..d90c1cf70c83 100644 --- a/Packs/GoogleDrive/pack_metadata.json +++ b/Packs/GoogleDrive/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Google Drive", "description": "Google Drive allows users to store files on their servers, synchronize files across devices, and share files. This integration helps you to create a new drive, query past activity and view change logs performed by the users, as well as list drives and files, and manage their permissions.", "support": "xsoar", - "currentVersion": "1.2.48", + "currentVersion": "1.3.0", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "",