howler-api 4.1.0.dev1626__tar.gz → 4.1.0.dev1635__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.1.0.dev1626 → howler_api-4.1.0.dev1635}/PKG-INFO +2 -1
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/api/v1/hit.py +3 -2
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/cronjobs/retention.py +27 -5
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/event.py +1 -21
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/howler_data.py +1 -29
- howler_api-4.1.0.dev1635/howler/odm/models/log.py +31 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/services/case_service.py +30 -4
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/services/hit_service.py +5 -4
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/pyproject.toml +1 -1
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/README.md +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/__init__.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/actions/__init__.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/actions/add_label.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/actions/add_to_bundle.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/actions/add_to_case.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/actions/change_field.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/actions/demote.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/actions/example_plugin.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/actions/prioritization.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/actions/promote.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/actions/remove_from_bundle.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/actions/remove_label.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/actions/transition.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/api/__init__.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/api/base.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/api/socket.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/api/v1/__init__.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/api/v1/action.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/api/v1/analytic.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/api/v1/auth.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/api/v1/clue.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/api/v1/configs.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/api/v1/dossier.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/api/v1/help.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/api/v1/notebook.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/api/v1/overview.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/api/v1/search.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/api/v1/template.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/api/v1/tool.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/api/v1/user.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/api/v1/utils/__init__.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/api/v1/utils/etag.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/api/v1/utils/params.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/api/v1/utils/permission_helper.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/api/v1/view.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/api/v2/__init__.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/api/v2/case.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/api/v2/fuzzy.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/api/v2/ingest.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/api/v2/search.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/app.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/common/README.md +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/common/__init__.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/common/classification.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/common/classification.yml +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/common/exceptions.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/common/loader.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/common/logging/__init__.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/common/logging/audit.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/common/logging/format.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/common/net.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/common/net_static.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/common/random_user.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/common/swagger.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/config.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/cronjobs/__init__.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/cronjobs/action_queue_worker.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/cronjobs/correlation.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/cronjobs/view_cleanup.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/datastore/README.md +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/datastore/__init__.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/datastore/bulk.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/datastore/collection.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/datastore/constants.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/datastore/exceptions.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/datastore/howler_store.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/datastore/migrations/__init__.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/datastore/migrations/action_owner.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/datastore/migrations/base.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/datastore/migrations/fix_process.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/datastore/migrations/runner.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/datastore/operations.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/datastore/schemas.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/datastore/store.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/datastore/support/__init__.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/datastore/support/build.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/datastore/support/schemas.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/datastore/types.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/datastore/utils.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/error.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/external/README.md +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/external/__init__.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/external/check_duplicates.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/external/generate_mitre.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/external/generate_sigma_rules.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/external/generate_tlds.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/external/reindex_data.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/external/run_migrations.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/external/wipe_databases.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/gunicorn_config.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/healthz.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/helper/__init__.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/helper/azure.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/helper/discover.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/helper/hit.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/helper/oauth.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/helper/search.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/helper/workflow.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/helper/ws.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/README.md +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/__init__.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/base.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/charter.txt +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/constants.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/helper.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/howler_enum.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/mixins.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/__init__.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/action.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/analytic.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/assemblyline.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/aws.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/azure.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/case.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/cbs.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/clue.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/config.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/dossier.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ecs/__init__.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ecs/agent.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ecs/autonomous_system.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ecs/client.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ecs/cloud.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ecs/code_signature.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ecs/container.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ecs/dns.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ecs/egress.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ecs/elf.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ecs/email.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ecs/error.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ecs/event.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ecs/faas.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ecs/file.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ecs/geo.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ecs/group.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ecs/hash.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ecs/host.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ecs/http.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ecs/ingress.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ecs/interface.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ecs/network.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ecs/observer.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ecs/organization.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ecs/os.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ecs/pe.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ecs/process.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ecs/registry.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ecs/related.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ecs/rule.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ecs/server.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ecs/threat.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ecs/tls.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ecs/url.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ecs/user.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ecs/user_agent.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ecs/vulnerability.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/gcp.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/hit.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/lead.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/localized_label.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/migration.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/overview.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/ownership.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/permission_request.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/pivot.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/record.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/template.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/user.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/models/view.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/random_data.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/odm/randomizer.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/patched.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/plugins/__init__.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/plugins/config.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/remote/__init__.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/remote/datatypes/README.md +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/remote/datatypes/__init__.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/remote/datatypes/counters.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/remote/datatypes/events.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/remote/datatypes/hash.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/remote/datatypes/lock.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/remote/datatypes/queues/__init__.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/remote/datatypes/queues/comms.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/remote/datatypes/queues/multi.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/remote/datatypes/queues/named.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/remote/datatypes/queues/priority.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/remote/datatypes/set.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/remote/datatypes/user_quota_tracker.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/security/__init__.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/security/login.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/security/socket.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/security/utils.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/services/__init__.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/services/action_service.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/services/analytic_service.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/services/auth_service.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/services/bundle_compat_service.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/services/comms_service.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/services/config_service.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/services/correlation_service.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/services/docs_service.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/services/dossier_service.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/services/event_service.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/services/fuzzy_service.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/services/jwt_service.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/services/lucene_service.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/services/notebook_service.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/services/overview_service.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/services/permission_service.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/services/search_service.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/services/template_service.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/services/user_service.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/services/viewer_service.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/telemetry.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/utils/__init__.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/utils/annotations.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/utils/chunk.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/utils/compat.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/utils/constants.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/utils/dict_utils.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/utils/indexes.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/utils/isotime.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/utils/list_utils.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/utils/lucene.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/utils/net_utils.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/utils/path.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/utils/socket_utils.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/utils/str_utils.py +0 -0
- {howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/utils/uid.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: howler-api
|
|
3
|
-
Version: 4.1.0.
|
|
3
|
+
Version: 4.1.0.dev1635
|
|
4
4
|
Summary: Howler - API server
|
|
5
5
|
License: MIT
|
|
6
6
|
Keywords: howler,alerting,gc,canada,cse-cst,cse,cst,cyber,cccs
|
|
@@ -18,6 +18,7 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.12
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.13
|
|
20
20
|
Classifier: Programming Language :: Python :: 3.14
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
21
22
|
Classifier: Topic :: Software Development :: Libraries
|
|
22
23
|
Requires-Dist: apscheduler (==3.11.3)
|
|
23
24
|
Requires-Dist: authlib (>=1.6.0,<2.0.0)
|
|
@@ -27,7 +27,8 @@ from howler.datastore.exceptions import DataStoreException, VersionConflictExcep
|
|
|
27
27
|
from howler.datastore.operations import OdmHelper, OdmUpdateOperation
|
|
28
28
|
from howler.helper.workflow import WorkflowException
|
|
29
29
|
from howler.odm.models.hit import Hit
|
|
30
|
-
from howler.odm.models.howler_data import Comment,
|
|
30
|
+
from howler.odm.models.howler_data import Comment, HitStatusTransition
|
|
31
|
+
from howler.odm.models.log import LogOperationType
|
|
31
32
|
from howler.odm.models.user import User
|
|
32
33
|
from howler.security.login import api_login
|
|
33
34
|
from howler.security.utils import is_classification_accessible, validate_bulk_operation_targets
|
|
@@ -407,7 +408,7 @@ def update_hit(
|
|
|
407
408
|
"explanation": f"Hit updated by {user.uname}\n\n" + "\n".join(explanation),
|
|
408
409
|
"new_value": "N/A",
|
|
409
410
|
"previous_value": "None",
|
|
410
|
-
"type":
|
|
411
|
+
"type": LogOperationType.APPENDED,
|
|
411
412
|
"user": user.uname,
|
|
412
413
|
},
|
|
413
414
|
silent=True,
|
|
@@ -9,8 +9,13 @@ from pytz import timezone
|
|
|
9
9
|
from howler.common.logging import get_logger
|
|
10
10
|
from howler.config import DEBUG, config
|
|
11
11
|
from howler.datastore.howler_store import HowlerDatastore
|
|
12
|
+
from howler.datastore.operations import OdmHelper
|
|
13
|
+
from howler.odm.models.case import CaseItemTypes
|
|
14
|
+
from howler.odm.models.hit import Hit
|
|
15
|
+
from howler.services import case_service
|
|
12
16
|
|
|
13
17
|
logger = get_logger(__file__)
|
|
18
|
+
hit_helper = OdmHelper(Hit)
|
|
14
19
|
|
|
15
20
|
|
|
16
21
|
def execute():
|
|
@@ -25,9 +30,7 @@ def execute():
|
|
|
25
30
|
|
|
26
31
|
ds = datastore()
|
|
27
32
|
|
|
28
|
-
ds
|
|
29
|
-
|
|
30
|
-
ds.hit.commit()
|
|
33
|
+
_delete_matching_hits(ds, f"event.created:{{* TO {cutoff}}} OR howler.expiry:{{* TO now}}")
|
|
31
34
|
|
|
32
35
|
logger.debug("Deletion complete")
|
|
33
36
|
|
|
@@ -82,8 +85,7 @@ def _execute_rules(ds: HowlerDatastore) -> None:
|
|
|
82
85
|
|
|
83
86
|
try:
|
|
84
87
|
count = ds.hit.count(combined_query, filters=None).get("count", -1)
|
|
85
|
-
ds
|
|
86
|
-
ds.hit.commit()
|
|
88
|
+
_delete_matching_hits(ds, combined_query)
|
|
87
89
|
logger.debug("Retention rule '%s' complete", rule.name)
|
|
88
90
|
result = {"rule": rule.name, "status": "ok", "deleted": count, "cutoff": cutoff}
|
|
89
91
|
except Exception:
|
|
@@ -98,6 +100,26 @@ def _execute_rules(ds: HowlerDatastore) -> None:
|
|
|
98
100
|
logger.info("Rule result: '%s'", result)
|
|
99
101
|
|
|
100
102
|
|
|
103
|
+
def _delete_matching_hits(ds: HowlerDatastore, query: str) -> None:
|
|
104
|
+
"""Remove matching hits after cleaning their references from cases and hits."""
|
|
105
|
+
hit_ids = {hit.howler.id for hit in ds.hit.stream_search(query)}
|
|
106
|
+
|
|
107
|
+
if hit_ids:
|
|
108
|
+
id_query = " OR ".join(hit_ids)
|
|
109
|
+
for case in ds.case.stream_search(f"items.value:({id_query})"):
|
|
110
|
+
item_ids = [item.id for item in case.items if item.type == CaseItemTypes.HIT and item.value in hit_ids]
|
|
111
|
+
if item_ids:
|
|
112
|
+
case_service.remove_case_items(case, item_ids)
|
|
113
|
+
|
|
114
|
+
ds.hit.update_by_query(
|
|
115
|
+
f"howler.related:({id_query})",
|
|
116
|
+
[hit_helper.list_remove("howler.related", hit_id, silent=True) for hit_id in hit_ids],
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
ds.hit.delete_by_query(query)
|
|
120
|
+
ds.hit.commit()
|
|
121
|
+
|
|
122
|
+
|
|
101
123
|
def _remove_analytics_without_hits(ds: HowlerDatastore):
|
|
102
124
|
matched_analytics = _find_analytics_with_hits(ds)
|
|
103
125
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# mypy: ignore-errors
|
|
2
2
|
|
|
3
3
|
from howler import odm
|
|
4
|
-
from howler.common.exceptions import HowlerValueError
|
|
5
4
|
from howler.common.logging import get_logger
|
|
6
5
|
from howler.odm.howler_enum import HowlerEnum
|
|
7
6
|
from howler.odm.mixins import DatastoreMixin
|
|
7
|
+
from howler.odm.models.log import Log
|
|
8
8
|
from howler.odm.models.record import Record
|
|
9
9
|
|
|
10
10
|
logger = get_logger(__file__)
|
|
@@ -30,26 +30,6 @@ class Comment(odm.Model):
|
|
|
30
30
|
)
|
|
31
31
|
|
|
32
32
|
|
|
33
|
-
@odm.model(index=True, store=True, description="Log definition.")
|
|
34
|
-
class Log(odm.Model):
|
|
35
|
-
timestamp = odm.Date(description="Timestamp at which the Log event took place.")
|
|
36
|
-
key = odm.Optional(odm.Keyword(description="The key whose value changed."))
|
|
37
|
-
explanation = odm.Optional(odm.Text(description="A manual description of the changes made."))
|
|
38
|
-
new_value = odm.Optional(odm.Keyword(description="The value the key is changing to."))
|
|
39
|
-
previous_value = odm.Optional(odm.Keyword(description="The value the key is changing from."))
|
|
40
|
-
user = odm.Keyword(description="User ID who created the log event.")
|
|
41
|
-
|
|
42
|
-
def __init__(self, data: dict = None, *args, **kwargs):
|
|
43
|
-
if "explanation" not in data:
|
|
44
|
-
required_keys = {"key", "new_value", "previous_value"}
|
|
45
|
-
if required_keys.intersection(set(data.keys())) != required_keys:
|
|
46
|
-
raise HowlerValueError(
|
|
47
|
-
f"If no explanation provided, you must provide the following values: {','.join(required_keys)}"
|
|
48
|
-
)
|
|
49
|
-
|
|
50
|
-
super().__init__(data, *args, **kwargs)
|
|
51
|
-
|
|
52
|
-
|
|
53
33
|
DEFAULT_LABELS = {"assignments": [], "generic": []}
|
|
54
34
|
|
|
55
35
|
|
|
@@ -3,10 +3,10 @@ from datetime import datetime
|
|
|
3
3
|
from typing import Optional
|
|
4
4
|
|
|
5
5
|
from howler import odm
|
|
6
|
-
from howler.common.exceptions import HowlerValueError
|
|
7
6
|
from howler.odm.constants import Status
|
|
8
7
|
from howler.odm.howler_enum import HowlerEnum
|
|
9
8
|
from howler.odm.models.lead import Lead
|
|
9
|
+
from howler.odm.models.log import Log
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class Scrutiny(str, HowlerEnum):
|
|
@@ -31,12 +31,6 @@ class HitStatusTransition(str, HowlerEnum):
|
|
|
31
31
|
DEMOTE = "demote"
|
|
32
32
|
|
|
33
33
|
|
|
34
|
-
class HitOperationType(str, HowlerEnum):
|
|
35
|
-
APPENDED = "appended"
|
|
36
|
-
REMOVED = "removed"
|
|
37
|
-
SET = "set"
|
|
38
|
-
|
|
39
|
-
|
|
40
34
|
class Escalation(str, HowlerEnum):
|
|
41
35
|
MISS = "miss"
|
|
42
36
|
HIT = "hit"
|
|
@@ -107,28 +101,6 @@ class Comment(odm.Model):
|
|
|
107
101
|
)
|
|
108
102
|
|
|
109
103
|
|
|
110
|
-
@odm.model(index=True, store=True, description="Log definition.")
|
|
111
|
-
class Log(odm.Model):
|
|
112
|
-
timestamp = odm.Date(description="Timestamp at which the Log event took place.")
|
|
113
|
-
key = odm.Optional(odm.Keyword(description="The key whose value changed."))
|
|
114
|
-
explanation = odm.Optional(odm.Text(description="A manual description of the changes made."))
|
|
115
|
-
previous_version = odm.Optional(odm.Keyword(description="The version this action was applied to."))
|
|
116
|
-
new_value = odm.Optional(odm.Keyword(description="The value the key is changing to."))
|
|
117
|
-
type = odm.Optional(odm.Enum(values=HitOperationType, description="The operation performed on the value."))
|
|
118
|
-
previous_value = odm.Optional(odm.Keyword(description="The value the key is changing from."))
|
|
119
|
-
user = odm.Keyword(description="User ID who created the log event.")
|
|
120
|
-
|
|
121
|
-
def __init__(self, data: dict = None, *args, **kwargs):
|
|
122
|
-
if "explanation" not in data:
|
|
123
|
-
required_keys = {"key", "new_value", "type", "previous_value"}
|
|
124
|
-
if required_keys.intersection(set(data.keys())) != required_keys:
|
|
125
|
-
raise HowlerValueError(
|
|
126
|
-
f"If no explanation provided, you must provide the following values: {','.join(required_keys)}"
|
|
127
|
-
)
|
|
128
|
-
|
|
129
|
-
super().__init__(data, *args, **kwargs)
|
|
130
|
-
|
|
131
|
-
|
|
132
104
|
@odm.model(index=True, store=True, description="Hit outline header.")
|
|
133
105
|
class Header(odm.Model):
|
|
134
106
|
threat: str | None = odm.Optional(odm.Keyword(description="The IP of the threat."))
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from howler import odm
|
|
2
|
+
from howler.common.exceptions import HowlerValueError
|
|
3
|
+
from howler.odm.howler_enum import HowlerEnum
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class LogOperationType(str, HowlerEnum):
|
|
7
|
+
APPENDED = "appended"
|
|
8
|
+
REMOVED = "removed"
|
|
9
|
+
SET = "set"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@odm.model(index=True, store=True, description="Log definition.") # noqa: F821
|
|
13
|
+
class Log(odm.Model):
|
|
14
|
+
timestamp = odm.Date(description="Timestamp at which the Log event took place.")
|
|
15
|
+
key = odm.Optional(odm.Keyword(description="The key whose value changed."))
|
|
16
|
+
explanation = odm.Optional(odm.Text(description="A manual description of the changes made."))
|
|
17
|
+
previous_version = odm.Optional(odm.Keyword(description="The version this action was applied to."))
|
|
18
|
+
new_value = odm.Optional(odm.Keyword(description="The value the key is changing to."))
|
|
19
|
+
type = odm.Optional(odm.Enum(values=LogOperationType, description="The operation performed on the value."))
|
|
20
|
+
previous_value = odm.Optional(odm.Keyword(description="The value the key is changing from."))
|
|
21
|
+
user = odm.Keyword(description="User ID who created the log event.")
|
|
22
|
+
|
|
23
|
+
def __init__(self, data: dict = None, *args, **kwargs):
|
|
24
|
+
if "explanation" not in data:
|
|
25
|
+
required_keys = {"key", "new_value", "previous_value"}
|
|
26
|
+
if required_keys.intersection(set(data.keys())) != required_keys:
|
|
27
|
+
raise HowlerValueError(
|
|
28
|
+
f"If no explanation provided, you must provide the following values: {','.join(required_keys)}"
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
super().__init__(data, *args, **kwargs)
|
|
@@ -26,6 +26,7 @@ from howler.odm.models.case import Case, CaseItem, CaseItemTypes, CaseLog, CaseR
|
|
|
26
26
|
from howler.odm.models.ecs.related import Related
|
|
27
27
|
from howler.odm.models.event import Event
|
|
28
28
|
from howler.odm.models.hit import Hit
|
|
29
|
+
from howler.odm.models.log import Log
|
|
29
30
|
from howler.odm.models.user import User
|
|
30
31
|
from howler.security.utils import is_classification_accessible
|
|
31
32
|
from howler.services import comms_service, event_service, hit_service
|
|
@@ -788,7 +789,7 @@ def remove_case_items( # noqa: C901
|
|
|
788
789
|
case.items = [item for item in case.items if item.id not in ids_to_remove]
|
|
789
790
|
|
|
790
791
|
for backing_obj, backing_obj_version in backing_objs:
|
|
791
|
-
remove_backreference(backing_obj, case.case_id)
|
|
792
|
+
remove_backreference(backing_obj, case.case_id, user=user)
|
|
792
793
|
backing_obj.save(version=backing_obj_version)
|
|
793
794
|
|
|
794
795
|
recompute_case_metadata(case)
|
|
@@ -845,7 +846,7 @@ def append_hit(
|
|
|
845
846
|
|
|
846
847
|
case.items.append(item)
|
|
847
848
|
|
|
848
|
-
add_backreference(hit, case.case_id)
|
|
849
|
+
add_backreference(hit, case.case_id, user=user)
|
|
849
850
|
hit.save(version=hit_version)
|
|
850
851
|
|
|
851
852
|
recompute_case_metadata(case)
|
|
@@ -889,7 +890,7 @@ def append_event(
|
|
|
889
890
|
|
|
890
891
|
case.items.append(item)
|
|
891
892
|
|
|
892
|
-
add_backreference(event, case.case_id)
|
|
893
|
+
add_backreference(event, case.case_id, user=user)
|
|
893
894
|
event.save(version=event_version)
|
|
894
895
|
|
|
895
896
|
recompute_case_metadata(case)
|
|
@@ -996,7 +997,11 @@ def recompute_case_metadata(case: Case) -> None: # noqa: C901
|
|
|
996
997
|
case.indicators = sorted(indicators)
|
|
997
998
|
|
|
998
999
|
|
|
999
|
-
def add_backreference(
|
|
1000
|
+
def add_backreference(
|
|
1001
|
+
backing_obj: Hit | Event | None,
|
|
1002
|
+
case_id: str,
|
|
1003
|
+
user: User | None = None,
|
|
1004
|
+
) -> bool:
|
|
1000
1005
|
"""Add a back-reference from a hit or event to a case, in memory only.
|
|
1001
1006
|
|
|
1002
1007
|
Records the case ID in the backing object's ``howler.related`` list so
|
|
@@ -1023,12 +1028,23 @@ def add_backreference(backing_obj: Hit | Event | None, case_id: str) -> bool:
|
|
|
1023
1028
|
return False
|
|
1024
1029
|
|
|
1025
1030
|
backing_obj.howler.related.append(case_id)
|
|
1031
|
+
backing_obj.howler.log.append(
|
|
1032
|
+
Log(
|
|
1033
|
+
{
|
|
1034
|
+
"timestamp": "NOW",
|
|
1035
|
+
"explanation": f"Added to case {case_id}",
|
|
1036
|
+
"user": user.uname if user else "system",
|
|
1037
|
+
}
|
|
1038
|
+
)
|
|
1039
|
+
)
|
|
1040
|
+
|
|
1026
1041
|
return True
|
|
1027
1042
|
|
|
1028
1043
|
|
|
1029
1044
|
def remove_backreference(
|
|
1030
1045
|
backing_obj: Hit | Event | None,
|
|
1031
1046
|
case_id: str,
|
|
1047
|
+
user: User | None = None,
|
|
1032
1048
|
):
|
|
1033
1049
|
"""Remove a back-reference from a hit or event to a case, in memory only.
|
|
1034
1050
|
|
|
@@ -1052,6 +1068,16 @@ def remove_backreference(
|
|
|
1052
1068
|
if case_id in backing_obj.howler.related:
|
|
1053
1069
|
backing_obj.howler.related.remove(case_id)
|
|
1054
1070
|
|
|
1071
|
+
backing_obj.howler.log.append(
|
|
1072
|
+
Log(
|
|
1073
|
+
{
|
|
1074
|
+
"timestamp": "NOW",
|
|
1075
|
+
"explanation": f"Removed from case {case_id}",
|
|
1076
|
+
"user": user.uname if user else "system",
|
|
1077
|
+
}
|
|
1078
|
+
)
|
|
1079
|
+
)
|
|
1080
|
+
|
|
1055
1081
|
|
|
1056
1082
|
def rename_case_item(
|
|
1057
1083
|
case: str | Case | None,
|
|
@@ -29,7 +29,8 @@ from howler.helper.hit import (
|
|
|
29
29
|
from howler.helper.workflow import Transition, Workflow
|
|
30
30
|
from howler.odm.models.ecs.event import ECSEvent
|
|
31
31
|
from howler.odm.models.hit import Hit
|
|
32
|
-
from howler.odm.models.howler_data import
|
|
32
|
+
from howler.odm.models.howler_data import HitStatusTransition, Status
|
|
33
|
+
from howler.odm.models.log import Log, LogOperationType
|
|
33
34
|
from howler.odm.models.user import User
|
|
34
35
|
from howler.security.utils import is_classification_accessible
|
|
35
36
|
from howler.services import action_service, analytic_service, dossier_service, overview_service, template_service
|
|
@@ -625,16 +626,16 @@ def _update_hit(
|
|
|
625
626
|
|
|
626
627
|
if is_list:
|
|
627
628
|
operation_type = (
|
|
628
|
-
|
|
629
|
+
LogOperationType.APPENDED
|
|
629
630
|
if operation.operation
|
|
630
631
|
in (
|
|
631
632
|
ESCollection.UPDATE_APPEND,
|
|
632
633
|
ESCollection.UPDATE_APPEND_IF_MISSING,
|
|
633
634
|
)
|
|
634
|
-
else
|
|
635
|
+
else LogOperationType.REMOVED
|
|
635
636
|
)
|
|
636
637
|
else:
|
|
637
|
-
operation_type =
|
|
638
|
+
operation_type = LogOperationType.SET
|
|
638
639
|
|
|
639
640
|
logger.debug("%s - %s - %s -> %s", hit_id, operation.key, previous_value, operation.value)
|
|
640
641
|
final_operations.append(operation)
|
|
@@ -244,7 +244,7 @@ suppress-none-returning = true
|
|
|
244
244
|
[tool.poetry]
|
|
245
245
|
package-mode = true
|
|
246
246
|
name = "howler-api"
|
|
247
|
-
version = "4.1.0.
|
|
247
|
+
version = "4.1.0.dev1635"
|
|
248
248
|
description = "Howler - API server"
|
|
249
249
|
authors = [
|
|
250
250
|
"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
|
{howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/api/v1/utils/permission_helper.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
|
{howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/cronjobs/action_queue_worker.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
|
{howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/datastore/migrations/__init__.py
RENAMED
|
File without changes
|
{howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/datastore/migrations/action_owner.py
RENAMED
|
File without changes
|
|
File without changes
|
{howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/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
|
{howler_api-4.1.0.dev1626 → howler_api-4.1.0.dev1635}/howler/external/generate_sigma_rules.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
|