pycti 6.6.0__py3-none-any.whl → 6.6.2__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 pycti might be problematic. Click here for more details.

@@ -408,6 +408,12 @@ class Indicator:
408
408
  stix_object["x_opencti_workflow_id"] = (
409
409
  self.opencti.get_attribute_in_extension("workflow_id", stix_object)
410
410
  )
411
+ if "x_mitre_platforms" not in stix_object:
412
+ stix_object["x_mitre_platforms"] = (
413
+ self.opencti.get_attribute_in_mitre_extension(
414
+ "platforms", stix_object
415
+ )
416
+ )
411
417
 
412
418
  return self.create(
413
419
  stix_id=stix_object["id"],
@@ -0,0 +1,408 @@
1
+ from typing import Dict, List, Optional
2
+
3
+
4
+ class Role:
5
+ """Representation of a role in OpenCTI
6
+
7
+ Roles can have capabilities. Groups have roles, and the combined
8
+ capabilities of those roles determine what a group of users can do on the
9
+ platform.
10
+
11
+ Check the properties attribute of the class to understand what default
12
+ properties are fetched.
13
+ """
14
+
15
+ def __init__(self, opencti):
16
+ self.opencti = opencti
17
+ self.properties = """
18
+ id
19
+ standard_id
20
+ entity_type
21
+ parent_types
22
+ name
23
+ description
24
+ created_at
25
+ updated_at
26
+ capabilities {
27
+ id
28
+ name
29
+ description
30
+ }
31
+ can_manage_sensitive_config
32
+ """
33
+
34
+ def list(self, **kwargs) -> List[Dict]:
35
+ """Search or list the roles on the server.
36
+
37
+ :param search:
38
+ Defaults to None.
39
+ :type search: str, optional
40
+ :param first: Defaults to 500 Return the first x results from ID or
41
+ beginning if $after is not specified.
42
+ :type first: int, optional
43
+ :param after: Return all results after the given ID, useful for
44
+ pagination. Ignored if returning all results, defaults to None.
45
+ :type after: str, optional
46
+ :param orderBy: Field to order by. Must be one of "name",
47
+ "created_at", "updated_at", or "_score". Defaults
48
+ to "name", defaults to "name".
49
+ :type orderBy: str, optional
50
+ :param orderMode: Direction to order in, either "asc" or "desc",
51
+ defaults to "asc".
52
+ :type orderMode: str, optional
53
+ :param customAttributes: Defaults to None. Custom attributes to return
54
+ from query. If None, defaults are used.
55
+ :type customAttributes: str, optional
56
+ :param getAll: Defaults to False. Retrieve all results. If true then
57
+ the "first" param is ignored.
58
+ :type getAll: bool, optional
59
+ :param withPagination: Defaults to False Whether to include pagination
60
+ pageInfo properties in result.
61
+ :type withPagination: bool, optional
62
+
63
+ :return: List of Python dictionaries with the properties of the role.
64
+ :rtype: List[Dict]
65
+ """
66
+ search = kwargs.get("search", None)
67
+ first = kwargs.get("first", 500)
68
+ after = kwargs.get("after", None)
69
+ order_by = kwargs.get("orderBy", None)
70
+ order_mode = kwargs.get("orderMode", None)
71
+ custom_attributes = kwargs.get("customAttributes", None)
72
+ get_all = kwargs.get("getAll", False)
73
+ with_pagination = kwargs.get("withPagination", False)
74
+
75
+ self.opencti.admin_logger.info(
76
+ "Searching roles matching search term", {"search": search}
77
+ )
78
+
79
+ if get_all:
80
+ first = 100
81
+
82
+ query = (
83
+ """
84
+ query RoleList($first: Int, $after: ID, $orderBy: RolesOrdering, $orderMode: OrderingMode, $search: String) {
85
+ roles(first: $first, after: $after, orderBy: $orderBy, orderMode: $orderMode, search: $search) {
86
+ edges {
87
+ node {
88
+ """
89
+ + (self.properties if custom_attributes is None else custom_attributes)
90
+ + """
91
+ }
92
+ }
93
+ pageInfo {
94
+ startCursor
95
+ endCursor
96
+ hasNextPage
97
+ hasPreviousPage
98
+ globalCount
99
+ }
100
+ }
101
+ }
102
+ """
103
+ )
104
+ result = self.opencti.query(
105
+ query,
106
+ {
107
+ "first": first,
108
+ "after": after,
109
+ "orderBy": order_by,
110
+ "orderMode": order_mode,
111
+ "search": search,
112
+ },
113
+ )
114
+ if get_all:
115
+ final_data = []
116
+ data = self.opencti.process_multiple(result["data"]["roles"])
117
+ final_data = final_data + data
118
+ while result["data"]["roles"]["pageInfo"]["hasNextPage"]:
119
+ after = result["data"]["roles"]["pageInfo"]["endCursor"]
120
+ result = self.opencti.query(
121
+ query,
122
+ {
123
+ "first": first,
124
+ "after": after,
125
+ "orderBy": order_by,
126
+ "orderMode": order_mode,
127
+ "search": search,
128
+ },
129
+ )
130
+ data = self.opencti.process_multiple(result["data"]["roles"])
131
+ final_data = final_data + data
132
+ return final_data
133
+ else:
134
+ return self.opencti.process_multiple(
135
+ result["data"]["roles"], with_pagination
136
+ )
137
+
138
+ def read(self, **kwargs) -> Optional[Dict]:
139
+ """Get a role given its ID or a search term
140
+
141
+ One of id or search must be provided.
142
+
143
+ :param id: ID of the role on the platform
144
+ :type id: str, optional
145
+ :param search: Search term for a role, e.g. its name
146
+ :type search: str, optional
147
+ :param customAttributes: Custom attributes on the role to return
148
+ :type customAttributes: str, optional
149
+
150
+ :return: Representation of the role
151
+ :rtype: Optional[Dict]
152
+ """
153
+ id = kwargs.get("id", None)
154
+ search = kwargs.get("search", None)
155
+ custom_attributes = kwargs.get("customAttributes", None)
156
+
157
+ if id is not None:
158
+ self.opencti.admin_logger.info("Reading role", {"id": id})
159
+ query = (
160
+ """
161
+ query RoleRead($id: String!) {
162
+ role(id: $id) {
163
+ """
164
+ + (self.properties if custom_attributes is None else custom_attributes)
165
+ + """
166
+ }
167
+ }
168
+ """
169
+ )
170
+ result = self.opencti.query(query, {"id": id})
171
+ return self.opencti.process_multiple_fields(result["data"]["role"])
172
+ elif search is not None:
173
+ result = self.list(search=search)
174
+ return result[0] if len(result) > 0 else None
175
+ else:
176
+ self.opencti.admin_logger.error(
177
+ "[opencti_role] Missing parameters: id or search"
178
+ )
179
+ return None
180
+
181
+ def delete(self, **kwargs):
182
+ """Delete a role given its ID
183
+
184
+ :param id: ID for the role on the platform.
185
+ :type id: str
186
+ """
187
+ id = kwargs.get("id", None)
188
+
189
+ if id is None:
190
+ self.opencti.admin_logger.error("[opencti_role] Missing parameter: id")
191
+ return None
192
+
193
+ self.opencti.admin_logger.info("Deleting role", {"id": id})
194
+ query = """
195
+ mutation RoleDelete($id: ID!) {
196
+ roleEdit(id: $id) {
197
+ delete
198
+ }
199
+ }
200
+ """
201
+ self.opencti.query(query, {"id": id})
202
+
203
+ def create(self, **kwargs) -> Optional[Dict]:
204
+ """Add a new role to OpenCTI.
205
+
206
+ :param name: Name to assign to the role.
207
+ :type name: str
208
+ :param description: Optional. Description of the role, defaults to
209
+ None.
210
+ :type description: str, optional
211
+ :param customAttributes: Custom attributes to return on role
212
+ :type customAttributes: str, optional
213
+ :return: Representation of the role.
214
+ :rtype: Optional[Dict]
215
+ """
216
+ name = kwargs.get("name", None)
217
+ description = kwargs.get("description", None)
218
+ custom_attributes = kwargs.get("customAttributes", None)
219
+
220
+ if name is None:
221
+ self.opencti.admin_logger.error("[opencti_role] Missing parameter: name")
222
+ return None
223
+
224
+ self.opencti.admin_logger.info(
225
+ "Creating new role", {"name": name, "description": description}
226
+ )
227
+ query = (
228
+ """
229
+ mutation RoleCreate($input: RoleAddInput!) {
230
+ roleAdd(input: $input) {
231
+ """
232
+ + (self.properties if custom_attributes is None else custom_attributes)
233
+ + """
234
+ }
235
+ }
236
+ """
237
+ )
238
+ result = self.opencti.query(
239
+ query, {"input": {"name": name, "description": description}}
240
+ )
241
+ return self.opencti.process_multiple_fields(result["data"]["roleAdd"])
242
+
243
+ def update_field(self, **kwargs) -> Optional[Dict]:
244
+ """Updates a given role with the given inputs
245
+
246
+ Example of input::
247
+
248
+ [
249
+ {
250
+ "key": "name",
251
+ "value": "NewCustomRole"
252
+ },
253
+ {
254
+ "key": "can_manage_sensitive_config",
255
+ "value": False
256
+ }
257
+ ]
258
+
259
+ :param id: ID for the role on the platform
260
+ :type id: str
261
+ :param input: List of EditInput objects
262
+ :type input: List[Dict]
263
+ :param customAttributes: Custom attributes to return on the role
264
+ :type customAttributes: str, optional
265
+
266
+ :return: Representation of the role
267
+ :rtype: Optional[Dict]
268
+ """
269
+ id = kwargs.get("id", None)
270
+ input = kwargs.get("input", None)
271
+ custom_attributes = kwargs.get("customAttributes", None)
272
+
273
+ if id is None or input is None:
274
+ self.opencti.admin_logger.error(
275
+ "[opencti_role] Missing parameters: id and input"
276
+ )
277
+ return None
278
+
279
+ self.opencti.admin_logger.info(
280
+ "Editing role with input", {"id": id, "input": input}
281
+ )
282
+ query = (
283
+ """
284
+ mutation RoleUpdate($id: ID!, $input: [EditInput]!) {
285
+ roleEdit(id: $id) {
286
+ fieldPatch(input: $input) {
287
+ """
288
+ + (self.properties if custom_attributes is None else custom_attributes)
289
+ + """
290
+ }
291
+ }
292
+ }
293
+ """
294
+ )
295
+ result = self.opencti.query(query, {"id": id, "input": input})
296
+ return self.opencti.process_multiple_fields(
297
+ result["data"]["roleEdit"]["fieldPatch"]
298
+ )
299
+
300
+ def add_capability(self, **kwargs) -> Optional[Dict]:
301
+ """Adds a capability to a role
302
+
303
+ :param id: ID of the role.
304
+ :type id: str
305
+ :param capability_id: ID of the capability to add.
306
+ :type capability_id: str
307
+ :return: Representation of the relationship, including the role and
308
+ capability
309
+ :rtype: Optional[Dict]
310
+ """
311
+ id = kwargs.get("id", None)
312
+ capability_id = kwargs.get("capability_id", None)
313
+
314
+ if id is None or capability_id is None:
315
+ self.opencti.admin_logger(
316
+ "[opencti_role] Missing parameters: id and capability_id"
317
+ )
318
+ return None
319
+
320
+ self.opencti.admin_logger.info(
321
+ "Adding capability to role", {"roleId": id, "capabilityId": capability_id}
322
+ )
323
+ query = (
324
+ """
325
+ mutation RoleEditAddCapability($id: ID!, $input: InternalRelationshipAddInput!) {
326
+ roleEdit(id: $id) {
327
+ relationAdd(input: $input) {
328
+ id
329
+ entity_type
330
+ parent_types
331
+ created_at
332
+ updated_at
333
+ from {
334
+ ... on Role {
335
+ """
336
+ + self.properties
337
+ + """
338
+ }
339
+ }
340
+ to {
341
+ ... on Capability {
342
+ id, name, description
343
+ }
344
+ }
345
+ }
346
+ }
347
+ }
348
+ """
349
+ )
350
+ result = self.opencti.query(
351
+ query,
352
+ {
353
+ "id": id,
354
+ "input": {"relationship_type": "has-capability", "toId": capability_id},
355
+ },
356
+ )
357
+ return self.opencti.process_multiple_fields(
358
+ result["data"]["roleEdit"]["relationAdd"]
359
+ )
360
+
361
+ def delete_capability(self, **kwargs) -> Optional[Dict]:
362
+ """Removes a capability from a role
363
+
364
+ :param id: ID of the role
365
+ :type id: str
366
+ :param capability_id: ID of the capability to remove
367
+ :type capability_id: str
368
+ :return: Representation of the role after removing the capability
369
+ :rtype: Optional[Dict]
370
+ """
371
+ id = kwargs.get("id", None)
372
+ capability_id = kwargs.get("capability_id", None)
373
+
374
+ if id is None or capability_id is None:
375
+ self.opencti.admin_logger.error(
376
+ "[opencti_role] Missing parameters: id and capability_id"
377
+ )
378
+ return None
379
+
380
+ self.opencti.admin_logger.info(
381
+ "Removing capability from role",
382
+ {"roleId": id, "capabilityId": capability_id},
383
+ )
384
+ query = (
385
+ """
386
+ mutation RoleEditDeleteCapability($id: ID!, $toId: StixRef!) {
387
+ roleEdit(id: $id) {
388
+ relationDelete(toId: $toId, relationship_type: "has-capability") {
389
+ """
390
+ + self.properties
391
+ + """
392
+ }
393
+ }
394
+ }
395
+ """
396
+ )
397
+ result = self.opencti.query(query, {"id": id, "toId": capability_id})
398
+ return self.opencti.process_multiple_fields(
399
+ result["data"]["roleEdit"]["relationDelete"]
400
+ )
401
+
402
+ def process_multiple_fields(self, data):
403
+ if "capabilities" in data:
404
+ data["capabilities"] = self.opencti.process_multiple(data["capabilities"])
405
+ data["capabilitiesIds"] = self.opencti.process_multiple_ids(
406
+ data["capabilities"]
407
+ )
408
+ return data