DropboxEventsCollector

Collect events from Dropbox's logs.

Analytics & SIEM · Dropbox

Details

IDDropboxEventsCollector
ProviderDropbox
CategoryAnalytics & SIEM
From Version6.8.0
Docker Imagedemisto/py3-tools:1.0.0.10120494
Supported ModulesAgentix XSIAM

README

Collect events from Dropbox’s logs.
This integration was integrated and tested with version 2 of Dropbox API

Configure Dropbox Event Collector on Cortex XSIAM

  1. Navigate to Settings > Configurations > Data Collection > Automation and Feed Integrations.
  2. Search for Dropbox Event Collector.
  3. Click Add instance to create and configure a new integration instance.

    Parameter Description Required
    Server URL The endpoint from which to get the logs. True
    App Key The App key (created in the Dropbox app console). True
    App Secret The App secret (created in the Dropbox app console). True
    First fetch in timestamp format First fetch in timestamp format (<number> <time unit>, e.g., 12 hours, 7 days) False
    The maximum number of events per fetch   False
    Trust any certificate (not secure)   False
    Use system proxy settings   False
  4. Run the !dropbox-auth-start command to test the connection and the authorization process.

Commands

You can execute these commands from the Cortex XSIAM War Room, 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.

dropbox-auth-start


Run this command to start the authorization process and follow the instructions in the command results. This command generates a link. By clicking the link, you get a code for the dropbox-auth-complete command.

Base Command

dropbox-auth-start

Input

There are no input arguments for this command.

Context Output

There is no context output for this command.

dropbox-auth-complete


Run this command to complete the authorization process. Should be used after running the dropbox-auth-start command.

Base Command

dropbox-auth-complete

Input

Argument Name Description Required
code The code that returns from Dropbox. Required

Context Output

There is no context output for this command.

dropbox-auth-test


Run this command to test the connectivity to Dropbox.

Note: Use this command instead of the Test button in the UI.

Base Command

dropbox-auth-test

Input

There are no input arguments for this command.

Context Output

There is no context output for this command.

dropbox-auth-reset


Resets the authentication.

Base Command

dropbox-auth-reset

Input

There are no input arguments for this command.

Context Output

There is no context output for this command.

dropbox-get-events


Get events.

Base Command

dropbox-get-events

Input

Argument Name Description Required
limit The maximum events to fetch. Default is 500. Optional
should_push_events Set this argument to true to create events, otherwise the command will only display them. Possible values are: true, false. Default is false. Required
from Fetch events from this time (<number> <time unit>, e.g., 12 hours, 7 days). Default is 3 days. Optional

Context Output

There is no context output for this command.

Command example

!dropbox-get-events should_push_events='false' limit=3

Human Readable Output

Dropbox logs

Actor Context Details Event _ Category Event _ Type Involve Non Team _ Member Origin Timestamp
.tag: admin
admin: {“.tag”: “team_member”, “account_id”: “123456”, “display_name”: “John Smith”, “email”: “JohnSmith@example.com”, “team_member_id”: “111111”}
.tag: team_member
account_id: 123456
display_name: John Smith
email: JohnSmith@example.com
team_member_id: 111111
.tag: member_change_status_details
previous_value: {“.tag”: “not_joined”}
new_value: {“.tag”: “active”}
action: {“.tag”: “team_join_details”, “linked_apps”: [], “linked_devices”: [], “linked_shared_folders”: [], “has_linked_apps”: false, “has_linked_devices”: true, “has_linked_shared_folders”: false}
.tag: members .tag: member_change_status
description: Changed member status (invited, joined, suspended, etc.)
false geo_location: {“city”: “Tel Aviv”, “region”: “Tel Aviv”, “country”: “IL”, “ip_address”: “1.1.1.1”}
access_method: {“.tag”: “end_user”, “end_user”: {“.tag”: “web”, “session_id”: “222222”}}
2022-05-16T11:34:29Z
.tag: admin
admin: {“.tag”: “team_member”, “account_id”: “123456”, “display_name”: “John Smith”, “email”: “JohnSmith@example.com”, “team_member_id”: “111111”}
.tag: team_member
account_id: 123456
display_name: John Smith
email: JohnSmith@example.com
team_member_id: 111111
.tag: member_change_admin_role_details
new_value: {“.tag”: “team_admin”}
previous_value: {“.tag”: “member_only”}
.tag: members .tag: member_change_admin_role
description: Changed team member admin role
false geo_location: {“city”: “Tel Aviv”, “region”: “Tel Aviv”, “country”: “IL”, “ip_address”: “1.1.1.1”}
access_method: {“.tag”: “end_user”, “end_user”: {“.tag”: “web”, “session_id”: “222222”}}
2022-05-16T11:34:29Z
.tag: admin
admin: {“.tag”: “team_member”, “account_id”: “123456”, “display_name”: “John Smith”, “email”: “JohnSmith@example.com”, “team_member_id”: “111111”}
.tag: team .tag: member_send_invite_policy_changed_details
new_value: {“.tag”: “everyone”}
previous_value: {“.tag”: “specific_members”}
.tag: team_policies .tag: member_send_invite_policy_changed
description: Changed member send invite policy for team
false geo_location: {“city”: “Tel Aviv”, “region”: “Tel Aviv”, “country”: “IL”, “ip_address”: “1.1.1.1”}
access_method: {“.tag”: “end_user”, “end_user”: {“.tag”: “web”, “session_id”: “222222”}}
2022-05-16T11:34:33Z

Configuration parameters

  • url — Server URL (required)
  • credentials — App key (required)
  • fetch_from — First fetch in timestamp format (<number> <time unit>, e.g., 12 hours, 7 days)
  • limit — The maximum number of events per fetch.
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings

Commands (5)

  • dropbox-auth-complete

    Completes the authentication.

  • dropbox-auth-reset

    Resets the authentication.

  • dropbox-auth-start

    Starts the authentication.

  • dropbox-auth-test

    Tests the authentication.

  • dropbox-get-events

    Get events.

import json

import demistomock as demisto
import requests_mock
from freezegun import freeze_time

DEMISTO_PARAMS = {
    "limit": 100,
    "credentials": {
        "identifier": "admin@your.domain",
        "password": "123456",
    },
}
DATETIME_FORMAT = "%Y-%m-%dT%H:%M:%SZ"
AUTH_URL = "https://api.dropbox.com/oauth2/token"
EVENTS_URL = "https://api.dropbox.com/2/team_log/get_events"


def util_load_json(path):
    with open(path, encoding="utf-8") as f:
        return json.loads(f.read())


def mock_set_last_run(last_run):
    return last_run


@freeze_time("2022-05-17T00:00:00Z")
def test_fetch_incidents_few_incidents(mocker):
    """
    Given
        - 6 events was created in Dropbox side in the last 7 days.
    When
        - fetch-events is running (with max_fetch set to 100).
    Then
        - Verify that all 6 events were created in XSIAM.
        - Verify last_run was set as expected.
    """

    mocker.patch.object(demisto, "params", return_value=DEMISTO_PARAMS)
    mocker.patch.object(demisto, "args", return_value={"should_push_events": True})
    mocker.patch.object(demisto, "getIntegrationContext", return_value={"refresh_token": "111111"})
    mocker.patch("DropboxEventCollector.send_events_to_xsiam")
    last_run = mocker.patch.object(demisto, "setLastRun", side_effect=mock_set_last_run) or {}
    results = mocker.patch.object(demisto, "results")

    with requests_mock.Mocker() as m:
        m.post(AUTH_URL, json={"access_token": "222222"})
        m.post(EVENTS_URL, json=util_load_json("test_data/events_1_.json"))
        m.post(f"{EVENTS_URL}/continue", json=util_load_json("test_data/events_2_.json"))

        from DropboxEventCollector import main

        main("dropbox-get-events", demisto.params() | demisto.args())

    events = results.call_args[0][0]["Contents"]
    assert last_run.call_args[0][0].get("start_time") == "2022-05-16T11:48:29Z"
    assert len(events) == 6


@freeze_time("2022-05-17T00:00:00Z")
def test_fetch_events_no_incidents(mocker):
    """
    Given
        - No events was created in Dropbox side in the last 7 days.
    When
        - fetch-events is running.
    Then
        - Make sure no events was created in XSIAM.
        - Make sure last_run was set as expected.
    """

    mocker.patch.object(demisto, "params", return_value=DEMISTO_PARAMS)
    mocker.patch.object(demisto, "args", return_value={"should_push_events": True})
    mocker.patch.object(demisto, "getIntegrationContext", return_value={"refresh_token": "111111"})
    mocker.patch("DropboxEventCollector.send_events_to_xsiam")
    last_run = mocker.patch.object(demisto, "setLastRun", side_effect=mock_set_last_run)
    results = mocker.patch.object(demisto, "results")

    with requests_mock.Mocker() as m:
        m.post(AUTH_URL, json={"access_token": "222222"})
        m.post(EVENTS_URL, json={})

        from DropboxEventCollector import main

        main("dropbox-get-events", demisto.params() | demisto.args())

    events = results.call_args[0][0]["Contents"]
    assert not last_run.call_args
    assert not events


@freeze_time("2022-05-17T00:00:00Z")
def test_fetch_events_max_fetch_set_to_one(mocker):
    """
    Given
        - 3 events was created in Jira side in the last 7 days.
    When
        - fetch-events is running (with max_fetch set to 1).
    Then
        - Verify that only 1 event were created in XSIAM.
        - Verify last_run was set as expected.
    """

    params = DEMISTO_PARAMS.copy()
    params["limit"] = 1

    mocker.patch.object(demisto, "params", return_value=params)
    mocker.patch.object(demisto, "args", return_value={"should_push_events": True})
    mocker.patch.object(demisto, "getIntegrationContext", return_value={"refresh_token": "111111"})
    mocker.patch("DropboxEventCollector.send_events_to_xsiam")
    last_run = mocker.patch.object(demisto, "setLastRun", side_effect=mock_set_last_run)
    results = mocker.patch.object(demisto, "results")

    with requests_mock.Mocker() as m:
        m.post(AUTH_URL, json={"access_token": "222222"})
        m.post(EVENTS_URL, json=util_load_json("test_data/events_1_.json"))
        m.post(f"{EVENTS_URL}/continue", json=util_load_json("test_data/events_2_.json"))

        from DropboxEventCollector import main

        main("dropbox-get-events", demisto.params() | demisto.args())

    events = results.call_args[0][0]["Contents"]
    assert last_run.call_args[0][0].get("start_time") == "2022-05-16T11:34:30Z"
    assert len(events) == 1


def test_time_field_added_to_events(mocker):
    """
    Given:
        - Events are fetched from Dropbox with timestamp fields.
    When:
        - The dropbox-get-events command is executed with should_push_events enabled.
    Then:
        - Ensure each event has a _time field equal to its timestamp value.
    """
    mocker.patch.object(demisto, "params", return_value=DEMISTO_PARAMS)
    mocker.patch.object(demisto, "args", return_value={"should_push_events": True})
    mocker.patch.object(demisto, "getIntegrationContext", return_value={"refresh_token": "111111"})
    send_events_mock = mocker.patch("DropboxEventCollector.send_events_to_xsiam")

    with requests_mock.Mocker() as m:
        m.post(AUTH_URL, json={"access_token": "222222"})
        m.post(EVENTS_URL, json=util_load_json("test_data/events_1_.json"))
        m.post(f"{EVENTS_URL}/continue", json=util_load_json("test_data/events_2_.json"))

        from DropboxEventCollector import main

        main("dropbox-get-events", demisto.params() | demisto.args())

    sent_events = send_events_mock.call_args[0][0]

    # Verify all events have _time field matching their timestamp
    for event in sent_events:
        assert event["_time"] == event["timestamp"]