prelude-sdk-beta 1402__tar.gz → 1404__tar.gz

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-sdk-beta might be problematic. Click here for more details.

Files changed (34) hide show
  1. {prelude_sdk_beta-1402 → prelude_sdk_beta-1404}/PKG-INFO +1 -1
  2. {prelude_sdk_beta-1402 → prelude_sdk_beta-1404}/prelude_sdk_beta/controllers/build_controller.py +8 -2
  3. {prelude_sdk_beta-1402 → prelude_sdk_beta-1404}/prelude_sdk_beta/controllers/detect_controller.py +17 -4
  4. {prelude_sdk_beta-1402 → prelude_sdk_beta-1404}/prelude_sdk_beta/controllers/http_controller.py +20 -0
  5. {prelude_sdk_beta-1402 → prelude_sdk_beta-1404}/prelude_sdk_beta/controllers/iam_controller.py +11 -4
  6. {prelude_sdk_beta-1402 → prelude_sdk_beta-1404}/prelude_sdk_beta/controllers/jobs_controller.py +13 -2
  7. {prelude_sdk_beta-1402 → prelude_sdk_beta-1404}/prelude_sdk_beta/controllers/scm_controller.py +97 -18
  8. {prelude_sdk_beta-1402 → prelude_sdk_beta-1404}/prelude_sdk_beta/models/account.py +6 -1
  9. {prelude_sdk_beta-1402 → prelude_sdk_beta-1404}/prelude_sdk_beta.egg-info/PKG-INFO +1 -1
  10. {prelude_sdk_beta-1402 → prelude_sdk_beta-1404}/setup.cfg +1 -1
  11. {prelude_sdk_beta-1402 → prelude_sdk_beta-1404}/LICENSE +0 -0
  12. {prelude_sdk_beta-1402 → prelude_sdk_beta-1404}/README.md +0 -0
  13. {prelude_sdk_beta-1402 → prelude_sdk_beta-1404}/prelude_sdk_beta/__init__.py +0 -0
  14. {prelude_sdk_beta-1402 → prelude_sdk_beta-1404}/prelude_sdk_beta/controllers/__init__.py +0 -0
  15. {prelude_sdk_beta-1402 → prelude_sdk_beta-1404}/prelude_sdk_beta/controllers/export_controller.py +0 -0
  16. {prelude_sdk_beta-1402 → prelude_sdk_beta-1404}/prelude_sdk_beta/controllers/generate_controller.py +0 -0
  17. {prelude_sdk_beta-1402 → prelude_sdk_beta-1404}/prelude_sdk_beta/controllers/partner_controller.py +0 -0
  18. {prelude_sdk_beta-1402 → prelude_sdk_beta-1404}/prelude_sdk_beta/controllers/probe_controller.py +0 -0
  19. {prelude_sdk_beta-1402 → prelude_sdk_beta-1404}/prelude_sdk_beta/models/__init__.py +0 -0
  20. {prelude_sdk_beta-1402 → prelude_sdk_beta-1404}/prelude_sdk_beta/models/codes.py +0 -0
  21. {prelude_sdk_beta-1402 → prelude_sdk_beta-1404}/prelude_sdk_beta.egg-info/SOURCES.txt +0 -0
  22. {prelude_sdk_beta-1402 → prelude_sdk_beta-1404}/prelude_sdk_beta.egg-info/dependency_links.txt +0 -0
  23. {prelude_sdk_beta-1402 → prelude_sdk_beta-1404}/prelude_sdk_beta.egg-info/requires.txt +0 -0
  24. {prelude_sdk_beta-1402 → prelude_sdk_beta-1404}/prelude_sdk_beta.egg-info/top_level.txt +0 -0
  25. {prelude_sdk_beta-1402 → prelude_sdk_beta-1404}/pyproject.toml +0 -0
  26. {prelude_sdk_beta-1402 → prelude_sdk_beta-1404}/tests/test_build.py +0 -0
  27. {prelude_sdk_beta-1402 → prelude_sdk_beta-1404}/tests/test_detect.py +0 -0
  28. {prelude_sdk_beta-1402 → prelude_sdk_beta-1404}/tests/test_generate.py +0 -0
  29. {prelude_sdk_beta-1402 → prelude_sdk_beta-1404}/tests/test_iam.py +0 -0
  30. {prelude_sdk_beta-1402 → prelude_sdk_beta-1404}/tests/test_partner.py +0 -0
  31. {prelude_sdk_beta-1402 → prelude_sdk_beta-1404}/tests/test_probe.py +0 -0
  32. {prelude_sdk_beta-1402 → prelude_sdk_beta-1404}/tests/test_scm.py +0 -0
  33. {prelude_sdk_beta-1402 → prelude_sdk_beta-1404}/tests/test_scm_build.py +0 -0
  34. {prelude_sdk_beta-1402 → prelude_sdk_beta-1404}/tests/testutils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: prelude-sdk-beta
3
- Version: 1402
3
+ Version: 1404
4
4
  Summary: For interacting with the Prelude API
5
5
  Home-page: https://github.com/preludeorg
6
6
  Author: Prelude Research
@@ -271,7 +271,10 @@ class BuildController(HttpController):
271
271
  headers=self.account.headers,
272
272
  timeout=10,
273
273
  )
274
- return res.json()
274
+ threat_hunt = res.json()
275
+ if self.account.resolve_enums:
276
+ self.resolve_enums(threat_hunt, [(Control, "control")])
277
+ return threat_hunt
275
278
 
276
279
  @verify_credentials
277
280
  def update_threat_hunt(
@@ -296,7 +299,10 @@ class BuildController(HttpController):
296
299
  headers=self.account.headers,
297
300
  timeout=10,
298
301
  )
299
- return res.json()
302
+ threat_hunt = res.json()
303
+ if self.account.resolve_enums:
304
+ self.resolve_enums(threat_hunt, [(Control, "control")])
305
+ return threat_hunt
300
306
 
301
307
  @verify_credentials
302
308
  def delete_threat_hunt(self, threat_hunt_id: str):
@@ -1,5 +1,6 @@
1
1
  from prelude_sdk_beta.controllers.http_controller import HttpController
2
2
  from prelude_sdk_beta.models.account import verify_credentials
3
+ from prelude_sdk_beta.models.codes import Control, RunCode
3
4
 
4
5
 
5
6
  class DetectController(HttpController):
@@ -59,7 +60,10 @@ class DetectController(HttpController):
59
60
  params=params,
60
61
  timeout=10,
61
62
  )
62
- return res.json()
63
+ endpoints = res.json()
64
+ if self.account.resolve_enums:
65
+ self.resolve_enums(endpoints, [(Control, "control")])
66
+ return endpoints
63
67
 
64
68
  @verify_credentials
65
69
  def describe_activity(self, filters: dict, view: str = "protected"):
@@ -169,7 +173,10 @@ class DetectController(HttpController):
169
173
  params=filters if filters else {},
170
174
  timeout=10,
171
175
  )
172
- return res.json()
176
+ threat_hunts = res.json()
177
+ if self.account.resolve_enums:
178
+ self.resolve_enums(threat_hunts, [(Control, "control")])
179
+ return threat_hunts
173
180
 
174
181
  @verify_credentials
175
182
  def get_threat_hunt(self, threat_hunt_id):
@@ -179,7 +186,10 @@ class DetectController(HttpController):
179
186
  headers=self.account.headers,
180
187
  timeout=10,
181
188
  )
182
- return res.json()
189
+ threat_hunt = res.json()
190
+ if self.account.resolve_enums:
191
+ self.resolve_enums(threat_hunt, [(Control, "control")])
192
+ return threat_hunt
183
193
 
184
194
  @verify_credentials
185
195
  def do_threat_hunt(self, threat_hunt_id):
@@ -214,7 +224,10 @@ class DetectController(HttpController):
214
224
  json=dict(items=items),
215
225
  timeout=10,
216
226
  )
217
- return res.json()
227
+ schedule = res.json()
228
+ if self.account.resolve_enums:
229
+ self.resolve_enums(schedule, [(RunCode, "run_code")])
230
+ return schedule
218
231
 
219
232
  @verify_credentials
220
233
  def unschedule(self, items: list):
@@ -22,6 +22,26 @@ class HttpController(object):
22
22
  self._session.mount("http://", HTTPAdapter(max_retries=retry))
23
23
  self._session.mount("https://", HTTPAdapter(max_retries=retry))
24
24
 
25
+ def resolve_enums(self, data, enum_params: list[tuple]):
26
+ for [enum_class, key] in enum_params:
27
+ self._resolve_enum(data, enum_class, key)
28
+
29
+ def _resolve_enum(self, data, enum_class, key):
30
+ if isinstance(data, list):
31
+ for item in data:
32
+ if isinstance(item, dict):
33
+ self._resolve_enum(item, enum_class, key)
34
+ elif isinstance(data, dict):
35
+ for k, v in data.items():
36
+ if k == key:
37
+ if isinstance(v, list):
38
+ for i, item in enumerate(v):
39
+ v[i] = enum_class[item].name
40
+ elif v is not None:
41
+ data[k] = enum_class[v].name
42
+ elif isinstance(v, dict) or isinstance(v, list):
43
+ self._resolve_enum(v, enum_class, key)
44
+
25
45
  def get(self, url, retry=True, **kwargs):
26
46
  res = self._session.get(url, **kwargs)
27
47
  if res.status_code == 200:
@@ -1,6 +1,6 @@
1
1
  from prelude_sdk_beta.controllers.http_controller import HttpController
2
2
  from prelude_sdk_beta.models.account import verify_credentials
3
- from prelude_sdk_beta.models.codes import Mode, Permission
3
+ from prelude_sdk_beta.models.codes import Control, Mode, Permission
4
4
 
5
5
 
6
6
  class IAMAccountController(HttpController):
@@ -14,7 +14,12 @@ class IAMAccountController(HttpController):
14
14
  res = self.get(
15
15
  f"{self.account.hq}/iam/account", headers=self.account.headers, timeout=10
16
16
  )
17
- return res.json()
17
+ account = res.json()
18
+ if self.account.resolve_enums:
19
+ self.resolve_enums(
20
+ account, [(Mode, "mode"), (Permission, "permission"), (Control, "id")]
21
+ )
22
+ return account
18
23
 
19
24
  @verify_credentials
20
25
  def purge_account(self):
@@ -100,7 +105,10 @@ class IAMAccountController(HttpController):
100
105
  headers=self.account.headers,
101
106
  timeout=10,
102
107
  )
103
- return res.json()
108
+ user = res.json()
109
+ if self.account.resolve_enums:
110
+ self.resolve_enums(user, [(Permission, "permission")])
111
+ return user
104
112
 
105
113
  @verify_credentials
106
114
  def create_service_user(self, name: str):
@@ -173,7 +181,6 @@ class IAMAccountController(HttpController):
173
181
  )
174
182
  return res.json()
175
183
 
176
-
177
184
  def sign_up(self, company, email, name):
178
185
  """(NOT AVAIABLE IN PRODUCTION) Create a new user and account"""
179
186
  body = dict(company=company, email=email, name=name)
@@ -1,5 +1,8 @@
1
+ from itertools import chain
2
+
1
3
  from prelude_sdk_beta.controllers.http_controller import HttpController
2
4
  from prelude_sdk_beta.models.account import verify_credentials
5
+ from prelude_sdk_beta.models.codes import BackgroundJobTypes, Control
3
6
 
4
7
 
5
8
  class JobsController(HttpController):
@@ -13,7 +16,10 @@ class JobsController(HttpController):
13
16
  res = self.get(
14
17
  f"{self.account.hq}/jobs/statuses", headers=self.account.headers, timeout=30
15
18
  )
16
- return res.json()
19
+ jobs = res.json()
20
+ if self.account.resolve_enums:
21
+ self.resolve_enums(jobs, [(Control, "control")])
22
+ return jobs
17
23
 
18
24
  @verify_credentials
19
25
  def job_status(self, job_id: str):
@@ -23,4 +29,9 @@ class JobsController(HttpController):
23
29
  headers=self.account.headers,
24
30
  timeout=30,
25
31
  )
26
- return res.json()
32
+ job = res.json()
33
+ if self.account.resolve_enums:
34
+ self.resolve_enums(
35
+ job, [(Control, "control"), (BackgroundJobTypes, "job_type")]
36
+ )
37
+ return job
@@ -4,8 +4,9 @@ from prelude_sdk_beta.models.codes import (
4
4
  Control,
5
5
  ControlCategory,
6
6
  PartnerEvents,
7
+ PolicyType,
8
+ NotationType,
7
9
  RunCode,
8
- SCMCategory,
9
10
  )
10
11
 
11
12
 
@@ -25,7 +26,18 @@ class ScmController(HttpController):
25
26
  params=params,
26
27
  timeout=30,
27
28
  )
28
- return res.json()
29
+ data = res.json()
30
+ if self.account.resolve_enums:
31
+ self.resolve_enums(
32
+ data,
33
+ [
34
+ (Control, "controls"),
35
+ (Control, "control"),
36
+ (ControlCategory, "category"),
37
+ (PartnerEvents, "event"),
38
+ ],
39
+ )
40
+ return data
29
41
 
30
42
  @verify_credentials
31
43
  def inboxes(self, filter: str = None, orderby: str = None, top: int = None):
@@ -37,7 +49,18 @@ class ScmController(HttpController):
37
49
  params=params,
38
50
  timeout=30,
39
51
  )
40
- return res.json()
52
+ data = res.json()
53
+ if self.account.resolve_enums:
54
+ self.resolve_enums(
55
+ data,
56
+ [
57
+ (Control, "controls"),
58
+ (Control, "control"),
59
+ (ControlCategory, "category"),
60
+ (PartnerEvents, "event"),
61
+ ],
62
+ )
63
+ return data
41
64
 
42
65
  @verify_credentials
43
66
  def users(self, filter: str = None, orderby: str = None, top: int = None):
@@ -49,7 +72,18 @@ class ScmController(HttpController):
49
72
  params=params,
50
73
  timeout=30,
51
74
  )
52
- return res.json()
75
+ data = res.json()
76
+ if self.account.resolve_enums:
77
+ self.resolve_enums(
78
+ data,
79
+ [
80
+ (Control, "controls"),
81
+ (Control, "control"),
82
+ (ControlCategory, "category"),
83
+ (PartnerEvents, "event"),
84
+ ],
85
+ )
86
+ return data
53
87
 
54
88
  @verify_credentials
55
89
  def technique_summary(self, techniques: str):
@@ -84,7 +118,12 @@ class ScmController(HttpController):
84
118
  headers=self.account.headers,
85
119
  timeout=30,
86
120
  )
87
- return res.json()
121
+ data = res.json()
122
+ if self.account.resolve_enums:
123
+ self.resolve_enums(
124
+ data, [(Control, "control"), (ControlCategory, "category")]
125
+ )
126
+ return data
88
127
 
89
128
  @verify_credentials
90
129
  def evaluation(
@@ -104,7 +143,10 @@ class ScmController(HttpController):
104
143
  headers=self.account.headers,
105
144
  timeout=30,
106
145
  )
107
- return res.json()
146
+ data = res.json()
147
+ if self.account.resolve_enums:
148
+ self.resolve_enums(data, [(PolicyType, "policy_type")])
149
+ return data
108
150
 
109
151
  @verify_credentials
110
152
  def update_evaluation(self, partner: Control, instance_id: str):
@@ -126,7 +168,10 @@ class ScmController(HttpController):
126
168
  params=params,
127
169
  timeout=10,
128
170
  )
129
- return res.json()
171
+ groups = res.json()
172
+ if self.account.resolve_enums:
173
+ self.resolve_enums(groups, [(Control, "control")])
174
+ return groups
130
175
 
131
176
  @verify_credentials
132
177
  def update_partner_groups(
@@ -150,7 +195,10 @@ class ScmController(HttpController):
150
195
  headers=self.account.headers,
151
196
  timeout=10,
152
197
  )
153
- return res.json()
198
+ exceptions = res.json()
199
+ if self.account.resolve_enums:
200
+ self.resolve_enums(exceptions, [(ControlCategory, "category")])
201
+ return exceptions
154
202
 
155
203
  @verify_credentials
156
204
  def create_object_exception(
@@ -208,7 +256,12 @@ class ScmController(HttpController):
208
256
  headers=self.account.headers,
209
257
  timeout=10,
210
258
  )
211
- return res.json()
259
+ exceptions = res.json()
260
+ if self.account.resolve_enums:
261
+ self.resolve_enums(
262
+ exceptions, [(Control, "control"), (ControlCategory, "category")]
263
+ )
264
+ return exceptions
212
265
 
213
266
  @verify_credentials
214
267
  def create_policy_exception(
@@ -240,13 +293,13 @@ class ScmController(HttpController):
240
293
  setting_names=None,
241
294
  ):
242
295
  """Update policy exceptions"""
243
- body = dict(control=partner.name, instance_id=instance_id)
296
+ body = dict(control=partner.name, instance_id=instance_id, policy_id=policy_id)
244
297
  if expires != self.default:
245
298
  body["expires"] = expires
246
299
  if setting_names:
247
300
  body["setting_names"] = setting_names
248
- res = self.post(
249
- f"{self.account.hq}/scm/exceptions/policies/{policy_id}",
301
+ res = self.put(
302
+ f"{self.account.hq}/scm/exceptions/policies",
250
303
  json=body,
251
304
  headers=self.account.headers,
252
305
  timeout=10,
@@ -256,9 +309,9 @@ class ScmController(HttpController):
256
309
  @verify_credentials
257
310
  def delete_policy_exception(self, instance_id: str, policy_id: str):
258
311
  """Delete policy exceptions"""
259
- body = dict(instance_id=instance_id)
312
+ body = dict(instance_id=instance_id, policy_id=policy_id)
260
313
  res = self.delete(
261
- f"{self.account.hq}/scm/exceptions/policies/{policy_id}",
314
+ f"{self.account.hq}/scm/exceptions/policies",
262
315
  json=body,
263
316
  headers=self.account.headers,
264
317
  timeout=10,
@@ -273,7 +326,10 @@ class ScmController(HttpController):
273
326
  headers=self.account.headers,
274
327
  timeout=10,
275
328
  )
276
- return res.json()
329
+ views = res.json()
330
+ if self.account.resolve_enums:
331
+ self.resolve_enums(views, [(ControlCategory, "category")])
332
+ return views
277
333
 
278
334
  @verify_credentials
279
335
  def create_view(self, category: ControlCategory, filter: str, name: str):
@@ -412,7 +468,17 @@ class ScmController(HttpController):
412
468
  headers=self.account.headers,
413
469
  timeout=10,
414
470
  )
415
- return res.json()
471
+ notifications = res.json()
472
+ if self.account.resolve_enums:
473
+ self.resolve_enums(
474
+ notifications,
475
+ [
476
+ (ControlCategory, "control_category"),
477
+ (PartnerEvents, "event"),
478
+ (RunCode, "run_code"),
479
+ ],
480
+ )
481
+ return notifications
416
482
 
417
483
  @verify_credentials
418
484
  def delete_notification(self, notification_id: str):
@@ -472,7 +538,10 @@ class ScmController(HttpController):
472
538
  headers=self.account.headers,
473
539
  timeout=10,
474
540
  )
475
- return res.json()
541
+ notations = res.json()
542
+ if self.account.resolve_enums:
543
+ self.resolve_enums(notations, [(NotationType, "event")])
544
+ return notations
476
545
 
477
546
  @verify_credentials
478
547
  def list_history(
@@ -486,4 +555,14 @@ class ScmController(HttpController):
486
555
  params=params,
487
556
  timeout=10,
488
557
  )
489
- return res.json()
558
+ history = res.json()
559
+ if self.account.resolve_enums:
560
+ self.resolve_enums(
561
+ history,
562
+ [
563
+ (Control, "control"),
564
+ (ControlCategory, "category"),
565
+ (PartnerEvents, "event"),
566
+ ],
567
+ )
568
+ return history
@@ -83,7 +83,7 @@ def exchange_token(
83
83
  class Account:
84
84
 
85
85
  @staticmethod
86
- def from_keychain(profile: str = "default"):
86
+ def from_keychain(profile: str = "default", resolve_enums: bool = False):
87
87
  """
88
88
  Create an account object from a pre-configured profile in your keychain file
89
89
  """
@@ -100,6 +100,7 @@ class Account:
100
100
  oidc=profile_items.get("oidc"),
101
101
  profile=profile,
102
102
  slug=profile_items.get("slug"),
103
+ resolve_enums=resolve_enums,
103
104
  )
104
105
 
105
106
  @staticmethod
@@ -111,6 +112,7 @@ class Account:
111
112
  hq: str = "https://api.us1.preludesecurity.com",
112
113
  oidc: str | None = None,
113
114
  slug: str | None = None,
115
+ resolve_enums: bool = False,
114
116
  ):
115
117
  """
116
118
  Create an account object from an access token or a refresh token
@@ -131,6 +133,7 @@ class Account:
131
133
  slug=slug,
132
134
  token=token,
133
135
  token_location=None,
136
+ resolve_enums=resolve_enums,
134
137
  )
135
138
 
136
139
 
@@ -151,6 +154,7 @@ class _Account:
151
154
  token_location: str | None = os.path.join(
152
155
  Path.home(), ".prelude", "tokens.json"
153
156
  ),
157
+ resolve_enums: bool = False,
154
158
  ):
155
159
  if token is None and token_location is None:
156
160
  raise ValueError(
@@ -168,6 +172,7 @@ class _Account:
168
172
  self.slug = slug
169
173
  self.token = token
170
174
  self.token_location = token_location
175
+ self.resolve_enums = resolve_enums
171
176
  if self.token_location and not os.path.exists(self.token_location):
172
177
  head, _ = os.path.split(Path(self.token_location))
173
178
  Path(head).mkdir(parents=True, exist_ok=True)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: prelude-sdk-beta
3
- Version: 1402
3
+ Version: 1404
4
4
  Summary: For interacting with the Prelude API
5
5
  Home-page: https://github.com/preludeorg
6
6
  Author: Prelude Research
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = prelude-sdk-beta
3
- version = 1402
3
+ version = 1404
4
4
  author = Prelude Research
5
5
  author_email = support@preludesecurity.com
6
6
  description = For interacting with the Prelude API
File without changes