mmisp-lib 0.8.2__tar.gz → 0.8.3__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 (164) hide show
  1. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/PKG-INFO +2 -1
  2. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/pyproject.toml +2 -1
  3. mmisp_lib-0.8.3/src/mmisp/api_schemas/object_templates.py +50 -0
  4. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/database.py +5 -0
  5. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/mixins.py +2 -0
  6. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/models/attribute.py +4 -4
  7. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/models/auth_key.py +3 -3
  8. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/models/event.py +1 -1
  9. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/models/feed.py +3 -3
  10. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/models/galaxy.py +1 -1
  11. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/models/galaxy_cluster.py +2 -2
  12. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/models/identity_provider.py +1 -1
  13. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/models/object.py +39 -6
  14. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/models/server.py +5 -5
  15. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/models/tag.py +1 -1
  16. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/models/user.py +7 -7
  17. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/mypy.py +6 -1
  18. mmisp_lib-0.8.3/src/mmisp/db/object_json_type.py +34 -0
  19. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/tests/fixtures.py +214 -234
  20. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp_lib.egg-info/PKG-INFO +2 -1
  21. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp_lib.egg-info/SOURCES.txt +2 -0
  22. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp_lib.egg-info/requires.txt +1 -0
  23. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/LICENSE +0 -0
  24. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/README.md +0 -0
  25. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/setup.cfg +0 -0
  26. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/api_schemas/__init__.py +0 -0
  27. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/api_schemas/attributes.py +0 -0
  28. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/api_schemas/auth_keys.py +0 -0
  29. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/api_schemas/authentication.py +0 -0
  30. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/api_schemas/common.py +0 -0
  31. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/api_schemas/events.py +0 -0
  32. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/api_schemas/feeds.py +0 -0
  33. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/api_schemas/galaxies.py +0 -0
  34. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/api_schemas/galaxy_clusters.py +0 -0
  35. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/api_schemas/galaxy_common.py +0 -0
  36. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/api_schemas/jobs.py +0 -0
  37. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/api_schemas/logs.py +0 -0
  38. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/api_schemas/noticelists.py +0 -0
  39. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/api_schemas/objects.py +0 -0
  40. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/api_schemas/organisations.py +0 -0
  41. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/api_schemas/py.typed +0 -0
  42. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/api_schemas/responses/__init__.py +0 -0
  43. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/api_schemas/responses/check_graph_response.py +0 -0
  44. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/api_schemas/responses/standard_status_response.py +0 -0
  45. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/api_schemas/roles.py +0 -0
  46. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/api_schemas/server.py +0 -0
  47. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/api_schemas/servers.py +0 -0
  48. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/api_schemas/shadow_attribute.py +0 -0
  49. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/api_schemas/sharing_groups.py +0 -0
  50. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/api_schemas/sightings.py +0 -0
  51. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/api_schemas/statistics.py +0 -0
  52. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/api_schemas/tags.py +0 -0
  53. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/api_schemas/taxonomies.py +0 -0
  54. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/api_schemas/user_settings.py +0 -0
  55. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/api_schemas/users.py +0 -0
  56. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/api_schemas/warninglists.py +0 -0
  57. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/api_schemas/workflows.py +0 -0
  58. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/commandline_tool/__init__.py +0 -0
  59. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/commandline_tool/main.py +0 -0
  60. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/commandline_tool/organisation.py +0 -0
  61. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/commandline_tool/py.typed +0 -0
  62. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/commandline_tool/setup.py +0 -0
  63. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/commandline_tool/user.py +0 -0
  64. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/__init__.py +0 -0
  65. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/additional_properties.py +0 -0
  66. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/all_models.py +0 -0
  67. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/config.py +0 -0
  68. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/lib.py +0 -0
  69. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/list_json_type.py +0 -0
  70. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/models/__init__.py +0 -0
  71. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/models/admin_setting.py +0 -0
  72. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/models/blocklist.py +0 -0
  73. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/models/correlation.py +0 -0
  74. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/models/log.py +0 -0
  75. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/models/noticelist.py +0 -0
  76. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/models/organisation.py +0 -0
  77. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/models/post.py +0 -0
  78. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/models/role.py +0 -0
  79. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/models/shadow_attribute.py +0 -0
  80. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/models/sharing_group.py +0 -0
  81. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/models/sighting.py +0 -0
  82. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/models/taxonomy.py +0 -0
  83. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/models/threat_level.py +0 -0
  84. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/models/user_setting.py +0 -0
  85. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/models/warninglist.py +0 -0
  86. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/models/workflow.py +0 -0
  87. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/models/workflow_blueprint.py +0 -0
  88. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/print_changes.py +0 -0
  89. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/py.typed +0 -0
  90. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/db/uuid_type.py +0 -0
  91. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/lib/__init__.py +0 -0
  92. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/lib/actions.py +0 -0
  93. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/lib/attribute_search_filter.py +0 -0
  94. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/lib/attributes.py +0 -0
  95. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/lib/distribution.py +0 -0
  96. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/lib/fallbacks.py +0 -0
  97. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/lib/galaxies.py +0 -0
  98. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/lib/galaxy_clusters.py +0 -0
  99. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/lib/logger.py +0 -0
  100. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/lib/permissions.py +0 -0
  101. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/lib/py.typed +0 -0
  102. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/lib/serialisation_helper.py +0 -0
  103. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/lib/uuid.py +0 -0
  104. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/plugins/__init__.py +0 -0
  105. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/plugins/enrichment/__init__.py +0 -0
  106. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/plugins/enrichment/data.py +0 -0
  107. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/plugins/enrichment/enrichment_plugin.py +0 -0
  108. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/plugins/exceptions.py +0 -0
  109. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/plugins/models/__init__.py +0 -0
  110. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/plugins/models/attribute.py +0 -0
  111. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/plugins/plugin_info.py +0 -0
  112. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/plugins/plugin_type.py +0 -0
  113. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/plugins/py.typed +0 -0
  114. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/tests/__init__.py +0 -0
  115. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/tests/compatibility_helpers.py +0 -0
  116. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/tests/generators/attribute_generator.py +0 -0
  117. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/tests/generators/feed_generator.py +0 -0
  118. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/tests/generators/model_generators/attribute_generator.py +0 -0
  119. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/tests/generators/model_generators/auth_key_generator.py +0 -0
  120. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/tests/generators/model_generators/correlation_exclusions_generator.py +0 -0
  121. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/tests/generators/model_generators/correlation_value_generator.py +0 -0
  122. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/tests/generators/model_generators/default_correlation_generator.py +0 -0
  123. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/tests/generators/model_generators/event_generator.py +0 -0
  124. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/tests/generators/model_generators/galaxy_generator.py +0 -0
  125. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/tests/generators/model_generators/identity_provider_generator.py +0 -0
  126. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/tests/generators/model_generators/noticelist_generator.py +0 -0
  127. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/tests/generators/model_generators/object_generator.py +0 -0
  128. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/tests/generators/model_generators/organisation_generator.py +0 -0
  129. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/tests/generators/model_generators/over_correlating_value_generator.py +0 -0
  130. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/tests/generators/model_generators/post_generator.py +0 -0
  131. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/tests/generators/model_generators/role_generator.py +0 -0
  132. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/tests/generators/model_generators/server_generator.py +0 -0
  133. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/tests/generators/model_generators/shadow_attribute_generator.py +0 -0
  134. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/tests/generators/model_generators/sharing_group_generator.py +0 -0
  135. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/tests/generators/model_generators/sighting_generator.py +0 -0
  136. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/tests/generators/model_generators/tag_generator.py +0 -0
  137. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/tests/generators/model_generators/taxonomy_generator.py +0 -0
  138. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/tests/generators/model_generators/user_generator.py +0 -0
  139. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/tests/generators/model_generators/user_setting_generator.py +0 -0
  140. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/tests/generators/model_generators/warninglist_generator.py +0 -0
  141. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/tests/generators/model_generators/workflow_generator.py +0 -0
  142. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/tests/generators/object_generator.py +0 -0
  143. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/tests/generators/sighting_generator.py +0 -0
  144. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/tests/generators/tag_generator.py +0 -0
  145. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/tests/generators/taxonomies_generator.py +0 -0
  146. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/util/__init__.py +0 -0
  147. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/util/crypto.py +0 -0
  148. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/util/models.py +0 -0
  149. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/util/partial.py +0 -0
  150. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/util/py.typed +0 -0
  151. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/util/uuid.py +0 -0
  152. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/workflows/__init__.py +0 -0
  153. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/workflows/execution.py +0 -0
  154. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/workflows/fastapi.py +0 -0
  155. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/workflows/graph.py +0 -0
  156. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/workflows/input.py +0 -0
  157. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/workflows/legacy.py +0 -0
  158. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/workflows/misp_core_format.py +0 -0
  159. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/workflows/modules.py +0 -0
  160. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp/workflows/py.typed +0 -0
  161. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp_lib.egg-info/dependency_links.txt +0 -0
  162. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp_lib.egg-info/entry_points.txt +0 -0
  163. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/src/mmisp_lib.egg-info/top_level.txt +0 -0
  164. {mmisp_lib-0.8.2 → mmisp_lib-0.8.3}/tests/test_commandline_tool.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: mmisp-lib
3
- Version: 0.8.2
3
+ Version: 0.8.3
4
4
  Requires-Python: >=3.11.0
5
5
  Description-Content-Type: text/markdown
6
6
  License-File: LICENSE
@@ -21,6 +21,7 @@ Requires-Dist: nanoid==2.0.0
21
21
  Requires-Dist: cryptography==42.0.5
22
22
  Requires-Dist: jinja2~=3.1.4
23
23
  Requires-Dist: fire
24
+ Requires-Dist: packaging
24
25
  Provides-Extra: dev
25
26
  Requires-Dist: ruff>=0.3.7; extra == "dev"
26
27
  Requires-Dist: mypy==1.8.0; extra == "dev"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "mmisp-lib"
3
- version = "0.8.2"
3
+ version = "0.8.3"
4
4
  description = ""
5
5
  authors = []
6
6
  readme = "README.md"
@@ -25,6 +25,7 @@ dependencies = [
25
25
  "cryptography==42.0.5",
26
26
  "jinja2~=3.1.4",
27
27
  "fire",
28
+ "packaging",
28
29
  ]
29
30
 
30
31
 
@@ -0,0 +1,50 @@
1
+ from pydantic import BaseModel, Field
2
+ from pydantic.types import UUID
3
+
4
+
5
+ class ObjectTemplatesRequirements(BaseModel):
6
+ requiredOneOf: list[str] | None
7
+ required: list[str] | None
8
+
9
+
10
+ class ObjectTemplate(BaseModel):
11
+ class Config:
12
+ allow_population_by_field_name = True
13
+
14
+ id: int
15
+ user_id: int
16
+ org_id: int
17
+ uuid: UUID
18
+ name: str
19
+ meta_category: str = Field(..., alias="meta-category")
20
+ description: str
21
+ version: str
22
+ requirements: ObjectTemplatesRequirements
23
+ fixed: bool
24
+ active: bool
25
+
26
+
27
+ class ObjectTemplateElement(BaseModel):
28
+ class Config:
29
+ allow_population_by_field_name = True
30
+
31
+ id: int
32
+ object_template_id: int
33
+ object_relation: str
34
+ type: str # AttributeType?
35
+ ui_priority: int = Field(..., alias="ui-priority")
36
+ categories: list
37
+ sane_default: list
38
+ values_list: list
39
+ description: str
40
+ disable_correlation: bool | None
41
+ multiple: bool
42
+
43
+
44
+ class RespObjectTemplateView(BaseModel):
45
+ ObjectTemplate: ObjectTemplate
46
+ ObjectTemplateElement: list[ObjectTemplateElement]
47
+
48
+
49
+ class RespItemObjectTemplateIndex(BaseModel):
50
+ ObjectTemplate: ObjectTemplate
@@ -1,6 +1,7 @@
1
1
  import contextlib
2
2
  import time
3
3
  from collections.abc import AsyncIterator
4
+ from contextvars import ContextVar
4
5
  from typing import Self, TypeAlias
5
6
 
6
7
  from sqlalchemy.engine.url import make_url
@@ -20,6 +21,8 @@ Base = declarative_base()
20
21
 
21
22
  _no_database: str = "DatabaseSessionManager is not initialized"
22
23
 
24
+ dry_run: ContextVar[bool] = ContextVar("dry_run", default=False)
25
+
23
26
 
24
27
  class DatabaseSessionManager:
25
28
  def __init__(self: Self, db_url: str = config.DATABASE_URL) -> None:
@@ -108,6 +111,8 @@ class DatabaseSessionManager:
108
111
  async def get_db() -> AsyncIterator[Session]:
109
112
  async with sessionmanager.session() as session:
110
113
  yield session
114
+ if dry_run.get():
115
+ await session.rollback()
111
116
 
112
117
 
113
118
  async def create_all_models() -> None:
@@ -18,6 +18,8 @@ class DictMixin:
18
18
  if omit is None:
19
19
  omit = set()
20
20
 
21
+ print(self.__mapper__.c.keys())
22
+
21
23
  unloaded = inspect(self).unloaded
22
24
  d = {}
23
25
  for key in self.__mapper__.c.keys(): # type:ignore[attr-defined]
@@ -40,7 +40,7 @@ class Attribute(Base, DictMixin):
40
40
  Integer, ForeignKey("events.id", ondelete="CASCADE"), nullable=False, index=True
41
41
  )
42
42
  object_id: Mapped[int] = mapped_column(Integer, nullable=False, default=0, index=True)
43
- object_relation: Mapped[str] = mapped_column(String(255), index=True)
43
+ object_relation: Mapped[str | None] = mapped_column(String(255), index=True)
44
44
  category: Mapped[str] = mapped_column(String(255), nullable=False, index=True)
45
45
  type: Mapped[str] = mapped_column(String(100), nullable=False, index=True)
46
46
  value1: Mapped[str] = mapped_column(Text, nullable=False)
@@ -49,11 +49,11 @@ class Attribute(Base, DictMixin):
49
49
  timestamp: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
50
50
  distribution: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
51
51
  sharing_group_id: Mapped[int] = mapped_column(Integer, index=True, default=0)
52
- comment: Mapped[str] = mapped_column(Text)
52
+ comment: Mapped[str | None] = mapped_column(Text)
53
53
  deleted: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
54
54
  disable_correlation: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
55
- first_seen: Mapped[int] = mapped_column(BigInteger, index=True)
56
- last_seen: Mapped[int] = mapped_column(BigInteger, index=True)
55
+ first_seen: Mapped[int | None] = mapped_column(BigInteger, index=True)
56
+ last_seen: Mapped[int | None] = mapped_column(BigInteger, index=True)
57
57
 
58
58
  event = relationship("Event", back_populates="attributes", lazy="joined") # type:ignore[var-annotated]
59
59
  mispobject = relationship(
@@ -19,7 +19,7 @@ class AuthKey(Base):
19
19
  created: Mapped[int] = mapped_column(Integer, nullable=False, default=time)
20
20
  expiration: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
21
21
  read_only: Mapped[bool] = mapped_column(Boolean, nullable=False, default=0)
22
- comment: Mapped[str] = mapped_column(String(255))
23
- allowed_ips: Mapped[str] = mapped_column(String(255))
24
- unique_ips: Mapped[str] = mapped_column(String(255))
22
+ comment: Mapped[str | None] = mapped_column(String(255))
23
+ allowed_ips: Mapped[str | None] = mapped_column(String(255))
24
+ unique_ips: Mapped[str | None] = mapped_column(String(255))
25
25
  user_id: Mapped[int] = mapped_column(Integer, ForeignKey("users.id"), nullable=False)
@@ -37,7 +37,7 @@ class Event(Base):
37
37
  sighting_timestamp: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
38
38
  disable_correlation: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
39
39
  extends_uuid: Mapped[str] = mapped_column(String(40), default="", index=True)
40
- protected: Mapped[bool] = mapped_column(Boolean)
40
+ protected: Mapped[bool] = mapped_column(Boolean, default=False)
41
41
 
42
42
  attributes = relationship("Attribute", back_populates="event") # type:ignore[assignment,var-annotated]
43
43
  mispobjects = relationship("Object", back_populates="event") # type:ignore[assignment,var-annotated]
@@ -11,7 +11,7 @@ class Feed(Base):
11
11
  name: Mapped[str] = mapped_column(String(255), nullable=False)
12
12
  provider: Mapped[str] = mapped_column(String(255), nullable=False)
13
13
  url: Mapped[str] = mapped_column(String(255), nullable=False)
14
- rules: Mapped[str] = mapped_column(Text, default=None)
14
+ rules: Mapped[str | None] = mapped_column(Text, default=None)
15
15
  enabled: Mapped[bool] = mapped_column(Boolean, default=False)
16
16
  distribution: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
17
17
  sharing_group_id: Mapped[int] = mapped_column(Integer, nullable=False, default=0, index=True)
@@ -23,11 +23,11 @@ class Feed(Base):
23
23
  event_id: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
24
24
  publish: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
25
25
  override_ids: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
26
- settings: Mapped[str] = mapped_column(Text)
26
+ settings: Mapped[str | None] = mapped_column(Text)
27
27
  input_source: Mapped[str] = mapped_column(String(255), nullable=False, default="network", index=True)
28
28
  delete_local_file: Mapped[bool] = mapped_column(Boolean, default=False)
29
29
  lookup_visible: Mapped[bool] = mapped_column(Boolean, default=False)
30
- headers: Mapped[str] = mapped_column(Text)
30
+ headers: Mapped[str | None] = mapped_column(Text)
31
31
  caching_enabled: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
32
32
  force_to_ids: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
33
33
  orgc_id: Mapped[int] = mapped_column(Integer, nullable=False, default=0, index=True)
@@ -21,7 +21,7 @@ class Galaxy(Base, DictMixin, UpdateMixin):
21
21
  version: Mapped[str] = mapped_column(String(255), nullable=False)
22
22
  icon: Mapped[str] = mapped_column(String(255), nullable=False, default="")
23
23
  namespace: Mapped[str] = mapped_column(String(255), nullable=False, default="misp", index=True)
24
- kill_chain_order: Mapped[str] = mapped_column(String(255))
24
+ kill_chain_order: Mapped[str | None] = mapped_column(String(255))
25
25
  """must be serialized"""
26
26
  enabled: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
27
27
  local_only: Mapped[bool] = mapped_column(Boolean, default=False)
@@ -33,8 +33,8 @@ class GalaxyCluster(Base, UpdateMixin, DictMixin):
33
33
  orgc_id: Mapped[int] = mapped_column(Integer, nullable=False, index=True, default=0)
34
34
  default: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False, index=True)
35
35
  locked: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
36
- extends_uuid: Mapped[str] = mapped_column(String(40), index=True)
37
- extends_version: Mapped[int] = mapped_column(Integer, index=True, nullable=True, default=None)
36
+ extends_uuid: Mapped[str | None] = mapped_column(String(40), index=True)
37
+ extends_version: Mapped[int | None] = mapped_column(Integer, index=True, nullable=True, default=None)
38
38
  published: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
39
39
  deleted: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
40
40
 
@@ -17,7 +17,7 @@ class OIDCIdentityProvider(Base):
17
17
  base_url: Mapped[str] = mapped_column(String(255), nullable=False)
18
18
  client_id: Mapped[str] = mapped_column(String(255), nullable=False)
19
19
  client_secret: Mapped[str] = mapped_column(String(255), nullable=False)
20
- scope: Mapped[str] = mapped_column(String(255))
20
+ scope: Mapped[str] = mapped_column(String(255), default="openid")
21
21
  """Possibility to add more scopes to be requested from the idp in addition to the default scopes,
22
22
  currently not used."""
23
23
  created: Mapped[DateTime] = mapped_column(DateTime, default=datetime.utcnow)
@@ -1,9 +1,13 @@
1
- from sqlalchemy import Boolean, ForeignKey, Integer, String
1
+ from typing import Optional
2
+
3
+ from sqlalchemy import Boolean, ForeignKey, Integer, String, Text
2
4
  from sqlalchemy.orm import relationship
3
5
 
4
6
  from mmisp.db.database import Base
7
+ from mmisp.db.list_json_type import DBListJson
5
8
  from mmisp.db.mixins import DictMixin
6
9
  from mmisp.db.mypy import Mapped, mapped_column
10
+ from mmisp.db.object_json_type import DBObjectJson
7
11
  from mmisp.lib.uuid import uuid
8
12
 
9
13
 
@@ -13,7 +17,7 @@ class Object(Base, DictMixin):
13
17
  id: Mapped[int] = mapped_column(Integer, primary_key=True, nullable=False)
14
18
  uuid: Mapped[str] = mapped_column(String(255), unique=True, default=uuid, index=True)
15
19
  name: Mapped[str] = mapped_column(String(255), index=True)
16
- meta_category: Mapped[str] = mapped_column("meta-category", String(255), index=True, key="meta_category")
20
+ meta_category: Mapped[str] = mapped_column("meta-category", String(255), index=True)
17
21
  description: Mapped[str] = mapped_column(String(255))
18
22
  template_uuid: Mapped[str] = mapped_column(String(255), index=True, default=None)
19
23
  template_version: Mapped[int] = mapped_column(Integer, index=True, nullable=False)
@@ -44,12 +48,41 @@ class ObjectTemplate(Base, DictMixin):
44
48
  __tablename__ = "object_templates"
45
49
 
46
50
  id: Mapped[int] = mapped_column(Integer, primary_key=True, nullable=False)
47
- uuid: Mapped[str] = mapped_column(String(255), unique=True, default=uuid, index=True)
48
- name: Mapped[str] = mapped_column(String(255), index=True)
49
51
  user_id: Mapped[int] = mapped_column(Integer, ForeignKey("users.id"), index=True, nullable=False)
50
52
  org_id: Mapped[int] = mapped_column(Integer, ForeignKey("organisations.id"), index=True, nullable=False)
51
- description: Mapped[str] = mapped_column(String(255))
53
+ uuid: Mapped[str] = mapped_column(String(255), unique=True, default=uuid, index=True)
54
+ name: Mapped[Optional[str]] = mapped_column(String(255), nullable=True, index=True)
55
+ meta_category: Mapped[Optional[str]] = mapped_column(
56
+ "meta-category", String(255), nullable=True, index=True, key="meta_category"
57
+ )
58
+ description: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
52
59
  version: Mapped[int] = mapped_column(Integer, nullable=False)
53
- requirements: Mapped[str] = mapped_column(String(255))
60
+ requirements: Mapped[dict | None] = mapped_column(DBObjectJson, nullable=True)
54
61
  fixed: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
55
62
  active: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
63
+
64
+ elements: Mapped[list["ObjectTemplateElement"]] = relationship(
65
+ "ObjectTemplateElement", back_populates="object_template", lazy="raise_on_sql"
66
+ )
67
+
68
+
69
+ class ObjectTemplateElement(Base, DictMixin):
70
+ __tablename__ = "object_template_elements"
71
+
72
+ id: Mapped[int] = mapped_column(Integer, primary_key=True, nullable=False)
73
+ object_template_id: Mapped[int] = mapped_column(
74
+ Integer, ForeignKey(ObjectTemplate.id, ondelete="CASCADE"), nullable=False, index=True
75
+ )
76
+ object_relation: Mapped[Optional[str]] = mapped_column(String(255), nullable=True, index=True)
77
+ type: Mapped[Optional[str]] = mapped_column(Text, nullable=True, index=True)
78
+ ui_priority: Mapped[int] = mapped_column("ui-priority", Integer, nullable=False, key="ui_priority")
79
+ categories: Mapped[list[str] | None] = mapped_column(DBListJson, nullable=True)
80
+ sane_default: Mapped[list[str] | None] = mapped_column(DBListJson, nullable=True)
81
+ values_list: Mapped[list[str] | None] = mapped_column(DBListJson, nullable=True)
82
+ description: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
83
+ disable_correlation: Mapped[Optional[bool]] = mapped_column(Boolean, nullable=True)
84
+ multiple: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
85
+
86
+ object_template: Mapped[ObjectTemplate] = relationship(
87
+ ObjectTemplate, back_populates="elements", lazy="raise_on_sql"
88
+ )
@@ -22,17 +22,17 @@ class Server(Base, DictMixin):
22
22
  pull_galaxy_clusters: Mapped[bool] = mapped_column(Boolean, default=False)
23
23
  push_analyst_data: Mapped[bool] = mapped_column(Boolean, default=False)
24
24
  pull_analyst_data: Mapped[bool] = mapped_column(Boolean, default=False)
25
- last_pulled_id: Mapped[int] = mapped_column("lastpulledid", Integer)
26
- last_pushed_id: Mapped[int] = mapped_column("lastpushedid", Integer)
27
- organization: Mapped[str] = mapped_column(String(10), default=None)
25
+ last_pulled_id: Mapped[int] = mapped_column("lastpulledid", Integer, nullable=True)
26
+ last_pushed_id: Mapped[int] = mapped_column("lastpushedid", Integer, nullable=True)
27
+ organization: Mapped[str | None] = mapped_column(String(10), default=None)
28
28
  remote_org_id: Mapped[int] = mapped_column(Integer, nullable=False, index=True)
29
29
  publish_without_email: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
30
30
  unpublish_event: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
31
31
  self_signed: Mapped[bool] = mapped_column(Boolean, nullable=False)
32
32
  pull_rules: Mapped[str] = mapped_column(Text, nullable=False)
33
33
  push_rules: Mapped[str] = mapped_column(Text, nullable=False)
34
- cert_file: Mapped[str] = mapped_column(String(255))
35
- client_cert_file: Mapped[str] = mapped_column(String(255))
34
+ cert_file: Mapped[str | None] = mapped_column(String(255))
35
+ client_cert_file: Mapped[str | None] = mapped_column(String(255))
36
36
  internal: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
37
37
  skip_proxy: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
38
38
  caching_enabled: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
@@ -15,7 +15,7 @@ class Tag(Base):
15
15
  org_id: Mapped[int] = mapped_column(Integer, nullable=False, default=0, index=True)
16
16
  user_id: Mapped[int] = mapped_column(Integer, nullable=False, default=0, index=True)
17
17
  hide_tag: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
18
- numerical_value: Mapped[int] = mapped_column(Integer, index=True)
18
+ numerical_value: Mapped[int | None] = mapped_column(Integer, index=True)
19
19
  is_galaxy: Mapped[bool] = mapped_column(Boolean, default=False)
20
20
  is_custom_galaxy: Mapped[bool] = mapped_column(Boolean, default=False)
21
21
  local_only: Mapped[bool] = mapped_column(Boolean, default=False)
@@ -20,8 +20,8 @@ class User(Base):
20
20
  autoalert: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False)
21
21
  authkey: Mapped[str] = mapped_column(String(40), nullable=True, default=None)
22
22
  invited_by: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
23
- gpgkey: Mapped[str] = mapped_column(Text)
24
- certif_public: Mapped[str] = mapped_column(Text)
23
+ gpgkey: Mapped[str | None] = mapped_column(Text)
24
+ certif_public: Mapped[str | None] = mapped_column(Text)
25
25
  nids_sid: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
26
26
  termsaccepted: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False)
27
27
  newsread: Mapped[int] = mapped_column(Integer, default=0)
@@ -35,16 +35,16 @@ class User(Base):
35
35
  force_logout: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False)
36
36
  date_created: Mapped[int] = mapped_column(Integer, default=time)
37
37
  date_modified: Mapped[int] = mapped_column(Integer, default=time, onupdate=time)
38
- sub: Mapped[str] = mapped_column(String(255), unique=True)
38
+ sub: Mapped[str] = mapped_column(String(255), unique=True, nullable=True)
39
39
  external_auth_required: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
40
- external_auth_key: Mapped[str] = mapped_column(Text)
40
+ external_auth_key: Mapped[str] = mapped_column(Text, nullable=True)
41
41
  last_api_access: Mapped[int] = mapped_column(Integer, default=0)
42
42
  notification_daily: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
43
43
  notification_weekly: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
44
44
  notification_monthly: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
45
- totp: Mapped[str] = mapped_column(String(255))
46
- hotp_counter: Mapped[int] = mapped_column(Integer)
47
- last_pw_change: Mapped[int] = mapped_column(BigInteger)
45
+ totp: Mapped[str | None] = mapped_column(String(255), nullable=True)
46
+ hotp_counter: Mapped[int | None] = mapped_column(Integer, nullable=True)
47
+ last_pw_change: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
48
48
 
49
49
  # Relationships
50
50
  org = relationship("Organisation", back_populates="users", lazy="raise_on_sql")
@@ -1,6 +1,11 @@
1
+ import importlib.metadata
1
2
  from typing import TYPE_CHECKING
2
3
 
3
- if TYPE_CHECKING:
4
+ from packaging.version import Version
5
+
6
+ sa_version = Version(importlib.metadata.version("sqlalchemy"))
7
+
8
+ if TYPE_CHECKING or sa_version >= Version("2.0"):
4
9
  from sqlalchemy.orm import Mapped, mapped_column # type:ignore[attr-defined]
5
10
  else:
6
11
  from sqlalchemy import Column
@@ -0,0 +1,34 @@
1
+ import json
2
+ from typing import Any, Self
3
+
4
+ from sqlalchemy.engine import Dialect
5
+ from sqlalchemy.types import Text, TypeDecorator
6
+
7
+
8
+ class DBObjectJson(TypeDecorator):
9
+ impl = Text
10
+
11
+ def load_dialect_impl(self: Self, dialect: Dialect) -> Any:
12
+ return dialect.type_descriptor(Text)
13
+
14
+ def process_bind_param(self: Self, value: Any, dialect: Dialect) -> str | None:
15
+ """Handle value before getting into the DB"""
16
+ if value is None:
17
+ return None
18
+ if not isinstance(value, dict):
19
+ raise ValueError(f"this type should only be used for dicts, got {type(value)}")
20
+ return json.dumps(value)
21
+
22
+ def process_result_value(self: Self, value: Any, dialect: Dialect) -> dict | None:
23
+ """Handle values from the database"""
24
+ if value is None:
25
+ return None
26
+
27
+ res = json.loads(value)
28
+ print("Result is", res)
29
+ if res == []:
30
+ res = {}
31
+ if not isinstance(res, dict):
32
+ raise ValueError(f"this type should only be used for dicts got: {type(res)}")
33
+
34
+ return res