assemblyline-core 4.6.1.dev28__tar.gz → 4.6.1.dev31__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.
Files changed (90) hide show
  1. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/PKG-INFO +1 -1
  2. assemblyline_core-4.6.1.dev31/assemblyline_core/VERSION +1 -0
  3. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/plumber/run_plumber.py +90 -5
  4. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core.egg-info/PKG-INFO +1 -1
  5. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/test/test_plumber.py +40 -3
  6. assemblyline_core-4.6.1.dev28/assemblyline_core/VERSION +0 -1
  7. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/LICENCE.md +0 -0
  8. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/README.md +0 -0
  9. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/__init__.py +0 -0
  10. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/alerter/__init__.py +0 -0
  11. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/alerter/processing.py +0 -0
  12. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/alerter/run_alerter.py +0 -0
  13. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/archiver/__init__.py +0 -0
  14. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/archiver/run_archiver.py +0 -0
  15. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/badlist_client.py +0 -0
  16. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/dispatching/__init__.py +0 -0
  17. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/dispatching/__main__.py +0 -0
  18. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/dispatching/client.py +0 -0
  19. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/dispatching/dispatcher.py +0 -0
  20. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/dispatching/schedules.py +0 -0
  21. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/dispatching/timeout.py +0 -0
  22. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/expiry/__init__.py +0 -0
  23. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/expiry/run_expiry.py +0 -0
  24. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/ingester/__init__.py +0 -0
  25. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/ingester/__main__.py +0 -0
  26. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/ingester/constants.py +0 -0
  27. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/ingester/ingester.py +0 -0
  28. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/metrics/__init__.py +0 -0
  29. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/metrics/es_metrics.py +0 -0
  30. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/metrics/heartbeat_formatter.py +0 -0
  31. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/metrics/helper.py +0 -0
  32. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/metrics/metrics_server.py +0 -0
  33. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/metrics/run_heartbeat_manager.py +0 -0
  34. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/metrics/run_metrics_aggregator.py +0 -0
  35. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/metrics/run_statistics_aggregator.py +0 -0
  36. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/plumber/__init__.py +0 -0
  37. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/replay/__init__.py +0 -0
  38. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/replay/client.py +0 -0
  39. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/replay/creator/__init__.py +0 -0
  40. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/replay/creator/run.py +0 -0
  41. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/replay/creator/run_worker.py +0 -0
  42. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/replay/loader/__init__.py +0 -0
  43. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/replay/loader/run.py +0 -0
  44. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/replay/loader/run_worker.py +0 -0
  45. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/replay/replay.py +0 -0
  46. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/safelist_client.py +0 -0
  47. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/scaler/__init__.py +0 -0
  48. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/scaler/collection.py +0 -0
  49. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/scaler/controllers/__init__.py +0 -0
  50. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/scaler/controllers/docker_ctl.py +0 -0
  51. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/scaler/controllers/interface.py +0 -0
  52. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/scaler/controllers/kubernetes_ctl.py +0 -0
  53. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/scaler/run_scaler.py +0 -0
  54. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/scaler/scaler_server.py +0 -0
  55. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/server_base.py +0 -0
  56. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/signature_client.py +0 -0
  57. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/submission_client.py +0 -0
  58. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/tasking_client.py +0 -0
  59. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/updater/__init__.py +0 -0
  60. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/updater/helper.py +0 -0
  61. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/updater/run_updater.py +0 -0
  62. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/vacuum/__init__.py +0 -0
  63. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/vacuum/crawler.py +0 -0
  64. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/vacuum/department_map.py +0 -0
  65. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/vacuum/safelist.py +0 -0
  66. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/vacuum/stream_map.py +0 -0
  67. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/vacuum/worker.py +0 -0
  68. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/workflow/__init__.py +0 -0
  69. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core/workflow/run_workflow.py +0 -0
  70. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core.egg-info/SOURCES.txt +0 -0
  71. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core.egg-info/dependency_links.txt +0 -0
  72. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core.egg-info/requires.txt +0 -0
  73. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/assemblyline_core.egg-info/top_level.txt +0 -0
  74. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/setup.cfg +0 -0
  75. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/setup.py +0 -0
  76. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/test/test_alerter.py +0 -0
  77. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/test/test_badlist_client.py +0 -0
  78. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/test/test_dispatcher.py +0 -0
  79. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/test/test_expiry.py +0 -0
  80. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/test/test_replay.py +0 -0
  81. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/test/test_safelist_client.py +0 -0
  82. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/test/test_scaler.py +0 -0
  83. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/test/test_scheduler.py +0 -0
  84. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/test/test_signature_client.py +0 -0
  85. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/test/test_simulation.py +0 -0
  86. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/test/test_tasking_client.py +0 -0
  87. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/test/test_vacuum.py +0 -0
  88. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/test/test_worker_ingest.py +0 -0
  89. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/test/test_worker_submit.py +0 -0
  90. {assemblyline_core-4.6.1.dev28 → assemblyline_core-4.6.1.dev31}/test/test_workflow.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: assemblyline-core
3
- Version: 4.6.1.dev28
3
+ Version: 4.6.1.dev31
4
4
  Summary: Assemblyline 4 - Core components
5
5
  Home-page: https://github.com/CybercentreCanada/assemblyline-core/
6
6
  Author: CCCS Assemblyline development team
@@ -0,0 +1 @@
1
+ 4.6.1.dev31
@@ -7,22 +7,22 @@ disabled or deleted for which a service queue exists, the dispatcher will be inf
7
7
  had an error.
8
8
  """
9
9
  import threading
10
- import warnings
10
+ from copy import deepcopy
11
11
  from typing import Optional
12
12
 
13
13
  from assemblyline.common.constants import service_queue_name
14
- from assemblyline.common.forge import get_service_queue, get_config
14
+ from assemblyline.common.forge import get_config, get_service_queue
15
15
  from assemblyline.common.isotime import DAY_IN_SECONDS, now_as_iso
16
16
  from assemblyline.odm.models.apikey import get_apikey_id
17
17
  from assemblyline.odm.models.error import Error
18
18
  from assemblyline.odm.models.service import Service
19
19
  from assemblyline.odm.models.user import load_roles, load_roles_form_acls
20
+ from assemblyline.odm.models.user_settings import SubmissionProfileParams
20
21
  from assemblyline.remote.datatypes import retry_call
21
22
  from assemblyline.remote.datatypes.queues.named import NamedQueue
22
23
  from assemblyline_core.dispatching.client import DispatchClient
23
24
  from assemblyline_core.server_base import CoreBase, ServiceStage
24
25
 
25
-
26
26
  DAY = 60 * 60 * 24
27
27
  TASK_DELETE_CHUNK = 10000
28
28
 
@@ -56,8 +56,14 @@ class Plumber(CoreBase):
56
56
  name="redis_notification_queue_cleanup")
57
57
  nq_thread.start()
58
58
 
59
+ # Start a user apikey cleanup thread
59
60
  ua_thread = threading.Thread(target=self.user_apikey_cleanup, daemon=True, name="user_apikey_cleanup")
60
61
  ua_thread.start()
62
+
63
+ # Start a user setting migration thread
64
+ usm_thread = threading.Thread(target=self.migrate_user_settings, daemon=True, name="migrate_user_settings")
65
+ usm_thread.start()
66
+
61
67
  self.service_queue_plumbing()
62
68
 
63
69
  def service_queue_plumbing(self):
@@ -193,8 +199,6 @@ class Plumber(CoreBase):
193
199
  self.sleep(2)
194
200
  self.log.info(f"Done watching {service_name} service queue")
195
201
 
196
-
197
-
198
202
  def user_apikey_cleanup(self):
199
203
  query = "id:*"
200
204
  offset = 0
@@ -246,7 +250,88 @@ class Plumber(CoreBase):
246
250
  user['apikeys'] = {}
247
251
  self.datastore.user.save(uname, user)
248
252
 
253
+ def migrate_user_settings(self):
254
+ service_list = self.datastore.list_all_services(as_obj=False)
249
255
 
256
+ # Migrate user settings to the new format
257
+ for doc in self.datastore.user_settings.scan_with_search_after(query={
258
+ "bool": {
259
+ "must": {
260
+ "query_string": {
261
+ "query": "*",
262
+ }
263
+ }
264
+ }
265
+ }):
266
+ user_settings = doc["_source"]
267
+ if user_settings.get('submission_profiles'):
268
+ # User settings already migrated, skip
269
+ continue
270
+
271
+ # Create the list of submission profiles
272
+ submission_profiles = {
273
+ # Grant everyone a default of which all settings from before 4.6 should be transferred
274
+ "default" : SubmissionProfileParams(user_settings).as_primitives(strip_null=True)
275
+ }
276
+
277
+ profile_error_checks = {}
278
+ # Try to apply the original settings to the system-defined profiles
279
+ for profile in self.config.submission.profiles:
280
+ updates = deepcopy(user_settings)
281
+ profile_error_checks.setdefault(profile.name, 0)
282
+ validated_profile = profile.params.as_primitives(strip_null=True)
283
+
284
+ updates.setdefault("services", {})
285
+ updates["services"].setdefault("selected", [])
286
+ updates["services"].setdefault("excluded", [])
287
+
288
+ # Append the exclusion list set by the profile
289
+ updates['services']['excluded'] = updates['services']['excluded'] + \
290
+ list(validated_profile.get("services", {}).get("excluded", []))
291
+
292
+ # Ensure the selected services are not in the excluded list
293
+ for service in service_list:
294
+ if service['name'] in updates['services']['selected'] and service['name'] in updates['services']['excluded']:
295
+ updates['services']['included'].remove(service['name'])
296
+ profile_error_checks[profile.name] += 1
297
+ elif service['category'] in updates['services']['selected'] and service['category'] in updates['services']['excluded']:
298
+ updates['services']['included'].remove(service['category'])
299
+ profile_error_checks[profile.name] += 1
300
+
301
+
302
+ # Check the services parameters
303
+ for param_type, list_of_params in profile.restricted_params.items():
304
+ # Check if there are restricted submission parameters
305
+ if param_type == "submission":
306
+ requested_params = (set(list_of_params) & set(updates.keys())) - set({'services', 'service_spec'})
307
+ if requested_params:
308
+ # Track the number of errors for each profile
309
+ profile_error_checks[profile.name] += len(requested_params)
310
+ for param in requested_params:
311
+ # Remove the parameter from the updates
312
+ updates.pop(param, None)
313
+
314
+ # Check if there are restricted service parameters
315
+ else:
316
+ service_spec = updates.get('service_spec', {}).get(param_type, {})
317
+ requested_params = set(list_of_params) & set(service_spec)
318
+ if requested_params:
319
+ # Track the number of errors for each profile
320
+ profile_error_checks[profile.name] += len(requested_params)
321
+ for param in requested_params:
322
+ # Remove the parameter from the updates
323
+ service_spec.pop(param, None)
324
+
325
+ if not service_spec:
326
+ # Remove the service spec if empty
327
+ updates['service_spec'].pop(param_type, None)
328
+ submission_profiles[profile.name] = SubmissionProfileParams(updates).as_primitives(strip_null=True)
329
+
330
+ # Assign the profile with the least number of errors
331
+ user_settings['submission_profiles'] = submission_profiles
332
+ user_settings['preferred_submission_profile'] = sorted(profile_error_checks.items(), key=lambda x: x[1])[0][0]
333
+
334
+ self.datastore.user_settings.save(doc["_id"], user_settings)
250
335
 
251
336
 
252
337
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: assemblyline-core
3
- Version: 4.6.1.dev28
3
+ Version: 4.6.1.dev31
4
4
  Summary: Assemblyline 4 - Core components
5
5
  Home-page: https://github.com/CybercentreCanada/assemblyline-core/
6
6
  Author: CCCS Assemblyline development team
@@ -1,14 +1,15 @@
1
1
  from time import sleep
2
2
  from unittest import mock
3
3
 
4
- from assemblyline.odm.messages.task import Task
5
- from assemblyline.odm.models.service import Service
6
- from assemblyline.odm.random_data import random_model_obj
7
4
  from assemblyline_core.plumber.run_plumber import Plumber
8
5
  from assemblyline_core.server_base import ServiceStage
9
6
  from mocking import TrueCountTimes
10
7
  from redis import Redis
11
8
 
9
+ from assemblyline.odm.messages.task import Task
10
+ from assemblyline.odm.models.service import Service
11
+ from assemblyline.odm.random_data import random_model_obj
12
+
12
13
 
13
14
  def test_expire_missing_service():
14
15
  redis = mock.MagicMock(spec=Redis)
@@ -107,3 +108,39 @@ def test_cleanup_old_tasks(datastore_connection):
107
108
  q="task.start_time_in_millis:0",
108
109
  track_total_hits=True,
109
110
  size=0)['hits']['total']['value'] == 0
111
+
112
+ def test_user_setting_migrations(datastore_connection):
113
+ from assemblyline.odm.models.config import SubmissionProfileParams
114
+
115
+ SubmissionProfileParams.fields().keys()
116
+ # Create a bunch of random "old" tasks and clean them up
117
+ redis = mock.MagicMock(spec=Redis)
118
+ redis_persist = mock.MagicMock(spec=Redis)
119
+ plumber = Plumber(redis=redis, redis_persist=redis_persist, datastore=datastore_connection, delay=1)
120
+
121
+ # Create a user with old settings (format prior to 4.6)
122
+ settings = {'classification': 'TLP:CLEAR', 'deep_scan': False, 'description': '', 'download_encoding': 'cart', 'default_external_sources': ['Malware Bazaar', 'VirusTotal'], 'default_zip_password': 'zippy', 'executive_summary': False, 'expand_min_score': 500, 'generate_alert': False, 'ignore_cache': False, 'ignore_dynamic_recursion_prevention': False, 'ignore_recursion_prevention': False, 'ignore_filtering': False, 'malicious': False, 'priority': 369, 'profile': False, 'service_spec': {'AVClass': {'include_malpedia_dataset': False}}, 'services': {'selected': ['Extraction', 'ConfigExtractor', 'YARA'], 'excluded': [], 'rescan': [], 'resubmit': [], 'runtime_excluded': []}, 'submission_view': 'report', 'ttl': 0}
123
+ datastore_connection.ds.client.index(index="user_settings", id="admin", document=settings)
124
+ datastore_connection.user_settings.commit()
125
+
126
+ # Initiate the migration
127
+ plumber.migrate_user_settings()
128
+
129
+ # Check that the settings have been migrated
130
+ migrated_settings = datastore_connection.user_settings.get("admin", as_obj=False)
131
+
132
+ # Deprecated settings should be removed
133
+ assert "ignore_dynamic_recursion_prevention" not in migrated_settings
134
+
135
+ # All former submission settings at the root-level should be moved to submission profiles
136
+ assert all([key not in migrated_settings for key in SubmissionProfileParams.fields().keys()] )
137
+
138
+ for name, settings in migrated_settings['submission_profiles'].items():
139
+ assert settings['classification'] == 'TLP:C'
140
+ assert settings['deep_scan'] is False
141
+ assert settings['generate_alert'] is False
142
+ assert settings['ignore_cache'] is False
143
+ assert settings['priority'] == 369
144
+ # Full service spec should be preserved in default profile, but not in pre-defined ones
145
+ assert settings['service_spec'] == {} if name != "default" else {'AVClass': {'include_malpedia_dataset': False}}
146
+ assert settings['ttl'] == 0
@@ -1 +0,0 @@
1
- 4.6.1.dev28