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.
- prelude_cli_beta/cli.py +52 -0
- prelude_cli_beta/views/auth.py +56 -0
- prelude_cli_beta/views/build.py +488 -0
- prelude_cli_beta/views/configure.py +29 -0
- prelude_cli_beta/views/detect.py +438 -0
- prelude_cli_beta/views/generate.py +125 -0
- prelude_cli_beta/views/iam.py +368 -0
- prelude_cli_beta/views/jobs.py +50 -0
- prelude_cli_beta/views/partner.py +192 -0
- prelude_cli_beta/views/scm.py +744 -0
- prelude_cli_beta/views/shared.py +37 -0
- prelude_cli_beta-1407.dist-info/METADATA +38 -0
- prelude_cli_beta-1407.dist-info/RECORD +20 -0
- prelude_cli_beta-1407.dist-info/entry_points.txt +3 -0
- prelude_cli_beta-1407.dist-info/top_level.txt +1 -0
- prelude_cli_beta-1405.dist-info/METADATA +0 -46
- prelude_cli_beta-1405.dist-info/RECORD +0 -20
- prelude_cli_beta-1405.dist-info/top_level.txt +0 -1
- prelude_sdk_beta/controllers/build_controller.py +0 -309
- prelude_sdk_beta/controllers/detect_controller.py +0 -243
- prelude_sdk_beta/controllers/export_controller.py +0 -31
- prelude_sdk_beta/controllers/generate_controller.py +0 -40
- prelude_sdk_beta/controllers/http_controller.py +0 -63
- prelude_sdk_beta/controllers/iam_controller.py +0 -278
- prelude_sdk_beta/controllers/jobs_controller.py +0 -26
- prelude_sdk_beta/controllers/partner_controller.py +0 -166
- prelude_sdk_beta/controllers/probe_controller.py +0 -14
- prelude_sdk_beta/controllers/scm_controller.py +0 -424
- prelude_sdk_beta/models/account.py +0 -264
- prelude_sdk_beta/models/codes.py +0 -446
- {prelude_sdk_beta → prelude_cli_beta}/__init__.py +0 -0
- {prelude_sdk_beta/controllers → prelude_cli_beta/templates}/__init__.py +0 -0
- {prelude_sdk_beta/models → prelude_cli_beta/views}/__init__.py +0 -0
- {prelude_cli_beta-1405.dist-info → prelude_cli_beta-1407.dist-info}/WHEEL +0 -0
- {prelude_cli_beta-1405.dist-info → prelude_cli_beta-1407.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
from datetime import datetime, timezone
|
|
2
|
-
|
|
3
|
-
from prelude_sdk.controllers.http_controller import HttpController
|
|
4
|
-
from prelude_sdk.models.account import verify_credentials
|
|
5
|
-
from prelude_sdk.models.codes import Control
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class PartnerController(HttpController):
|
|
9
|
-
|
|
10
|
-
def __init__(self, account):
|
|
11
|
-
super().__init__(account)
|
|
12
|
-
|
|
13
|
-
@verify_credentials
|
|
14
|
-
def attach(
|
|
15
|
-
self,
|
|
16
|
-
partner: Control,
|
|
17
|
-
api: str,
|
|
18
|
-
user: str,
|
|
19
|
-
secret: str,
|
|
20
|
-
name: str | None = None,
|
|
21
|
-
instance_id: str | None = None,
|
|
22
|
-
):
|
|
23
|
-
"""Attach a partner to your account"""
|
|
24
|
-
params = dict()
|
|
25
|
-
if name:
|
|
26
|
-
params["name"] = name
|
|
27
|
-
if api:
|
|
28
|
-
params["api"] = api
|
|
29
|
-
if user:
|
|
30
|
-
params["user"] = user
|
|
31
|
-
if secret:
|
|
32
|
-
params["secret"] = secret
|
|
33
|
-
extra = f"/{instance_id}" if instance_id else ""
|
|
34
|
-
res = self.post(
|
|
35
|
-
f"{self.account.hq}/partner/{partner.name}{extra}",
|
|
36
|
-
headers=self.account.headers,
|
|
37
|
-
json=params,
|
|
38
|
-
timeout=10,
|
|
39
|
-
)
|
|
40
|
-
return res.json()
|
|
41
|
-
|
|
42
|
-
@verify_credentials
|
|
43
|
-
def detach(self, partner: Control, instance_id: str):
|
|
44
|
-
"""Detach a partner from your Detect account"""
|
|
45
|
-
res = self.delete(
|
|
46
|
-
f"{self.account.hq}/partner/{partner.name}/{instance_id}",
|
|
47
|
-
headers=self.account.headers,
|
|
48
|
-
timeout=10,
|
|
49
|
-
)
|
|
50
|
-
return res.json()
|
|
51
|
-
|
|
52
|
-
@verify_credentials
|
|
53
|
-
def block(self, partner: Control, test_id: str):
|
|
54
|
-
"""Report to a partner to block a test"""
|
|
55
|
-
params = dict(test_id=test_id)
|
|
56
|
-
res = self.post(
|
|
57
|
-
f"{self.account.hq}/partner/block/{partner.name}",
|
|
58
|
-
headers=self.account.headers,
|
|
59
|
-
json=params,
|
|
60
|
-
timeout=30,
|
|
61
|
-
)
|
|
62
|
-
return res.json()
|
|
63
|
-
|
|
64
|
-
@verify_credentials
|
|
65
|
-
def endpoints(
|
|
66
|
-
self,
|
|
67
|
-
partner: Control,
|
|
68
|
-
platform: str,
|
|
69
|
-
hostname: str = "",
|
|
70
|
-
offset: int = 0,
|
|
71
|
-
count: int = 100,
|
|
72
|
-
):
|
|
73
|
-
"""Get a list of endpoints from a partner"""
|
|
74
|
-
params = dict(platform=platform, hostname=hostname, offset=offset, count=count)
|
|
75
|
-
res = self.get(
|
|
76
|
-
f"{self.account.hq}/partner/endpoints/{partner.name}",
|
|
77
|
-
headers=self.account.headers,
|
|
78
|
-
params=params,
|
|
79
|
-
timeout=30,
|
|
80
|
-
)
|
|
81
|
-
return res.json()
|
|
82
|
-
|
|
83
|
-
@verify_credentials
|
|
84
|
-
def deploy(self, partner: Control, host_ids: list):
|
|
85
|
-
"""Deploy probes on all specified partner endpoints"""
|
|
86
|
-
params = dict(host_ids=host_ids)
|
|
87
|
-
res = self.post(
|
|
88
|
-
f"{self.account.hq}/partner/deploy/{partner.name}",
|
|
89
|
-
headers=self.account.headers,
|
|
90
|
-
json=params,
|
|
91
|
-
timeout=30,
|
|
92
|
-
)
|
|
93
|
-
return res.json()
|
|
94
|
-
|
|
95
|
-
@verify_credentials
|
|
96
|
-
def list_reports(self, partner: Control, test_id: str | None):
|
|
97
|
-
"""Get reports to a partner for a test"""
|
|
98
|
-
params = dict(test_id=test_id) if test_id else dict()
|
|
99
|
-
res = self.get(
|
|
100
|
-
f"{self.account.hq}/partner/reports/{partner.name}",
|
|
101
|
-
headers=self.account.headers,
|
|
102
|
-
json=params,
|
|
103
|
-
timeout=30,
|
|
104
|
-
)
|
|
105
|
-
return res.json()
|
|
106
|
-
|
|
107
|
-
@verify_credentials
|
|
108
|
-
def ioa_stats(self, test_id: str | None = None):
|
|
109
|
-
"""Get IOA stats"""
|
|
110
|
-
params = dict(test_id=test_id) if test_id else dict()
|
|
111
|
-
res = self.get(
|
|
112
|
-
f"{self.account.hq}/partner/ioa_stats",
|
|
113
|
-
headers=self.account.headers,
|
|
114
|
-
json=params,
|
|
115
|
-
timeout=30,
|
|
116
|
-
)
|
|
117
|
-
return res.json()
|
|
118
|
-
|
|
119
|
-
@verify_credentials
|
|
120
|
-
def observed_detected(self, test_id: str | None = None, hours: int | None = None):
|
|
121
|
-
"""Get observed_detected stats"""
|
|
122
|
-
params = dict()
|
|
123
|
-
if test_id:
|
|
124
|
-
params["test_id"] = test_id
|
|
125
|
-
if hours:
|
|
126
|
-
params["start_epoch_ms"] = (
|
|
127
|
-
datetime.now(timezone.utc).timestamp() - hours * 60 * 60
|
|
128
|
-
) * 1000
|
|
129
|
-
|
|
130
|
-
res = self.get(
|
|
131
|
-
f"{self.account.hq}/partner/observed_detected",
|
|
132
|
-
headers=self.account.headers,
|
|
133
|
-
json=params,
|
|
134
|
-
timeout=30,
|
|
135
|
-
)
|
|
136
|
-
return res.json()
|
|
137
|
-
|
|
138
|
-
@verify_credentials
|
|
139
|
-
def list_advisories(
|
|
140
|
-
self, partner: Control, start: str = None, limit: int = None, offset: int = None
|
|
141
|
-
):
|
|
142
|
-
"""Get advisory reports provided by a partner"""
|
|
143
|
-
params = dict()
|
|
144
|
-
if start:
|
|
145
|
-
params["start"] = start
|
|
146
|
-
if limit:
|
|
147
|
-
params["limit"] = limit
|
|
148
|
-
if offset:
|
|
149
|
-
params["offset"] = offset
|
|
150
|
-
res = self.get(
|
|
151
|
-
f"{self.account.hq}/partner/advisories/{partner.name}",
|
|
152
|
-
headers=self.account.headers,
|
|
153
|
-
params=params,
|
|
154
|
-
timeout=30,
|
|
155
|
-
)
|
|
156
|
-
return res.json()
|
|
157
|
-
|
|
158
|
-
@verify_credentials
|
|
159
|
-
def partner_groups(self, partner: Control, instance_id: str):
|
|
160
|
-
"""Get a list of partner groups"""
|
|
161
|
-
res = self.get(
|
|
162
|
-
f"{self.account.hq}/partner/groups/{partner.name}/{instance_id}",
|
|
163
|
-
headers=self.account.headers,
|
|
164
|
-
timeout=30,
|
|
165
|
-
)
|
|
166
|
-
return res.json()
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
from prelude_sdk.controllers.http_controller import HttpController
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
class ProbeController(HttpController):
|
|
5
|
-
|
|
6
|
-
def __init__(self, account):
|
|
7
|
-
super().__init__(account)
|
|
8
|
-
|
|
9
|
-
def download(self, name: str, dos: str):
|
|
10
|
-
"""Download a probe executable"""
|
|
11
|
-
res = self.get(
|
|
12
|
-
f"{self.account.hq}/download/{name}", headers=dict(dos=dos), timeout=10
|
|
13
|
-
)
|
|
14
|
-
return res.text
|
|
@@ -1,424 +0,0 @@
|
|
|
1
|
-
from prelude_sdk.controllers.http_controller import HttpController
|
|
2
|
-
from prelude_sdk.models.account import verify_credentials
|
|
3
|
-
from prelude_sdk.models.codes import Control, ControlCategory, PartnerEvents, RunCode
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class ScmController(HttpController):
|
|
7
|
-
default = -1
|
|
8
|
-
|
|
9
|
-
def __init__(self, account):
|
|
10
|
-
super().__init__(account)
|
|
11
|
-
|
|
12
|
-
@verify_credentials
|
|
13
|
-
def endpoints(self, filter: str = None, orderby: str = None, top: int = None):
|
|
14
|
-
"""List endpoints with SCM analysis"""
|
|
15
|
-
params = {"$filter": filter, "$orderby": orderby, "$top": top}
|
|
16
|
-
res = self.get(
|
|
17
|
-
f"{self.account.hq}/scm/endpoints",
|
|
18
|
-
headers=self.account.headers,
|
|
19
|
-
params=params,
|
|
20
|
-
timeout=30,
|
|
21
|
-
)
|
|
22
|
-
return res.json()
|
|
23
|
-
|
|
24
|
-
@verify_credentials
|
|
25
|
-
def inboxes(self, filter: str = None, orderby: str = None, top: int = None):
|
|
26
|
-
"""List inboxes with SCM analysis"""
|
|
27
|
-
params = {"$filter": filter, "$orderby": orderby, "$top": top}
|
|
28
|
-
res = self.get(
|
|
29
|
-
f"{self.account.hq}/scm/inboxes",
|
|
30
|
-
headers=self.account.headers,
|
|
31
|
-
params=params,
|
|
32
|
-
timeout=30,
|
|
33
|
-
)
|
|
34
|
-
return res.json()
|
|
35
|
-
|
|
36
|
-
@verify_credentials
|
|
37
|
-
def users(self, filter: str = None, orderby: str = None, top: int = None):
|
|
38
|
-
"""List users with SCM analysis"""
|
|
39
|
-
params = {"$filter": filter, "$orderby": orderby, "$top": top}
|
|
40
|
-
res = self.get(
|
|
41
|
-
f"{self.account.hq}/scm/users",
|
|
42
|
-
headers=self.account.headers,
|
|
43
|
-
params=params,
|
|
44
|
-
timeout=30,
|
|
45
|
-
)
|
|
46
|
-
return res.json()
|
|
47
|
-
|
|
48
|
-
@verify_credentials
|
|
49
|
-
def technique_summary(self, techniques: str):
|
|
50
|
-
"""Get policy evaluation summary by technique"""
|
|
51
|
-
res = self.get(
|
|
52
|
-
f"{self.account.hq}/scm/technique_summary",
|
|
53
|
-
params=dict(techniques=techniques),
|
|
54
|
-
headers=self.account.headers,
|
|
55
|
-
timeout=30,
|
|
56
|
-
)
|
|
57
|
-
return res.json()
|
|
58
|
-
|
|
59
|
-
@verify_credentials
|
|
60
|
-
def evaluation_summary(
|
|
61
|
-
self,
|
|
62
|
-
endpoint_filter: str = None,
|
|
63
|
-
inbox_filter: str = None,
|
|
64
|
-
user_filter: str = None,
|
|
65
|
-
techniques: str = None,
|
|
66
|
-
):
|
|
67
|
-
"""Get policy evaluation summary"""
|
|
68
|
-
params = dict(
|
|
69
|
-
endpoints_filter=endpoint_filter,
|
|
70
|
-
inboxes_filter=inbox_filter,
|
|
71
|
-
users_filter=user_filter,
|
|
72
|
-
)
|
|
73
|
-
if techniques:
|
|
74
|
-
params["techniques"] = techniques
|
|
75
|
-
res = self.get(
|
|
76
|
-
f"{self.account.hq}/scm/evaluation_summary",
|
|
77
|
-
params=params,
|
|
78
|
-
headers=self.account.headers,
|
|
79
|
-
timeout=30,
|
|
80
|
-
)
|
|
81
|
-
return res.json()
|
|
82
|
-
|
|
83
|
-
@verify_credentials
|
|
84
|
-
def evaluation(
|
|
85
|
-
self,
|
|
86
|
-
partner: Control,
|
|
87
|
-
instance_id: str,
|
|
88
|
-
filter: str = None,
|
|
89
|
-
techniques: str = None,
|
|
90
|
-
):
|
|
91
|
-
"""Get policy evaluations for given partner"""
|
|
92
|
-
params = {"$filter": filter}
|
|
93
|
-
if techniques:
|
|
94
|
-
params["techniques"] = techniques
|
|
95
|
-
res = self.get(
|
|
96
|
-
f"{self.account.hq}/scm/evaluations/{partner.name}/{instance_id}",
|
|
97
|
-
params=params,
|
|
98
|
-
headers=self.account.headers,
|
|
99
|
-
timeout=30,
|
|
100
|
-
)
|
|
101
|
-
return res.json()
|
|
102
|
-
|
|
103
|
-
@verify_credentials
|
|
104
|
-
def update_evaluation(self, partner: Control, instance_id: str):
|
|
105
|
-
"""Update policy evaluations for given partner"""
|
|
106
|
-
res = self.post(
|
|
107
|
-
f"{self.account.hq}/scm/evaluations/{partner.name}/{instance_id}",
|
|
108
|
-
headers=self.account.headers,
|
|
109
|
-
timeout=60,
|
|
110
|
-
)
|
|
111
|
-
return res.json()
|
|
112
|
-
|
|
113
|
-
@verify_credentials
|
|
114
|
-
def list_partner_groups(self, filter: str = None, orderby: str = None):
|
|
115
|
-
"""List groups"""
|
|
116
|
-
params = {"$filter": filter, "$orderby": orderby}
|
|
117
|
-
res = self.get(
|
|
118
|
-
f"{self.account.hq}/scm/groups",
|
|
119
|
-
headers=self.account.headers,
|
|
120
|
-
params=params,
|
|
121
|
-
timeout=10,
|
|
122
|
-
)
|
|
123
|
-
return res.json()
|
|
124
|
-
|
|
125
|
-
@verify_credentials
|
|
126
|
-
def update_partner_groups(
|
|
127
|
-
self, partner: Control, instance_id: str, group_ids: list[str]
|
|
128
|
-
):
|
|
129
|
-
"""Update groups"""
|
|
130
|
-
body = dict(group_ids=group_ids)
|
|
131
|
-
res = self.post(
|
|
132
|
-
f"{self.account.hq}/scm/groups/{partner.name}/{instance_id}",
|
|
133
|
-
headers=self.account.headers,
|
|
134
|
-
json=body,
|
|
135
|
-
timeout=10,
|
|
136
|
-
)
|
|
137
|
-
return res.json()
|
|
138
|
-
|
|
139
|
-
@verify_credentials
|
|
140
|
-
def list_object_exceptions(self):
|
|
141
|
-
"""List object exceptions"""
|
|
142
|
-
res = self.get(
|
|
143
|
-
f"{self.account.hq}/scm/exceptions/objects",
|
|
144
|
-
headers=self.account.headers,
|
|
145
|
-
timeout=10,
|
|
146
|
-
)
|
|
147
|
-
return res.json()
|
|
148
|
-
|
|
149
|
-
@verify_credentials
|
|
150
|
-
def create_object_exception(
|
|
151
|
-
self, category: ControlCategory, filter, name=None, expires: str = None
|
|
152
|
-
):
|
|
153
|
-
"""Create an object exception"""
|
|
154
|
-
body = dict(category=category.name, filter=filter)
|
|
155
|
-
if name:
|
|
156
|
-
body["name"] = name
|
|
157
|
-
if expires:
|
|
158
|
-
body["expires"] = expires
|
|
159
|
-
res = self.post(
|
|
160
|
-
f"{self.account.hq}/scm/exceptions/objects",
|
|
161
|
-
json=body,
|
|
162
|
-
headers=self.account.headers,
|
|
163
|
-
timeout=10,
|
|
164
|
-
)
|
|
165
|
-
return res.json()
|
|
166
|
-
|
|
167
|
-
@verify_credentials
|
|
168
|
-
def update_object_exception(
|
|
169
|
-
self, exception_id, expires=default, filter=None, name=None
|
|
170
|
-
):
|
|
171
|
-
"""Update an object exception"""
|
|
172
|
-
body = dict()
|
|
173
|
-
if expires != self.default:
|
|
174
|
-
body["expires"] = expires
|
|
175
|
-
if filter:
|
|
176
|
-
body["filter"] = filter
|
|
177
|
-
if name:
|
|
178
|
-
body["name"] = name
|
|
179
|
-
res = self.post(
|
|
180
|
-
f"{self.account.hq}/scm/exceptions/objects/{exception_id}",
|
|
181
|
-
json=body,
|
|
182
|
-
headers=self.account.headers,
|
|
183
|
-
timeout=10,
|
|
184
|
-
)
|
|
185
|
-
return res.json()
|
|
186
|
-
|
|
187
|
-
@verify_credentials
|
|
188
|
-
def delete_object_exception(self, exception_id):
|
|
189
|
-
"""Delete an object exception"""
|
|
190
|
-
res = self.delete(
|
|
191
|
-
f"{self.account.hq}/scm/exceptions/objects/{exception_id}",
|
|
192
|
-
headers=self.account.headers,
|
|
193
|
-
timeout=10,
|
|
194
|
-
)
|
|
195
|
-
return res.json()
|
|
196
|
-
|
|
197
|
-
@verify_credentials
|
|
198
|
-
def list_policy_exceptions(self):
|
|
199
|
-
"""List policy exceptions"""
|
|
200
|
-
res = self.get(
|
|
201
|
-
f"{self.account.hq}/scm/exceptions/policies",
|
|
202
|
-
headers=self.account.headers,
|
|
203
|
-
timeout=10,
|
|
204
|
-
)
|
|
205
|
-
return res.json()
|
|
206
|
-
|
|
207
|
-
@verify_credentials
|
|
208
|
-
def put_policy_exceptions(
|
|
209
|
-
self, partner: Control, expires, instance_id: str, policy_id, setting_names
|
|
210
|
-
):
|
|
211
|
-
"""Put policy exceptions"""
|
|
212
|
-
body = dict(
|
|
213
|
-
control=partner.name,
|
|
214
|
-
expires=expires,
|
|
215
|
-
instance_id=instance_id,
|
|
216
|
-
policy_id=policy_id,
|
|
217
|
-
setting_names=setting_names,
|
|
218
|
-
)
|
|
219
|
-
res = self.put(
|
|
220
|
-
f"{self.account.hq}/scm/exceptions/policies",
|
|
221
|
-
json=body,
|
|
222
|
-
headers=self.account.headers,
|
|
223
|
-
timeout=10,
|
|
224
|
-
)
|
|
225
|
-
return res.json()
|
|
226
|
-
|
|
227
|
-
@verify_credentials
|
|
228
|
-
def list_views(self):
|
|
229
|
-
"""List views"""
|
|
230
|
-
res = self.get(
|
|
231
|
-
f"{self.account.hq}/scm/views",
|
|
232
|
-
headers=self.account.headers,
|
|
233
|
-
timeout=10,
|
|
234
|
-
)
|
|
235
|
-
return res.json()
|
|
236
|
-
|
|
237
|
-
@verify_credentials
|
|
238
|
-
def create_view(self, category: ControlCategory, filter: str, name: str):
|
|
239
|
-
"""Create a view"""
|
|
240
|
-
body = dict(category=category.name, filter=filter, name=name)
|
|
241
|
-
res = self.post(
|
|
242
|
-
f"{self.account.hq}/scm/views",
|
|
243
|
-
json=body,
|
|
244
|
-
headers=self.account.headers,
|
|
245
|
-
timeout=10,
|
|
246
|
-
)
|
|
247
|
-
return res.json()
|
|
248
|
-
|
|
249
|
-
@verify_credentials
|
|
250
|
-
def update_view(
|
|
251
|
-
self, view_id, category: ControlCategory = None, filter=None, name=None
|
|
252
|
-
):
|
|
253
|
-
"""Update a view"""
|
|
254
|
-
body = dict()
|
|
255
|
-
if category:
|
|
256
|
-
body["category"] = category.name
|
|
257
|
-
if filter:
|
|
258
|
-
body["filter"] = filter
|
|
259
|
-
if name:
|
|
260
|
-
body["name"] = name
|
|
261
|
-
res = self.post(
|
|
262
|
-
f"{self.account.hq}/scm/views/{view_id}",
|
|
263
|
-
json=body,
|
|
264
|
-
headers=self.account.headers,
|
|
265
|
-
timeout=10,
|
|
266
|
-
)
|
|
267
|
-
return res.json()
|
|
268
|
-
|
|
269
|
-
@verify_credentials
|
|
270
|
-
def delete_view(self, view_id):
|
|
271
|
-
"""Delete a view"""
|
|
272
|
-
res = self.delete(
|
|
273
|
-
f"{self.account.hq}/scm/views/{view_id}",
|
|
274
|
-
headers=self.account.headers,
|
|
275
|
-
timeout=10,
|
|
276
|
-
)
|
|
277
|
-
return res.json()
|
|
278
|
-
|
|
279
|
-
@verify_credentials
|
|
280
|
-
def create_threat(
|
|
281
|
-
self,
|
|
282
|
-
name,
|
|
283
|
-
description=None,
|
|
284
|
-
id=None,
|
|
285
|
-
generated=None,
|
|
286
|
-
published=None,
|
|
287
|
-
source=None,
|
|
288
|
-
source_id=None,
|
|
289
|
-
techniques=None,
|
|
290
|
-
):
|
|
291
|
-
"""Create an scm threat"""
|
|
292
|
-
body = dict(name=name)
|
|
293
|
-
if description:
|
|
294
|
-
body["description"] = description
|
|
295
|
-
if id:
|
|
296
|
-
body["id"] = id
|
|
297
|
-
if generated:
|
|
298
|
-
body["generated"] = generated
|
|
299
|
-
if published:
|
|
300
|
-
body["published"] = published
|
|
301
|
-
if source:
|
|
302
|
-
body["source"] = source
|
|
303
|
-
if source_id:
|
|
304
|
-
body["source_id"] = source_id
|
|
305
|
-
if techniques:
|
|
306
|
-
body["techniques"] = techniques
|
|
307
|
-
|
|
308
|
-
res = self.post(
|
|
309
|
-
f"{self.account.hq}/scm/threats",
|
|
310
|
-
json=body,
|
|
311
|
-
headers=self.account.headers,
|
|
312
|
-
timeout=10,
|
|
313
|
-
)
|
|
314
|
-
return res.json()
|
|
315
|
-
|
|
316
|
-
@verify_credentials
|
|
317
|
-
def delete_threat(self, id):
|
|
318
|
-
"""Delete an existing scm threat"""
|
|
319
|
-
res = self.delete(
|
|
320
|
-
f"{self.account.hq}/scm/threats/{id}",
|
|
321
|
-
headers=self.account.headers,
|
|
322
|
-
timeout=10,
|
|
323
|
-
)
|
|
324
|
-
return res.json()
|
|
325
|
-
|
|
326
|
-
@verify_credentials
|
|
327
|
-
def get_threat(self, id):
|
|
328
|
-
"""Get specific scm threat"""
|
|
329
|
-
res = self.get(
|
|
330
|
-
f"{self.account.hq}/scm/threats/{id}",
|
|
331
|
-
headers=self.account.headers,
|
|
332
|
-
timeout=10,
|
|
333
|
-
)
|
|
334
|
-
return res.json()
|
|
335
|
-
|
|
336
|
-
@verify_credentials
|
|
337
|
-
def list_threats(self):
|
|
338
|
-
"""List all scm threats"""
|
|
339
|
-
res = self.get(
|
|
340
|
-
f"{self.account.hq}/scm/threats", headers=self.account.headers, timeout=10
|
|
341
|
-
)
|
|
342
|
-
return res.json()
|
|
343
|
-
|
|
344
|
-
@verify_credentials
|
|
345
|
-
def parse_threat_intel(self, file: str):
|
|
346
|
-
with open(file, "rb") as f:
|
|
347
|
-
body = f.read()
|
|
348
|
-
res = self.post(
|
|
349
|
-
f"{self.account.hq}/scm/threat-intel",
|
|
350
|
-
data=body,
|
|
351
|
-
headers=self.account.headers | {"Content-Type": "application/pdf"},
|
|
352
|
-
timeout=30,
|
|
353
|
-
)
|
|
354
|
-
return res.json()
|
|
355
|
-
|
|
356
|
-
@verify_credentials
|
|
357
|
-
def parse_from_partner_advisory(self, partner: Control, advisory_id: str):
|
|
358
|
-
params = dict(advisory_id=advisory_id)
|
|
359
|
-
res = self.post(
|
|
360
|
-
f"{self.account.hq}/scm/partner-advisories/{partner.name}",
|
|
361
|
-
headers=self.account.headers,
|
|
362
|
-
json=params,
|
|
363
|
-
timeout=30,
|
|
364
|
-
)
|
|
365
|
-
return res.json()
|
|
366
|
-
|
|
367
|
-
@verify_credentials
|
|
368
|
-
def list_notifications(self):
|
|
369
|
-
res = self.get(
|
|
370
|
-
f"{self.account.hq}/scm/notifications",
|
|
371
|
-
headers=self.account.headers,
|
|
372
|
-
timeout=10,
|
|
373
|
-
)
|
|
374
|
-
return res.json()
|
|
375
|
-
|
|
376
|
-
@verify_credentials
|
|
377
|
-
def delete_notification(self, notification_id: str):
|
|
378
|
-
res = self.delete(
|
|
379
|
-
f"{self.account.hq}/scm/notifications/{notification_id}",
|
|
380
|
-
headers=self.account.headers,
|
|
381
|
-
timeout=10,
|
|
382
|
-
)
|
|
383
|
-
return res.json()
|
|
384
|
-
|
|
385
|
-
@verify_credentials
|
|
386
|
-
def upsert_notification(
|
|
387
|
-
self,
|
|
388
|
-
control_category: ControlCategory,
|
|
389
|
-
event: PartnerEvents,
|
|
390
|
-
run_code: RunCode,
|
|
391
|
-
scheduled_hour: int,
|
|
392
|
-
emails: list[str] = None,
|
|
393
|
-
filter: str = None,
|
|
394
|
-
id: str = None,
|
|
395
|
-
message: str = "",
|
|
396
|
-
slack_urls: list[str] = None,
|
|
397
|
-
suppress_empty: bool = True,
|
|
398
|
-
teams_urls: list[str] = None,
|
|
399
|
-
title: str = "SCM Notification",
|
|
400
|
-
):
|
|
401
|
-
body = dict(
|
|
402
|
-
control_category=control_category.name,
|
|
403
|
-
event=event.name,
|
|
404
|
-
run_code=run_code.name,
|
|
405
|
-
scheduled_hour=scheduled_hour,
|
|
406
|
-
suppress_empty=suppress_empty,
|
|
407
|
-
)
|
|
408
|
-
if id:
|
|
409
|
-
body["id"] = id
|
|
410
|
-
if filter:
|
|
411
|
-
body["filter"] = filter
|
|
412
|
-
if emails:
|
|
413
|
-
body["email"] = dict(emails=emails, message=message, subject=title)
|
|
414
|
-
if slack_urls:
|
|
415
|
-
body["slack"] = dict(hook_urls=slack_urls, message=message)
|
|
416
|
-
if teams_urls:
|
|
417
|
-
body["teams"] = dict(hook_urls=teams_urls, message=message)
|
|
418
|
-
res = self.put(
|
|
419
|
-
f"{self.account.hq}/scm/notifications",
|
|
420
|
-
json=body,
|
|
421
|
-
headers=self.account.headers,
|
|
422
|
-
timeout=10,
|
|
423
|
-
)
|
|
424
|
-
return res.json()
|