Skip to content

Commit b8c12c0

Browse files
authored
Feature/watchlists (#367)
* initial watchlists commands * error handling * add `bulk generate-template` * require id or type option on `list-users` * unused import * mark departing_employee & high_risk as deprecated * silence py42 deprecation warnings * add deprecation_warning util func * add user-risk-profile updates to `code42 users` cmd group * fix bulk header names * watchlists cmd tests * fix existing alias cmd tests * rename commands from add>update * actually use --clear option on risk-profile update cmds * add append-note logic to bulk risk-profile update * not handling user_id in csv * new user risk profile cmd tests * PR feedback & style * brackets around user metavar * documentation updates * use get_watchlist_members instead of get_included_users * switch tests to use get_all_watchlist_members * change list-users > list-members in user guide * appease flake8 * add --only-included-users option to `list-members` cmd * move f-string docstrings to help params * document --only-included-users option * add > remove in test * changelog
1 parent 4902e57 commit b8c12c0

16 files changed

Lines changed: 1486 additions & 81 deletions

File tree

CHANGELOG.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88
The intended audience of this file is for py42 consumers -- as such, changes that don't affect
99
how a consumer would use the library (e.g. adding unit tests, updating documentation, etc) are not captured here.
1010

11+
12+
## Unreleased
13+
14+
### Added
15+
16+
- `watchlists` command group for interacting with watchlists.
17+
- `watchlists add` for adding users to a watchlist
18+
- `watchlists remove` for removing users from a watchlist
19+
- `watchlists list` for listing existing watchlists
20+
- `watchlists list-members` for listing users who are members of a given watchlist
21+
- `watchlist bulk add|remove` for adding/removing multiple users via CSV file
22+
23+
- `users update-start-date` command to add/modify the "start date" property of a User's risk profile.
24+
- `users update-departure-date` command to add/modify the "end date" property of a User's risk profile.
25+
- `users update-risk-profile-notes` command to add/modify the "notes" property of a User's risk profile.
26+
27+
### Deprecated
28+
29+
- `departing-employee` and `high-risk-employee` command groups. These actions have been replaced by the `watchlists` command group.
30+
1131
## 1.13.0 - 2022-04-04
1232

1333
### Added

docs/commands.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,27 @@
1010
Alerts <commands/alerts.rst>
1111
Audit Logs <commands/auditlogs.rst>
1212
Cases <commands/cases.rst>
13-
Departing Employee <commands/departingemployee.rst>
1413
Devices <commands/devices.rst>
15-
High Risk Employee <commands/highriskemployee.rst>
1614
Legal Hold <commands/legalhold.rst>
1715
Profile <commands/profile.rst>
1816
Security Data <commands/securitydata.rst>
1917
Trusted Activities <commands/trustedactivities.rst>
2018
Users <commands/users.rst>
19+
Watchlists <commands/watchlists.rst>
20+
(DEPRECATED) Departing Employee <commands/departingemployee.rst>
21+
(DEPRECATED) High Risk Employee <commands/highriskemployee.rst>
2122
```
2223

2324
* [Alert Rules](commands/alertrules.rst)
2425
* [Alerts](commands/alerts.rst)
2526
* [Audit Logs](commands/auditlogs.rst)
2627
* [Cases](commands/cases.rst)
27-
* [Departing Employee](commands/departingemployee.rst)
2828
* [Devices](commands/devices.rst)
29-
* [High Risk Employee](commands/highriskemployee.rst)
3029
* [Legal Hold](commands/legalhold.rst)
3130
* [Profile](commands/profile.rst)
3231
* [Security Data](commands/securitydata.rst)
3332
* [Trusted Activities](commands/trustedactivities.rst)
3433
* [Users](commands/users.rst)
34+
* [Watchlists](commands/watchlists.rst)
35+
* [(DEPRECATED) Departing Employee](commands/departingemployee.rst)
36+
* [(DEPRECATED) High Risk Employee](commands/highriskemployee.rst)

docs/commands/watchlists.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.. click:: code42cli.cmds.watchlists:watchlists
2+
:prog: watchlists
3+
:nested: full

docs/guides.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
Get started with the Code42 command-line interface (CLI) <userguides/gettingstarted.md>
1010
Configure a profile <userguides/profile.md>
1111
Ingest data into a SIEM <userguides/siemexample.md>
12-
Manage detection list users <userguides/detectionlists.md>
1312
Manage legal hold users <userguides/legalhold.md>
1413
Clean up your environment by deactivating devices <userguides/deactivatedevices.md>
1514
Write custom extension scripts using the Code42 CLI and Py42 <userguides/extensions.md>
@@ -18,12 +17,13 @@
1817
Configure alert rules <userguides/alertrules.md>
1918
Add and manage cases <userguides/cases.md>
2019
Perform bulk actions <userguides/bulkcommands.md>
20+
Manage watchlist members <userguides/watchlists.md>
21+
(DEPRECATED) Manage detection list users <userguides/detectionlists.md>
2122
```
2223

2324
* [Get started with the Code42 command-line interface (CLI)](userguides/gettingstarted.md)
2425
* [Configure a profile](userguides/profile.md)
2526
* [Ingest data into a SIEM](userguides/siemexample.md)
26-
* [Manage detection list users](userguides/detectionlists.md)
2727
* [Manage legal hold users](userguides/legalhold.md)
2828
* [Clean up your environment by deactivating devices](userguides/deactivatedevices.md)
2929
* [Write custom extension scripts using the Code42 CLI and Py42](userguides/extensions.md)
@@ -32,3 +32,5 @@
3232
* [Configure alert rules](userguides/alertrules.md)
3333
* [Add and manage cases](userguides/cases.md)
3434
* [Perform bulk actions](userguides/bulkcommands.md)
35+
* [Manage watchlist members](userguides/watchlists.md)
36+
* [(DEPRECATED) Manage detection list users](userguides/detectionlists.md)

docs/userguides/detectionlists.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
1-
# Manage Detection List Users
1+
# (DEPRECATED) Manage Detection List Users
2+
3+
```{eval-rst}
4+
.. note::
5+
6+
Detection Lists have been replaced by Watchlists.
7+
8+
Functionality for adding users to Departing Employee and High Risk Employee categories has been migrated to the :code:`code42 watchlists` command group.
9+
10+
Functionality for listing and managing User Risk Profiles (e.g. adding Cloud Aliases, Notes, and Start/End dates to a user profile) has been migrated to the :code:`code42 users` command group.
11+
```
212

313
Use the `departing-employee` commands to add employees to or remove employees from the Departing Employees list. Use the `high-risk-employee` commands to add employees to or remove employees from the High Risk list, or update risk tags for those users.
414

docs/userguides/users.md

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,34 @@ code42 users add-role --username "sean.cassidy@example.com" --role-name "Desktop
3434

3535
Similarly, use the `remove-role` command to remove a role from a user.
3636

37+
## Manage User Risk Profile info
38+
39+
To set a start or end/departure date on a User's profile (useful for users on the "New Hire" and "Departing" Watchlists):
40+
41+
```bash
42+
code42 users update-start-date 2020-03-10 user@example.com
43+
44+
code42 users update-departure-date 2022-06-20 user@example.com
45+
```
46+
47+
To clear the value of start_date/end_date on a User's profile, use the `--clear` option to the above commands:
48+
49+
```bash
50+
code42 users update-departure-date --clear user@example.com
51+
```
52+
53+
To update a User's Risk Profile notes field:
54+
55+
```bash
56+
code42 users update-risk-profile-notes user@example.com "New note text"
57+
```
58+
59+
By default, the note text will overwrite notes are already on the profile. To keep existing note data, use the `--append` option:
60+
61+
```bash
62+
code42 users update-risk-profile-notes user@example.com "Additional note text" --append
63+
```
64+
3765
## Deactivate a User
3866

3967
You can deactivate a user with the following command:
@@ -73,17 +101,18 @@ Alternatively, to move multiple users between organizations, fill out the `move`
73101
code42 users bulk move bulk-command.csv
74102
```
75103

76-
## Get CSV Template
104+
## Get CSV Template for bulk commands
77105

78-
The following command generates a CSV template to either update users' data, or move users between organizations. The csv file is saved to the current working directory.
106+
The following command generates a CSV template for each of the available bulk user commands. The CSV file is saved to the current working directory.
79107
```bash
80-
code42 trusted-activities bulk generate-template [update|move]
108+
code42 users bulk generate-template [update|move|add-alias|remove-alias|update-risk-profile]
81109
```
82110

83111
Once generated, fill out and use each of the CSV templates with their respective bulk commands.
84112
```bash
85-
code42 trusted-activities bulk [update|move|reactivate|deactivate] bulk-command.csv
113+
code42 users bulk [update|move|deactivate|reactivate|add-alias|remove-alias|update-risk-profile] bulk-command.csv
86114
```
115+
87116
A CSV with a `username` column and a single username on each new line is used for the `reactivate` and `deactivate` bulk commands. These commands are not available as options for `generate-template`.
88117

89118
Learn more about [Managing Users](../commands/users.md).

docs/userguides/watchlists.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Manage watchlist members
2+
3+
## List created watchlists
4+
5+
To list all the watchlists active in your Code42 environment, run:
6+
7+
```bash
8+
code42 watchlists list
9+
```
10+
11+
## List all members of a watchlist
12+
13+
You can list watchlists either by their Type:
14+
15+
```bash
16+
code42 watchlists list-members --watchlist-type DEPARTING_EMPLOYEE
17+
```
18+
19+
or by their ID (get watchlist IDs from `code42 watchlist list` output):
20+
21+
```bash
22+
code42 watchlists list-members --watchlist-id 6e6c5acc-2568-4e5f-8324-e73f2811fa7c
23+
```
24+
25+
A "member" of a watchlist is any user that the watchlist alerting rules apply to. Users can be members of a watchlist
26+
either by being explicitly added (via console or `code42 watchlists add [USER_ID|USERNAME]`), but they can also be
27+
implicitly included based on some user profile property (like working in a specific department). To get a list of only
28+
those "members" who have been explicitly added (and thus can be removed via the `code42 watchlists remove [USER_ID|USERNAME]`
29+
command), add the `--only-included-users` option to `list-members`.
30+
31+
## Add or remove a single user from watchlist membership
32+
33+
A user can be added to a watchlist using either the watchlist ID or Type, just like listing watchlists, and the user
34+
can be identified either by their user_id or their username:
35+
36+
```bash
37+
code42 watchlist add --watchlist-type NEW_EMPLOYEE 9871230
38+
```
39+
40+
```bash
41+
code42 watchlist add --watchlist-id 6e6c5acc-2568-4e5f-8324-e73f2811fa7c user@example.com
42+
```
43+
44+
## Bulk adding/removing users from watchlists
45+
46+
The bulk watchlist commands read input from a CSV file.
47+
48+
Like the individual commands, they can take either a user_id/username or watchlist_id/watchlist_type to identify who
49+
to add to which watchlist. Because of this flexibility, the CSV does require a header row identifying each column.
50+
51+
You can generate a template CSV with the correct header values using the command:
52+
53+
```bash
54+
code42 watchlists bulk generate-template [add|remove]
55+
```
56+
57+
If both username and user_id are provided in the CSV row, the user_id value will take precedence. If watchlist_type and watchlist_id columns
58+
are both provided, the watchlist_id will take precedence.
59+
60+
## Add Watchlist-related metadata to User's Profile
61+
62+
Some Watchlists store related metadata to the watchlist member on the User Risk Profile. For example, when adding a user
63+
to the Departing Watchlist in the Code42 admin console, you can specify a "departure date" for the user. These values
64+
can be set/updated from the CLI under the [Users command group](./users.md#manage-user-risk-profile-info)

src/code42cli/click_ext/groups.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from py42.exceptions import Py42InvalidRuleOperationError
1818
from py42.exceptions import Py42InvalidUsernameError
1919
from py42.exceptions import Py42LegalHoldNotFoundOrPermissionDeniedError
20+
from py42.exceptions import Py42NotFoundError
2021
from py42.exceptions import Py42OrgNotFoundError
2122
from py42.exceptions import Py42TrustedActivityConflictError
2223
from py42.exceptions import Py42TrustedActivityIdNotFound
@@ -25,6 +26,8 @@
2526
from py42.exceptions import Py42UserAlreadyAddedError
2627
from py42.exceptions import Py42UsernameMustBeEmailError
2728
from py42.exceptions import Py42UserNotOnListError
29+
from py42.exceptions import Py42UserRiskProfileNotFound
30+
from py42.exceptions import Py42WatchlistNotFound
2831

2932
from code42cli.errors import Code42CLIError
3033
from code42cli.errors import LoggedCLIError
@@ -90,6 +93,9 @@ def invoke(self, ctx):
9093
Py42TrustedActivityIdNotFound,
9194
Py42CloudAliasLimitExceededError,
9295
Py42CloudAliasCharacterLimitExceededError,
96+
Py42UserRiskProfileNotFound,
97+
Py42WatchlistNotFound,
98+
Py42NotFoundError,
9399
) as err:
94100
msg = err.args[0]
95101
self.logger.log_error(msg)

src/code42cli/cmds/departing_employee.py

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,16 @@
1717
from code42cli.file_readers import read_csv_arg
1818
from code42cli.options import format_option
1919
from code42cli.options import sdk_options
20+
from code42cli.util import deprecation_warning
2021

2122

2223
def _get_filter_choices():
2324
filters = DepartingEmployeeFilters.choices()
2425
return get_choices(filters)
2526

2627

28+
DEPRECATION_TEXT = "(DEPRECATED): Use `code42 watchlists` commands instead."
29+
2730
DATE_FORMAT = "%Y-%m-%d"
2831
filter_option = click.option(
2932
"--filter",
@@ -34,19 +37,18 @@ def _get_filter_choices():
3437
)
3538

3639

37-
@click.group(cls=OrderedGroup)
40+
@click.group(cls=OrderedGroup, help=f"{DEPRECATION_TEXT}\n\nAdd and remove employees from the Departing Employees detection list.")
3841
@sdk_options(hidden=True)
3942
def departing_employee(state):
40-
"""Add and remove employees from the Departing Employees detection list."""
4143
pass
4244

4345

44-
@departing_employee.command("list")
46+
@departing_employee.command("list", help=f"{DEPRECATION_TEXT}\n\nLists the users on the Departing Employees list.")
4547
@sdk_options()
4648
@format_option
4749
@filter_option
4850
def _list(state, format, filter):
49-
"""Lists the users on the Departing Employees list."""
51+
deprecation_warning(DEPRECATION_TEXT)
5052
employee_generator = _get_departing_employees(state.sdk, filter)
5153
list_employees(
5254
employee_generator,
@@ -55,7 +57,7 @@ def _list(state, format, filter):
5557
)
5658

5759

58-
@departing_employee.command()
60+
@departing_employee.command(help=f"{DEPRECATION_TEXT}\n\nAdd a user to the Departing Employees detection list.")
5961
@username_arg
6062
@click.option(
6163
"--departure-date",
@@ -66,22 +68,22 @@ def _list(state, format, filter):
6668
@notes_option
6769
@sdk_options()
6870
def add(state, username, cloud_alias, departure_date, notes):
69-
"""Add a user to the Departing Employees detection list."""
71+
72+
deprecation_warning(DEPRECATION_TEXT)
7073
_add_departing_employee(state.sdk, username, cloud_alias, departure_date, notes)
7174

7275

73-
@departing_employee.command()
76+
@departing_employee.command(help=f"{DEPRECATION_TEXT}\n\nRemove a user from the Departing Employees detection list.")
7477
@username_arg
7578
@sdk_options()
7679
def remove(state, username):
77-
"""Remove a user from the Departing Employees detection list."""
80+
deprecation_warning(DEPRECATION_TEXT)
7881
_remove_departing_employee(state.sdk, username)
7982

8083

81-
@departing_employee.group(cls=OrderedGroup)
84+
@departing_employee.group(cls=OrderedGroup, help=f"{DEPRECATION_TEXT}\n\nTools for executing bulk departing employee actions.")
8285
@sdk_options(hidden=True)
8386
def bulk(state):
84-
"""Tools for executing bulk departing employee actions."""
8587
pass
8688

8789

@@ -101,12 +103,13 @@ def bulk(state):
101103

102104
@bulk.command(
103105
name="add",
104-
help="Bulk add users to the departing employees detection list using a CSV file with "
105-
f"format: {','.join(DEPARTING_EMPLOYEE_CSV_HEADERS)}.",
106+
help=f"{DEPRECATION_TEXT}\n\nBulk add users to the departing employees detection list using "
107+
f"a CSV file with format: {','.join(DEPARTING_EMPLOYEE_CSV_HEADERS)}.",
106108
)
107109
@read_csv_arg(headers=DEPARTING_EMPLOYEE_CSV_HEADERS)
108110
@sdk_options()
109111
def bulk_add(state, csv_rows):
112+
deprecation_warning(DEPRECATION_TEXT)
110113
sdk = state.sdk # Force initialization of py42 to only happen once.
111114

112115
def handle_row(username, cloud_alias, departure_date, notes):
@@ -131,11 +134,13 @@ def handle_row(username, cloud_alias, departure_date, notes):
131134

132135
@bulk.command(
133136
name="remove",
134-
help=f"Bulk remove users from the departing employees detection list using a CSV file with format {','.join(REMOVE_EMPLOYEE_HEADERS)}.",
137+
help=f"{DEPRECATION_TEXT}\n\nBulk remove users from the departing employees detection list "
138+
f"using a CSV file with format {','.join(REMOVE_EMPLOYEE_HEADERS)}.",
135139
)
136140
@read_csv_arg(headers=REMOVE_EMPLOYEE_HEADERS)
137141
@sdk_options()
138142
def bulk_remove(state, csv_rows):
143+
deprecation_warning(DEPRECATION_TEXT)
139144
sdk = state.sdk
140145

141146
def handle_row(username):

0 commit comments

Comments
 (0)