prelude-cli-beta 1405__py3-none-any.whl → 1407__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of prelude-cli-beta might be problematic. Click here for more details.

Files changed (35) hide show
  1. prelude_cli_beta/cli.py +52 -0
  2. prelude_cli_beta/views/auth.py +56 -0
  3. prelude_cli_beta/views/build.py +488 -0
  4. prelude_cli_beta/views/configure.py +29 -0
  5. prelude_cli_beta/views/detect.py +438 -0
  6. prelude_cli_beta/views/generate.py +125 -0
  7. prelude_cli_beta/views/iam.py +368 -0
  8. prelude_cli_beta/views/jobs.py +50 -0
  9. prelude_cli_beta/views/partner.py +192 -0
  10. prelude_cli_beta/views/scm.py +744 -0
  11. prelude_cli_beta/views/shared.py +37 -0
  12. prelude_cli_beta-1407.dist-info/METADATA +38 -0
  13. prelude_cli_beta-1407.dist-info/RECORD +20 -0
  14. prelude_cli_beta-1407.dist-info/entry_points.txt +3 -0
  15. prelude_cli_beta-1407.dist-info/top_level.txt +1 -0
  16. prelude_cli_beta-1405.dist-info/METADATA +0 -46
  17. prelude_cli_beta-1405.dist-info/RECORD +0 -20
  18. prelude_cli_beta-1405.dist-info/top_level.txt +0 -1
  19. prelude_sdk_beta/controllers/build_controller.py +0 -309
  20. prelude_sdk_beta/controllers/detect_controller.py +0 -243
  21. prelude_sdk_beta/controllers/export_controller.py +0 -31
  22. prelude_sdk_beta/controllers/generate_controller.py +0 -40
  23. prelude_sdk_beta/controllers/http_controller.py +0 -63
  24. prelude_sdk_beta/controllers/iam_controller.py +0 -278
  25. prelude_sdk_beta/controllers/jobs_controller.py +0 -26
  26. prelude_sdk_beta/controllers/partner_controller.py +0 -166
  27. prelude_sdk_beta/controllers/probe_controller.py +0 -14
  28. prelude_sdk_beta/controllers/scm_controller.py +0 -424
  29. prelude_sdk_beta/models/account.py +0 -264
  30. prelude_sdk_beta/models/codes.py +0 -446
  31. {prelude_sdk_beta → prelude_cli_beta}/__init__.py +0 -0
  32. {prelude_sdk_beta/controllers → prelude_cli_beta/templates}/__init__.py +0 -0
  33. {prelude_sdk_beta/models → prelude_cli_beta/views}/__init__.py +0 -0
  34. {prelude_cli_beta-1405.dist-info → prelude_cli_beta-1407.dist-info}/WHEEL +0 -0
  35. {prelude_cli_beta-1405.dist-info → prelude_cli_beta-1407.dist-info}/licenses/LICENSE +0 -0
@@ -1,264 +0,0 @@
1
- import configparser
2
- import json
3
- import os
4
- from functools import wraps
5
- from pathlib import Path
6
-
7
- import requests
8
-
9
-
10
- class Keychain:
11
-
12
- def __init__(
13
- self,
14
- keychain_location: str | None = os.path.join(
15
- Path.home(), ".prelude", "keychain.ini"
16
- ),
17
- ):
18
- self.keychain_location = keychain_location
19
- if self.keychain_location and not os.path.exists(self.keychain_location):
20
- head, _ = os.path.split(Path(self.keychain_location))
21
- Path(head).mkdir(parents=True, exist_ok=True)
22
- open(self.keychain_location, "x").close()
23
- self.configure_keychain("", "")
24
-
25
- def read_keychain(self):
26
- cfg = configparser.ConfigParser()
27
- cfg.read(self.keychain_location)
28
- return cfg
29
-
30
- def configure_keychain(
31
- self,
32
- account,
33
- handle,
34
- hq="https://api.us1.preludesecurity.com",
35
- oidc=None,
36
- profile="default",
37
- slug=None,
38
- ):
39
- cfg = self.read_keychain()
40
- cfg[profile] = {"account": account, "handle": handle, "hq": hq}
41
- if oidc:
42
- cfg[profile]["oidc"] = oidc
43
- if slug:
44
- cfg[profile]["slug"] = slug
45
- with open(self.keychain_location, "w") as f:
46
- cfg.write(f)
47
-
48
- def get_profile(self, profile="default") -> dict:
49
- try:
50
- cfg = self.read_keychain()
51
- profile = next(s for s in cfg.sections() if s == profile)
52
- return dict(cfg[profile].items())
53
- except StopIteration:
54
- raise Exception(
55
- "Could not find profile %s for account in %s"
56
- % (profile, self.keychain_location)
57
- )
58
-
59
-
60
- def exchange_token(
61
- account: str, handle: str, hq: str, auth_flow: str, auth_params: dict
62
- ):
63
- """
64
- Two token exchange auth flows:
65
- 1) Password auth: auth_flow = "password", auth_params = {"password": "your_password"}
66
- 2) Refresh token auth: auth_flow = "refresh", auth_params = {"refresh_token": "your_refresh_token"}
67
- 3) Exchange an OIDC authorization code for tokens:
68
- auth_flow = "oauth_code", auth_params = {"code": "your_authorization_code", "verifier": "your_verifier", "source": "cli"}
69
- """
70
- res = requests.post(
71
- f"{hq}/iam/token",
72
- headers=dict(account=account, _product="py-sdk"),
73
- json=dict(auth_flow=auth_flow, handle=handle, **auth_params),
74
- timeout=10,
75
- )
76
- if res.status_code == 401:
77
- raise Exception("Error logging in: Unauthorized")
78
- if not res.ok:
79
- raise Exception("Error logging in: %s" % res.text)
80
- return res.json()
81
-
82
-
83
- class Account:
84
-
85
- @staticmethod
86
- def from_keychain(profile: str = "default"):
87
- """
88
- Create an account object from a pre-configured profile in your keychain file
89
- """
90
- keychain = Keychain()
91
- profile_items = keychain.get_profile(profile)
92
- if any([item not in profile_items for item in ["account", "handle", "hq"]]):
93
- raise ValueError(
94
- "Please make sure you are using an up-to-date profile with the following fields: account, handle, hq"
95
- )
96
- return _Account(
97
- account=profile_items["account"],
98
- handle=profile_items["handle"],
99
- hq=profile_items["hq"],
100
- oidc=profile_items.get("oidc"),
101
- profile=profile,
102
- slug=profile_items.get("slug"),
103
- )
104
-
105
- @staticmethod
106
- def from_token(
107
- account: str,
108
- handle: str,
109
- token: str | None = None,
110
- refresh_token: str | None = None,
111
- hq: str = "https://api.us1.preludesecurity.com",
112
- oidc: str | None = None,
113
- slug: str | None = None,
114
- ):
115
- """
116
- Create an account object from an access token or a refresh token
117
- """
118
- if not any([token, refresh_token]):
119
- raise ValueError("Please provide either an access token or a refresh token")
120
- if refresh_token:
121
- res = exchange_token(
122
- account, handle, hq, "refresh", dict(refresh_token=refresh_token)
123
- )
124
- token = res["token"]
125
- return _Account(
126
- account,
127
- handle,
128
- hq,
129
- keychain_location=None,
130
- oidc=oidc,
131
- slug=slug,
132
- token=token,
133
- token_location=None,
134
- )
135
-
136
-
137
- class _Account:
138
-
139
- def __init__(
140
- self,
141
- account: str,
142
- handle: str,
143
- hq: str,
144
- oidc: str | None = None,
145
- profile: str | None = None,
146
- slug: str | None = None,
147
- token: str | None = None,
148
- keychain_location: str | None = os.path.join(
149
- Path.home(), ".prelude", "keychain.ini"
150
- ),
151
- token_location: str | None = os.path.join(
152
- Path.home(), ".prelude", "tokens.json"
153
- ),
154
- ):
155
- if token is None and token_location is None:
156
- raise ValueError(
157
- "Please provide either an access token or a token location"
158
- )
159
-
160
- super().__init__()
161
- self.account = account
162
- self.handle = handle
163
- self.headers = dict(account=account, _product="py-sdk")
164
- self.hq = hq
165
- self.keychain = Keychain(keychain_location)
166
- self.oidc = oidc
167
- self.profile = profile
168
- self.slug = slug
169
- self.token = token
170
- self.token_location = token_location
171
- if self.token_location and not os.path.exists(self.token_location):
172
- head, _ = os.path.split(Path(self.token_location))
173
- Path(head).mkdir(parents=True, exist_ok=True)
174
- with open(self.token_location, "x") as f:
175
- json.dump({}, f)
176
- self.source = "cli" if self.oidc else "main"
177
-
178
- @property
179
- def token_key(self):
180
- return f"{self.handle}/{self.oidc}" if self.oidc else self.handle
181
-
182
- def _read_tokens(self):
183
- with open(self.token_location, "r") as f:
184
- return json.load(f)
185
-
186
- def save_new_token(self, new_tokens):
187
- existing_tokens = self._read_tokens()
188
- if self.token_key not in existing_tokens:
189
- existing_tokens[self.token_key] = dict()
190
- existing_tokens[self.token_key][self.hq] = new_tokens
191
- with open(self.token_location, "w") as f:
192
- json.dump(existing_tokens, f)
193
-
194
- def _verify(self):
195
- if not self.token_location:
196
- raise ValueError("Please provide a token location to continue")
197
- if self.profile and not any([self.handle, self.account]):
198
- raise ValueError(
199
- "Please configure your %s profile to continue" % self.profile
200
- )
201
-
202
- def password_login(self, password, new_password=None):
203
- self._verify()
204
- tokens = exchange_token(
205
- self.account,
206
- self.handle,
207
- self.hq,
208
- "password_change" if new_password else "password",
209
- dict(password=password, new_password=new_password),
210
- )
211
- self.save_new_token(tokens)
212
- return tokens
213
-
214
- def refresh_tokens(self):
215
- self._verify()
216
- existing_tokens = self._read_tokens().get(self.token_key, {}).get(self.hq, {})
217
- if not (refresh_token := existing_tokens.get("refresh_token")):
218
- raise Exception("No refresh token found, please login first to continue")
219
- tokens = exchange_token(
220
- self.account,
221
- self.handle,
222
- self.hq,
223
- "refresh",
224
- dict(refresh_token=refresh_token, source=self.source),
225
- )
226
- tokens = existing_tokens | tokens
227
- self.save_new_token(tokens)
228
- return tokens
229
-
230
- def exchange_authorization_code(self, authorization_code: str, verifier: str):
231
- self._verify()
232
- tokens = exchange_token(
233
- self.account,
234
- self.handle,
235
- self.hq,
236
- "oauth_code",
237
- dict(code=authorization_code, verifier=verifier, source=self.source),
238
- )
239
- existing_tokens = self._read_tokens().get(self.token_key, {}).get(self.hq, {})
240
- tokens = existing_tokens | tokens
241
- self.save_new_token(tokens)
242
- return tokens
243
-
244
- def get_token(self):
245
- if self.token:
246
- return self.token
247
-
248
- tokens = self._read_tokens().get(self.token_key, {}).get(self.hq, {})
249
- if "token" not in tokens:
250
- raise Exception("Please login to continue")
251
- return tokens["token"]
252
-
253
- def update_auth_header(self):
254
- self.headers |= dict(authorization=f"Bearer {self.get_token()}")
255
-
256
-
257
- def verify_credentials(func):
258
- @wraps(verify_credentials)
259
- def handler(*args, **kwargs):
260
- args[0].account.update_auth_header()
261
- return func(*args, **kwargs)
262
-
263
- handler.__wrapped__ = func
264
- return handler
@@ -1,446 +0,0 @@
1
- import logging
2
-
3
- from enum import Enum, EnumMeta
4
-
5
-
6
- class MissingItem(EnumMeta):
7
- def __getitem__(cls, name):
8
- try:
9
- return super().__getitem__(name.upper())
10
- except (AttributeError, KeyError):
11
- try:
12
- return cls(int(name))
13
- except ValueError:
14
- return cls(name)
15
-
16
-
17
- class RunCode(Enum, metaclass=MissingItem):
18
- INVALID = -1
19
- DAILY = 1
20
- WEEKLY = 2
21
- MONTHLY = 3
22
- SMART = 4
23
- DEBUG = 5
24
- RUN_ONCE = 6
25
- MONDAY = 10
26
- TUESDAY = 11
27
- WEDNESDAY = 12
28
- THURSDAY = 13
29
- FRIDAY = 14
30
- SATURDAY = 15
31
- SUNDAY = 16
32
- MONTH_1 = 20
33
-
34
- @classmethod
35
- def _missing_(cls, value):
36
- return RunCode.DAILY
37
-
38
-
39
- class Mode(Enum, metaclass=MissingItem):
40
- MANUAL = 0
41
- FROZEN = 1
42
- AUTOPILOT = 2
43
-
44
- @classmethod
45
- def _missing_(cls, value):
46
- return Mode.MANUAL
47
-
48
-
49
- class Permission(Enum, metaclass=MissingItem):
50
- INVALID = -1
51
- ADMIN = 0
52
- EXECUTIVE = 1
53
- BUILD = 2
54
- SERVICE = 3
55
- SUPPORT = 5
56
-
57
- @classmethod
58
- def _missing_(cls, value):
59
- return Permission.INVALID
60
-
61
-
62
- class ExitCode(Enum):
63
- MISSING = -1
64
- UNKNOWN_ERROR = 1
65
- MALFORMED_TEST = 2
66
- UNREPORTED = 3
67
- PROCESS_BLOCKED = 9
68
- PROCESS_BLOCKED_GRACEFULLY = 15
69
- PROTECTED = 100
70
- UNPROTECTED = 101
71
- TIMED_OUT = 102
72
- FAILED_CLEANUP = 103
73
- TEST_NOT_RELEVANT = 104
74
- DYNAMIC_QUARANTINE = 105
75
- BLOCKED_AT_PERIMETER = 106
76
- EXPLOIT_PREVENTED = 107
77
- ENDPOINT_NOT_RELEVANT = 108
78
- INSUFFICIENT_PRIVILEGES = 109
79
- INCORRECTLY_BLOCKED = 110
80
- PREVENTED_EXECUTION = 126
81
- STATIC_QUARANTINE = 127
82
- BLOCKED = 137
83
- UNEXPECTED_ERROR = 256
84
-
85
- @classmethod
86
- def _missing_(cls, value):
87
- if value and not isinstance(value, int):
88
- return cls(int(value))
89
- logging.warning("Unknown ExitCode: %s", str(value))
90
- return ExitCode.MISSING
91
-
92
- @property
93
- def state(self):
94
- for k, v in State.mapping().items():
95
- if self in v:
96
- return k
97
- return State.NONE
98
-
99
-
100
- class State(Enum):
101
- NONE = 0
102
- PROTECTED = 1
103
- UNPROTECTED = 2
104
- ERROR = 3
105
- NOT_RELEVANT = 4
106
-
107
- @classmethod
108
- def mapping(cls):
109
- return {
110
- State.ERROR: [
111
- ExitCode.FAILED_CLEANUP,
112
- ExitCode.INCORRECTLY_BLOCKED,
113
- ExitCode.MALFORMED_TEST,
114
- ExitCode.TIMED_OUT,
115
- ExitCode.UNEXPECTED_ERROR,
116
- ExitCode.UNKNOWN_ERROR,
117
- ExitCode.UNREPORTED,
118
- ],
119
- State.NONE: [ExitCode.MISSING],
120
- State.NOT_RELEVANT: [
121
- ExitCode.ENDPOINT_NOT_RELEVANT,
122
- ExitCode.INSUFFICIENT_PRIVILEGES,
123
- ExitCode.TEST_NOT_RELEVANT,
124
- ],
125
- State.PROTECTED: [
126
- ExitCode.BLOCKED,
127
- ExitCode.BLOCKED_AT_PERIMETER,
128
- ExitCode.DYNAMIC_QUARANTINE,
129
- ExitCode.EXPLOIT_PREVENTED,
130
- ExitCode.PREVENTED_EXECUTION,
131
- ExitCode.PROCESS_BLOCKED,
132
- ExitCode.PROCESS_BLOCKED_GRACEFULLY,
133
- ExitCode.PROTECTED,
134
- ExitCode.STATIC_QUARANTINE,
135
- ],
136
- State.UNPROTECTED: [
137
- ExitCode.UNPROTECTED,
138
- ],
139
- }
140
-
141
-
142
- class DOS(Enum):
143
- none = "none"
144
- arm64 = "arm64"
145
- x86_64 = "x86_64"
146
- aarch64 = "arm64"
147
- amd64 = "x86_64"
148
- x86 = "x86_64"
149
-
150
- @classmethod
151
- def normalize(cls, dos: str):
152
- try:
153
- arch = dos.split("-", 1)[-1]
154
- return dos[: -len(arch)].lower() + cls[arch.lower()].value
155
- except (KeyError, IndexError, AttributeError):
156
- return cls.none.value
157
-
158
-
159
- class Control(Enum, metaclass=MissingItem):
160
- INVALID = -1
161
- NONE = 0
162
- CROWDSTRIKE = 1
163
- DEFENDER = 2
164
- SPLUNK = 3
165
- SENTINELONE = 4
166
- VECTR = 5
167
- S3 = 6
168
- INTUNE = 7
169
- SERVICENOW = 8
170
- OKTA = 9
171
- M365 = 10
172
- ENTRA = 11
173
- JAMF = 12
174
- CROWDSTRIKE_IDENTITY = 13
175
- GMAIL = 14
176
- GOOGLE_IDENTITY = 15
177
- DEFENDER_DISCOVERY = 16
178
- TENABLE = 17
179
- EC2 = 18
180
- AWS_SSM = 19
181
- AZURE_VM = 20
182
- GITHUB = 21
183
- TENABLE_DISCOVERY = 22
184
- QUALYS = 23
185
- QUALYS_DISCOVERY = 24
186
-
187
- @classmethod
188
- def _missing_(cls, value):
189
- return Control.INVALID
190
-
191
- @property
192
- def control_category(self):
193
- for k, v in ControlCategory.mapping().items():
194
- if self in v:
195
- return k
196
- return ControlCategory.NONE
197
-
198
- @property
199
- def scm_category(self):
200
- for k, v in SCMCategory.control_mapping().items():
201
- if self in v:
202
- return k
203
- return SCMCategory.NONE
204
-
205
-
206
- class ControlCategory(Enum, metaclass=MissingItem):
207
- INVALID = -1
208
- NONE = 0
209
- CLOUD = 1
210
- EMAIL = 2
211
- IDENTITY = 3
212
- NETWORK = 4
213
- XDR = 5
214
- ASSET_MANAGER = 6
215
- DISCOVERED_DEVICES = 7
216
- VULN_MANAGER = 8
217
- SIEM = 9
218
- PRIVATE_REPO = 10
219
-
220
- @classmethod
221
- def _missing_(cls, value):
222
- return ControlCategory.INVALID
223
-
224
- @classmethod
225
- def mapping(cls):
226
- return {
227
- ControlCategory.ASSET_MANAGER: [
228
- Control.AWS_SSM,
229
- Control.INTUNE,
230
- Control.JAMF,
231
- ],
232
- ControlCategory.CLOUD: [],
233
- ControlCategory.DISCOVERED_DEVICES: [
234
- Control.AZURE_VM,
235
- Control.DEFENDER_DISCOVERY,
236
- Control.EC2,
237
- Control.QUALYS_DISCOVERY,
238
- Control.SERVICENOW,
239
- Control.TENABLE_DISCOVERY,
240
- ],
241
- ControlCategory.EMAIL: [
242
- Control.GMAIL,
243
- Control.M365,
244
- ],
245
- ControlCategory.IDENTITY: [
246
- Control.CROWDSTRIKE_IDENTITY,
247
- Control.ENTRA,
248
- Control.GOOGLE_IDENTITY,
249
- Control.OKTA,
250
- ],
251
- ControlCategory.NETWORK: [],
252
- ControlCategory.PRIVATE_REPO: [
253
- Control.GITHUB,
254
- ],
255
- ControlCategory.SIEM: [
256
- Control.S3,
257
- Control.SPLUNK,
258
- Control.VECTR,
259
- ],
260
- ControlCategory.VULN_MANAGER: [Control.QUALYS, Control.TENABLE],
261
- ControlCategory.XDR: [
262
- Control.CROWDSTRIKE,
263
- Control.DEFENDER,
264
- Control.SENTINELONE,
265
- ],
266
- }
267
-
268
-
269
- class SCMCategory(Enum, metaclass=MissingItem):
270
- INVALID = -1
271
- NONE = 0
272
- ENDPOINT = 1
273
- INBOX = 2
274
- USER = 3
275
-
276
- @classmethod
277
- def _missing_(cls, value):
278
- return SCMCategory.INVALID
279
-
280
- @classmethod
281
- def control_mapping(cls):
282
- return {
283
- SCMCategory.ENDPOINT: [
284
- Control.AWS_SSM,
285
- Control.AZURE_VM,
286
- Control.CROWDSTRIKE,
287
- Control.DEFENDER,
288
- Control.DEFENDER_DISCOVERY,
289
- Control.EC2,
290
- Control.INTUNE,
291
- Control.JAMF,
292
- Control.QUALYS,
293
- Control.QUALYS_DISCOVERY,
294
- Control.SENTINELONE,
295
- Control.SERVICENOW,
296
- Control.TENABLE,
297
- Control.TENABLE_DISCOVERY,
298
- ],
299
- SCMCategory.USER: [
300
- Control.CROWDSTRIKE_IDENTITY,
301
- Control.ENTRA,
302
- Control.GOOGLE_IDENTITY,
303
- Control.OKTA,
304
- ],
305
- SCMCategory.INBOX: [
306
- Control.GMAIL,
307
- Control.M365,
308
- ],
309
- }
310
-
311
- @classmethod
312
- def category_mapping(cls):
313
- return {
314
- SCMCategory.ENDPOINT: [
315
- ControlCategory.ASSET_MANAGER,
316
- ControlCategory.DISCOVERED_DEVICES,
317
- ControlCategory.VULN_MANAGER,
318
- ControlCategory.XDR,
319
- ],
320
- SCMCategory.USER: [ControlCategory.IDENTITY],
321
- SCMCategory.INBOX: [ControlCategory.EMAIL],
322
- }
323
-
324
-
325
- class BackgroundJobTypes(Enum, metaclass=MissingItem):
326
- INVALID = -1
327
- UPDATE_SCM = 1
328
- DEPLOY_PROBE = 2
329
- OBSERVED_DETECTED = 3
330
- PRELUDE_ENDPOINT_SYNC = 4
331
- EXPORT_SCM = 5
332
- PARTNER_GROUPS = 6
333
-
334
- @classmethod
335
- def _missing_(cls, value):
336
- return BackgroundJobTypes.INVALID
337
-
338
-
339
- class EDRResponse(Enum, metaclass=MissingItem):
340
- INVALID = -1
341
- OBSERVE = 1
342
- DETECT = 2
343
- PREVENT = 3
344
-
345
- @classmethod
346
- def _missing_(cls, value):
347
- return EDRResponse.INVALID
348
-
349
-
350
- class PartnerEvents(Enum, metaclass=MissingItem):
351
- INVALID = -1
352
- REDUCED_FUNCTIONALITY_MODE = 1
353
- NO_EDR = 2
354
- MISSING_EDR_POLICY = 3
355
- MISSING_AV_POLICY = 4
356
- MISSING_MFA = 5
357
- NO_ASSET_MANAGER = 6
358
- MISCONFIGURED_POLICY_SETTING = 7
359
- MISSING_SCAN = 8
360
- OUT_OF_DATE_SCAN = 9
361
- NO_VULN_MANAGER = 10
362
- USER_MISSING_ASSET_MANAGER = 11
363
- USER_MISSING_EDR = 12
364
- USER_MISSING_VULN_MANAGER = 13
365
-
366
- @classmethod
367
- def _missing_(cls, value):
368
- return PartnerEvents.INVALID
369
-
370
- @classmethod
371
- def control_category_mapping(cls):
372
- return {
373
- PartnerEvents.REDUCED_FUNCTIONALITY_MODE: [ControlCategory.XDR],
374
- PartnerEvents.NO_EDR: [
375
- ControlCategory.XDR,
376
- ],
377
- PartnerEvents.MISSING_EDR_POLICY: [ControlCategory.XDR],
378
- PartnerEvents.MISSING_AV_POLICY: [ControlCategory.XDR],
379
- PartnerEvents.MISSING_MFA: [ControlCategory.IDENTITY],
380
- PartnerEvents.NO_ASSET_MANAGER: [ControlCategory.ASSET_MANAGER],
381
- PartnerEvents.MISCONFIGURED_POLICY_SETTING: [
382
- ControlCategory.XDR,
383
- ControlCategory.EMAIL,
384
- ControlCategory.IDENTITY,
385
- ],
386
- PartnerEvents.MISSING_SCAN: [ControlCategory.VULN_MANAGER],
387
- PartnerEvents.OUT_OF_DATE_SCAN: [ControlCategory.VULN_MANAGER],
388
- PartnerEvents.NO_VULN_MANAGER: [ControlCategory.VULN_MANAGER],
389
- PartnerEvents.USER_MISSING_ASSET_MANAGER: [ControlCategory.IDENTITY],
390
- PartnerEvents.USER_MISSING_EDR: [ControlCategory.IDENTITY],
391
- PartnerEvents.USER_MISSING_VULN_MANAGER: [ControlCategory.IDENTITY],
392
- }
393
-
394
-
395
- class AlertTypes(Enum, metaclass=MissingItem):
396
- INVALID = -1
397
- NEW_REDUCED_FUNCTIONALITY_MODE_ENDPOINTS = 1
398
- NEW_NO_EDR_ENDPOINTS = 2
399
- NEW_MISSING_EDR_POLICY_ENDPOINTS = 3
400
- NEW_MISSING_AV_POLICY_ENDPOINTS = 4
401
- NEW_MISSING_MFA_USERS = 5
402
- NEW_NO_ASSET_MANAGER_ENDPOINTS = 6
403
- NEW_POLICY_SETTING_FAILURE = 7
404
- NEW_POLICY_SETTING_PASS = 8
405
- NEW_MISSING_SCAN_ENDPOINTS = 9
406
- NEW_NO_VULN_MANAGER_ENDPOINTS = 10
407
- NEW_OUT_OF_DATE_SCAN_ENDPOINTS = 11
408
- NEW_USER_MISSING_ASSET_MANAGER = 12
409
- NEW_USER_MISSING_EDR = 13
410
- NEW_USER_MISSING_VULN_MANAGER = 14
411
-
412
- @classmethod
413
- def _missing_(cls, value):
414
- return AlertTypes.INVALID
415
-
416
-
417
- class PolicyType(Enum, metaclass=MissingItem):
418
- INVALID = 0
419
- EDR = 1
420
- AV = 2
421
- IDENTITY_PASSWORD = 3
422
- EMAIL_ANTIPHISH = 4
423
- EMAIL_OUTBOUND = 5
424
- EMAIL_CONTENT = 6
425
- EMAIL_MALWARE = 7
426
- EMAIL_ATTACHMENT = 8
427
- EMAIL_LINKS = 9
428
- EMAIL_DKIM = 10
429
- DEVICE_COMPLIANCE = 11
430
- IDENTITY_MFA = 12
431
-
432
- @classmethod
433
- def _missing_(cls, value):
434
- return PolicyType.INVALID
435
-
436
-
437
- class Platform(Enum, metaclass=MissingItem):
438
- INVALID = 0
439
- WINDOWS = 1
440
- DARWIN = 2
441
- LINUX = 3
442
- ALL = 4
443
-
444
- @classmethod
445
- def _missing_(cls, value):
446
- return Platform.INVALID
File without changes