mmisp-lib 0.9.0__tar.gz → 0.10.0__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 (185) hide show
  1. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/PKG-INFO +9 -6
  2. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/pyproject.toml +10 -6
  3. mmisp_lib-0.10.0/src/mmisp/api_schemas/attribute_common.py +48 -0
  4. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/api_schemas/attributes.py +134 -137
  5. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/api_schemas/auth_keys.py +43 -37
  6. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/api_schemas/authentication.py +2 -4
  7. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/api_schemas/common.py +19 -5
  8. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/api_schemas/events.py +143 -263
  9. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/api_schemas/feeds.py +29 -34
  10. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/api_schemas/galaxies.py +48 -81
  11. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/api_schemas/galaxy_clusters.py +52 -36
  12. mmisp_lib-0.10.0/src/mmisp/api_schemas/galaxy_common.py +73 -0
  13. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/api_schemas/jobs.py +46 -52
  14. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/api_schemas/noticelists.py +8 -12
  15. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/api_schemas/object_templates.py +37 -22
  16. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/api_schemas/objects.py +40 -30
  17. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/api_schemas/organisations.py +24 -30
  18. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/api_schemas/roles.py +34 -56
  19. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/api_schemas/servers.py +4 -4
  20. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/api_schemas/shadow_attribute.py +1 -1
  21. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/api_schemas/sharing_groups.py +26 -21
  22. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/api_schemas/sightings.py +12 -15
  23. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/api_schemas/tags.py +8 -18
  24. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/api_schemas/taxonomies.py +42 -16
  25. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/api_schemas/user_settings.py +7 -5
  26. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/api_schemas/users.py +40 -37
  27. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/api_schemas/warninglists.py +12 -30
  28. mmisp_lib-0.10.0/src/mmisp/api_schemas/worker.py +41 -0
  29. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/api_schemas/workflows.py +1 -1
  30. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/commandline_tool/organisation.py +15 -15
  31. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/commandline_tool/setup.py +5 -0
  32. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/db/config.py +10 -8
  33. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/db/database.py +28 -3
  34. mmisp_lib-0.10.0/src/mmisp/db/list_json_type.py +7 -0
  35. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/db/mixins.py +6 -4
  36. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/db/models/admin_setting.py +1 -2
  37. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/db/models/attribute.py +13 -12
  38. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/db/models/auth_key.py +7 -4
  39. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/db/models/event.py +10 -11
  40. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/db/models/feed.py +13 -10
  41. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/db/models/galaxy.py +10 -11
  42. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/db/models/galaxy_cluster.py +59 -15
  43. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/db/models/object.py +9 -10
  44. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/db/models/organisation.py +7 -8
  45. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/db/models/role.py +2 -6
  46. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/db/models/server.py +1 -1
  47. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/db/models/sharing_group.py +4 -4
  48. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/db/models/tag.py +2 -1
  49. mmisp_lib-0.10.0/src/mmisp/db/models/tasks.py +23 -0
  50. mmisp_lib-0.10.0/src/mmisp/db/models/taxonomy.py +61 -0
  51. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/db/models/threat_level.py +1 -2
  52. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/db/models/user.py +16 -16
  53. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/db/models/user_setting.py +3 -1
  54. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/db/models/workflow.py +2 -1
  55. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/db/mypy.py +3 -1
  56. mmisp_lib-0.10.0/src/mmisp/db/object_json_type.py +7 -0
  57. mmisp_lib-0.10.0/src/mmisp/db/types.py +94 -0
  58. mmisp_lib-0.10.0/src/mmisp/db/uuid_type.py +7 -0
  59. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/lib/attribute_search_filter.py +2 -2
  60. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/lib/distribution.py +7 -0
  61. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/lib/galaxy_clusters.py +2 -2
  62. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/lib/logger.py +97 -0
  63. mmisp_lib-0.10.0/src/mmisp/lib/settings.py +41 -0
  64. mmisp_lib-0.10.0/src/mmisp/lib/standard_threat_levels.py +26 -0
  65. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/plugins/enrichment/data.py +5 -6
  66. mmisp_lib-0.10.0/src/mmisp/plugins/exceptions.py +100 -0
  67. mmisp_lib-0.10.0/src/mmisp/plugins/factory.py +110 -0
  68. mmisp_lib-0.10.0/src/mmisp/plugins/loader.py +108 -0
  69. mmisp_lib-0.10.0/src/mmisp/plugins/protocols.py +66 -0
  70. mmisp_lib-0.10.0/src/mmisp/plugins/types.py +35 -0
  71. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/tests/compatibility_helpers.py +2 -0
  72. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/tests/fixtures.py +46 -23
  73. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/tests/generators/attribute_generator.py +8 -8
  74. mmisp_lib-0.10.0/src/mmisp/tests/generators/feed_generator.py +66 -0
  75. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/tests/generators/model_generators/post_generator.py +4 -2
  76. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/tests/generators/model_generators/shadow_attribute_generator.py +2 -2
  77. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/tests/generators/object_generator.py +14 -13
  78. mmisp_lib-0.10.0/src/mmisp/util/async_download.py +34 -0
  79. mmisp_lib-0.10.0/src/mmisp/util/github.py +97 -0
  80. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp_lib.egg-info/PKG-INFO +9 -6
  81. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp_lib.egg-info/SOURCES.txt +12 -5
  82. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp_lib.egg-info/requires.txt +8 -5
  83. mmisp_lib-0.9.0/src/mmisp/api_schemas/galaxy_common.py +0 -25
  84. mmisp_lib-0.9.0/src/mmisp/db/list_json_type.py +0 -31
  85. mmisp_lib-0.9.0/src/mmisp/db/models/taxonomy.py +0 -45
  86. mmisp_lib-0.9.0/src/mmisp/db/object_json_type.py +0 -34
  87. mmisp_lib-0.9.0/src/mmisp/db/uuid_type.py +0 -19
  88. mmisp_lib-0.9.0/src/mmisp/plugins/enrichment/enrichment_plugin.py +0 -41
  89. mmisp_lib-0.9.0/src/mmisp/plugins/exceptions.py +0 -18
  90. mmisp_lib-0.9.0/src/mmisp/plugins/plugin_info.py +0 -26
  91. mmisp_lib-0.9.0/src/mmisp/plugins/plugin_type.py +0 -12
  92. mmisp_lib-0.9.0/src/mmisp/tests/generators/feed_generator.py +0 -82
  93. mmisp_lib-0.9.0/src/mmisp/tests/generators/model_generators/event_generator.py +0 -19
  94. mmisp_lib-0.9.0/src/mmisp/util/models.py +0 -14
  95. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/LICENSE +0 -0
  96. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/README.md +0 -0
  97. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/setup.cfg +0 -0
  98. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/api_schemas/__init__.py +0 -0
  99. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/api_schemas/logs.py +0 -0
  100. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/api_schemas/py.typed +0 -0
  101. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/api_schemas/responses/__init__.py +0 -0
  102. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/api_schemas/responses/check_graph_response.py +0 -0
  103. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/api_schemas/responses/standard_status_response.py +0 -0
  104. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/api_schemas/server.py +0 -0
  105. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/api_schemas/statistics.py +0 -0
  106. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/commandline_tool/__init__.py +0 -0
  107. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/commandline_tool/main.py +0 -0
  108. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/commandline_tool/py.typed +0 -0
  109. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/commandline_tool/user.py +0 -0
  110. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/db/__init__.py +0 -0
  111. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/db/additional_properties.py +0 -0
  112. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/db/all_models.py +0 -0
  113. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/db/lib.py +0 -0
  114. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/db/models/__init__.py +0 -0
  115. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/db/models/blocklist.py +0 -0
  116. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/db/models/correlation.py +0 -0
  117. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/db/models/identity_provider.py +0 -0
  118. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/db/models/log.py +0 -0
  119. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/db/models/noticelist.py +0 -0
  120. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/db/models/post.py +0 -0
  121. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/db/models/shadow_attribute.py +0 -0
  122. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/db/models/sighting.py +0 -0
  123. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/db/models/warninglist.py +0 -0
  124. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/db/models/workflow_blueprint.py +0 -0
  125. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/db/print_changes.py +0 -0
  126. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/db/py.typed +0 -0
  127. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/lib/__init__.py +0 -0
  128. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/lib/actions.py +0 -0
  129. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/lib/attributes.py +0 -0
  130. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/lib/fallbacks.py +0 -0
  131. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/lib/galaxies.py +0 -0
  132. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/lib/permissions.py +0 -0
  133. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/lib/py.typed +0 -0
  134. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/lib/serialisation_helper.py +0 -0
  135. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/lib/standard_roles.py +0 -0
  136. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/lib/uuid.py +0 -0
  137. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/plugins/__init__.py +0 -0
  138. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/plugins/enrichment/__init__.py +0 -0
  139. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/plugins/models/__init__.py +0 -0
  140. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/plugins/models/attribute.py +0 -0
  141. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/plugins/py.typed +0 -0
  142. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/tests/__init__.py +0 -0
  143. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/tests/generators/model_generators/attribute_generator.py +0 -0
  144. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/tests/generators/model_generators/auth_key_generator.py +0 -0
  145. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/tests/generators/model_generators/correlation_exclusions_generator.py +0 -0
  146. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/tests/generators/model_generators/correlation_value_generator.py +0 -0
  147. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/tests/generators/model_generators/default_correlation_generator.py +0 -0
  148. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/tests/generators/model_generators/galaxy_generator.py +0 -0
  149. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/tests/generators/model_generators/identity_provider_generator.py +0 -0
  150. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/tests/generators/model_generators/noticelist_generator.py +0 -0
  151. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/tests/generators/model_generators/object_generator.py +0 -0
  152. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/tests/generators/model_generators/organisation_generator.py +0 -0
  153. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/tests/generators/model_generators/over_correlating_value_generator.py +0 -0
  154. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/tests/generators/model_generators/role_generator.py +0 -0
  155. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/tests/generators/model_generators/server_generator.py +0 -0
  156. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/tests/generators/model_generators/sharing_group_generator.py +0 -0
  157. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/tests/generators/model_generators/sighting_generator.py +0 -0
  158. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/tests/generators/model_generators/tag_generator.py +0 -0
  159. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/tests/generators/model_generators/taxonomy_generator.py +0 -0
  160. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/tests/generators/model_generators/user_generator.py +0 -0
  161. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/tests/generators/model_generators/user_setting_generator.py +0 -0
  162. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/tests/generators/model_generators/warninglist_generator.py +0 -0
  163. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/tests/generators/model_generators/workflow_generator.py +0 -0
  164. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/tests/generators/sighting_generator.py +0 -0
  165. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/tests/generators/tag_generator.py +0 -0
  166. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/tests/generators/taxonomies_generator.py +0 -0
  167. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/tests/maps.py +0 -0
  168. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/util/__init__.py +0 -0
  169. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/util/crypto.py +0 -0
  170. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/util/partial.py +0 -0
  171. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/util/py.typed +0 -0
  172. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/util/uuid.py +0 -0
  173. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/workflows/__init__.py +0 -0
  174. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/workflows/execution.py +0 -0
  175. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/workflows/fastapi.py +0 -0
  176. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/workflows/graph.py +0 -0
  177. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/workflows/input.py +0 -0
  178. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/workflows/legacy.py +0 -0
  179. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/workflows/misp_core_format.py +0 -0
  180. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/workflows/modules.py +0 -0
  181. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp/workflows/py.typed +0 -0
  182. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp_lib.egg-info/dependency_links.txt +0 -0
  183. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp_lib.egg-info/entry_points.txt +0 -0
  184. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/src/mmisp_lib.egg-info/top_level.txt +0 -0
  185. {mmisp_lib-0.9.0 → mmisp_lib-0.10.0}/tests/test_commandline_tool.py +0 -0
@@ -1,12 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mmisp-lib
3
- Version: 0.9.0
3
+ Version: 0.10.0
4
4
  Requires-Python: >=3.11.0
5
5
  Description-Content-Type: text/markdown
6
6
  License-File: LICENSE
7
7
  Requires-Dist: fastapi>=0.104.1
8
- Requires-Dist: SQLAlchemy[asyncio]~=1.4.46
9
- Requires-Dist: pydantic==1.10.13
8
+ Requires-Dist: SQLAlchemy[asyncio]~=2.0.0
9
+ Requires-Dist: pydantic==2.11.3
10
+ Requires-Dist: pydantic-settings==2.9.1
10
11
  Requires-Dist: uvicorn==0.24.0.post1
11
12
  Requires-Dist: python-dotenv==1.0.0
12
13
  Requires-Dist: alembic==1.8.1
@@ -22,13 +23,15 @@ Requires-Dist: cryptography==42.0.5
22
23
  Requires-Dist: jinja2~=3.1.4
23
24
  Requires-Dist: fire
24
25
  Requires-Dist: packaging
26
+ Requires-Dist: PyGithub
27
+ Requires-Dist: aiohttp
28
+ Requires-Dist: aiodns
25
29
  Provides-Extra: dev
26
30
  Requires-Dist: ruff>=0.3.7; extra == "dev"
27
31
  Requires-Dist: mypy==1.8.0; extra == "dev"
28
32
  Requires-Dist: pre-commit==3.6.0; extra == "dev"
29
- Requires-Dist: pytest==8.0.0; extra == "dev"
30
- Requires-Dist: pytest-test-groups; extra == "dev"
31
- Requires-Dist: pytest-asyncio==0.21.2; extra == "dev"
33
+ Requires-Dist: pytest==8.3.5; extra == "dev"
34
+ Requires-Dist: pytest-asyncio==0.26.0; extra == "dev"
32
35
  Requires-Dist: pytest-cov==4.1.0; extra == "dev"
33
36
  Requires-Dist: respx==0.20.2; extra == "dev"
34
37
  Requires-Dist: mysql-connector-python==8.3.0; extra == "dev"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "mmisp-lib"
3
- version = "0.9.0"
3
+ version = "0.10.0"
4
4
  description = ""
5
5
  authors = []
6
6
  readme = "README.md"
@@ -9,8 +9,9 @@ requires-python = ">=3.11.0"
9
9
 
10
10
  dependencies = [
11
11
  "fastapi>=0.104.1",
12
- "SQLAlchemy[asyncio]~=1.4.46",
13
- "pydantic==1.10.13",
12
+ "SQLAlchemy[asyncio]~=2.0.0",
13
+ "pydantic==2.11.3",
14
+ "pydantic-settings==2.9.1",
14
15
  "uvicorn==0.24.0.post1",
15
16
  "python-dotenv==1.0.0",
16
17
  "alembic==1.8.1",
@@ -26,6 +27,9 @@ dependencies = [
26
27
  "jinja2~=3.1.4",
27
28
  "fire",
28
29
  "packaging",
30
+ "PyGithub",
31
+ "aiohttp",
32
+ "aiodns",
29
33
  ]
30
34
 
31
35
 
@@ -34,9 +38,9 @@ dev = [
34
38
  "ruff>=0.3.7",
35
39
  "mypy==1.8.0",
36
40
  "pre-commit==3.6.0",
37
- "pytest==8.0.0",
38
- "pytest-test-groups",
39
- "pytest-asyncio==0.21.2",
41
+ "pytest==8.3.5",
42
+ # "pytest-test-groups",
43
+ "pytest-asyncio==0.26.0",
40
44
  "pytest-cov==4.1.0",
41
45
  "respx==0.20.2",
42
46
  "mysql-connector-python==8.3.0",
@@ -0,0 +1,48 @@
1
+ from datetime import datetime
2
+ from typing import Any, Self, Type
3
+ from uuid import UUID
4
+
5
+ from pydantic import BaseModel, field_serializer, field_validator
6
+
7
+ from mmisp.lib.attributes import (
8
+ AttributeCategories,
9
+ literal_valid_attribute_types,
10
+ )
11
+ from mmisp.lib.distribution import AttributeDistributionLevels
12
+
13
+
14
+ class CommonAttribute(BaseModel):
15
+ id: int
16
+ event_id: int
17
+ object_id: int
18
+ object_relation: str | None = None
19
+ category: AttributeCategories
20
+ type: literal_valid_attribute_types # type:ignore[valid-type]
21
+ value: str
22
+ to_ids: bool
23
+ uuid: UUID
24
+ timestamp: datetime
25
+ distribution: AttributeDistributionLevels
26
+ sharing_group_id: int
27
+ comment: str | None = None
28
+ deleted: bool = False
29
+ disable_correlation: bool = False
30
+ first_seen: datetime | None = None
31
+ last_seen: datetime | None = None
32
+
33
+ @field_serializer("timestamp")
34
+ def serialize_timestamp(self: Self, timestamp: datetime, _: Any) -> int:
35
+ return int(timestamp.timestamp())
36
+
37
+ @field_serializer("first_seen", "last_seen")
38
+ def serialize_timestamp_none(self: Self, timestamp: datetime, _: Any) -> int | None:
39
+ if timestamp is None:
40
+ return None
41
+ return int(timestamp.timestamp())
42
+
43
+ @field_validator("first_seen", mode="before")
44
+ @classmethod
45
+ def empty_string_to_none(cls: Type[Self], value: Any) -> Any:
46
+ if value == "":
47
+ return None
48
+ return value
@@ -1,7 +1,9 @@
1
- from typing import Annotated, Any, Optional, Type
1
+ from datetime import datetime
2
+ from typing import Annotated, Any, Optional, Self, Type
2
3
 
3
- from pydantic import BaseModel, Field, root_validator
4
+ from pydantic import BaseModel, ConfigDict, Field, field_serializer, field_validator, model_validator
4
5
 
6
+ from mmisp.api_schemas.attribute_common import CommonAttribute
5
7
  from mmisp.lib.attributes import (
6
8
  AttributeCategories,
7
9
  default_category,
@@ -10,7 +12,7 @@ from mmisp.lib.attributes import (
10
12
  mapper_val_safe_clsname,
11
13
  to_ids,
12
14
  )
13
- from mmisp.lib.distribution import AttributeDistributionLevels
15
+ from mmisp.lib.distribution import AttributeDistributionLevels, EventDistributionLevels
14
16
 
15
17
 
16
18
  class GetAttributeTag(BaseModel):
@@ -24,18 +26,22 @@ class GetAttributeTag(BaseModel):
24
26
 
25
27
  class SearchAttributesObject(BaseModel):
26
28
  id: int
27
- distribution: str
29
+ distribution: AttributeDistributionLevels
28
30
  sharing_group_id: int
29
31
 
30
32
 
31
33
  class SearchAttributesEvent(BaseModel):
32
34
  id: int
33
35
  org_id: int
34
- distribution: str
36
+ distribution: EventDistributionLevels
35
37
  info: str
36
38
  orgc_id: int
37
39
  uuid: str
38
- publish_timestamp: int
40
+ publish_timestamp: datetime
41
+
42
+ @field_serializer("publish_timestamp")
43
+ def serialize_timestamp(self: Self, timestamp: datetime, _: Any) -> int:
44
+ return int(timestamp.timestamp())
39
45
 
40
46
 
41
47
  class SearchAttributesAttributesDetails(BaseModel):
@@ -43,25 +49,36 @@ class SearchAttributesAttributesDetails(BaseModel):
43
49
  event_id: int | None = None
44
50
  object_id: int | None = None
45
51
  object_relation: str | None = None
46
- category: str
52
+ category: AttributeCategories
47
53
  type: str
48
54
  value: str
49
55
  to_ids: bool
50
56
  uuid: str
51
- timestamp: str
57
+ timestamp: datetime
52
58
  distribution: AttributeDistributionLevels
53
59
  sharing_group_id: int | None = None
54
60
  comment: str | None = None
55
61
  deleted: bool
56
62
  disable_correlation: bool
57
- first_seen: str | None = None
58
- last_seen: str | None = None
63
+ first_seen: datetime | None = None
64
+ last_seen: datetime | None = None
59
65
  event_uuid: str | None = None
60
66
  data: str | None = None
61
67
  Event: SearchAttributesEvent | None = None
62
68
  Object: SearchAttributesObject | None = None
63
69
  Tag: list[GetAttributeTag] | None = None
64
70
 
71
+ @field_serializer("timestamp")
72
+ def serialize_timestamp(self: Self, timestamp: datetime, _: Any) -> int:
73
+ return int(timestamp.timestamp())
74
+
75
+ @field_validator("first_seen", mode="before")
76
+ @classmethod
77
+ def empty_string_to_none(cls: Type[Self], value: Any) -> Any:
78
+ if value == "":
79
+ return None
80
+ return value
81
+
65
82
 
66
83
  class SearchAttributesAttributes(BaseModel):
67
84
  Attribute: list[SearchAttributesAttributesDetails]
@@ -95,39 +112,38 @@ class RestSearchFilter(BaseModel):
95
112
  value1: str | None = None
96
113
  value2: str | None = None
97
114
  type: str | None = None
98
- category: str | None = None
115
+ category: AttributeCategories | None = None
99
116
  org: str | None = None
100
117
  tags: list[str] | None = None
101
118
  from_: str | None = None
102
- to: str | None = None
119
+ to: datetime | None = None
103
120
  last: int | None = None
104
- eventid: str | None = None
121
+ eventid: int | None = None
105
122
  published: bool | None = None
106
123
  to_ids: bool | None = None
107
124
  deleted: bool | None = None
108
125
 
109
126
 
110
127
  class SearchAttributesBody(RestSearchFilter):
111
- class Config:
112
- allow_population_by_field_name = True
128
+ model_config = ConfigDict(populate_by_name=True)
113
129
 
114
130
  returnFormat: str = "json"
115
131
  page: int | None = None
116
132
  limit: int | None = None
117
133
  with_attachments: Annotated[bool | None, Field(alias="withAttachments")] = None
118
134
  uuid: str | None = None
119
- publish_timestamp: str | None = None
120
- timestamp: str | None = None
121
- attribute_timestamp: str | None = None
122
- enforce_warninglist: Annotated[bool | None, Field(alias="enforceWarninglist")]
123
- event_timestamp: str | None = None
135
+ publish_timestamp: datetime | None = None
136
+ timestamp: datetime | None = None
137
+ attribute_timestamp: datetime | None = None
138
+ enforce_warninglist: Annotated[bool | None, Field(alias="enforceWarninglist")] = None
139
+ event_timestamp: datetime | None = None
124
140
  threat_level_id: int | None = None
125
141
  eventinfo: str | None = None
126
142
  sharinggroup: list[str] | None = None
127
143
  decaying_model: Annotated[str | None, Field(alias="decayingModel")] = None
128
144
  score: str | None = None
129
- first_seen: str | None = None
130
- last_seen: str | None = None
145
+ first_seen: datetime | None = None
146
+ last_seen: datetime | None = None
131
147
  include_event_uuid: bool | None = Field(alias="includeEventUuid", default=None)
132
148
  include_event_tags: Annotated[bool | None, Field(alias="includeEventTags")] = None
133
149
  include_proposals: Annotated[bool | None, Field(alias="includeProposals")] = None
@@ -144,6 +160,19 @@ class SearchAttributesBody(RestSearchFilter):
144
160
  include_full_model: Annotated[bool | None, Field(alias="includeFullModel")] = None
145
161
  exclude_decayed: Annotated[bool | None, Field(alias="excludeDecayed")] = None
146
162
 
163
+ @field_serializer("timestamp", "publish_timestamp")
164
+ def serialize_timestamp(self: Self, timestamp: datetime | None, _: Any) -> int | None:
165
+ if timestamp is None:
166
+ return None
167
+ return int(timestamp.timestamp())
168
+
169
+ @field_validator("first_seen", mode="before")
170
+ @classmethod
171
+ def empty_string_to_none(cls: Type[Self], value: Any) -> Any:
172
+ if value == "":
173
+ return None
174
+ return value
175
+
147
176
 
148
177
  class RestoreAttributeResponse(BaseModel):
149
178
  id: int
@@ -155,18 +184,27 @@ class RestoreAttributeResponse(BaseModel):
155
184
  value: str
156
185
  to_ids: bool
157
186
  uuid: str
158
- timestamp: str
187
+ timestamp: datetime
159
188
  distribution: AttributeDistributionLevels
160
189
  sharing_group_id: int
161
190
  comment: str
162
191
  deleted: bool
163
192
  disable_correlation: bool
164
- first_seen: str
165
- last_seen: str
193
+ first_seen: datetime | None
194
+ last_seen: datetime | None
166
195
  event_uuid: str # new
196
+ model_config = ConfigDict(from_attributes=True)
197
+
198
+ @field_serializer("timestamp")
199
+ def serialize_timestamp(self: Self, timestamp: datetime, _: Any) -> int:
200
+ return int(timestamp.timestamp())
167
201
 
168
- class Config:
169
- orm_mode = True
202
+ @field_validator("first_seen", mode="before")
203
+ @classmethod
204
+ def empty_string_to_none(cls: Type[Self], value: Any) -> Any:
205
+ if value == "":
206
+ return None
207
+ return value
170
208
 
171
209
 
172
210
  class GetDescribeTypesAttributes(BaseModel):
@@ -190,24 +228,7 @@ class GetDescribeTypesResponse(BaseModel):
190
228
  result: GetDescribeTypesAttributes
191
229
 
192
230
 
193
- class GetAttributeAttributes(BaseModel):
194
- id: int
195
- event_id: int
196
- object_id: int
197
- object_relation: Optional[str] = Field(..., nullable=True)
198
- category: str
199
- type: str
200
- value: str
201
- to_ids: bool
202
- uuid: str
203
- timestamp: str
204
- distribution: AttributeDistributionLevels
205
- sharing_group_id: int
206
- comment: str | None = None
207
- deleted: bool = False
208
- disable_correlation: bool = False
209
- first_seen: Optional[str] = Field(..., nullable=True)
210
- last_seen: Optional[str] = Field(..., nullable=True)
231
+ class GetAttributeAttributes(CommonAttribute):
211
232
  event_uuid: str
212
233
  data: str | None = None
213
234
  Tag: list[GetAttributeTag] | None = None
@@ -215,47 +236,13 @@ class GetAttributeAttributes(BaseModel):
215
236
 
216
237
  class GetAttributeResponse(BaseModel):
217
238
  Attribute: GetAttributeAttributes
218
-
219
- class Config:
220
- orm_mode = True
239
+ model_config = ConfigDict(from_attributes=True)
221
240
 
222
241
 
223
- class GetAllAttributesResponse(BaseModel):
224
- id: int
225
- event_id: int | None = None
226
- object_id: int | None = None
227
- object_relation: str | None = None
228
- category: str | None = None
229
- type: str
242
+ class GetAllAttributesResponse(CommonAttribute):
230
243
  value1: str | None = None
231
244
  value2: str | None = None
232
- to_ids: bool | None = None
233
- uuid: str | None = None
234
- timestamp: str | None = None
235
- distribution: AttributeDistributionLevels | None = None
236
- sharing_group_id: int | None = None
237
- comment: str | None = None
238
- deleted: bool | None = None
239
- disable_correlation: bool | None = None
240
- first_seen: str | None = None
241
- last_seen: str | None = None
242
- value: str | None = None
243
-
244
- # @validator("sharing_group_id", always=True, allow_reuse=True)
245
- # @classmethod
246
- # def check_sharing_group_id(
247
- # cls: Type["GetAllAttributesResponse"], value: Any, values: Dict[str, Any]
248
- # ) -> Optional[int]: # noqa: ANN101
249
- # """
250
- # If distribution equals 4, sharing_group_id will be shown.
251
- # """
252
- # distribution = values.get("distribution", None)
253
- # if distribution == "4" and value is not None:
254
- # return value
255
- # return None
256
-
257
- class Config:
258
- orm_mode = True
245
+ model_config = ConfigDict(from_attributes=True)
259
246
 
260
247
 
261
248
  class EditAttributeTag(BaseModel):
@@ -281,22 +268,31 @@ class EditAttributeAttributes(BaseModel):
281
268
  value: str
282
269
  to_ids: bool
283
270
  uuid: str
284
- timestamp: str
271
+ timestamp: datetime
285
272
  distribution: AttributeDistributionLevels
286
273
  sharing_group_id: int
287
274
  comment: str | None = None
288
275
  deleted: bool
289
276
  disable_correlation: bool
290
- first_seen: str | None = None
291
- last_seen: str | None = None
277
+ first_seen: datetime | None = None
278
+ last_seen: datetime | None = None
292
279
  Tag: list[EditAttributeTag]
293
280
 
281
+ @field_serializer("timestamp")
282
+ def serialize_timestamp(self: Self, timestamp: datetime, _: Any) -> int:
283
+ return int(timestamp.timestamp())
284
+
285
+ @field_validator("first_seen", mode="before")
286
+ @classmethod
287
+ def empty_string_to_none(cls: Type[Self], value: Any) -> Any:
288
+ if value == "":
289
+ return None
290
+ return value
291
+
294
292
 
295
293
  class EditAttributeResponse(BaseModel):
296
294
  Attribute: EditAttributeAttributes
297
-
298
- class Config:
299
- orm_mode = True
295
+ model_config = ConfigDict(from_attributes=True)
300
296
 
301
297
 
302
298
  class EditAttributeBody(BaseModel):
@@ -309,17 +305,28 @@ class EditAttributeBody(BaseModel):
309
305
  category: str | None = None
310
306
  to_ids: bool | None = None
311
307
  uuid: str | None = None
312
- timestamp: str | None = None
308
+ timestamp: datetime | None = None
313
309
  distribution: AttributeDistributionLevels | None = None
314
310
  sharing_group_id: int | None = None
315
311
  comment: str | None = None
316
312
  deleted: bool | None = None
317
313
  disable_correlation: bool | None = None
318
- first_seen: str | None = None
319
- last_seen: str | None = None
314
+ first_seen: datetime | None = None
315
+ last_seen: datetime | None = None
316
+ model_config = ConfigDict(from_attributes=True)
317
+
318
+ @field_serializer("timestamp")
319
+ def serialize_timestamp(self: Self, timestamp: datetime | None, _: Any) -> int | None:
320
+ if timestamp is None:
321
+ return None
322
+ return int(timestamp.timestamp())
320
323
 
321
- class Config:
322
- orm_mode = True
324
+ @field_validator("first_seen", mode="before")
325
+ @classmethod
326
+ def empty_string_to_none(cls: Type[Self], value: Any) -> Any:
327
+ if value == "":
328
+ return None
329
+ return value
323
330
 
324
331
 
325
332
  class DeleteSelectedAttributeResponse(BaseModel):
@@ -329,56 +336,31 @@ class DeleteSelectedAttributeResponse(BaseModel):
329
336
  message: str
330
337
  url: str
331
338
  id: str
332
-
333
- class Config:
334
- orm_mode = True
339
+ model_config = ConfigDict(from_attributes=True)
335
340
 
336
341
 
337
342
  class DeleteAttributeResponse(BaseModel):
338
343
  message: str
339
-
340
- class Config:
341
- orm_mode = True
344
+ model_config = ConfigDict(from_attributes=True)
342
345
 
343
346
 
344
347
  class AddRemoveTagAttributeResponse(BaseModel):
345
348
  saved: bool
346
- success: Optional[str]
347
- check_publish: Optional[bool]
348
- errors: Optional[str]
349
-
350
- class Config:
351
- orm_mode = True
349
+ success: Optional[str] = None
350
+ check_publish: Optional[bool] = None
351
+ errors: Optional[str] = None
352
+ model_config = ConfigDict(from_attributes=True)
352
353
 
353
354
 
354
- class AddAttributeAttributes(BaseModel):
355
- id: int
356
- event_id: int
357
- object_id: int
358
- object_relation: Optional[str] = Field(..., nullable=True)
359
- category: str
360
- type: str
361
- value: str
355
+ class AddAttributeAttributes(CommonAttribute):
362
356
  value1: str
363
357
  value2: str
364
- to_ids: bool
365
- uuid: str
366
- timestamp: str
367
- distribution: AttributeDistributionLevels
368
- sharing_group_id: int
369
- comment: str | None = None
370
- deleted: bool
371
- disable_correlation: bool
372
- first_seen: str | None = None
373
- last_seen: str | None = None
374
358
  attribute_tag: list[str] | None = Field(default_factory=list, alias="AttributeTag")
375
359
 
376
360
 
377
361
  class AddAttributeResponse(BaseModel):
378
362
  Attribute: AddAttributeAttributes
379
-
380
- class Config:
381
- orm_mode = True
363
+ model_config = ConfigDict(from_attributes=True)
382
364
 
383
365
 
384
366
  class AddAttributeBody(BaseModel):
@@ -392,32 +374,47 @@ class AddAttributeBody(BaseModel):
392
374
  category: str | None = None
393
375
  to_ids: bool | None = None
394
376
  uuid: str | None = None
395
- timestamp: str | None = None
377
+ timestamp: datetime | None = None
396
378
  distribution: AttributeDistributionLevels | None = None
397
379
  sharing_group_id: int | None = None
398
380
  comment: str | None = None
399
381
  deleted: bool | None = None
400
382
  disable_correlation: bool | None = None
401
- first_seen: str | None = None
402
- last_seen: str | None = None
383
+ first_seen: datetime | None = None
384
+ last_seen: datetime | None = None
403
385
 
404
- @root_validator(allow_reuse=True)
405
- @classmethod
406
- def ensure_value_or_value1_is_set(cls: Type["AddAttributeBody"], data: dict[str, Any]) -> Optional[dict[str, Any]]: # noqa: ANN101
407
- required_values: list[str] = [str(data.get("value")), str(data.get("value1"))]
408
- if all(item is None for item in required_values):
386
+ @model_validator(mode="after")
387
+ def ensure_value_or_value1_is_set(self: Self) -> Self:
388
+ if self.value is None and self.value1 is None:
409
389
  raise ValueError("value or value1 has to be set")
410
- return data
390
+ return self
391
+
392
+ @field_serializer("timestamp")
393
+ def serialize_timestamp(self: Self, timestamp: datetime | None, _: Any) -> int | None:
394
+ if timestamp is None:
395
+ return None
396
+ return int(timestamp.timestamp())
397
+
398
+ @field_validator("first_seen", mode="before")
399
+ @classmethod
400
+ def empty_string_to_none(cls: Type[Self], value: Any) -> Any:
401
+ if value == "":
402
+ return None
403
+ return value
411
404
 
412
405
 
413
406
  GetAttributeStatisticsTypesResponseAttrs = {x: Field(default=None) for x in mapper_val_safe_clsname.keys()}
414
- GetAttributeStatisticsTypesResponseAttrs["__annotations__"] = {x: str | None for x in mapper_val_safe_clsname.keys()}
407
+ GetAttributeStatisticsTypesResponseAttrs["__annotations__"] = {
408
+ x: str | int | None for x in mapper_val_safe_clsname.keys()
409
+ }
415
410
  GetAttributeStatisticsTypesResponse = type( # type: ignore
416
411
  "GetAttributeStatisticsTypesResponse", (BaseModel,), GetAttributeStatisticsTypesResponseAttrs
417
412
  )
418
413
 
419
414
  GetAttributeStatisticsCategoriesResponseAttrs = {x.value: Field(default=None) for x in AttributeCategories}
420
- GetAttributeStatisticsCategoriesResponseAttrs["__annotations__"] = {x.value: str | None for x in AttributeCategories}
415
+ GetAttributeStatisticsCategoriesResponseAttrs["__annotations__"] = {
416
+ x.value: str | int | None for x in AttributeCategories
417
+ }
421
418
  GetAttributeStatisticsCategoriesResponse = type( # type: ignore
422
419
  "GetAttributeStatisticsCategoriesResponse", (BaseModel,), GetAttributeStatisticsCategoriesResponseAttrs
423
420
  )