assemblyline-ui 4.7.5.dev134__py3-none-any.whl → 4.7.5.dev136__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.
assemblyline_ui/VERSION CHANGED
@@ -1 +1 @@
1
- 4.7.5.dev134
1
+ 4.7.5.dev136
@@ -50,9 +50,16 @@ def verify_query(query):
50
50
  return True
51
51
 
52
52
 
53
+ def workflow_does_not_exist(workflow_id):
54
+ """Create an api response for when we want to report a workflow as not existing."""
55
+ return make_api_response({"success": False},
56
+ err=f"Workflow ID {workflow_id} does not exist",
57
+ status_code=404)
58
+
59
+
53
60
  @workflow_api.route("/", methods=["PUT"])
54
61
  @api_login(allow_readonly=False, require_role=[ROLES.workflow_manage])
55
- def add_workflow(**kwargs):
62
+ def add_workflow(user, **_):
56
63
  """
57
64
  Add a workflow to the system
58
65
 
@@ -92,10 +99,15 @@ def add_workflow(**kwargs):
92
99
  if not verify_query(query):
93
100
  return make_api_response({"success": False}, err="Query contains an error", status_code=400)
94
101
 
102
+ # Check that users are only creating workflows they can themselves see, if not set it will be UNRESTRICTED
103
+ if 'classification' in data:
104
+ if not CLASSIFICATION.is_accessible(user['classification'], data['classification']):
105
+ return make_api_response({"success": False}, err="Verify classification field", status_code=400)
106
+
95
107
  data.update({
96
108
  "workflow_id": get_random_id(),
97
- "creator": kwargs['user']['uname'],
98
- "edited_by": kwargs['user']['uname'],
109
+ "creator": user['uname'],
110
+ "edited_by": user['uname'],
99
111
  "priority": data['priority'] or None,
100
112
  "status": data['status'] or None,
101
113
  "origin": data.get('origin') or config.ui.fqdn
@@ -118,7 +130,7 @@ def add_workflow(**kwargs):
118
130
 
119
131
  @workflow_api.route("/<workflow_id>/", methods=["POST"])
120
132
  @api_login(allow_readonly=False, require_role=[ROLES.workflow_manage])
121
- def edit_workflow(workflow_id, **kwargs):
133
+ def edit_workflow(workflow_id, user, **_):
122
134
  """
123
135
  Edit a workflow.
124
136
 
@@ -153,28 +165,28 @@ def edit_workflow(workflow_id, **kwargs):
153
165
  if not verify_query(query):
154
166
  return make_api_response({"success": False}, err="Query contains an error", status_code=400)
155
167
 
168
+ if 'classification' in data:
169
+ if not CLASSIFICATION.is_accessible(user['classification'], data['classification']):
170
+ return make_api_response({"success": False}, err="Verify classification field", status_code=400)
171
+
156
172
  wf = STORAGE.workflow.get(workflow_id, as_obj=False)
157
- if wf:
158
- uname = kwargs['user']['uname']
159
- wf.update(data)
160
- wf.update({
161
- "edited_by": uname,
162
- "last_edit": now_as_iso(),
163
- "workflow_id": workflow_id
164
- })
173
+ if not wf or not CLASSIFICATION.is_accessible(user['classification'], wf['classification']):
174
+ return workflow_does_not_exist(workflow_id)
175
+
176
+ wf.update(data)
177
+ wf.update({
178
+ "edited_by": user['uname'],
179
+ "last_edit": now_as_iso(),
180
+ "workflow_id": workflow_id
181
+ })
165
182
 
166
183
  success = STORAGE.workflow.save(workflow_id, wf)
167
- if success:
168
- return make_api_response({"success": success})
169
- else:
170
- return make_api_response({"success": False},
171
- err="Workflow ID %s does not exist" % workflow_id,
172
- status_code=404)
184
+ return make_api_response({"success": success})
173
185
 
174
186
 
175
187
  @workflow_api.route("/enable/<workflow_id>/", methods=["PUT"])
176
188
  @api_login(allow_readonly=False, require_role=[ROLES.workflow_manage])
177
- def set_workflow_status(workflow_id, **_):
189
+ def set_workflow_status(workflow_id, user, **_):
178
190
  """
179
191
  Set the enabled status of a workflow
180
192
 
@@ -197,17 +209,22 @@ def set_workflow_status(workflow_id, **_):
197
209
 
198
210
  if enabled is None:
199
211
  return make_api_response({"success": False}, err="Enabled field is required", status_code=400)
200
- else:
201
- return make_api_response({'success': STORAGE.workflow.update(
202
- workflow_id, [
203
- (STORAGE.workflow.UPDATE_SET, 'enabled', enabled),
204
- (STORAGE.workflow.UPDATE_SET, 'last_edit', now_as_iso()),
205
- ])})
212
+
213
+ wf = STORAGE.workflow.get(workflow_id, as_obj=False)
214
+ if not wf or not CLASSIFICATION.is_accessible(user['classification'], wf['classification']):
215
+ return workflow_does_not_exist(workflow_id)
216
+
217
+ return make_api_response({'success': STORAGE.workflow.update(
218
+ workflow_id, [
219
+ (STORAGE.workflow.UPDATE_SET, 'enabled', enabled),
220
+ (STORAGE.workflow.UPDATE_SET, 'last_edit', now_as_iso()),
221
+ ]
222
+ )})
206
223
 
207
224
 
208
225
  @workflow_api.route("/<workflow_id>/", methods=["GET"])
209
226
  @api_login(audit=False, allow_readonly=False, require_role=[ROLES.workflow_view])
210
- def get_workflow(workflow_id, **kwargs):
227
+ def get_workflow(workflow_id, user, **_):
211
228
  """
212
229
  Load the user account information.
213
230
 
@@ -231,18 +248,11 @@ def get_workflow(workflow_id, **kwargs):
231
248
  }
232
249
  """
233
250
  wf = STORAGE.workflow.get(workflow_id, as_obj=False)
234
- if wf:
235
- wf['origin'] = wf.get('origin', config.ui.fqdn)
236
- if CLASSIFICATION.is_accessible(kwargs['user']['classification'], wf['classification']):
237
- return make_api_response(wf)
238
- else:
239
- return make_api_response({},
240
- err="You're not allowed to view workflow ID: %s" % workflow_id,
241
- status_code=403)
242
- else:
243
- return make_api_response({},
244
- err="Workflow ID %s does not exist" % workflow_id,
245
- status_code=404)
251
+ if not wf or not CLASSIFICATION.is_accessible(user['classification'], wf['classification']):
252
+ return workflow_does_not_exist(workflow_id)
253
+
254
+ wf['origin'] = wf.get('origin', config.ui.fqdn)
255
+ return make_api_response(wf)
246
256
 
247
257
 
248
258
  @workflow_api.route("/labels/", methods=["GET"])
@@ -273,7 +283,7 @@ def list_workflow_labels(**kwargs):
273
283
 
274
284
  @workflow_api.route("/<workflow_id>/", methods=["DELETE"])
275
285
  @api_login(audit=False, allow_readonly=False, require_role=[ROLES.workflow_manage])
276
- def remove_workflow(workflow_id, **_):
286
+ def remove_workflow(workflow_id, user, **_):
277
287
  """
278
288
  Remove the specified workflow.
279
289
 
@@ -291,18 +301,16 @@ def remove_workflow(workflow_id, **_):
291
301
  "success": true # Was the remove successful?
292
302
  }
293
303
  """
294
- wf = STORAGE.workflow.get(workflow_id)
295
- if wf:
296
- return make_api_response({"success": STORAGE.workflow.delete(workflow_id)})
297
- else:
298
- return make_api_response({"success": False},
299
- err="Workflow ID %s does not exist" % workflow_id,
300
- status_code=404)
304
+ wf: Workflow = STORAGE.workflow.get(workflow_id)
305
+ if not wf or not CLASSIFICATION.is_accessible(user['classification'], wf.classification.value):
306
+ return workflow_does_not_exist(workflow_id)
307
+
308
+ return make_api_response({"success": STORAGE.workflow.delete(workflow_id)})
301
309
 
302
310
 
303
311
  @workflow_api.route("/<workflow_id>/run/", methods=["GET"])
304
312
  @api_login(audit=False, allow_readonly=False, require_role=[ROLES.workflow_manage])
305
- def run_workflow(workflow_id, **_):
313
+ def run_workflow(workflow_id, user, **_):
306
314
  """
307
315
  Run the specified workflow against all existing alerts that match the query
308
316
 
@@ -320,12 +328,10 @@ def run_workflow(workflow_id, **_):
320
328
  "success": true # Was the run successful?
321
329
  }
322
330
  """
323
- wf = STORAGE.workflow.get(workflow_id)
324
- if wf:
325
- # Process workflow against all alerts in the system matching the query
326
- ret_value = STORAGE.alert.update_by_query(query=wf['query'], operations=get_alert_update_ops(wf))
327
- return make_api_response({"success": ret_value is not False})
328
- else:
329
- return make_api_response({"success": False},
330
- err="Workflow ID %s does not exist" % workflow_id,
331
- status_code=404)
331
+ wf: Workflow = STORAGE.workflow.get(workflow_id)
332
+ if not wf or not CLASSIFICATION.is_accessible(user['classification'], wf.classification.value):
333
+ return workflow_does_not_exist(workflow_id)
334
+
335
+ # Process workflow against all alerts in the system matching the query
336
+ ret_value = STORAGE.alert.update_by_query(query=wf.query, operations=get_alert_update_ops(wf))
337
+ return make_api_response({"success": ret_value is not False})
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: assemblyline-ui
3
- Version: 4.7.5.dev134
3
+ Version: 4.7.5.dev136
4
4
  Summary: Assemblyline 4 - API and Socket IO server
5
5
  Home-page: https://github.com/CybercentreCanada/assemblyline-ui/
6
6
  Author: CCCS Assemblyline development team
@@ -1,4 +1,4 @@
1
- assemblyline_ui/VERSION,sha256=CA5LH5dLaiodirbLX1tm_4jU9dbTshQblYlWDhe1pbs,13
1
+ assemblyline_ui/VERSION,sha256=guLXhJP2yFv4AlHUYdv8hIkyjUsJQKVSAfEEudW8LQQ,13
2
2
  assemblyline_ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  assemblyline_ui/app.py,sha256=ok96rpL0-Hb5amqa7ojhuB0boQceZG7E32NX6LZm-f4,7849
4
4
  assemblyline_ui/config.py,sha256=20P-Ya22ZgPiSy9ynqB0NgVBzjnKDh9rVmpDB6rawxA,10564
@@ -43,7 +43,7 @@ assemblyline_ui/api/v4/system.py,sha256=4JhLhpmPfKzbXiHsBoJxSZP-ibu-lnmk4FrtaLEx
43
43
  assemblyline_ui/api/v4/ui.py,sha256=6Z_7C3F34I8cBwnGfyYACeaXtmKXH3ZD30KLsO5a0G4,10625
44
44
  assemblyline_ui/api/v4/user.py,sha256=94yE9rq2XnWgf1N8AEHPbMWiP23yCgzFvZ1nm0Ka7f0,47890
45
45
  assemblyline_ui/api/v4/webauthn.py,sha256=ouVWMMd0aMnNV5iaKbWY1AnsUE5_BKAtaUg9j77Rvow,4875
46
- assemblyline_ui/api/v4/workflow.py,sha256=Uz50960KyvFDm39NKYNSq5OXT0CA0u_FO5xPP61aYiQ,10579
46
+ assemblyline_ui/api/v4/workflow.py,sha256=KHv1GaPgK0Gf4WvTva4J6zFigVc_hsoIsosd1spmy0E,11047
47
47
  assemblyline_ui/helper/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
48
48
  assemblyline_ui/helper/datastore.py,sha256=J0zXpIOU8pfTGeMFIPp1dIuhRVA8K1xnxB7r96T_ekU,10973
49
49
  assemblyline_ui/helper/discover.py,sha256=oJBML1dQl0H2Ic-lm5jI4YWIpm9RRW-mGT5sP-2tb9c,1686
@@ -75,8 +75,8 @@ assemblyline_ui/sio/live_submission.py,sha256=WGX2Q2Rs5mlMqOQsqttxZD-IYtVdxPmxnc
75
75
  assemblyline_ui/sio/retrohunt.py,sha256=F7lYBfkLoWPB04RbupokiIBb7qau6qXS4CM_l4yUiH4,2413
76
76
  assemblyline_ui/sio/status.py,sha256=_Bxf1KLPOJEUIk4J9_j9fzvQWUXqSIT9xnJKhT1hhuc,1980
77
77
  assemblyline_ui/sio/submission.py,sha256=9ByTUmOgANr6f5GlQkiJdP3lAOVAykplwG-reY4_q2o,2601
78
- assemblyline_ui-4.7.5.dev134.dist-info/licenses/LICENCE.md,sha256=NSkYo9EH8h5oOkzg4VhjAHF4339MqPP2cQ8msTPgl-c,1396
79
- assemblyline_ui-4.7.5.dev134.dist-info/METADATA,sha256=W5UBtBgH0n7XxM-ZMxGi9BsJ5yuClYdHpU2KED7_AS4,8183
80
- assemblyline_ui-4.7.5.dev134.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
81
- assemblyline_ui-4.7.5.dev134.dist-info/top_level.txt,sha256=WLa7-PKLJTbMUbKKU3q3kg5_uAV67hss5kC71PAbIeg,16
82
- assemblyline_ui-4.7.5.dev134.dist-info/RECORD,,
78
+ assemblyline_ui-4.7.5.dev136.dist-info/licenses/LICENCE.md,sha256=NSkYo9EH8h5oOkzg4VhjAHF4339MqPP2cQ8msTPgl-c,1396
79
+ assemblyline_ui-4.7.5.dev136.dist-info/METADATA,sha256=1XHR1GvL1l53M5gBiWDHIHgrrKciIBSTWG6dJJ5ztCM,8183
80
+ assemblyline_ui-4.7.5.dev136.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
81
+ assemblyline_ui-4.7.5.dev136.dist-info/top_level.txt,sha256=WLa7-PKLJTbMUbKKU3q3kg5_uAV67hss5kC71PAbIeg,16
82
+ assemblyline_ui-4.7.5.dev136.dist-info/RECORD,,