howler-api 4.0.0.dev657__tar.gz → 4.0.0.dev664__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.
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/PKG-INFO +1 -1
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/api/v2/case.py +15 -13
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/services/case_service.py +44 -18
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/pyproject.toml +1 -1
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/README.md +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/__init__.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/actions/__init__.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/actions/add_label.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/actions/change_field.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/actions/demote.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/actions/example_plugin.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/actions/prioritization.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/actions/promote.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/actions/remove_label.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/actions/transition.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/api/__init__.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/api/base.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/api/socket.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/api/v1/__init__.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/api/v1/action.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/api/v1/analytic.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/api/v1/auth.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/api/v1/clue.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/api/v1/configs.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/api/v1/dossier.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/api/v1/help.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/api/v1/hit.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/api/v1/notebook.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/api/v1/overview.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/api/v1/search.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/api/v1/template.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/api/v1/tool.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/api/v1/user.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/api/v1/utils/__init__.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/api/v1/utils/etag.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/api/v1/view.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/api/v2/__init__.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/api/v2/ingest.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/api/v2/search.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/app.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/common/README.md +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/common/__init__.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/common/classification.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/common/classification.yml +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/common/exceptions.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/common/loader.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/common/logging/__init__.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/common/logging/audit.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/common/logging/format.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/common/net.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/common/net_static.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/common/random_user.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/common/swagger.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/config.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/cronjobs/__init__.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/cronjobs/retention.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/cronjobs/view_cleanup.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/datastore/README.md +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/datastore/__init__.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/datastore/bulk.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/datastore/collection.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/datastore/constants.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/datastore/exceptions.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/datastore/howler_store.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/datastore/migrations/fix_process.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/datastore/operations.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/datastore/schemas.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/datastore/store.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/datastore/support/__init__.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/datastore/support/build.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/datastore/support/schemas.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/datastore/types.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/error.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/external/__init__.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/external/generate_mitre.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/external/generate_sigma_rules.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/external/generate_tlds.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/external/reindex_data.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/external/wipe_databases.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/gunicorn_config.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/healthz.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/helper/__init__.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/helper/azure.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/helper/discover.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/helper/hit.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/helper/oauth.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/helper/search.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/helper/workflow.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/helper/ws.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/README.md +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/__init__.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/base.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/charter.txt +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/constants.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/helper.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/howler_enum.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/__init__.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/action.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/analytic.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/assemblyline.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/aws.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/azure.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/case.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/cbs.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/clue.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/config.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/dossier.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/__init__.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/agent.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/autonomous_system.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/client.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/cloud.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/code_signature.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/container.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/dns.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/egress.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/elf.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/email.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/error.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/event.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/faas.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/file.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/geo.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/group.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/hash.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/host.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/http.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/ingress.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/interface.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/network.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/observer.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/organization.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/os.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/pe.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/process.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/registry.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/related.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/rule.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/server.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/threat.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/tls.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/url.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/user.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/user_agent.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/vulnerability.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/gcp.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/hit.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/howler_data.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/lead.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/localized_label.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/observable.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/overview.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/pivot.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/record.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/template.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/user.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/view.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/random_data.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/randomizer.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/patched.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/plugins/__init__.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/plugins/config.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/remote/__init__.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/remote/datatypes/README.md +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/remote/datatypes/__init__.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/remote/datatypes/counters.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/remote/datatypes/events.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/remote/datatypes/hash.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/remote/datatypes/lock.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/remote/datatypes/queues/__init__.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/remote/datatypes/queues/comms.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/remote/datatypes/queues/multi.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/remote/datatypes/queues/named.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/remote/datatypes/queues/priority.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/remote/datatypes/set.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/remote/datatypes/user_quota_tracker.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/security/__init__.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/security/socket.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/security/utils.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/services/__init__.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/services/action_service.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/services/analytic_service.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/services/auth_service.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/services/config_service.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/services/docs_service.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/services/dossier_service.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/services/event_service.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/services/hit_service.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/services/jwt_service.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/services/lucene_service.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/services/notebook_service.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/services/observable_service.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/services/overview_service.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/services/search_service.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/services/template_service.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/services/user_service.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/utils/__init__.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/utils/annotations.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/utils/chunk.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/utils/compat.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/utils/dict_utils.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/utils/isotime.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/utils/list_utils.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/utils/lucene.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/utils/path.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/utils/socket_utils.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/utils/str_utils.py +0 -0
- {howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/utils/uid.py +0 -0
|
@@ -246,42 +246,44 @@ def append_item(id: str, user: User, **kwargs): # noqa: C901
|
|
|
246
246
|
|
|
247
247
|
|
|
248
248
|
@generate_swagger_docs()
|
|
249
|
-
@case_api.route("/<
|
|
249
|
+
@case_api.route("/<case_id>/items", methods=["DELETE"])
|
|
250
250
|
@api_login(required_priv=["R", "W"])
|
|
251
|
-
def delete_item(
|
|
252
|
-
"""Delete
|
|
251
|
+
def delete_item(case_id: str, **kwargs):
|
|
252
|
+
"""Delete one or more items from a case
|
|
253
253
|
|
|
254
|
-
This endpoint removes
|
|
254
|
+
This endpoint removes items from a case's items list. If an item is a hit or
|
|
255
255
|
observable, the bidirectional relationship is cleaned up - the case reference will
|
|
256
256
|
be removed from the backing object's related.cases list.
|
|
257
257
|
|
|
258
258
|
Variables:
|
|
259
|
-
|
|
259
|
+
case_id => The id of the case to modify
|
|
260
260
|
|
|
261
261
|
Arguments:
|
|
262
262
|
None
|
|
263
263
|
|
|
264
264
|
Data Block:
|
|
265
265
|
{
|
|
266
|
-
"
|
|
266
|
+
"values": ["item-id-123", "item-id-456"] # The values of the items to delete
|
|
267
267
|
}
|
|
268
268
|
|
|
269
269
|
Result Example:
|
|
270
270
|
{
|
|
271
|
-
|
|
271
|
+
...case # The updated case data
|
|
272
272
|
}
|
|
273
273
|
"""
|
|
274
274
|
body = request.json
|
|
275
275
|
|
|
276
|
-
if not body or not isinstance(body, dict) or "
|
|
277
|
-
return bad_request(err="Request body must be a JSON object with a '
|
|
276
|
+
if not body or not isinstance(body, dict) or "values" not in body:
|
|
277
|
+
return bad_request(err="Request body must be a JSON object with a 'values' field.")
|
|
278
|
+
|
|
279
|
+
values = body["values"]
|
|
280
|
+
if not isinstance(values, list) or not values:
|
|
281
|
+
return bad_request(err="'values' must be a non-empty list.")
|
|
278
282
|
|
|
279
283
|
try:
|
|
280
|
-
case_service.
|
|
284
|
+
return ok(case_service.remove_case_items(case_id, values))
|
|
281
285
|
except DataStoreException as e:
|
|
282
286
|
logger.exception("Save Error")
|
|
283
287
|
return internal_error(err=str(e))
|
|
284
|
-
except InvalidDataException as e:
|
|
288
|
+
except (InvalidDataException, NotFoundException) as e:
|
|
285
289
|
return bad_request(err=str(e))
|
|
286
|
-
|
|
287
|
-
return ok()
|
|
@@ -320,8 +320,14 @@ def append_hit(case_id: str, item: CaseItem) -> Case:
|
|
|
320
320
|
|
|
321
321
|
hit = ds.hit.get(item.value)
|
|
322
322
|
|
|
323
|
+
if hit is None:
|
|
324
|
+
raise NotFoundException(f"Hit {item.value} not found, cannot be added to case")
|
|
325
|
+
|
|
323
326
|
_case.items.append(item)
|
|
324
327
|
|
|
328
|
+
if not ds.case.save(_case.case_id, _case):
|
|
329
|
+
raise DataStoreException(f"Failed to save {_case.case_id} with new item {item.value}")
|
|
330
|
+
|
|
325
331
|
_add_backreference(hit, _case.case_id)
|
|
326
332
|
|
|
327
333
|
_sync_case_metadata(_case.case_id)
|
|
@@ -362,7 +368,7 @@ def append_observable(case_id: str, item: CaseItem) -> Case:
|
|
|
362
368
|
|
|
363
369
|
_case.items.append(item)
|
|
364
370
|
|
|
365
|
-
if not
|
|
371
|
+
if not ds.case.save(_case.case_id, _case):
|
|
366
372
|
raise DataStoreException(f"Failed to save {_case.case_id} with new item {item.value}")
|
|
367
373
|
|
|
368
374
|
_add_backreference(observable, _case.case_id)
|
|
@@ -585,20 +591,26 @@ def remove_backreference(backing_obj: Hit | Observable | None, case_id: str):
|
|
|
585
591
|
datastore()[backing_obj.__class__.__name__.lower()].save(backing_obj.howler.id, backing_obj)
|
|
586
592
|
|
|
587
593
|
|
|
588
|
-
def
|
|
589
|
-
"""Remove
|
|
594
|
+
def remove_case_items(case_id: str, values: list[str]):
|
|
595
|
+
"""Remove one or more items from a case in a single atomic operation.
|
|
590
596
|
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
the
|
|
597
|
+
Validates that every requested value exists within the case before making
|
|
598
|
+
any modifications. If any value is missing the call raises NotFoundException
|
|
599
|
+
without altering the case. When all values are confirmed, all matching
|
|
600
|
+
items are removed in memory, the case is persisted once, and back-references
|
|
601
|
+
are cleaned up from any associated hits or observables.
|
|
594
602
|
|
|
595
603
|
Args:
|
|
596
|
-
case_id: Unique identifier of the case to remove
|
|
597
|
-
|
|
604
|
+
case_id: Unique identifier of the case to remove items from.
|
|
605
|
+
item_values: List of item values (IDs / URLs) to remove.
|
|
606
|
+
|
|
607
|
+
Returns:
|
|
608
|
+
The updated Case object.
|
|
598
609
|
|
|
599
610
|
Raises:
|
|
600
|
-
NotFoundException: If the case does not exist
|
|
601
|
-
|
|
611
|
+
NotFoundException: If the case does not exist, or if any requested value
|
|
612
|
+
is not present in the case's items list.
|
|
613
|
+
DataStoreException: If persisting the updated case fails.
|
|
602
614
|
"""
|
|
603
615
|
ds = datastore()
|
|
604
616
|
|
|
@@ -607,20 +619,34 @@ def remove_case_item(case_id: str, item_value: str):
|
|
|
607
619
|
if not _case:
|
|
608
620
|
raise NotFoundException(f"Case {case_id} does not exist")
|
|
609
621
|
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
raise NotFoundException(f"Case item {item_value} does not exist")
|
|
622
|
+
# Build a lookup of value → item for all items currently in the case.
|
|
623
|
+
items_by_value = {_item["value"]: _item for _item in _case.items}
|
|
613
624
|
|
|
614
|
-
|
|
615
|
-
if
|
|
616
|
-
|
|
625
|
+
# Pre-validate all requested values before touching anything.
|
|
626
|
+
missing = [v for v in values if v not in items_by_value]
|
|
627
|
+
if missing:
|
|
628
|
+
raise NotFoundException(f"Case item(s) not found in case: {', '.join(missing)}")
|
|
617
629
|
|
|
618
|
-
|
|
630
|
+
# Resolve items and collect backing objects that need back-reference cleanup.
|
|
631
|
+
items_to_remove = [items_by_value[v] for v in values]
|
|
632
|
+
backing_objs: list[Hit | Observable] = []
|
|
633
|
+
for item in items_to_remove:
|
|
634
|
+
if item.type in [CaseItemTypes.HIT, CaseItemTypes.OBSERVABLE]:
|
|
635
|
+
obj = ds[item.type].get(item.value)
|
|
636
|
+
if obj:
|
|
637
|
+
backing_objs.append(obj)
|
|
638
|
+
|
|
639
|
+
# Remove all items in memory, then persist the case once.
|
|
640
|
+
for item in items_to_remove:
|
|
641
|
+
_case.items.remove(item)
|
|
619
642
|
|
|
620
643
|
if not ds.case.save(_case.case_id, _case):
|
|
621
644
|
raise DataStoreException("Failed to save case after item removal")
|
|
622
645
|
|
|
623
|
-
|
|
646
|
+
# Clean up back-references after the case is safely persisted.
|
|
647
|
+
for backing_obj in backing_objs:
|
|
624
648
|
remove_backreference(backing_obj, _case.case_id)
|
|
625
649
|
|
|
626
650
|
_sync_case_metadata(case_id)
|
|
651
|
+
|
|
652
|
+
return _case
|
|
@@ -152,7 +152,7 @@ suppress-none-returning = true
|
|
|
152
152
|
[tool.poetry]
|
|
153
153
|
package-mode = true
|
|
154
154
|
name = "howler-api"
|
|
155
|
-
version = "4.0.0.
|
|
155
|
+
version = "4.0.0.dev664"
|
|
156
156
|
description = "Howler - API server"
|
|
157
157
|
authors = [
|
|
158
158
|
"Canadian Centre for Cyber Security <howler@cyber.gc.ca>",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/datastore/migrations/fix_process.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/odm/models/ecs/autonomous_system.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/remote/datatypes/queues/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/remote/datatypes/queues/priority.py
RENAMED
|
File without changes
|
|
File without changes
|
{howler_api-4.0.0.dev657 → howler_api-4.0.0.dev664}/howler/remote/datatypes/user_quota_tracker.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|