iotsploit-django 0.0.6__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 (127) hide show
  1. iotsploit_django-0.0.6/PKG-INFO +61 -0
  2. iotsploit_django-0.0.6/README.md +7 -0
  3. iotsploit_django-0.0.6/pyproject.toml +68 -0
  4. iotsploit_django-0.0.6/src/iotsploit_django/__init__.py +6 -0
  5. iotsploit_django-0.0.6/src/iotsploit_django/adapters/__init__.py +0 -0
  6. iotsploit_django-0.0.6/src/iotsploit_django/adapters/django/__init__.py +3 -0
  7. iotsploit_django-0.0.6/src/iotsploit_django/adapters/django/device_driver_manager_factory.py +35 -0
  8. iotsploit_django-0.0.6/src/iotsploit_django/adapters/django/device_models.py +251 -0
  9. iotsploit_django-0.0.6/src/iotsploit_django/adapters/django/device_registry_factory.py +13 -0
  10. iotsploit_django-0.0.6/src/iotsploit_django/adapters/django/driver_state_repo.py +62 -0
  11. iotsploit_django-0.0.6/src/iotsploit_django/adapters/django/exploit_manager_factory.py +33 -0
  12. iotsploit_django-0.0.6/src/iotsploit_django/adapters/django/iot_fuzzer/__init__.py +3 -0
  13. iotsploit_django-0.0.6/src/iotsploit_django/adapters/django/iot_fuzzer/models.py +821 -0
  14. iotsploit_django-0.0.6/src/iotsploit_django/adapters/django/plugins/__init__.py +3 -0
  15. iotsploit_django-0.0.6/src/iotsploit_django/adapters/django/plugins/models.py +183 -0
  16. iotsploit_django-0.0.6/src/iotsploit_django/adapters/django/plugins/repos.py +130 -0
  17. iotsploit_django-0.0.6/src/iotsploit_django/adapters/django/sqlalchemy_database.py +20 -0
  18. iotsploit_django-0.0.6/src/iotsploit_django/adapters/django/stream_manager.py +132 -0
  19. iotsploit_django-0.0.6/src/iotsploit_django/adapters/django/target_models.py +395 -0
  20. iotsploit_django-0.0.6/src/iotsploit_django/adapters/django/task_runner.py +27 -0
  21. iotsploit_django-0.0.6/src/iotsploit_django/adapters/memory/__init__.py +3 -0
  22. iotsploit_django-0.0.6/src/iotsploit_django/adapters/memory/driver_state_repo.py +20 -0
  23. iotsploit_django-0.0.6/src/iotsploit_django/adapters/memory/repos.py +41 -0
  24. iotsploit_django-0.0.6/src/iotsploit_django/adapters/memory/task_runner.py +29 -0
  25. iotsploit_django-0.0.6/src/iotsploit_django/adapters/sqlalchemy/__init__.py +3 -0
  26. iotsploit_django-0.0.6/src/iotsploit_django/adapters/sqlalchemy/database.py +29 -0
  27. iotsploit_django-0.0.6/src/iotsploit_django/apps.py +8 -0
  28. iotsploit_django-0.0.6/src/iotsploit_django/asgi.py +29 -0
  29. iotsploit_django-0.0.6/src/iotsploit_django/composition_root/__init__.py +7 -0
  30. iotsploit_django-0.0.6/src/iotsploit_django/composition_root/core_container.py +87 -0
  31. iotsploit_django-0.0.6/src/iotsploit_django/composition_root/fuzzer_container.py +32 -0
  32. iotsploit_django-0.0.6/src/iotsploit_django/composition_root/wiring.py +66 -0
  33. iotsploit_django-0.0.6/src/iotsploit_django/config.py +18 -0
  34. iotsploit_django-0.0.6/src/iotsploit_django/consumers.py +31 -0
  35. iotsploit_django-0.0.6/src/iotsploit_django/iot_fuzzer/__init__.py +3 -0
  36. iotsploit_django-0.0.6/src/iotsploit_django/iot_fuzzer/mappers.py +20 -0
  37. iotsploit_django-0.0.6/src/iotsploit_django/iot_fuzzer/service.py +10 -0
  38. iotsploit_django-0.0.6/src/iotsploit_django/iot_fuzzer/urls.py +215 -0
  39. iotsploit_django-0.0.6/src/iotsploit_django/iot_fuzzer/views.py +2385 -0
  40. iotsploit_django-0.0.6/src/iotsploit_django/migrations/0001_initial.py +437 -0
  41. iotsploit_django-0.0.6/src/iotsploit_django/migrations/__init__.py +0 -0
  42. iotsploit_django-0.0.6/src/iotsploit_django/models/AIModel_Model.py +313 -0
  43. iotsploit_django-0.0.6/src/iotsploit_django/models/ClassifiedInfo_Model.py +30 -0
  44. iotsploit_django-0.0.6/src/iotsploit_django/models/DoIP_Diagnostic_Database_Model.py +411 -0
  45. iotsploit_django-0.0.6/src/iotsploit_django/models/PassCondition_Model.py +23 -0
  46. iotsploit_django-0.0.6/src/iotsploit_django/models/Vehicle_Model.py +116 -0
  47. iotsploit_django-0.0.6/src/iotsploit_django/models/__init__.py +13 -0
  48. iotsploit_django-0.0.6/src/iotsploit_django/models.py +23 -0
  49. iotsploit_django-0.0.6/src/iotsploit_django/ports_impl/__init__.py +7 -0
  50. iotsploit_django-0.0.6/src/iotsploit_django/ports_impl/driver_state_repo.py +7 -0
  51. iotsploit_django-0.0.6/src/iotsploit_django/ports_impl/plugin_repo.py +12 -0
  52. iotsploit_django-0.0.6/src/iotsploit_django/ports_impl/stream_backend.py +7 -0
  53. iotsploit_django-0.0.6/src/iotsploit_django/ports_impl/task_runner.py +7 -0
  54. iotsploit_django-0.0.6/src/iotsploit_django/routing.py +24 -0
  55. iotsploit_django-0.0.6/src/iotsploit_django/settings/__init__.py +3 -0
  56. iotsploit_django-0.0.6/src/iotsploit_django/settings/base.py +160 -0
  57. iotsploit_django-0.0.6/src/iotsploit_django/settings/dev.py +5 -0
  58. iotsploit_django-0.0.6/src/iotsploit_django/settings/prod.py +5 -0
  59. iotsploit_django-0.0.6/src/iotsploit_django/tasks/__init__.py +13 -0
  60. iotsploit_django-0.0.6/src/iotsploit_django/tasks/celery_app.py +46 -0
  61. iotsploit_django-0.0.6/src/iotsploit_django/tasks/fuzzer_tasks.py +20 -0
  62. iotsploit_django-0.0.6/src/iotsploit_django/tasks/legacy_tasks_impl.py +420 -0
  63. iotsploit_django-0.0.6/src/iotsploit_django/tasks/plugin_tasks.py +119 -0
  64. iotsploit_django-0.0.6/src/iotsploit_django/tests/__init__.py +2 -0
  65. iotsploit_django-0.0.6/src/iotsploit_django/tests/test_contracts_stage55.py +43 -0
  66. iotsploit_django-0.0.6/src/iotsploit_django/tools/__init__.py +0 -0
  67. iotsploit_django-0.0.6/src/iotsploit_django/tools/adb_mgr.py +907 -0
  68. iotsploit_django-0.0.6/src/iotsploit_django/tools/apt_mgr.py +74 -0
  69. iotsploit_django-0.0.6/src/iotsploit_django/tools/bash_script_engine.py +190 -0
  70. iotsploit_django-0.0.6/src/iotsploit_django/tools/bluetooth_mgr.py +319 -0
  71. iotsploit_django-0.0.6/src/iotsploit_django/tools/device_info.py +30 -0
  72. iotsploit_django-0.0.6/src/iotsploit_django/tools/discovery_server.py +163 -0
  73. iotsploit_django-0.0.6/src/iotsploit_django/tools/doip_mgr.py +500 -0
  74. iotsploit_django-0.0.6/src/iotsploit_django/tools/env_mgr.py +207 -0
  75. iotsploit_django-0.0.6/src/iotsploit_django/tools/file_obfuscator_service.py +245 -0
  76. iotsploit_django-0.0.6/src/iotsploit_django/tools/input_mgr.py +314 -0
  77. iotsploit_django-0.0.6/src/iotsploit_django/tools/iot_fuzzer_bridge.py +567 -0
  78. iotsploit_django-0.0.6/src/iotsploit_django/tools/iot_fuzzer_manager.py +998 -0
  79. iotsploit_django-0.0.6/src/iotsploit_django/tools/iot_fuzzer_service.py +1199 -0
  80. iotsploit_django-0.0.6/src/iotsploit_django/tools/iot_protocol_adapter.py +1415 -0
  81. iotsploit_django-0.0.6/src/iotsploit_django/tools/monitor_mgr.py +185 -0
  82. iotsploit_django-0.0.6/src/iotsploit_django/tools/net_audit_mgr.py +373 -0
  83. iotsploit_django-0.0.6/src/iotsploit_django/tools/obd_test.py +807 -0
  84. iotsploit_django-0.0.6/src/iotsploit_django/tools/ota_mgr.py +63 -0
  85. iotsploit_django-0.0.6/src/iotsploit_django/tools/plugin_sudo_runner.py +161 -0
  86. iotsploit_django-0.0.6/src/iotsploit_django/tools/privilege_mgr.py +218 -0
  87. iotsploit_django-0.0.6/src/iotsploit_django/tools/python_submodule_engine.py +136 -0
  88. iotsploit_django-0.0.6/src/iotsploit_django/tools/report_mgr.py +725 -0
  89. iotsploit_django-0.0.6/src/iotsploit_django/tools/sat_utils.py +113 -0
  90. iotsploit_django-0.0.6/src/iotsploit_django/tools/ssh_mgr.py +109 -0
  91. iotsploit_django-0.0.6/src/iotsploit_django/tools/third_party/INA219.py +213 -0
  92. iotsploit_django-0.0.6/src/iotsploit_django/tools/usb_mgr.py +60 -0
  93. iotsploit_django-0.0.6/src/iotsploit_django/tools/utils/__init__.py +23 -0
  94. iotsploit_django-0.0.6/src/iotsploit_django/tools/vehicle_utils.py +373 -0
  95. iotsploit_django-0.0.6/src/iotsploit_django/tools/wifi_mgr.py +404 -0
  96. iotsploit_django-0.0.6/src/iotsploit_django/tools/xlogger.py +122 -0
  97. iotsploit_django-0.0.6/src/iotsploit_django/urls.py +18 -0
  98. iotsploit_django-0.0.6/src/iotsploit_django/view_handlers/__init__.py +4 -0
  99. iotsploit_django-0.0.6/src/iotsploit_django/view_handlers/ai_model_views.py +493 -0
  100. iotsploit_django-0.0.6/src/iotsploit_django/view_handlers/console_logs_views.py +139 -0
  101. iotsploit_django-0.0.6/src/iotsploit_django/view_handlers/device_views.py +246 -0
  102. iotsploit_django-0.0.6/src/iotsploit_django/view_handlers/file_views.py +264 -0
  103. iotsploit_django-0.0.6/src/iotsploit_django/view_handlers/firmware_views.py +473 -0
  104. iotsploit_django-0.0.6/src/iotsploit_django/view_handlers/target_views.py +388 -0
  105. iotsploit_django-0.0.6/src/iotsploit_django/view_handlers/vehicle_views.py +16 -0
  106. iotsploit_django-0.0.6/src/iotsploit_django/web/__init__.py +4 -0
  107. iotsploit_django-0.0.6/src/iotsploit_django/web/api/__init__.py +3 -0
  108. iotsploit_django-0.0.6/src/iotsploit_django/web/api/ai_urls.py +30 -0
  109. iotsploit_django-0.0.6/src/iotsploit_django/web/api/console_logs_urls.py +16 -0
  110. iotsploit_django-0.0.6/src/iotsploit_django/web/api/devices_urls.py +25 -0
  111. iotsploit_django-0.0.6/src/iotsploit_django/web/api/files_urls.py +19 -0
  112. iotsploit_django-0.0.6/src/iotsploit_django/web/api/firmware_urls.py +30 -0
  113. iotsploit_django-0.0.6/src/iotsploit_django/web/api/misc_urls.py +15 -0
  114. iotsploit_django-0.0.6/src/iotsploit_django/web/api/plugins_urls.py +53 -0
  115. iotsploit_django-0.0.6/src/iotsploit_django/web/api/recovery_urls.py +12 -0
  116. iotsploit_django-0.0.6/src/iotsploit_django/web/api/targets_urls.py +26 -0
  117. iotsploit_django-0.0.6/src/iotsploit_django/web/api/tools_urls.py +14 -0
  118. iotsploit_django-0.0.6/src/iotsploit_django/web/api/urls.py +24 -0
  119. iotsploit_django-0.0.6/src/iotsploit_django/web/api/vehicle_urls.py +10 -0
  120. iotsploit_django-0.0.6/src/iotsploit_django/web/views.py +2048 -0
  121. iotsploit_django-0.0.6/src/iotsploit_django/websocket/__init__.py +3 -0
  122. iotsploit_django-0.0.6/src/iotsploit_django/websocket/ai_assistant_consumer.py +7 -0
  123. iotsploit_django-0.0.6/src/iotsploit_django/websocket/ai_assistant_consumer_impl.py +764 -0
  124. iotsploit_django-0.0.6/src/iotsploit_django/websocket/consumers.py +29 -0
  125. iotsploit_django-0.0.6/src/iotsploit_django/websocket/consumers_impl.py +728 -0
  126. iotsploit_django-0.0.6/src/iotsploit_django/websocket/routing.py +21 -0
  127. iotsploit_django-0.0.6/src/iotsploit_django/wsgi.py +15 -0
@@ -0,0 +1,61 @@
1
+ Metadata-Version: 2.3
2
+ Name: iotsploit-django
3
+ Version: 0.0.6
4
+ Summary: IoTSploit Django ring package (HTTP/WS/ORM/Celery + composition root)
5
+ License: GPL-3.0-or-later
6
+ Keywords: iot,security,testing,pentest,django
7
+ Author: IoTSploit Team
8
+ Author-email: support@iotsploit.org
9
+ Requires-Python: >=3.10,<4.0
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Intended Audience :: Information Technology
13
+ Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Security
20
+ Classifier: Topic :: System :: Hardware
21
+ Provides-Extra: platforms
22
+ Requires-Dist: Django (>=4.2,<5.0)
23
+ Requires-Dist: SQLAlchemy (>=2.0)
24
+ Requires-Dist: aiohttp (>=3.9)
25
+ Requires-Dist: asgiref (>=3.7)
26
+ Requires-Dist: bluepy (>=1.3)
27
+ Requires-Dist: celery (>=5.3)
28
+ Requires-Dist: channels (>=4.0)
29
+ Requires-Dist: channels-redis (>=4.1)
30
+ Requires-Dist: colorlog (>=6.8)
31
+ Requires-Dist: cryptography (>=41.0)
32
+ Requires-Dist: daphne (>=4.0)
33
+ Requires-Dist: django-cors-headers (>=4.0)
34
+ Requires-Dist: django-csp (>=3.7,<4.0)
35
+ Requires-Dist: django-extensions (>=3.2)
36
+ Requires-Dist: elevate (>=0.1)
37
+ Requires-Dist: iotsploit-core (>=0.0.6,<0.0.7)
38
+ Requires-Dist: iotsploit-platforms (>=0.0.6,<0.0.7) ; extra == "platforms"
39
+ Requires-Dist: mistune (>=3.0)
40
+ Requires-Dist: netifaces (>=0.11)
41
+ Requires-Dist: psutil (>=5.9)
42
+ Requires-Dist: pwntools (>=4.11)
43
+ Requires-Dist: pydantic (>=2.0)
44
+ Requires-Dist: pyusb (>=1.2)
45
+ Requires-Dist: pywifi (>=1.1)
46
+ Requires-Dist: redis (>=5.0)
47
+ Requires-Dist: requests (>=2.31)
48
+ Requires-Dist: smbus2 (>=0.4)
49
+ Project-URL: Documentation, https://www.iotsploit.org/
50
+ Project-URL: Homepage, https://www.iotsploit.org/
51
+ Project-URL: Repository, https://github.com/TKXB/iotsploit
52
+ Description-Content-Type: text/markdown
53
+
54
+ # iotsploit-django
55
+
56
+ `iotsploit-django` 是 IoTSploit 项目的 **Django 外圈(ring)**包:负责 HTTP/WS、ORM、Celery、Redis、以及对 `iotsploit-core` / `iosploit-fuzzer` 的组装注入(composition root)。
57
+
58
+ > 当前:`iotsploit-django` 已成为 Django 外圈宿主(settings/urls/asgi/celery/ws/models 等已迁入),不再依赖 `sat_toolkit` 作为 Django app。
59
+
60
+
61
+
@@ -0,0 +1,7 @@
1
+ # iotsploit-django
2
+
3
+ `iotsploit-django` 是 IoTSploit 项目的 **Django 外圈(ring)**包:负责 HTTP/WS、ORM、Celery、Redis、以及对 `iotsploit-core` / `iosploit-fuzzer` 的组装注入(composition root)。
4
+
5
+ > 当前:`iotsploit-django` 已成为 Django 外圈宿主(settings/urls/asgi/celery/ws/models 等已迁入),不再依赖 `sat_toolkit` 作为 Django app。
6
+
7
+
@@ -0,0 +1,68 @@
1
+ [tool.poetry]
2
+ name = "iotsploit-django"
3
+ version = "0.0.6"
4
+ description = "IoTSploit Django ring package (HTTP/WS/ORM/Celery + composition root)"
5
+ authors = ["IoTSploit Team <support@iotsploit.org>"]
6
+ readme = "README.md"
7
+ license = "GPL-3.0-or-later"
8
+ homepage = "https://www.iotsploit.org/"
9
+ repository = "https://github.com/TKXB/iotsploit"
10
+ documentation = "https://www.iotsploit.org/"
11
+ keywords = ["iot", "security", "testing", "pentest", "django"]
12
+ classifiers = [
13
+ "Development Status :: 3 - Alpha",
14
+ "Intended Audience :: Developers",
15
+ "Intended Audience :: Information Technology",
16
+ "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
17
+ "Topic :: Security",
18
+ "Topic :: System :: Hardware",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.10",
21
+ "Programming Language :: Python :: 3.11",
22
+ "Programming Language :: Python :: 3.12",
23
+ ]
24
+ packages = [{ include = "iotsploit_django", from = "src" }]
25
+
26
+ [tool.poetry.dependencies]
27
+ python = ">=3.10,<4.0"
28
+ iotsploit-core = "^0.0.6"
29
+ iotsploit-platforms = { version = "^0.0.6", optional = true }
30
+ Django = ">=4.2,<5.0"
31
+ channels = ">=4.0"
32
+ celery = ">=5.3"
33
+ redis = ">=5.0"
34
+ channels-redis = ">=4.1"
35
+ daphne = ">=4.0"
36
+ django-extensions = ">=3.2"
37
+ django-cors-headers = ">=4.0"
38
+ django-csp = ">=3.7,<4.0"
39
+ mistune = ">=3.0"
40
+ colorlog = ">=6.8"
41
+ SQLAlchemy = ">=2.0"
42
+ netifaces = ">=0.11"
43
+ psutil = ">=5.9"
44
+ requests = ">=2.31"
45
+ cryptography = ">=41.0"
46
+ pydantic = ">=2.0"
47
+ aiohttp = ">=3.9"
48
+ asgiref = ">=3.7"
49
+ elevate = ">=0.1"
50
+ pwntools = ">=4.11"
51
+ bluepy = ">=1.3"
52
+ pywifi = ">=1.1"
53
+ smbus2 = ">=0.4"
54
+ pyusb = ">=1.2"
55
+
56
+ [tool.poetry.extras]
57
+ platforms = ["iotsploit-platforms"]
58
+
59
+ [tool.poetry.group.dev.dependencies]
60
+ pytest = "^7.4.0"
61
+
62
+ [build-system]
63
+ requires = ["poetry-core>=1.8.0"]
64
+ build-backend = "poetry.core.masonry.api"
65
+
66
+ [tool.pytest.ini_options]
67
+ testpaths = ["tests"]
68
+ addopts = ["-q"]
@@ -0,0 +1,6 @@
1
+ """iotsploit-django: Django ring package for IoTSploit.
2
+
3
+ Host package for the Django outer ring.
4
+ """
5
+
6
+
@@ -0,0 +1,3 @@
1
+ """Django-specific adapters (ORM, admin, settings bindings)."""
2
+
3
+
@@ -0,0 +1,35 @@
1
+ from __future__ import annotations
2
+
3
+ from pathlib import Path
4
+
5
+ from iotsploit_django.adapters.django.driver_state_repo import DjangoDriverStateRepository
6
+ from iotsploit_django.adapters.memory.driver_state_repo import MemoryDriverStateRepository
7
+ from iotsploit_core.core.device_manager import DeviceDriverManager
8
+ from iotsploit_django.config import DEVICE_PLUGINS_DIR
9
+
10
+
11
+ def get_device_driver_manager(
12
+ *,
13
+ plugins_dir: str | Path | None = None,
14
+ usb_config_file: str | Path | None = None,
15
+ use_persistence: bool = True,
16
+ ) -> DeviceDriverManager:
17
+ """Composition root for Django runtime.
18
+
19
+ Core `DeviceDriverManager` is framework-free; this wires persistence adapters.
20
+ """
21
+
22
+ repo = DjangoDriverStateRepository() if use_persistence else MemoryDriverStateRepository()
23
+ # Ensure stable defaults regardless of CWD (Django/gunicorn may change working directory).
24
+ if plugins_dir is None:
25
+ plugins_dir = DEVICE_PLUGINS_DIR
26
+ if usb_config_file is None:
27
+ # repo_root/conf/usb_devices.json
28
+ usb_config_file = str(Path(__file__).resolve().parents[3] / "conf" / "usb_devices.json")
29
+ return DeviceDriverManager(
30
+ driver_state_repo=repo,
31
+ plugins_dir=plugins_dir,
32
+ usb_config_file=usb_config_file,
33
+ )
34
+
35
+
@@ -0,0 +1,251 @@
1
+ """
2
+ SQLAlchemy ORM mappings for Device domain (adapter layer).
3
+
4
+ Kept under Django adapters because runtime wiring currently uses Django settings to locate DB.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import datetime
10
+ import json
11
+ import os
12
+ from typing import Any, Dict, List, Optional, Type
13
+
14
+ from sqlalchemy import Boolean, Column, DateTime, Enum as SQLAlchemyEnum, JSON, String
15
+
16
+ from iotsploit_django.adapters.django.sqlalchemy_database import get_default_sqlalchemy_db
17
+ from iotsploit_core.domain.device import Device, DeviceType, SerialDevice, SocketCANDevice, USBDevice
18
+ from iotsploit_django.tools.xlogger import xlog
19
+
20
+ _db = get_default_sqlalchemy_db()
21
+ Base = _db.Base
22
+ engine = _db.engine
23
+ SessionLocal = _db.SessionLocal
24
+
25
+
26
+ class DeviceDBModel(Base):
27
+ __tablename__ = "devices"
28
+
29
+ device_id = Column(String, primary_key=True)
30
+ name = Column(String)
31
+ device_type = Column(SQLAlchemyEnum(DeviceType))
32
+ attributes = Column(JSON)
33
+
34
+ __mapper_args__ = {"polymorphic_on": device_type, "polymorphic_identity": "device"}
35
+
36
+ def __init__(self, device: Device):
37
+ self.device_id = device.device_id
38
+ self.name = device.name
39
+ self.device_type = device.device_type
40
+ self.attributes = device.attributes
41
+
42
+
43
+ class SerialDeviceDBModel(DeviceDBModel):
44
+ __mapper_args__ = {"polymorphic_identity": DeviceType.Serial}
45
+
46
+ def __init__(self, device: SerialDevice):
47
+ super().__init__(device)
48
+ self.attributes["port"] = device.port
49
+ self.attributes["baud_rate"] = device.baud_rate
50
+
51
+
52
+ class USBDeviceDBModel(DeviceDBModel):
53
+ __mapper_args__ = {"polymorphic_identity": DeviceType.USB}
54
+
55
+ def __init__(self, device: USBDevice):
56
+ super().__init__(device)
57
+ self.attributes["vendor_id"] = device.vendor_id
58
+ self.attributes["product_id"] = device.product_id
59
+
60
+
61
+ class CANDeviceDBModel(DeviceDBModel):
62
+ __mapper_args__ = {"polymorphic_identity": DeviceType.CAN}
63
+
64
+ def __init__(self, device: SocketCANDevice):
65
+ super().__init__(device)
66
+ self.attributes["interface"] = device.interface
67
+
68
+
69
+ class DeviceManager:
70
+ _instance = None
71
+
72
+ def __new__(cls):
73
+ if cls._instance is None:
74
+ cls._instance = super(DeviceManager, cls).__new__(cls)
75
+ cls._instance.initialize()
76
+ return cls._instance
77
+
78
+ def initialize(self):
79
+ self.devices: Dict[DeviceType, Type[Device]] = {}
80
+ Base.metadata.create_all(engine)
81
+ self.Session = SessionLocal
82
+ self.current_device: Optional[Device] = None
83
+
84
+ @classmethod
85
+ def get_instance(cls):
86
+ return cls()
87
+
88
+ def register_device(self, device_type: DeviceType, device_class: Type[Device]):
89
+ self.devices[device_type] = device_class
90
+
91
+ def create_device(self, device_type: DeviceType, **kwargs) -> Device:
92
+ if device_type in self.devices:
93
+ device_class = self.devices[device_type]
94
+ device = device_class(**kwargs)
95
+ self.save_device(device)
96
+ return device
97
+ raise ValueError(f"No device type registered for: {device_type}")
98
+
99
+ def save_device(self, device: Device):
100
+ session = self.Session()
101
+ try:
102
+ existing_device = session.query(DeviceDBModel).filter_by(device_id=device.device_id).first()
103
+ if existing_device:
104
+ xlog.info(
105
+ f"Device with device_id '{device.device_id}' already exists. Skipping insertion.",
106
+ name="device_model",
107
+ )
108
+ return
109
+
110
+ if isinstance(device, SerialDevice):
111
+ device_model = SerialDeviceDBModel(device)
112
+ elif isinstance(device, USBDevice):
113
+ device_model = USBDeviceDBModel(device)
114
+ elif isinstance(device, SocketCANDevice):
115
+ device_model = CANDeviceDBModel(device)
116
+ else:
117
+ device_model = DeviceDBModel(device)
118
+
119
+ session.add(device_model)
120
+ session.commit()
121
+ xlog.info(
122
+ f"Device with device_id '{device.device_id}' has been added to the database.",
123
+ name="device_model",
124
+ )
125
+ except Exception as e:
126
+ session.rollback()
127
+ xlog.error(f"An error occurred while saving device '{device.device_id}': {e}", name="device_model")
128
+ raise
129
+ finally:
130
+ session.close()
131
+
132
+ def get_all_devices(self) -> List[Dict[str, Any]]:
133
+ session = self.Session()
134
+ try:
135
+ devices = session.query(DeviceDBModel).all()
136
+ result = []
137
+ for d in devices:
138
+ if d.device_type == DeviceType.Serial:
139
+ device = SerialDevice(
140
+ device_id=d.device_id,
141
+ name=d.name,
142
+ port=d.attributes.get("port", ""),
143
+ baud_rate=d.attributes.get("baud_rate", 115200),
144
+ attributes=d.attributes,
145
+ )
146
+ elif d.device_type == DeviceType.USB:
147
+ device = USBDevice(
148
+ device_id=d.device_id,
149
+ name=d.name,
150
+ vendor_id=d.attributes.get("vendor_id", ""),
151
+ product_id=d.attributes.get("product_id", ""),
152
+ attributes=d.attributes,
153
+ )
154
+ elif d.device_type == DeviceType.CAN:
155
+ device = SocketCANDevice(
156
+ device_id=d.device_id,
157
+ name=d.name,
158
+ interface=d.attributes.get("interface", "can0"),
159
+ attributes=d.attributes,
160
+ )
161
+ else:
162
+ device = Device(
163
+ device_id=d.device_id,
164
+ name=d.name,
165
+ device_type=d.device_type,
166
+ attributes=d.attributes,
167
+ )
168
+ result.append(device.to_dict())
169
+ return result
170
+ except Exception as e:
171
+ xlog.error(f"Error getting devices: {e}", name="device_model")
172
+ return []
173
+ finally:
174
+ session.close()
175
+
176
+ def parse_and_set_device_from_json(self, json_file_path: str):
177
+ import warnings
178
+
179
+ warnings.warn(
180
+ "parse_and_set_device_from_json is deprecated. "
181
+ "Devices are now auto-discovered by drivers or use 'device_import' CLI command.",
182
+ DeprecationWarning,
183
+ stacklevel=2,
184
+ )
185
+
186
+ if not os.path.exists(json_file_path):
187
+ xlog.error(f"File not found: {json_file_path}", name="device_model")
188
+ return
189
+
190
+ with open(json_file_path, "r") as file:
191
+ data = json.load(file)
192
+
193
+ imported_count = 0
194
+ for device in data.get("devices", []):
195
+ device_type = DeviceType(device.get("device_type", "USB"))
196
+ device_class = self.devices.get(device_type, Device)
197
+
198
+ device_data: Dict[str, Any] = {
199
+ "device_id": device.get("device_id"),
200
+ "name": device.get("name"),
201
+ "attributes": device.get("attributes", {}),
202
+ }
203
+
204
+ if device_type == DeviceType.Serial:
205
+ device_data["port"] = device.get("port")
206
+ device_data["baud_rate"] = device.get("baud_rate")
207
+ elif device_type == DeviceType.USB:
208
+ device_data["vendor_id"] = device.get("vendor_id")
209
+ device_data["product_id"] = device.get("product_id")
210
+ elif device_type == DeviceType.CAN:
211
+ device_data["interface"] = device.get("interface", "can0")
212
+
213
+ device_instance = self.create_device(device_type, **device_data)
214
+ self.current_device = device_instance
215
+ imported_count += 1
216
+
217
+ xlog.info(
218
+ f"Imported {imported_count} devices from JSON file: {json_file_path}",
219
+ name="device_model",
220
+ )
221
+
222
+ def get_current_device(self) -> Optional[Device]:
223
+ return self.current_device
224
+
225
+ def set_current_device(self, device: Device):
226
+ self.current_device = device
227
+
228
+
229
+ class DeviceDriverState(Base):
230
+ __tablename__ = "device_driver_states"
231
+
232
+ driver_name = Column(String, primary_key=True)
233
+ enabled = Column(Boolean, default=True)
234
+ description = Column(String, nullable=True)
235
+ last_updated = Column(DateTime, default=lambda: datetime.datetime.now())
236
+
237
+ def __init__(self, driver_name, enabled=True, description=None):
238
+ self.driver_name = driver_name
239
+ self.enabled = enabled
240
+ self.description = description
241
+ self.last_updated = datetime.datetime.now()
242
+
243
+ def to_dict(self):
244
+ return {
245
+ "driver_name": self.driver_name,
246
+ "enabled": self.enabled,
247
+ "description": self.description,
248
+ "last_updated": str(self.last_updated),
249
+ }
250
+
251
+
@@ -0,0 +1,13 @@
1
+ from __future__ import annotations
2
+
3
+ from iotsploit_django.adapters.django.device_driver_manager_factory import get_device_driver_manager
4
+ from iotsploit_core.core.device_registry import DeviceRegistry
5
+
6
+
7
+ def get_device_registry(*, use_persistence: bool = True) -> DeviceRegistry:
8
+ """Composition root for Django runtime."""
9
+
10
+ driver_manager = get_device_driver_manager(use_persistence=use_persistence)
11
+ return DeviceRegistry.get_instance(driver_manager=driver_manager)
12
+
13
+
@@ -0,0 +1,62 @@
1
+ from __future__ import annotations
2
+
3
+ import datetime
4
+
5
+ from iotsploit_django.adapters.django.device_models import DeviceDriverState
6
+ from iotsploit_django.adapters.django.sqlalchemy_database import get_default_sqlalchemy_db
7
+
8
+
9
+ class DjangoDriverStateRepository:
10
+ """SQLAlchemy-backed driver state repo (adapter layer).
11
+
12
+ NOTE: This uses the SQLAlchemy DB factory that is configured via Django settings.
13
+ """
14
+
15
+ def __init__(self) -> None:
16
+ self._db = get_default_sqlalchemy_db()
17
+ # Ensure the table exists; previously this was implicitly created via other model managers.
18
+ try:
19
+ self._db.Base.metadata.create_all(self._db.engine)
20
+ except Exception:
21
+ # Keep repository resilient; callers will treat missing persistence as "no saved states".
22
+ pass
23
+
24
+ def get_enabled(self, driver_name: str) -> bool | None:
25
+ session = self._db.SessionLocal()
26
+ try:
27
+ row = session.query(DeviceDriverState).filter_by(driver_name=driver_name).first()
28
+ return None if row is None else bool(row.enabled)
29
+ except Exception:
30
+ return None
31
+ finally:
32
+ session.close()
33
+
34
+ def set_enabled(self, driver_name: str, enabled: bool, description: str | None = None) -> None:
35
+ session = self._db.SessionLocal()
36
+ try:
37
+ row = session.query(DeviceDriverState).filter_by(driver_name=driver_name).first()
38
+ if row:
39
+ row.enabled = bool(enabled)
40
+ row.last_updated = datetime.datetime.now()
41
+ if description is not None:
42
+ row.description = description
43
+ else:
44
+ row = DeviceDriverState(driver_name=driver_name, enabled=bool(enabled), description=description)
45
+ session.add(row)
46
+ session.commit()
47
+ except Exception:
48
+ session.rollback()
49
+ finally:
50
+ session.close()
51
+
52
+ def list_enabled(self) -> dict[str, bool]:
53
+ session = self._db.SessionLocal()
54
+ try:
55
+ rows = session.query(DeviceDriverState).all()
56
+ return {r.driver_name: bool(r.enabled) for r in rows}
57
+ except Exception:
58
+ return {}
59
+ finally:
60
+ session.close()
61
+
62
+
@@ -0,0 +1,33 @@
1
+ from __future__ import annotations
2
+
3
+ from pathlib import Path
4
+
5
+ from iotsploit_django.adapters.django.plugins.repos import DjangoPluginGroupRepository, DjangoPluginMetaRepository
6
+ from iotsploit_django.adapters.django.task_runner import CeleryTaskRunner
7
+ from iotsploit_django.adapters.memory.task_runner import InProcessTaskRunner
8
+ from iotsploit_core.core.exploit_manager import ExploitPluginManager
9
+
10
+
11
+ def get_exploit_plugin_manager(
12
+ *,
13
+ plugins_dir: str | Path | None = None,
14
+ use_celery: bool = True,
15
+ ) -> ExploitPluginManager:
16
+ """Composition root for Django runtime.
17
+
18
+ Core `ExploitPluginManager` is framework-free; this function wires Django ORM repos
19
+ and (optionally) Celery as the TaskRunner.
20
+ """
21
+
22
+ repo = DjangoPluginMetaRepository()
23
+ group_repo = DjangoPluginGroupRepository()
24
+ runner = CeleryTaskRunner() if use_celery else InProcessTaskRunner()
25
+
26
+ return ExploitPluginManager(
27
+ plugin_repo=repo,
28
+ group_repo=group_repo,
29
+ task_runner=runner,
30
+ plugins_dir=plugins_dir,
31
+ )
32
+
33
+
@@ -0,0 +1,3 @@
1
+ """IoT Fuzzer Django adapter (Django ORM models, admin integration)."""
2
+
3
+