diff --git a/docs/guides.md b/docs/guides.md index f57d67bb..a513aad1 100644 --- a/docs/guides.md +++ b/docs/guides.md @@ -9,27 +9,15 @@ Getting Started Basics - userguides/searches userguides/orgdevices Device Settings Org Settings Backup Sets - userguides/cases - userguides/trustedactivities - V2 File Events - userguides/userriskprofile - userguides/watchlists ``` * [Getting Started](userguides/gettingstarted.md) * [Basics](userguides/basics.md) -* [Executing Searches](userguides/searches.md) * [Get Active Devices From An Organization](userguides/orgdevices.md) * [Device Settings](userguides/devicesettings.md) * [Org Settings](userguides/orgsettings.md) * [Backup Sets](userguides/backupsets.md) -* [Cases](userguides/cases.md) -* [Trust Settings](userguides/trustedactivities.md) -* [V2 File Events](userguides/v2apis.md) -* [User Risk Profiles](userguides/userriskprofile.md) -* [Watchlists](userguides/watchlists.md) diff --git a/docs/methoddocs/alerts.md b/docs/methoddocs/alerts.md index 550d6a46..d46b8b80 100644 --- a/docs/methoddocs/alerts.md +++ b/docs/methoddocs/alerts.md @@ -13,8 +13,6 @@ Call the appropriate classmethod on your desired filter class with the `value` y `FilterGroup` object that can be passed to `AlertQuery`'s `all()` or `any()` methods to create complex queries that match multiple filter rules. -See [Executing Searches](../userguides/searches.md) for more on building search queries. - ```{eval-rst} .. automodule:: py42.sdk.queries.alerts.filters.alert_filter :members: diff --git a/docs/methoddocs/fileeventqueries.md b/docs/methoddocs/fileeventqueries.md index 9efe2776..14848388 100644 --- a/docs/methoddocs/fileeventqueries.md +++ b/docs/methoddocs/fileeventqueries.md @@ -3,7 +3,6 @@ ```{eval-rst} .. warning:: V1 file events, saved searches, and queries are **deprecated**. ``` -For details on using the new file event data model, see the [V2 File Events User Guide](../userguides/v2apis.md). ```{eval-rst} .. autoclass:: py42.sdk.queries.fileevents.file_event_query.FileEventQuery @@ -35,8 +34,6 @@ known MD5 hashes of the files: filename_filter = FileName.is_in(['confidential_plans.docx', 'confidential_plan_projections.xlsx']) md5_filter = MD5.is_in(['133765f4fff5e3038b9352a4d14e1532', 'ea16f0cbfc76f6eba292871f8a8c794b']) -See [Executing Searches](../userguides/searches.md) for more on building search queries. - ### Event Filters ```{eval-rst} diff --git a/docs/methoddocs/fileeventqueriesv2.md b/docs/methoddocs/fileeventqueriesv2.md index 9cc01564..b81ccb9e 100644 --- a/docs/methoddocs/fileeventqueriesv2.md +++ b/docs/methoddocs/fileeventqueriesv2.md @@ -1,7 +1,5 @@ # File Event Queries - V2 -For details on using the new file event data model, see the [V2 File Events User Guide](../userguides/v2apis.md). - ```{eval-rst} .. autoclass:: py42.sdk.queries.fileevents.v2.file_event_query.FileEventQuery :members: @@ -42,8 +40,6 @@ known MD5 hashes of the files: filename_filter = File.Name.is_in(['confidential_plans.docx', 'confidential_plan_projections.xlsx']) md5_filter = File.MD5.is_in(['133765f4fff5e3038b9352a4d14e1532', 'ea16f0cbfc76f6eba292871f8a8c794b']) -See [Executing Searches](../userguides/searches.md) for more on building search queries. - ### Destination Filters ```{eval-rst} diff --git a/docs/methoddocs/securitydata.md b/docs/methoddocs/securitydata.md index 02a97d1d..afb9f9a5 100644 --- a/docs/methoddocs/securitydata.md +++ b/docs/methoddocs/securitydata.md @@ -3,7 +3,6 @@ ```{eval-rst} .. warning:: V1 file events, saved searches, and queries are **deprecated**. ``` -For details on using the new file event data model, see the [V2 File Events User Guide](../userguides/v2apis.md). ```{eval-rst} .. autoclass:: py42.clients.securitydata.SecurityDataClient diff --git a/docs/userguides/cases.md b/docs/userguides/cases.md deleted file mode 100644 index 870f8925..00000000 --- a/docs/userguides/cases.md +++ /dev/null @@ -1,48 +0,0 @@ -# Cases - -Use py42 to quickly and easily manage cases. - -## Create, View, or Modify Cases - -To get started, create a new case. - -```python -case = sdk.cases.create("new-case") -``` - -Once you've created a case, or if you're working with an existing one, you can use the case's `number` to view details about that case. - -```python - -# view details about a case -case = sdk.cases.get(case_number) - -``` - -You can also access a case by its `number` to update its details. For example, to update a case's status to `CLOSED`: - -```python -from py42.constants import CaseStatus - -response = sdk.cases.update(case_number, status=CaseStatus.CLOSED) -``` - -Case statuses can be set to either `OPEN` or `CLOSED`. Constants for these statuses are available at [Case Status](https://py42docs.code42.com/en/stable/methoddocs/constants.html#py42.constants.CaseStatus). - -## View Details for all OPEN Cases - -This section describes how to view the details of all cases with an `OPEN` status. - -```python -from py42.constants import CaseStatus - -response = sdk.cases.get_all(status=CaseStatus.OPEN) - -for page in response: - cases = page["cases"] - for case in cases: - print(case) -``` - -For complete details, see - [Cases](../methoddocs/cases.md). diff --git a/docs/userguides/searches.md b/docs/userguides/searches.md deleted file mode 100644 index 9e80ba59..00000000 --- a/docs/userguides/searches.md +++ /dev/null @@ -1,137 +0,0 @@ -# Executing Searches - -py42 features a powerful, flexible query system for quickly and easily searching file events and alerts. -This guide explains the syntax for building queries and executing searches. - -```{eval-rst} -.. _anchor_search_file_events: -``` -## Search File Events - -To query for V2 file events, import the required modules and classes and create the SDK: -```python -import py42.sdk -from py42.sdk.queries.fileevents.v2 import * -sdk = py42.sdk.from_local_account("https://console.us.code42.com", "my_username", "my_password") -``` - -V1 events are **DEPRECATED**. If you need to build V1 queries, the corresponding V1 modules can be imported in a similar manner. - -```python -from py42.sdk.queries.fileevents.v1 import * -``` - -**For more details on updating to V2 file events, see the [V2 File Events Guide](v2apis.md)** - -You must create `query_filter.FilterGroup` objects to conduct searches. Filter groups have a type -(in the form of a class), such as `email.Sender`, and an operator (in the form of a function), such as `is_in()`. -Some example filter groups look like this: - -```python -from py42.sdk.queries.fileevents.v2 import * -source_email_filter = source.EmailSender.is_in(["test.user@example.com", "test.sender@example.com"]) -event_action_filter = event.Action.exists() -destination_ip_filter = destination.PrivateIpAddress.eq("127.0.0.1") -``` - -It is also possible to create `query_filter.FilterGroups` from raw JSON. For example: - -```python -raw_json = """{"filterClause":"AND","filters":[{"display":null,"value":"P1D","operator":"WITHIN_THE_LAST","term":"eventTimestamp"}]}""" -json_dict = json.loads(raw_json) -filter_group = FilterGroup.from_dict(json_dict) -``` - -```{eval-rst} -.. important:: - The filter terms and query objects for file events have changed for V2. Make sure you're using the appropriate modules to construct your queries. -``` - -There are two operators when building `file_event_query.FileEventQuery` objects: `any()` and `all()`. - -`any()` gets results where at least one of the filters is true and `all()` gets results where all of the filters are true. - -```python -any_query = FileEventQuery.any(source_email_filter, event_action_filter) -all_query = FileEventQuery.all(event_action_filter, destination_ip_filter) -``` - -For convenience, the `FileEventQuery` constructor works the same way as `all()`: - -```python -all_query = FileEventQuery(event_action_filter, destination_ip_filter) -``` - -You can put filters in an iterable and unpack them (using the `*` operator) in a `FileEventQuery`. This is a common -use case for programs that need to conditionally build up filters: - -```python -# Conditionally appends filters to a list for crafting a query - -filter_list = [] -if need_trusted: - filter_list.append(risk.Trusted.is_true()) -elif need_user_emails: - user_email_filter = user.Email.is_in(["foo@example.com", "baz@example.com"]) - filter_list.append(user_email_filter) -# Notice the use of the '*' operator to unpack filter_list -query = FileEventQuery(*filter_list) -``` - -To execute the search, use `securitydata.SecurityModule.search_file_events()`: - -```python -# Prints the MD5 hashes of all the events where files were read by browser or other app. - -query = FileEventQuery(event.Action.eq(event.Action.APPLICATION_READ)) -response = sdk.securitydata.search_file_events(query) -file_events = response["fileEvents"] -for event in file_events: - print(event["file"]["hash"]["md5"]) -``` - -If the number of events exceeds 10,000 against a query, use `securitydata.SecurityModule.search_all_file_events()`: - -```python -query = FileEventQuery(event.Action.eq(event.Action.APPLICATION_READ)) -response = sdk.securitydata.search_all_file_events(query) -file_events = response["fileEvents"] -for event in file_events: - print(event["file"]["hash"]["md5"]) -while response["nextPgToken"] is not None: - response = sdk.securitydata.search_all_file_events(query, page_token=response["nextPgToken"]) - file_events = response["fileEvents"] - for event in file_events: - print(event["file"]["hash"]["md5"]) -``` - -```{eval-rst} -.. _anchor_search_alerts: -``` -## Search Alerts - -Alert searches work in a very similar way to file event searches. - -To start, import the filters and query object: - -```python -from py42.sdk.queries.alerts.filters import * -from py42.sdk.queries.alerts.alert_query import AlertQuery - -# Create a query for getting all open alerts with severity either 'High' or 'Medium'. - -filters = [AlertState.eq(AlertState.OPEN), Severity.is_in([Severity.HIGH, Severity.MEDIUM])] -query = AlertQuery(*filters) -``` - -For a full list of available filters, see the [alerts method docs](../methoddocs/alerts.md#filter-classes). - -To execute the search, use the `sdk.alerts.search()` method: - -```python -# Prints the actor property from each search result -response = sdk.alerts.search(query) -alerts = response["alerts"] -for alert in alerts: - print(alert["actor"]) -``` diff --git a/docs/userguides/trustedactivities.md b/docs/userguides/trustedactivities.md deleted file mode 100644 index 50204e13..00000000 --- a/docs/userguides/trustedactivities.md +++ /dev/null @@ -1,53 +0,0 @@ -# Trust Settings - -Use py42 to quickly and easily manage trusted activities and resources, including domains and Slack workspaces. - -## Create, View, or Modify Trusted Activities - -To get started, create a new trusted activity resource. - -```python -from py42.constants import TrustedActivityType - -response = sdk.trustedactivities.create(TrustedActivityType.DOMAIN, "test-domain.com") -``` -Constants for the each type of trusted activity are available at [Trusted Activity Type](https://py42docs.code42.com/en/stable/methoddocs/constants.html#py42.constants.TrustedActivityType) - - -Once you've created a trusted activity, or if you're working with an existing one, you can use the trusted activity's `resourceId` to view details about it. - -```python -response = sdk.trustedactivities.get(resource_id) - -``` - -You can also access a trusted activity by its `resourceId` to update its details. For example, to add a description to a trusted activity: - -```python -response = sdk.trustedactivities.update(resource_id, description="This is a trusted activity.") -``` - -To clear the description of a trusted activity, pass an empty string `description=""` to the `update()` method. - -```{eval-rst} -.. important:: - If you try to create with the same value as an already existing activity, you will get a `py42.exceptions.Py42TrustedActivityConflictError`. - -``` - -## View Details for all Trusted Domains - -This section describes how to view the details of all trusted activities of the type `DOMAIN`. - -```python -from py42.constants import TrustedActivityType - -response = sdk.trustedactivities.get_all(type=TrustedActivityType.DOMAIN) - -for page in response: - resources = page["trustResources"] - for resource in resources: - print(resource) -``` -For complete details, see - [Trusted Activities](../methoddocs/trustedactivities.md). diff --git a/docs/userguides/userriskprofile.md b/docs/userguides/userriskprofile.md deleted file mode 100644 index 152bce49..00000000 --- a/docs/userguides/userriskprofile.md +++ /dev/null @@ -1,58 +0,0 @@ -# User Risk Profile - -A user risk profile is created for each user. Use py42 to manage these user risk profiles. - -## Update a User Risk Profile - -Determine the user ID to manage a user's risk profile. For example, the following code uses the `get_username()` method to find the ID of a user with the username `test.user@code42.com`. - -```python -response = sdk.userriskprofile.get_username() - -user_id = response.data["userId"] -``` - -Use the user ID with the `update()` method to manage a user risk profiles' `startDate`, `endDate`, and `notes` fields. - -The `startDate` and `endDate` arguments expect a format of `YYYY-MM-DD` or a `datetime` object. - -The following code updates the departure date of the user risk profile to March 1st, 2025: - -```python -# update the user risk profile -sdk.userriskprofile.update(user_id, end_date="2025-03-01", notes="Updated the departure date.") - -# view updated user details -py42.util.print_response(sdk.userriskprofile.get(user_id)) -``` - -If you want to clear a field, provide an empty string to the corresponding argument. - -For example, the following code will clear the `endDate` and `notes` fields: - -```python -# clear fields on the user risk profile -sdk.userriskprofile.update(user_id, end_date="", notes="") -``` - -## Manage Cloud Aliases - -Each user risk profile starts with a default alias of their code42 username and can have one additional cloud alias. -Use the `UserRiskProfileClient` to manage these aliases. - -Use `add_cloud_aliases()` to assign additional cloud aliases to a user: - -```python -user_id = "test-user-123" -cloud_aliases = "test-user@email.com" -sdk.userriskprofile.add_cloud_aliases(user_id, cloud_aliases) - -# view updated user cloud aliases -py42.util.print_response(sdk.userriskprofile.get(user_id)) -``` - -Remove cloud aliases in a similar manner using the `delete_cloud_aliases()` method. Provide a list of values to add or remove multiple aliases at once. - -```python -sdk.userriskprofile.delete_cloud_aliases(user_id, ["test-user@email.com", "username@email.com"]) -``` diff --git a/docs/userguides/v2apis.md b/docs/userguides/v2apis.md deleted file mode 100644 index 9ef58723..00000000 --- a/docs/userguides/v2apis.md +++ /dev/null @@ -1,31 +0,0 @@ -# V2 File Events - -```{eval-rst} -.. warning:: V1 file events, saved searches, and queries are **deprecated**. -``` - -For details on the updated File Event Model, see the V2 File Events API documentation on the [Developer Portal](https://developer.code42.com/api/#tag/File-Events). - -## Querying file events - -To query for V2 file events, import the V2 filter modules and `FileEventQuery` class with: -```python -from py42.sdk.queries.fileevents.v2 import * -``` - -Using the `FileEventQuery` and filter classes, construct a query and search for file events as detailed in the [Executing Searches Guide](searches.md). - -## Saved Searches - -All saved search methods functions have an additional optional `use_v2=False` argument. If set to `True`, the saved search module will ingest from the V2 saved search APIs. The `use_v2` argument defaults to `False` and the V1 saved searches are still available. - -For example, use the following to view all saved searches with the new V2 apis: - -```python -import py42.sdk - -sdk = py42.sdk.from_local_account("https://console.us.code42.com", "my_username", "my_password") -sdk.securitydata.savedsearches.get(use_v2=True) -``` - -Retrieving saved searches with V2 settings enabled will retrieve existing V1 saved search queries translated to the V2 model. Existing V1 queries that cannot be properly converted to V2 will be omitted from the response. diff --git a/docs/userguides/watchlists.md b/docs/userguides/watchlists.md deleted file mode 100644 index 0fff69dd..00000000 --- a/docs/userguides/watchlists.md +++ /dev/null @@ -1,69 +0,0 @@ -# Watchlists - -Use py42 to create and manage watchlists. - -Watchlists have replaced the Departing Employees and High Risk Employees detections lists. See the [Code42 support documentation](https://support.code42.com/Incydr/Admin/Monitoring_and_managing/Manage_watchlists) on managing watchlists for more information. - -## Create a Watchlist - -```python -from py42.constants import WatchlistType - -watchlist = sdk.watchlists.create(WatchlistType.DEPARTING) - -# store the id of the new watchlist -watchlist_id = watchlist.data["watchlistId"] -``` - -Watchlist types are available as constants in the [WatchlistType](https://py42docs.code42.com/en/stable/methoddocs/constants.html#py42.constants.WatchlistType) class. - -## View Watchlist Details - -There are several methods to view different details about watchlists. - -```python -import py42.util - -# Get information on all current watchlists -response = sdk.watchlists.get_all() - -# print all information to the console -for page in response: - py42.util.print_response(page) -``` - -Once you have the watchlist's ID, use the following methods to see more details: - -```python -# To get watchlist details -sdk.watchlists.get(watchlist_id) - -# To see all included users -sdk.watchlists.get_all_included_users(watchlist_id) -``` - -## Manage Users on Watchlists - -Use the `included_users` methods to manage individual users who are explicitly included on watchlists. - -Py42 allows you to reference a watchlist either by its ID or by its type. If adding individual users to a watchlist with the `add_included_users_by_watchlist_type()` method, py42 will create the watchlist for you if it doesn't already exist. - -For example, the following code demonstrates two methods to add users to the Departing watchlist: - -```python -user_uids = ["test-user-123", "test-user-456"] - -# METHOD 1: add by watchlist id -sdk.watchlists.add_included_users_by_watchlist_id(user_uids, watchlist_id) - -# METHOD 2: add by watchlist type -from py42.constants import WatchlistType - -# this method will create the DEPARTING watchlist for you if it doesn't already exist -sdk.watchlists.add_included_users_by_watchlist_type(user_ids, WatchlistType.DEPARTING) - -# View your updated watchlist users -sdk.watchlists.get_all_included_users(watchlist_id) -``` - -The `remove_included_users_by_watchlist_id()` and `remove_included_users_by_watchlist_type()` methods can be used similarly to remove users from a watchlist. diff --git a/src/py42/clients/alerts.py b/src/py42/clients/alerts.py index 996a98f1..91496156 100644 --- a/src/py42/clients/alerts.py +++ b/src/py42/clients/alerts.py @@ -27,8 +27,6 @@ def search(self, query, page_num=1, page_size=None): Args: query (:class:`py42.sdk.queries.alerts.alert_query.AlertQuery`): An alert query. - See the :ref:`Executing Searches User Guide ` to learn more - about how to construct a query. page_num (int, optional): The page number to get. Defaults to 1. page_size (int, optional): The number of items per page. Defaults to `py42.settings.items_per_page`. @@ -46,8 +44,6 @@ def search_all_pages(self, query): Args: query (:class:`py42.sdk.queries.alerts.alert_query.AlertQuery`): An alert query. - See the :ref:`Executing Searches User Guide ` to learn more - about how to construct a query. Returns: generator: An object that iterates over :class:`py42.response.Py42Response` objects