mmisp-lib 0.7.1__tar.gz → 0.7.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 (161) hide show
  1. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/PKG-INFO +1 -1
  2. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/pyproject.toml +1 -1
  3. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/api_schemas/galaxy_clusters.py +21 -1
  4. mmisp_lib-0.7.3/src/mmisp/db/mixins.py +62 -0
  5. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/db/models/galaxy_cluster.py +24 -4
  6. mmisp_lib-0.7.3/src/mmisp/db/uuid_type.py +19 -0
  7. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/lib/galaxies.py +3 -1
  8. mmisp_lib-0.7.3/src/mmisp/lib/galaxy_clusters.py +29 -0
  9. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/tests/fixtures.py +4 -4
  10. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp_lib.egg-info/PKG-INFO +1 -1
  11. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp_lib.egg-info/SOURCES.txt +2 -0
  12. mmisp_lib-0.7.1/src/mmisp/db/mixins.py +0 -18
  13. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/LICENSE +0 -0
  14. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/README.md +0 -0
  15. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/setup.cfg +0 -0
  16. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/api_schemas/__init__.py +0 -0
  17. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/api_schemas/attributes.py +0 -0
  18. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/api_schemas/auth_keys.py +0 -0
  19. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/api_schemas/authentication.py +0 -0
  20. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/api_schemas/common.py +0 -0
  21. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/api_schemas/events.py +0 -0
  22. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/api_schemas/feeds.py +0 -0
  23. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/api_schemas/galaxies.py +0 -0
  24. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/api_schemas/galaxy_common.py +0 -0
  25. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/api_schemas/jobs.py +0 -0
  26. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/api_schemas/logs.py +0 -0
  27. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/api_schemas/noticelists.py +0 -0
  28. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/api_schemas/objects.py +0 -0
  29. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/api_schemas/organisations.py +0 -0
  30. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/api_schemas/py.typed +0 -0
  31. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/api_schemas/responses/__init__.py +0 -0
  32. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/api_schemas/responses/check_graph_response.py +0 -0
  33. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/api_schemas/responses/standard_status_response.py +0 -0
  34. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/api_schemas/roles.py +0 -0
  35. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/api_schemas/server.py +0 -0
  36. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/api_schemas/servers.py +0 -0
  37. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/api_schemas/shadow_attribute.py +0 -0
  38. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/api_schemas/sharing_groups.py +0 -0
  39. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/api_schemas/sightings.py +0 -0
  40. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/api_schemas/statistics.py +0 -0
  41. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/api_schemas/tags.py +0 -0
  42. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/api_schemas/taxonomies.py +0 -0
  43. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/api_schemas/user_settings.py +0 -0
  44. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/api_schemas/users.py +0 -0
  45. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/api_schemas/warninglists.py +0 -0
  46. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/api_schemas/workflows.py +0 -0
  47. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/commandline_tool/__init__.py +0 -0
  48. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/commandline_tool/main.py +0 -0
  49. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/commandline_tool/organisation.py +0 -0
  50. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/commandline_tool/py.typed +0 -0
  51. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/commandline_tool/setup.py +0 -0
  52. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/commandline_tool/user.py +0 -0
  53. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/db/__init__.py +0 -0
  54. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/db/additional_properties.py +0 -0
  55. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/db/all_models.py +0 -0
  56. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/db/config.py +0 -0
  57. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/db/database.py +0 -0
  58. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/db/models/__init__.py +0 -0
  59. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/db/models/admin_setting.py +0 -0
  60. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/db/models/attribute.py +0 -0
  61. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/db/models/auth_key.py +0 -0
  62. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/db/models/blocklist.py +0 -0
  63. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/db/models/correlation.py +0 -0
  64. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/db/models/event.py +0 -0
  65. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/db/models/feed.py +0 -0
  66. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/db/models/galaxy.py +0 -0
  67. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/db/models/identity_provider.py +0 -0
  68. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/db/models/log.py +0 -0
  69. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/db/models/noticelist.py +0 -0
  70. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/db/models/object.py +0 -0
  71. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/db/models/organisation.py +0 -0
  72. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/db/models/post.py +0 -0
  73. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/db/models/role.py +0 -0
  74. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/db/models/server.py +0 -0
  75. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/db/models/shadow_attribute.py +0 -0
  76. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/db/models/sharing_group.py +0 -0
  77. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/db/models/sighting.py +0 -0
  78. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/db/models/tag.py +0 -0
  79. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/db/models/taxonomy.py +0 -0
  80. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/db/models/threat_level.py +0 -0
  81. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/db/models/user.py +0 -0
  82. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/db/models/user_setting.py +0 -0
  83. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/db/models/warninglist.py +0 -0
  84. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/db/models/workflow.py +0 -0
  85. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/db/models/workflow_blueprint.py +0 -0
  86. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/db/mypy.py +0 -0
  87. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/db/print_changes.py +0 -0
  88. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/db/py.typed +0 -0
  89. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/lib/__init__.py +0 -0
  90. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/lib/actions.py +0 -0
  91. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/lib/attribute_search_filter.py +0 -0
  92. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/lib/attributes.py +0 -0
  93. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/lib/distribution.py +0 -0
  94. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/lib/fallbacks.py +0 -0
  95. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/lib/logger.py +0 -0
  96. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/lib/logging.py +0 -0
  97. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/lib/permissions.py +0 -0
  98. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/lib/py.typed +0 -0
  99. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/lib/serialisation_helper.py +0 -0
  100. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/lib/uuid.py +0 -0
  101. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/plugins/__init__.py +0 -0
  102. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/plugins/enrichment/__init__.py +0 -0
  103. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/plugins/enrichment/data.py +0 -0
  104. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/plugins/enrichment/enrichment_plugin.py +0 -0
  105. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/plugins/exceptions.py +0 -0
  106. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/plugins/models/__init__.py +0 -0
  107. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/plugins/models/attribute.py +0 -0
  108. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/plugins/plugin_info.py +0 -0
  109. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/plugins/plugin_type.py +0 -0
  110. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/plugins/py.typed +0 -0
  111. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/tests/__init__.py +0 -0
  112. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/tests/compatibility_helpers.py +0 -0
  113. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/tests/generators/attribute_generator.py +0 -0
  114. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/tests/generators/feed_generator.py +0 -0
  115. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/tests/generators/model_generators/attribute_generator.py +0 -0
  116. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/tests/generators/model_generators/auth_key_generator.py +0 -0
  117. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/tests/generators/model_generators/correlation_exclusions_generator.py +0 -0
  118. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/tests/generators/model_generators/correlation_value_generator.py +0 -0
  119. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/tests/generators/model_generators/default_correlation_generator.py +0 -0
  120. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/tests/generators/model_generators/event_generator.py +0 -0
  121. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/tests/generators/model_generators/galaxy_generator.py +0 -0
  122. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/tests/generators/model_generators/identity_provider_generator.py +0 -0
  123. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/tests/generators/model_generators/noticelist_generator.py +0 -0
  124. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/tests/generators/model_generators/object_generator.py +0 -0
  125. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/tests/generators/model_generators/organisation_generator.py +0 -0
  126. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/tests/generators/model_generators/over_correlating_value_generator.py +0 -0
  127. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/tests/generators/model_generators/post_generator.py +0 -0
  128. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/tests/generators/model_generators/role_generator.py +0 -0
  129. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/tests/generators/model_generators/server_generator.py +0 -0
  130. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/tests/generators/model_generators/shadow_attribute_generator.py +0 -0
  131. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/tests/generators/model_generators/sharing_group_generator.py +0 -0
  132. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/tests/generators/model_generators/sighting_generator.py +0 -0
  133. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/tests/generators/model_generators/tag_generator.py +0 -0
  134. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/tests/generators/model_generators/taxonomy_generator.py +0 -0
  135. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/tests/generators/model_generators/user_generator.py +0 -0
  136. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/tests/generators/model_generators/user_setting_generator.py +0 -0
  137. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/tests/generators/model_generators/warninglist_generator.py +0 -0
  138. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/tests/generators/model_generators/workflow_generator.py +0 -0
  139. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/tests/generators/object_generator.py +0 -0
  140. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/tests/generators/sighting_generator.py +0 -0
  141. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/tests/generators/tag_generator.py +0 -0
  142. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/tests/generators/taxonomies_generator.py +0 -0
  143. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/util/__init__.py +0 -0
  144. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/util/crypto.py +0 -0
  145. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/util/models.py +0 -0
  146. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/util/partial.py +0 -0
  147. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/util/py.typed +0 -0
  148. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/util/uuid.py +0 -0
  149. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/workflows/__init__.py +0 -0
  150. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/workflows/execution.py +0 -0
  151. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/workflows/fastapi.py +0 -0
  152. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/workflows/graph.py +0 -0
  153. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/workflows/input.py +0 -0
  154. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/workflows/legacy.py +0 -0
  155. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/workflows/misp_core_format.py +0 -0
  156. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/workflows/modules.py +0 -0
  157. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp/workflows/py.typed +0 -0
  158. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp_lib.egg-info/dependency_links.txt +0 -0
  159. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp_lib.egg-info/requires.txt +0 -0
  160. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/src/mmisp_lib.egg-info/top_level.txt +0 -0
  161. {mmisp_lib-0.7.1 → mmisp_lib-0.7.3}/tests/test_commandline_tool.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mmisp-lib
3
- Version: 0.7.1
3
+ Version: 0.7.3
4
4
  Requires-Python: >=3.11.0
5
5
  Description-Content-Type: text/markdown
6
6
  License-File: LICENSE
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "mmisp-lib"
3
- version = "0.7.1"
3
+ version = "0.7.3"
4
4
  description = ""
5
5
  authors = []
6
6
  readme = "README.md"
@@ -1,4 +1,5 @@
1
1
  from datetime import datetime
2
+ from uuid import UUID
2
3
 
3
4
  from pydantic import BaseModel
4
5
 
@@ -17,7 +18,7 @@ class ExportGalaxyGalaxyElement(BaseModel):
17
18
 
18
19
  class GetGalaxyClusterResponse(BaseModel):
19
20
  id: int | None = None
20
- uuid: str | None = None
21
+ uuid: UUID | None = None
21
22
  collection_uuid: str
22
23
  type: str
23
24
  value: str
@@ -86,6 +87,12 @@ class AddGalaxyElement(BaseModel):
86
87
  value: str
87
88
 
88
89
 
90
+ class AddUpdateGalaxyElement(BaseModel):
91
+ id: int | None = None
92
+ key: str
93
+ value: str
94
+
95
+
89
96
  class AddGalaxyClusterRequest(BaseModel):
90
97
  value: str
91
98
  description: str
@@ -95,5 +102,18 @@ class AddGalaxyClusterRequest(BaseModel):
95
102
  GalaxyElement: list[AddGalaxyElement]
96
103
 
97
104
 
105
+ class PutGalaxyClusterRequest(BaseModel):
106
+ id: int
107
+ value: str
108
+ description: str
109
+ source: str
110
+ type: str
111
+ uuid: UUID
112
+ version: int
113
+ authors: list[str]
114
+ distribution: DistributionLevels
115
+ GalaxyElement: list[AddUpdateGalaxyElement]
116
+
117
+
98
118
  class AddGalaxyClusterResponse(BaseModel):
99
119
  pass
@@ -0,0 +1,62 @@
1
+ from typing import Self
2
+
3
+ from sqlalchemy import inspect
4
+ from sqlalchemy.ext.hybrid import hybrid_property
5
+
6
+
7
+ class DictMixin:
8
+ def asdict(self: Self, omit: set[str] | None = None) -> dict:
9
+ if omit is None:
10
+ omit = set()
11
+
12
+ unloaded = inspect(self).unloaded
13
+ d = {}
14
+ for key in self.__mapper__.c.keys(): # type:ignore[attr-defined]
15
+ if key in omit:
16
+ continue
17
+ if not key.startswith("_") and key not in unloaded:
18
+ d[key] = getattr(self, key)
19
+
20
+ for key, prop in inspect(self.__class__).all_orm_descriptors.items(): # type:ignore[union-attr]
21
+ if key in omit:
22
+ continue
23
+ if isinstance(prop, hybrid_property):
24
+ d[key] = getattr(self, key)
25
+ return d
26
+
27
+
28
+ class UpdateMixin:
29
+ def patch(self: Self, **kwargs) -> None:
30
+ """
31
+ Update model fields with provided keyword arguments.
32
+ Do not alter attributes not in kwargs
33
+
34
+ Args:
35
+ **kwargs: Key-value pairs to update the model fields.
36
+ """
37
+ for key, value in kwargs.items():
38
+ if hasattr(self, key):
39
+ setattr(self, key, value)
40
+
41
+ def put(self: Self, **kwargs) -> None:
42
+ """
43
+ Update all model fields with provided keyword arguments or set them to none.
44
+
45
+ Args:
46
+ **kwargs: Key-value pairs to update the model fields.
47
+ """
48
+ for key in self.__mapper__.c.keys(): # type:ignore[attr-defined]
49
+ if key.startswith("_"):
50
+ continue
51
+ if key in kwargs:
52
+ setattr(self, key, kwargs[key])
53
+ else:
54
+ setattr(self, key, None)
55
+
56
+ for key, prop in inspect(self.__class__).all_orm_descriptors.items(): # type:ignore[union-attr]
57
+ if not isinstance(prop, hybrid_property):
58
+ continue
59
+ if key in kwargs:
60
+ setattr(self, key, kwargs[key])
61
+ else:
62
+ setattr(self, key, None)
@@ -1,18 +1,24 @@
1
+ import json
2
+ from typing import Self
3
+
1
4
  from sqlalchemy import Boolean, ForeignKey, Integer, String, Text
5
+ from sqlalchemy.ext.hybrid import hybrid_property
2
6
  from sqlalchemy.orm import relationship
3
7
 
8
+ from mmisp.db.mixins import DictMixin, UpdateMixin
4
9
  from mmisp.db.mypy import Mapped, mapped_column
10
+ from mmisp.db.uuid_type import DBUUID
5
11
  from mmisp.lib.uuid import uuid
6
12
 
7
13
  from ..database import Base
8
14
  from .galaxy import Galaxy
9
15
 
10
16
 
11
- class GalaxyCluster(Base):
17
+ class GalaxyCluster(Base, UpdateMixin, DictMixin):
12
18
  __tablename__ = "galaxy_clusters"
13
19
 
14
20
  id: Mapped[int] = mapped_column(Integer, primary_key=True, nullable=False)
15
- uuid: Mapped[str] = mapped_column(String(255), unique=True, default=uuid, index=True)
21
+ uuid: Mapped[str] = mapped_column(DBUUID, unique=True, default=uuid, index=True)
16
22
  collection_uuid: Mapped[str] = mapped_column(String(255), nullable=False, index=True, default="")
17
23
  type: Mapped[str] = mapped_column(String(255), nullable=False, index=True)
18
24
  value: Mapped[str] = mapped_column(Text, nullable=False)
@@ -22,7 +28,7 @@ class GalaxyCluster(Base):
22
28
  Integer, ForeignKey(Galaxy.id, ondelete="CASCADE"), nullable=False, index=True
23
29
  )
24
30
  source: Mapped[str] = mapped_column(String(255), nullable=False, default="")
25
- authors: Mapped[str] = mapped_column(Text, nullable=False)
31
+ _authors: Mapped[str] = mapped_column("authors", Text, nullable=False)
26
32
  version: Mapped[int] = mapped_column(Integer, default=0, index=True)
27
33
  distribution: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
28
34
  sharing_group_id: Mapped[int] = mapped_column(Integer, index=True, nullable=True, default=None)
@@ -69,8 +75,22 @@ class GalaxyCluster(Base):
69
75
  uselist=False,
70
76
  ) # type:ignore[assignment,var-annotated]
71
77
 
78
+ def __init__(self: Self, *arg, **kwargs) -> None:
79
+ if "authors" in kwargs:
80
+ self._authors = json.dumps(kwargs["authors"])
81
+ del kwargs["authors"]
82
+ super().__init__(*arg, **kwargs)
83
+
84
+ @hybrid_property
85
+ def authors(self: Self) -> list[str]:
86
+ return json.loads(self._authors)
87
+
88
+ @authors.setter # type: ignore[no-redef]
89
+ def authors(self: Self, value: list[str]) -> None:
90
+ self._authors = json.dumps(value)
91
+
72
92
 
73
- class GalaxyElement(Base):
93
+ class GalaxyElement(Base, DictMixin, UpdateMixin):
74
94
  __tablename__ = "galaxy_elements"
75
95
 
76
96
  id: Mapped[int] = mapped_column(Integer, primary_key=True, nullable=False)
@@ -0,0 +1,19 @@
1
+ from typing import Any, Self
2
+
3
+ from sqlalchemy.engine import Dialect
4
+ from sqlalchemy.types import String, TypeDecorator
5
+
6
+
7
+ class DBUUID(TypeDecorator):
8
+ impl = String
9
+
10
+ def load_dialect_impl(self: Self, dialect: Dialect) -> Any:
11
+ return dialect.type_descriptor(String(36))
12
+
13
+ def process_bind_param(self: Self, value: Any, dialect: Dialect) -> str | None:
14
+ if value is None:
15
+ return None
16
+ return str(value)
17
+
18
+ def process_result_value(self: Self, value: Any, dialect: Dialect) -> str:
19
+ return value
@@ -8,7 +8,9 @@ def json_or_original_string(s: str) -> str | dict | list:
8
8
  return s
9
9
 
10
10
 
11
- def parse_galaxy_authors(str_authors: str) -> list[str]:
11
+ def parse_galaxy_authors(str_authors: str | list) -> list[str]:
12
+ if isinstance(str_authors, list):
13
+ return str_authors
12
14
  parsed_author = json_or_original_string(str_authors)
13
15
  if isinstance(parsed_author, str):
14
16
  parsed_author = [parsed_author] # force to be a list
@@ -0,0 +1,29 @@
1
+ from sqlalchemy.ext.asyncio import AsyncSession
2
+
3
+ from mmisp.api_schemas.galaxy_clusters import AddUpdateGalaxyElement
4
+ from mmisp.db.models.galaxy_cluster import GalaxyCluster, GalaxyElement
5
+
6
+
7
+ async def update_galaxy_cluster_elements(
8
+ db: AsyncSession, galaxy_cluster: GalaxyCluster, new: list[AddUpdateGalaxyElement]
9
+ ) -> None:
10
+ """Update the relationship of GalaxyCluster to GalaxyElements as defined by new_dict"""
11
+ old = [ge.asdict(omit={"galaxy_cluster_id"}) for ge in galaxy_cluster.galaxy_elements]
12
+
13
+ maybe_updated_dict = {item.id: item.dict() for item in new if item.id is not None}
14
+ added_dict = [item for item in new if item.id is None]
15
+ new_ids = {item.id for item in new if item.id is not None}
16
+ old_ids = {item["id"] for item in old if "id" in item}
17
+
18
+ to_delete = old_ids - new_ids
19
+ if new_ids - old_ids != set():
20
+ raise ValueError("new_ids are not a subset of old_ids")
21
+
22
+ for ge in galaxy_cluster.galaxy_elements:
23
+ if ge.id in to_delete:
24
+ await db.delete(ge)
25
+ else:
26
+ ge.patch(**maybe_updated_dict[ge.id])
27
+
28
+ for ge_dict in added_dict:
29
+ db.add(GalaxyElement(galaxy_cluster_id=galaxy_cluster.id, **ge_dict.dict(exclude_none=True)))
@@ -580,7 +580,7 @@ async def test_default_galaxy(db, galaxy_default_cluster_one_uuid, galaxy_defaul
580
580
  description="test",
581
581
  galaxy_id=galaxy.id,
582
582
  source="me",
583
- authors='["Konstantin Zangerle", "Test Writer"]',
583
+ authors=["Konstantin Zangerle", "Test Writer"],
584
584
  version=1,
585
585
  distribution=3,
586
586
  sharing_group_id=None,
@@ -602,7 +602,7 @@ async def test_default_galaxy(db, galaxy_default_cluster_one_uuid, galaxy_defaul
602
602
  description="test",
603
603
  galaxy_id=galaxy.id,
604
604
  source="me",
605
- authors='["Konstantin Zangerle", "Test Writer"]',
605
+ authors=["Konstantin Zangerle", "Test Writer"],
606
606
  version=1,
607
607
  distribution=3,
608
608
  sharing_group_id=None,
@@ -692,7 +692,7 @@ async def test_galaxy(db, instance_owner_org, galaxy_cluster_one_uuid, galaxy_cl
692
692
  description="test",
693
693
  galaxy_id=galaxy.id,
694
694
  source="me",
695
- authors='["Konstantin Zangerle", "Test Writer"]',
695
+ authors=["Konstantin Zangerle", "Test Writer"],
696
696
  version=1,
697
697
  distribution=3,
698
698
  sharing_group_id=None,
@@ -714,7 +714,7 @@ async def test_galaxy(db, instance_owner_org, galaxy_cluster_one_uuid, galaxy_cl
714
714
  description="test",
715
715
  galaxy_id=galaxy.id,
716
716
  source="me",
717
- authors='["Konstantin Zangerle", "Test Writer"]',
717
+ authors=["Konstantin Zangerle", "Test Writer"],
718
718
  version=1,
719
719
  distribution=3,
720
720
  sharing_group_id=None,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mmisp-lib
3
- Version: 0.7.1
3
+ Version: 0.7.3
4
4
  Requires-Python: >=3.11.0
5
5
  Description-Content-Type: text/markdown
6
6
  License-File: LICENSE
@@ -48,6 +48,7 @@ src/mmisp/db/mixins.py
48
48
  src/mmisp/db/mypy.py
49
49
  src/mmisp/db/print_changes.py
50
50
  src/mmisp/db/py.typed
51
+ src/mmisp/db/uuid_type.py
51
52
  src/mmisp/db/models/__init__.py
52
53
  src/mmisp/db/models/admin_setting.py
53
54
  src/mmisp/db/models/attribute.py
@@ -84,6 +85,7 @@ src/mmisp/lib/attributes.py
84
85
  src/mmisp/lib/distribution.py
85
86
  src/mmisp/lib/fallbacks.py
86
87
  src/mmisp/lib/galaxies.py
88
+ src/mmisp/lib/galaxy_clusters.py
87
89
  src/mmisp/lib/logger.py
88
90
  src/mmisp/lib/logging.py
89
91
  src/mmisp/lib/permissions.py
@@ -1,18 +0,0 @@
1
- from typing import Self
2
-
3
- from sqlalchemy import inspect
4
- from sqlalchemy.ext.hybrid import hybrid_property
5
-
6
-
7
- class DictMixin:
8
- def asdict(self: Self) -> dict:
9
- unloaded = inspect(self).unloaded
10
- d = {}
11
- for key in self.__mapper__.c.keys(): # type:ignore[attr-defined]
12
- if not key.startswith("_") and key not in unloaded:
13
- d[key] = getattr(self, key)
14
-
15
- for key, prop in inspect(self.__class__).all_orm_descriptors.items(): # type:ignore[union-attr]
16
- if isinstance(prop, hybrid_property):
17
- d[key] = getattr(self, key)
18
- return d
File without changes
File without changes
File without changes