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