howler-api 3.3.0.dev712__tar.gz → 3.3.0.dev715__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-3.3.0.dev712 → howler_api-3.3.0.dev715}/PKG-INFO +1 -1
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/api/v1/auth.py +4 -4
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/api/v1/clue.py +1 -1
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/api/v1/hit.py +2 -2
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/api/v1/tool.py +3 -3
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/app.py +1 -1
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/common/loader.py +2 -2
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/cronjobs/retention.py +1 -1
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/cronjobs/rules.py +12 -7
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/cronjobs/view_cleanup.py +1 -1
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/datastore/collection.py +32 -23
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/datastore/migrations/fix_process.py +3 -3
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/helper/discover.py +3 -3
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/helper.py +1 -1
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/random_data.py +6 -6
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/remote/datatypes/__init__.py +1 -1
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/security/__init__.py +4 -4
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/security/socket.py +4 -4
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/services/event_service.py +3 -3
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/pyproject.toml +1 -1
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/README.md +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/__init__.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/actions/__init__.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/actions/add_label.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/actions/add_to_bundle.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/actions/change_field.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/actions/demote.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/actions/example_plugin.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/actions/prioritization.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/actions/promote.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/actions/remove_from_bundle.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/actions/remove_label.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/actions/transition.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/api/__init__.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/api/base.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/api/socket.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/api/v1/__init__.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/api/v1/action.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/api/v1/analytic.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/api/v1/configs.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/api/v1/dossier.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/api/v1/help.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/api/v1/notebook.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/api/v1/overview.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/api/v1/search.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/api/v1/template.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/api/v1/user.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/api/v1/utils/__init__.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/api/v1/utils/etag.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/api/v1/view.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/common/README.md +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/common/__init__.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/common/classification.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/common/classification.yml +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/common/exceptions.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/common/logging/__init__.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/common/logging/audit.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/common/logging/format.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/common/net.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/common/net_static.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/common/random_user.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/common/swagger.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/config.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/cronjobs/__init__.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/datastore/README.md +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/datastore/__init__.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/datastore/bulk.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/datastore/constants.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/datastore/exceptions.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/datastore/howler_store.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/datastore/operations.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/datastore/schemas.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/datastore/store.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/datastore/support/__init__.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/datastore/support/build.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/datastore/support/schemas.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/datastore/types.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/error.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/external/README.md +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/external/__init__.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/external/generate_mitre.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/external/generate_sigma_rules.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/external/generate_tlds.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/external/reindex_data.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/external/wipe_databases.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/gunicorn_config.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/healthz.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/helper/__init__.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/helper/azure.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/helper/hit.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/helper/oauth.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/helper/search.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/helper/workflow.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/helper/ws.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/README.md +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/__init__.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/base.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/charter.txt +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/howler_enum.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/__init__.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/action.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/analytic.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/assemblyline.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/aws.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/azure.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/cbs.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/clue.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/config.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/dossier.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/ecs/__init__.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/ecs/agent.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/ecs/autonomous_system.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/ecs/client.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/ecs/cloud.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/ecs/code_signature.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/ecs/container.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/ecs/dns.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/ecs/egress.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/ecs/elf.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/ecs/email.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/ecs/error.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/ecs/event.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/ecs/faas.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/ecs/file.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/ecs/geo.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/ecs/group.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/ecs/hash.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/ecs/host.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/ecs/http.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/ecs/ingress.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/ecs/interface.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/ecs/network.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/ecs/observer.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/ecs/organization.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/ecs/os.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/ecs/pe.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/ecs/process.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/ecs/registry.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/ecs/related.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/ecs/rule.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/ecs/server.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/ecs/threat.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/ecs/tls.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/ecs/url.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/ecs/user.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/ecs/user_agent.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/ecs/vulnerability.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/gcp.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/hit.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/howler_data.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/lead.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/localized_label.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/overview.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/pivot.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/template.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/user.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/models/view.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/odm/randomizer.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/patched.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/plugins/__init__.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/plugins/config.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/remote/__init__.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/remote/datatypes/README.md +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/remote/datatypes/counters.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/remote/datatypes/events.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/remote/datatypes/hash.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/remote/datatypes/lock.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/remote/datatypes/queues/__init__.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/remote/datatypes/queues/comms.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/remote/datatypes/queues/multi.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/remote/datatypes/queues/named.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/remote/datatypes/queues/priority.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/remote/datatypes/set.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/remote/datatypes/user_quota_tracker.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/security/utils.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/services/__init__.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/services/action_service.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/services/analytic_service.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/services/auth_service.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/services/config_service.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/services/dossier_service.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/services/hit_service.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/services/jwt_service.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/services/lucene_service.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/services/notebook_service.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/services/overview_service.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/services/template_service.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/services/user_service.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/utils/__init__.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/utils/annotations.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/utils/chunk.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/utils/dict_utils.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/utils/isotime.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/utils/list_utils.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/utils/lucene.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/utils/path.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/utils/socket_utils.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/utils/str_utils.py +0 -0
- {howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/utils/uid.py +0 -0
|
@@ -347,23 +347,23 @@ def login(**_): # noqa: C901
|
|
|
347
347
|
# For sanity's sake, we throw exceptions throughout the authentication code and simply catch the exceptions here to
|
|
348
348
|
# return the corresponding HTTP Code to the user
|
|
349
349
|
except (OAuthError, AuthenticationException) as err:
|
|
350
|
-
logger.warning(
|
|
350
|
+
logger.warning("Authentication failure. (U:%s - IP:%s) [%s]", user, ip, err)
|
|
351
351
|
return unauthorized(err=str(err))
|
|
352
352
|
|
|
353
353
|
except AccessDeniedException as err:
|
|
354
|
-
logger.warning(
|
|
354
|
+
logger.warning("Authorization failure. (U:%s - IP:%s) [%s]", user, ip, err)
|
|
355
355
|
return forbidden(err=err.message)
|
|
356
356
|
|
|
357
357
|
except InvalidDataException as err:
|
|
358
358
|
return bad_request(err=err.message or str(err))
|
|
359
359
|
|
|
360
360
|
except HowlerException:
|
|
361
|
-
logger.exception(
|
|
361
|
+
logger.exception("Internal Authentication Error. (U:%s - IP:%s)", user, ip)
|
|
362
362
|
return internal_error(
|
|
363
363
|
err="Unhandled exception occured while Authenticating. Contact your administrator.",
|
|
364
364
|
)
|
|
365
365
|
|
|
366
|
-
logger.info(
|
|
366
|
+
logger.info("Login successful. (U:%s - IP:%s)", logged_in_uname, ip)
|
|
367
367
|
|
|
368
368
|
xsrf_token = generate_random_secret()
|
|
369
369
|
|
|
@@ -91,7 +91,7 @@ def proxy_to_clue(path, **kwargs):
|
|
|
91
91
|
timeout=5 * 60,
|
|
92
92
|
)
|
|
93
93
|
|
|
94
|
-
logger.debug(
|
|
94
|
+
logger.debug("Request to clue completed in %s ms", round(time.perf_counter() - start))
|
|
95
95
|
|
|
96
96
|
if not response.ok:
|
|
97
97
|
return bad_gateway(response.json(), err="Something went wrong when connecting to clue")
|
|
@@ -99,7 +99,7 @@ def create_hits(user: User, **kwargs):
|
|
|
99
99
|
response_body: dict[str, list[Any]] = {"valid": [], "invalid": []}
|
|
100
100
|
odms = []
|
|
101
101
|
ignore_extra_values: bool = bool(request.args.get("ignore_extra_values", False, type=lambda v: v.lower() == "true"))
|
|
102
|
-
logger.debug(
|
|
102
|
+
logger.debug("ignore_extra_values = %s", ignore_extra_values)
|
|
103
103
|
warnings = []
|
|
104
104
|
for hit in hits:
|
|
105
105
|
try:
|
|
@@ -108,7 +108,7 @@ def create_hits(user: User, **kwargs):
|
|
|
108
108
|
odms.append(odm)
|
|
109
109
|
warnings.extend(_warnings)
|
|
110
110
|
except HowlerException as e:
|
|
111
|
-
logger.warning(
|
|
111
|
+
logger.warning("%s when saving new hit!", type(e).__name__)
|
|
112
112
|
logger.warning(e)
|
|
113
113
|
response_body["invalid"].append({"input": hit, "error": str(e)})
|
|
114
114
|
|
|
@@ -67,7 +67,7 @@ def create_one_or_many_hits(tool_name: str, user: User, **kwargs): # noqa: C901
|
|
|
67
67
|
field_map = data.pop("map", None)
|
|
68
68
|
hits = data.pop("hits", None)
|
|
69
69
|
ignore_extra_values: bool = bool(request.args.get("ignore_extra_values", False, type=lambda v: v.lower() == "true"))
|
|
70
|
-
logger.debug(
|
|
70
|
+
logger.debug("ignore_extra_values = %s", ignore_extra_values)
|
|
71
71
|
# Check data type
|
|
72
72
|
if not isinstance(field_map, dict):
|
|
73
73
|
return bad_request(err="Invalid: 'map' field is missing or invalid.")
|
|
@@ -115,7 +115,7 @@ def create_one_or_many_hits(tool_name: str, user: User, **kwargs): # noqa: C901
|
|
|
115
115
|
try:
|
|
116
116
|
field_data: Optional[_Field] = hit_fields[target]
|
|
117
117
|
except KeyError:
|
|
118
|
-
logger.debug(
|
|
118
|
+
logger.debug("`%s` not in hit fields", target)
|
|
119
119
|
field_data = next(
|
|
120
120
|
(v for k, v in hit_fields.items() if get_parent_key(k) == target),
|
|
121
121
|
None,
|
|
@@ -153,7 +153,7 @@ def create_one_or_many_hits(tool_name: str, user: User, **kwargs): # noqa: C901
|
|
|
153
153
|
}
|
|
154
154
|
)
|
|
155
155
|
except HowlerException as e:
|
|
156
|
-
logger.warning(
|
|
156
|
+
logger.warning("%s when saving %s!", type(e).__name__, cur_id)
|
|
157
157
|
logger.warning(e)
|
|
158
158
|
|
|
159
159
|
out.append({"id": None, "error": str(e)})
|
|
@@ -206,7 +206,7 @@ if logger.parent:
|
|
|
206
206
|
|
|
207
207
|
# Setup APMs
|
|
208
208
|
if config.core.metrics.apm_server.server_url is not None:
|
|
209
|
-
logger.info(
|
|
209
|
+
logger.info("Exporting application metrics to: %s", config.core.metrics.apm_server.server_url)
|
|
210
210
|
ElasticAPM(
|
|
211
211
|
app,
|
|
212
212
|
server_url=config.core.metrics.apm_server.server_url,
|
|
@@ -58,9 +58,9 @@ def get_classification(yml_config: Optional[str] = None): # noqa: C901
|
|
|
58
58
|
)
|
|
59
59
|
|
|
60
60
|
if not yml_config_path.exists():
|
|
61
|
-
log.warning(
|
|
61
|
+
log.warning("%s does not exist!", yml_config_path)
|
|
62
62
|
yml_config_path = Path("/etc") / APP_NAME.replace("-dev", "") / "classification.yml"
|
|
63
|
-
log.warning(
|
|
63
|
+
log.warning("Checking at %s instead.", yml_config_path)
|
|
64
64
|
else:
|
|
65
65
|
yml_config_path = Path(yml_config)
|
|
66
66
|
|
|
@@ -39,7 +39,7 @@ def setup_job(sched: BaseScheduler):
|
|
|
39
39
|
|
|
40
40
|
return
|
|
41
41
|
|
|
42
|
-
logger.debug(
|
|
42
|
+
logger.debug("Initializing retention cronjob with cron %s", config.system.retention.crontab)
|
|
43
43
|
|
|
44
44
|
if DEBUG:
|
|
45
45
|
_kwargs: dict[str, Any] = {"next_run_time": datetime.now()}
|
|
@@ -44,7 +44,7 @@ def create_correlated_bundle(rule: Analytic, query: str, correlated_hits: list[H
|
|
|
44
44
|
# If a matching bundle exists already, just reused it (likely only ever lucene specific)
|
|
45
45
|
existing_result = datastore().hit.search(f"howler.hash:{hashed}", rows=1)
|
|
46
46
|
if existing_result["total"] > 0:
|
|
47
|
-
logger.debug(
|
|
47
|
+
logger.debug("Rule hash %s exists - skipping create", hashed)
|
|
48
48
|
return existing_result["items"][0]
|
|
49
49
|
|
|
50
50
|
child_ids = [match.howler.id for match in correlated_hits]
|
|
@@ -200,7 +200,10 @@ def create_executor(rule: Analytic): # noqa: C901
|
|
|
200
200
|
__scheduler_instance.remove_job(f"rule_{rule.analytic_id}")
|
|
201
201
|
# TODO: Allow restarting of rules
|
|
202
202
|
logger.critical(
|
|
203
|
-
|
|
203
|
+
"Rule %s (%s) has been stopped, due to an exception: %s",
|
|
204
|
+
rule.name,
|
|
205
|
+
rule.analytic_id,
|
|
206
|
+
type(e),
|
|
204
207
|
exc_info=True,
|
|
205
208
|
)
|
|
206
209
|
|
|
@@ -220,12 +223,12 @@ def register_rules(new_rule: Optional[Analytic] = None, test_override: bool = Fa
|
|
|
220
223
|
|
|
221
224
|
if new_rule:
|
|
222
225
|
if __scheduler_instance.get_job(f"rule_{new_rule.analytic_id}"):
|
|
223
|
-
logger.info(
|
|
226
|
+
logger.info("Updating existing rule: %s on interval %s", new_rule.analytic_id, new_rule.rule_crontab)
|
|
224
227
|
|
|
225
228
|
# remove the existing job
|
|
226
229
|
__scheduler_instance.remove_job(f"rule_{new_rule.analytic_id}")
|
|
227
230
|
else:
|
|
228
|
-
logger.info(
|
|
231
|
+
logger.info("Registering new rule: %s on interval %s", new_rule.analytic_id, new_rule.rule_crontab)
|
|
229
232
|
rules = [new_rule]
|
|
230
233
|
else:
|
|
231
234
|
logger.debug("Registering rules")
|
|
@@ -237,10 +240,12 @@ def register_rules(new_rule: Optional[Analytic] = None, test_override: bool = Fa
|
|
|
237
240
|
interval = rule.rule_crontab or f"{random.randint(0, 59)} * * * *" # noqa: S311
|
|
238
241
|
|
|
239
242
|
if __scheduler_instance.get_job(job_id):
|
|
240
|
-
logger.debug(
|
|
243
|
+
logger.debug("Rule %s already running!", job_id)
|
|
241
244
|
return
|
|
242
245
|
|
|
243
|
-
logger.debug(
|
|
246
|
+
logger.debug(
|
|
247
|
+
"Initializing rule cronjob with:\tJob ID: %s\tRule Name: %s\tCrontab: %s", job_id, rule.name, interval
|
|
248
|
+
)
|
|
244
249
|
|
|
245
250
|
if DEBUG or new_rule:
|
|
246
251
|
_kwargs: dict[str, Any] = {"next_run_time": datetime.now()}
|
|
@@ -255,7 +260,7 @@ def register_rules(new_rule: Optional[Analytic] = None, test_override: bool = Fa
|
|
|
255
260
|
**_kwargs,
|
|
256
261
|
)
|
|
257
262
|
|
|
258
|
-
logger.info(
|
|
263
|
+
logger.info("Initialized %s rules", total_initialized)
|
|
259
264
|
|
|
260
265
|
|
|
261
266
|
def setup_job(sched: BaseScheduler):
|
|
@@ -68,7 +68,7 @@ def setup_job(sched: BaseScheduler):
|
|
|
68
68
|
|
|
69
69
|
return
|
|
70
70
|
|
|
71
|
-
logger.debug(
|
|
71
|
+
logger.debug("Initializing view cleanup cronjob with cron %s", config.system.view_cleanup.crontab)
|
|
72
72
|
|
|
73
73
|
if DEBUG:
|
|
74
74
|
_kwargs: dict[str, Any] = {"next_run_time": datetime.now()}
|
|
@@ -398,7 +398,7 @@ class ESCollection(Generic[ModelType]):
|
|
|
398
398
|
except elasticsearch.exceptions.TransportError as e:
|
|
399
399
|
err_code, msg, cause = e.args
|
|
400
400
|
if err_code == 503 or err_code == "503":
|
|
401
|
-
logger.warning(
|
|
401
|
+
logger.warning("Looks like index %s is not ready yet, retrying...", self.name)
|
|
402
402
|
time.sleep(min(retries, self.MAX_RETRY_BACKOFF))
|
|
403
403
|
self.datastore.connection_reset()
|
|
404
404
|
retries += 1
|
|
@@ -411,7 +411,8 @@ class ESCollection(Generic[ModelType]):
|
|
|
411
411
|
retries += 1
|
|
412
412
|
elif err_code == 403 or err_code == "403":
|
|
413
413
|
logger.warning(
|
|
414
|
-
|
|
414
|
+
"Elasticsearch cluster is preventing writing operations on index %s, retrying...",
|
|
415
|
+
self.name,
|
|
415
416
|
)
|
|
416
417
|
time.sleep(min(retries, self.MAX_RETRY_BACKOFF))
|
|
417
418
|
self.datastore.connection_reset()
|
|
@@ -470,7 +471,7 @@ class ESCollection(Generic[ModelType]):
|
|
|
470
471
|
except elasticsearch.exceptions.TransportError as e:
|
|
471
472
|
err_code, _, _ = e.args
|
|
472
473
|
if err_code == 408 or err_code == "408":
|
|
473
|
-
logger.warning(
|
|
474
|
+
logger.warning("Waiting for index %s to get to status %s...", index, min_status)
|
|
474
475
|
else:
|
|
475
476
|
raise
|
|
476
477
|
|
|
@@ -576,8 +577,9 @@ class ESCollection(Generic[ModelType]):
|
|
|
576
577
|
|
|
577
578
|
if cur_shards > target_shards:
|
|
578
579
|
logger.info(
|
|
579
|
-
|
|
580
|
-
|
|
580
|
+
"Current shards (%s) is bigger then target shards (%s), we will be shrinking the index.",
|
|
581
|
+
cur_shards,
|
|
582
|
+
target_shards,
|
|
581
583
|
)
|
|
582
584
|
if cur_shards % target_shards != 0:
|
|
583
585
|
logger.info("The target shards is not a factor of the current shards, aborting...")
|
|
@@ -591,8 +593,9 @@ class ESCollection(Generic[ModelType]):
|
|
|
591
593
|
method = self.datastore.client.indices.shrink
|
|
592
594
|
elif cur_shards < target_shards:
|
|
593
595
|
logger.info(
|
|
594
|
-
|
|
595
|
-
|
|
596
|
+
"Current shards (%s) is smaller then target shards (%s), we will be splitting the index.",
|
|
597
|
+
cur_shards,
|
|
598
|
+
target_shards,
|
|
596
599
|
)
|
|
597
600
|
if target_shards % cur_shards != 0:
|
|
598
601
|
logger.warning("The current shards is not a factor of the target shards, aborting...")
|
|
@@ -601,13 +604,15 @@ class ESCollection(Generic[ModelType]):
|
|
|
601
604
|
method = self.datastore.client.indices.split
|
|
602
605
|
else:
|
|
603
606
|
logger.info(
|
|
604
|
-
|
|
605
|
-
"
|
|
607
|
+
"Current shards (%s) is equal to the target shards (%s), only housekeeping operations will be "
|
|
608
|
+
"performed.",
|
|
609
|
+
cur_shards,
|
|
610
|
+
target_shards,
|
|
606
611
|
)
|
|
607
612
|
|
|
608
613
|
if method:
|
|
609
614
|
# Before we do anything, we should make sure the source index is in a good state
|
|
610
|
-
logger.info(
|
|
615
|
+
logger.info("Waiting for %s status to be GREEN.", self.name.upper())
|
|
611
616
|
self._wait_for_status(self.name, min_status="green")
|
|
612
617
|
|
|
613
618
|
# Block all indexes to be written to
|
|
@@ -618,7 +623,7 @@ class ESCollection(Generic[ModelType]):
|
|
|
618
623
|
if not self.with_retries(self.datastore.client.indices.exists, index=temp_name):
|
|
619
624
|
# if there are specific settings to be applied to the index, apply them
|
|
620
625
|
if clone_setup_settings:
|
|
621
|
-
logger.info(
|
|
626
|
+
logger.info("Relocating index to node %s.", target_node.upper())
|
|
622
627
|
self.with_retries(
|
|
623
628
|
self.datastore.client.indices.put_settings,
|
|
624
629
|
index=self.index_name,
|
|
@@ -630,7 +635,7 @@ class ESCollection(Generic[ModelType]):
|
|
|
630
635
|
time.sleep(1)
|
|
631
636
|
|
|
632
637
|
# Make a clone of the current index
|
|
633
|
-
logger.info(
|
|
638
|
+
logger.info("Cloning %s into %s.", self.index_name.upper(), temp_name.upper())
|
|
634
639
|
self._safe_index_copy(
|
|
635
640
|
self.datastore.client.indices.clone,
|
|
636
641
|
self.index_name,
|
|
@@ -640,14 +645,16 @@ class ESCollection(Generic[ModelType]):
|
|
|
640
645
|
)
|
|
641
646
|
|
|
642
647
|
# Make 100% sure temporary index is ready
|
|
643
|
-
logger.info(
|
|
648
|
+
logger.info("Waiting for %s status to be GREEN.", temp_name.upper())
|
|
644
649
|
self._wait_for_status(temp_name, "green")
|
|
645
650
|
|
|
646
651
|
# Make sure temporary index is the alias if not already
|
|
647
652
|
if self._get_current_alias(self.name) != temp_name:
|
|
648
653
|
logger.info(
|
|
649
|
-
|
|
650
|
-
|
|
654
|
+
"Make %s the current alias for %s and delete %s.",
|
|
655
|
+
temp_name.upper(),
|
|
656
|
+
self.name.upper(),
|
|
657
|
+
self.index_name.upper(),
|
|
651
658
|
)
|
|
652
659
|
# Make the hot index the temporary index while deleting the original index
|
|
653
660
|
alias_actions = [
|
|
@@ -658,17 +665,19 @@ class ESCollection(Generic[ModelType]):
|
|
|
658
665
|
|
|
659
666
|
# Make sure the original index is deleted
|
|
660
667
|
if self.with_retries(self.datastore.client.indices.exists, index=self.index_name):
|
|
661
|
-
logger.info(
|
|
668
|
+
logger.info("Delete extra %s index.", self.index_name.upper())
|
|
662
669
|
self.with_retries(self.datastore.client.indices.delete, index=self.index_name)
|
|
663
670
|
|
|
664
671
|
# Shrink/split the temporary index into the original index
|
|
665
|
-
logger.info(
|
|
672
|
+
logger.info("Perform shard fix operation from %s to %s.", temp_name.upper(), self.index_name.upper())
|
|
666
673
|
self._safe_index_copy(method, temp_name, self.index_name, settings=settings)
|
|
667
674
|
|
|
668
675
|
# Make the original index the new alias
|
|
669
676
|
logger.info(
|
|
670
|
-
|
|
671
|
-
|
|
677
|
+
"Make %s the current alias for %s and delete %s.",
|
|
678
|
+
self.index_name.upper(),
|
|
679
|
+
self.name.upper(),
|
|
680
|
+
temp_name.upper(),
|
|
672
681
|
)
|
|
673
682
|
alias_actions = [
|
|
674
683
|
{"add": {"index": self.index_name, "alias": self.name}},
|
|
@@ -681,7 +690,7 @@ class ESCollection(Generic[ModelType]):
|
|
|
681
690
|
self.with_retries(self.datastore.client.indices.put_settings, settings=write_unblock_settings)
|
|
682
691
|
|
|
683
692
|
# Restore normal routing and replicas
|
|
684
|
-
logger.debug(
|
|
693
|
+
logger.debug("Restore original routing table for %s.", self.name.upper())
|
|
685
694
|
self.with_retries(
|
|
686
695
|
self.datastore.client.indices.put_settings,
|
|
687
696
|
index=self.name,
|
|
@@ -849,7 +858,7 @@ class ESCollection(Generic[ModelType]):
|
|
|
849
858
|
key_list.remove(row["_id"])
|
|
850
859
|
add_to_output(row["_source"], row["_id"])
|
|
851
860
|
except ValueError:
|
|
852
|
-
logger.exception(
|
|
861
|
+
logger.exception("MGet returned multiple documents for id: %s", row["_id"])
|
|
853
862
|
|
|
854
863
|
if key_list and error_on_missing:
|
|
855
864
|
raise MultiKeyError(key_list, out)
|
|
@@ -2359,7 +2368,7 @@ class ESCollection(Generic[ModelType]):
|
|
|
2359
2368
|
"""
|
|
2360
2369
|
# Create HOT index
|
|
2361
2370
|
if not self.with_retries(self.datastore.client.indices.exists, index=self.name):
|
|
2362
|
-
logger.debug(
|
|
2371
|
+
logger.debug("Index %s does not exist. Creating it now...", self.name.upper())
|
|
2363
2372
|
try:
|
|
2364
2373
|
self.with_retries(
|
|
2365
2374
|
self.datastore.client.indices.create,
|
|
@@ -2370,7 +2379,7 @@ class ESCollection(Generic[ModelType]):
|
|
|
2370
2379
|
except elasticsearch.exceptions.RequestError as e:
|
|
2371
2380
|
if "resource_already_exists_exception" not in str(e):
|
|
2372
2381
|
raise
|
|
2373
|
-
logger.warning(
|
|
2382
|
+
logger.warning("Tried to create an index template that already exists: %s", self.name.upper())
|
|
2374
2383
|
|
|
2375
2384
|
self.with_retries(
|
|
2376
2385
|
self.datastore.client.indices.put_alias,
|
{howler_api-3.3.0.dev712 → howler_api-3.3.0.dev715}/howler/datastore/migrations/fix_process.py
RENAMED
|
@@ -15,12 +15,12 @@ def migrate():
|
|
|
15
15
|
logger.info("Preconditions met, continuing.")
|
|
16
16
|
|
|
17
17
|
db_size = collection.search("howler.id:*", track_total_hits=True, rows=0)["total"]
|
|
18
|
-
logger.info(
|
|
18
|
+
logger.info("Database size pre-migration: %s", db_size)
|
|
19
19
|
else:
|
|
20
20
|
logger.info("Preconditions not met, stopping")
|
|
21
21
|
return
|
|
22
22
|
|
|
23
|
-
logger.info(
|
|
23
|
+
logger.info("We will delete %s hits. Continue?", result["total"])
|
|
24
24
|
prompt_result = input("y/[n]")
|
|
25
25
|
|
|
26
26
|
if prompt_result.lower() != "y":
|
|
@@ -32,7 +32,7 @@ def migrate():
|
|
|
32
32
|
collection.commit()
|
|
33
33
|
|
|
34
34
|
db_size_after = collection.search("howler.id:*", track_total_hits=True, rows=0)["total"]
|
|
35
|
-
logger.info(
|
|
35
|
+
logger.info("Database size post-migration: %s", db_size_after)
|
|
36
36
|
|
|
37
37
|
logger.info("Migration complete")
|
|
38
38
|
|
|
@@ -47,11 +47,11 @@ def get_apps_list(discovery_url: Optional[str]) -> list[dict[str, str]]:
|
|
|
47
47
|
)
|
|
48
48
|
|
|
49
49
|
except Exception:
|
|
50
|
-
logger.exception(
|
|
50
|
+
logger.exception("Failed to parse get app: %s", str(app))
|
|
51
51
|
else:
|
|
52
|
-
logger.warning(
|
|
52
|
+
logger.warning("Invalid response from server for apps discovery: %s", discovery_url)
|
|
53
53
|
except Exception:
|
|
54
|
-
logger.exception(
|
|
54
|
+
logger.exception("Failed to get apps from discover URL: %s", discovery_url)
|
|
55
55
|
|
|
56
56
|
DISCO_CACHE[discovery_url] = sorted(apps, key=lambda k: k["name"])
|
|
57
57
|
return sorted(apps, key=lambda k: k["name"])
|
|
@@ -361,7 +361,7 @@ def create_users_with_username(ds: HowlerDatastore, usernames: list[str]):
|
|
|
361
361
|
ds.user.save(username, user_data)
|
|
362
362
|
|
|
363
363
|
if "pytest" not in sys.modules:
|
|
364
|
-
logger.info(
|
|
364
|
+
logger.info("%s:%s", username, username)
|
|
365
365
|
|
|
366
366
|
ds.user.commit()
|
|
367
367
|
ds.user_avatar.commit()
|
|
@@ -137,7 +137,7 @@ def create_users(ds):
|
|
|
137
137
|
ds.view.save(admin_view.view_id, admin_view)
|
|
138
138
|
|
|
139
139
|
if "pytest" not in sys.modules:
|
|
140
|
-
logger.info(
|
|
140
|
+
logger.info("\t%s:%s", user_data.uname, admin_pass)
|
|
141
141
|
|
|
142
142
|
user_hash = get_password_hash(user_pass)
|
|
143
143
|
|
|
@@ -184,7 +184,7 @@ def create_users(ds):
|
|
|
184
184
|
ds.view.save(user_view.view_id, user_view)
|
|
185
185
|
|
|
186
186
|
if "pytest" not in sys.modules:
|
|
187
|
-
logger.info(
|
|
187
|
+
logger.info("\t%s:%s", user_data.uname, user_pass)
|
|
188
188
|
|
|
189
189
|
huey_hash = get_password_hash(huey_pass)
|
|
190
190
|
|
|
@@ -231,7 +231,7 @@ def create_users(ds):
|
|
|
231
231
|
ds.view.save(huey_view.view_id, huey_view)
|
|
232
232
|
|
|
233
233
|
if "pytest" not in sys.modules:
|
|
234
|
-
logger.info(
|
|
234
|
+
logger.info("\t%s:%s", huey_data.uname, huey_pass)
|
|
235
235
|
|
|
236
236
|
shawnh_view = View(
|
|
237
237
|
{
|
|
@@ -261,7 +261,7 @@ def create_users(ds):
|
|
|
261
261
|
ds.view.save(shawnh_view.view_id, shawnh_view)
|
|
262
262
|
|
|
263
263
|
if "pytest" not in sys.modules:
|
|
264
|
-
logger.info(
|
|
264
|
+
logger.info("\t%s:%s", shawn_data.uname, shawnh_pass)
|
|
265
265
|
|
|
266
266
|
goose_view = View(
|
|
267
267
|
{
|
|
@@ -291,7 +291,7 @@ def create_users(ds):
|
|
|
291
291
|
ds.view.save(goose_view.view_id, goose_view)
|
|
292
292
|
|
|
293
293
|
if "pytest" not in sys.modules:
|
|
294
|
-
logger.info(
|
|
294
|
+
logger.info("\t%s:%s", goose_data.uname, goose_pass)
|
|
295
295
|
|
|
296
296
|
ds.user.commit()
|
|
297
297
|
ds.user_avatar.commit()
|
|
@@ -892,7 +892,7 @@ if __name__ == "__main__":
|
|
|
892
892
|
|
|
893
893
|
for index, operations in INDEXES.items():
|
|
894
894
|
if index in args:
|
|
895
|
-
logger.info(
|
|
895
|
+
logger.info("Creating %s...", index)
|
|
896
896
|
|
|
897
897
|
# Create functions
|
|
898
898
|
for create_fn in operations[1]:
|
|
@@ -60,7 +60,7 @@ def retry_call(func, *args, **kw):
|
|
|
60
60
|
|
|
61
61
|
return ret_val
|
|
62
62
|
except (redis.ConnectionError, ConnectionResetError) as ce:
|
|
63
|
-
log.warning(
|
|
63
|
+
log.warning("No connection to Redis, reconnecting... [%s]", ce)
|
|
64
64
|
time.sleep(2**exponent)
|
|
65
65
|
exponent = exponent + 1 if exponent < maximum else exponent
|
|
66
66
|
|
|
@@ -186,7 +186,7 @@ class api_login(object): # noqa: D101, N801
|
|
|
186
186
|
|
|
187
187
|
ip = request.headers.get("X-Forwarded-For", request.remote_addr)
|
|
188
188
|
if "pytest" not in sys.modules:
|
|
189
|
-
logger.info(
|
|
189
|
+
logger.info("Logged in as %s from %s for path %s", user["uname"], ip, request.path)
|
|
190
190
|
|
|
191
191
|
# If auditing is enabled, write this successful access to the audit logs
|
|
192
192
|
if self.audit:
|
|
@@ -231,13 +231,13 @@ class api_login(object): # noqa: D101, N801
|
|
|
231
231
|
quota = user.get("api_quota", 25)
|
|
232
232
|
if not QUOTA_TRACKER.begin(user["uname"], quota):
|
|
233
233
|
if config.ui.enforce_quota:
|
|
234
|
-
logger.warning(
|
|
234
|
+
logger.warning("%s was prevented from using the api due to exceeded quota.", user["uname"])
|
|
235
235
|
FAILED_ATTEMPTS.labels("429").inc()
|
|
236
236
|
return too_many_requests(err=f"You've exceeded your maximum quota of {quota}")
|
|
237
237
|
else:
|
|
238
|
-
logger.debug(
|
|
238
|
+
logger.debug("Quota of %s exceeded for user %s.", quota, user["uname"])
|
|
239
239
|
else:
|
|
240
|
-
logger.debug(
|
|
240
|
+
logger.debug("Quota not enforced for %s", user["uname"])
|
|
241
241
|
|
|
242
242
|
# Save user data in kwargs for future reference in the wrapped method
|
|
243
243
|
kwargs["user"] = user
|
|
@@ -51,7 +51,7 @@ def websocket_auth(required_type: Optional[list[str]] = None, required_priv: Opt
|
|
|
51
51
|
raise AuthenticationException() # noqa: TRY301
|
|
52
52
|
|
|
53
53
|
if not set(required_priv) & set(privs):
|
|
54
|
-
logger.warning(
|
|
54
|
+
logger.warning("%s: Authentication header is invalid", ws_id)
|
|
55
55
|
ws.close(
|
|
56
56
|
1008,
|
|
57
57
|
ws_response(
|
|
@@ -63,7 +63,7 @@ def websocket_auth(required_type: Optional[list[str]] = None, required_priv: Opt
|
|
|
63
63
|
)
|
|
64
64
|
return forbidden()
|
|
65
65
|
|
|
66
|
-
logger.info(
|
|
66
|
+
logger.info("%s authenticated as %s", ws_id, user["uname"])
|
|
67
67
|
ws.send(
|
|
68
68
|
ws_response(
|
|
69
69
|
"info",
|
|
@@ -77,13 +77,13 @@ def websocket_auth(required_type: Optional[list[str]] = None, required_priv: Opt
|
|
|
77
77
|
|
|
78
78
|
f(ws, *args, ws_id=ws_id, username=user["uname"], privs=privs, **kwargs)
|
|
79
79
|
except ConnectionClosed:
|
|
80
|
-
logger.info(
|
|
80
|
+
logger.info("%s: Client closed connection", ws_id)
|
|
81
81
|
except (
|
|
82
82
|
AuthenticationException,
|
|
83
83
|
ValueError,
|
|
84
84
|
InvalidTokenError,
|
|
85
85
|
):
|
|
86
|
-
logger.warning(
|
|
86
|
+
logger.warning("%s: Authentication header is invalid", ws_id)
|
|
87
87
|
if ws:
|
|
88
88
|
ws.close(
|
|
89
89
|
1008,
|
|
@@ -54,7 +54,7 @@ def emit(event: str, data: Any):
|
|
|
54
54
|
if event not in handlers:
|
|
55
55
|
return
|
|
56
56
|
|
|
57
|
-
logger.debug(
|
|
57
|
+
logger.debug("event:%s - emitting data", event)
|
|
58
58
|
|
|
59
59
|
for handler in handlers[event]:
|
|
60
60
|
handler(data)
|
|
@@ -72,7 +72,7 @@ def on(event: str, handler: Callable):
|
|
|
72
72
|
|
|
73
73
|
handlers[event].append(handler)
|
|
74
74
|
|
|
75
|
-
logger.debug(
|
|
75
|
+
logger.debug("event:%s - added listener", event)
|
|
76
76
|
|
|
77
77
|
|
|
78
78
|
def off(event: str, handler: Callable):
|
|
@@ -90,4 +90,4 @@ def off(event: str, handler: Callable):
|
|
|
90
90
|
|
|
91
91
|
handlers[event] = [h for h in handlers[event] if h != handler]
|
|
92
92
|
|
|
93
|
-
logger.debug(
|
|
93
|
+
logger.debug("event:%s - removed listener", event)
|
|
@@ -152,7 +152,7 @@ suppress-none-returning = true
|
|
|
152
152
|
[tool.poetry]
|
|
153
153
|
package-mode = true
|
|
154
154
|
name = "howler-api"
|
|
155
|
-
version = "3.3.0.
|
|
155
|
+
version = "3.3.0.dev715"
|
|
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
|