howler-api 3.1.0.dev426__tar.gz → 3.1.1.485__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.1.0.dev426 → howler_api-3.1.1.485}/PKG-INFO +1 -1
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/api/v1/search.py +37 -1
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/datastore/collection.py +0 -3
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/services/lucene_service.py +3 -1
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/utils/lucene.py +1 -1
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/pyproject.toml +1 -1
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/README.md +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/__init__.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/actions/__init__.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/actions/add_label.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/actions/add_to_bundle.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/actions/change_field.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/actions/demote.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/actions/example_plugin.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/actions/prioritization.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/actions/promote.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/actions/remove_from_bundle.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/actions/remove_label.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/actions/transition.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/api/__init__.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/api/base.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/api/socket.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/api/v1/__init__.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/api/v1/action.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/api/v1/analytic.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/api/v1/auth.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/api/v1/clue.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/api/v1/configs.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/api/v1/dossier.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/api/v1/help.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/api/v1/hit.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/api/v1/notebook.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/api/v1/overview.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/api/v1/template.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/api/v1/tool.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/api/v1/user.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/api/v1/utils/__init__.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/api/v1/utils/etag.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/api/v1/view.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/app.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/common/README.md +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/common/__init__.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/common/classification.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/common/classification.yml +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/common/exceptions.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/common/loader.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/common/logging/__init__.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/common/logging/audit.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/common/logging/format.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/common/net.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/common/net_static.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/common/random_user.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/common/swagger.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/config.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/cronjobs/__init__.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/cronjobs/retention.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/cronjobs/rules.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/cronjobs/view_cleanup.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/datastore/README.md +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/datastore/__init__.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/datastore/bulk.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/datastore/constants.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/datastore/exceptions.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/datastore/howler_store.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/datastore/migrations/fix_process.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/datastore/operations.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/datastore/schemas.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/datastore/store.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/datastore/support/__init__.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/datastore/support/build.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/datastore/support/schemas.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/datastore/types.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/error.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/external/__init__.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/external/generate_mitre.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/external/generate_sigma_rules.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/external/generate_tlds.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/external/reindex_data.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/external/wipe_databases.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/gunicorn_config.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/healthz.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/helper/__init__.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/helper/azure.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/helper/discover.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/helper/hit.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/helper/oauth.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/helper/search.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/helper/workflow.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/helper/ws.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/README.md +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/__init__.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/base.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/charter.txt +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/helper.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/howler_enum.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/__init__.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/action.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/analytic.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/assemblyline.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/aws.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/azure.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/cbs.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/config.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/dossier.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/ecs/__init__.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/ecs/agent.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/ecs/autonomous_system.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/ecs/client.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/ecs/cloud.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/ecs/code_signature.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/ecs/container.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/ecs/dns.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/ecs/egress.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/ecs/elf.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/ecs/email.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/ecs/error.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/ecs/event.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/ecs/faas.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/ecs/file.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/ecs/geo.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/ecs/group.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/ecs/hash.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/ecs/host.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/ecs/http.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/ecs/ingress.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/ecs/interface.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/ecs/network.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/ecs/observer.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/ecs/organization.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/ecs/os.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/ecs/pe.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/ecs/process.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/ecs/registry.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/ecs/related.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/ecs/rule.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/ecs/server.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/ecs/threat.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/ecs/tls.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/ecs/url.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/ecs/user.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/ecs/user_agent.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/ecs/vulnerability.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/gcp.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/hit.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/howler_data.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/lead.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/localized_label.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/overview.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/pivot.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/template.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/user.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/models/view.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/random_data.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/odm/randomizer.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/patched.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/plugins/__init__.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/plugins/config.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/remote/__init__.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/remote/datatypes/README.md +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/remote/datatypes/__init__.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/remote/datatypes/counters.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/remote/datatypes/events.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/remote/datatypes/hash.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/remote/datatypes/lock.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/remote/datatypes/queues/__init__.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/remote/datatypes/queues/comms.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/remote/datatypes/queues/multi.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/remote/datatypes/queues/named.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/remote/datatypes/queues/priority.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/remote/datatypes/set.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/remote/datatypes/user_quota_tracker.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/security/__init__.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/security/socket.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/security/utils.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/services/__init__.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/services/action_service.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/services/analytic_service.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/services/auth_service.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/services/config_service.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/services/dossier_service.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/services/event_service.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/services/hit_service.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/services/jwt_service.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/services/notebook_service.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/services/overview_service.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/services/template_service.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/services/user_service.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/utils/__init__.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/utils/annotations.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/utils/chunk.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/utils/dict_utils.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/utils/isotime.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/utils/list_utils.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/utils/path.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/utils/socket_utils.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/utils/str_utils.py +0 -0
- {howler_api-3.1.0.dev426 → howler_api-3.1.1.485}/howler/utils/uid.py +0 -0
|
@@ -10,7 +10,7 @@ from sigma.rule import SigmaRule
|
|
|
10
10
|
from werkzeug.exceptions import BadRequest
|
|
11
11
|
from yaml.scanner import ScannerError
|
|
12
12
|
|
|
13
|
-
from howler.api import bad_request, make_subapi_blueprint, ok
|
|
13
|
+
from howler.api import bad_request, forbidden, make_subapi_blueprint, ok
|
|
14
14
|
from howler.common.loader import datastore
|
|
15
15
|
from howler.common.logging import get_logger
|
|
16
16
|
from howler.common.swagger import generate_swagger_docs
|
|
@@ -25,6 +25,8 @@ search_api._doc = "Perform search queries"
|
|
|
25
25
|
|
|
26
26
|
logger = get_logger(__file__)
|
|
27
27
|
|
|
28
|
+
SENSITIVE_USER_FIELDS = ["password", "apikeys", "*"]
|
|
29
|
+
|
|
28
30
|
|
|
29
31
|
def generate_params(request, fields, multi_fields, params=None):
|
|
30
32
|
"""Generate a list of parameters, combining the request data and the query arguments"""
|
|
@@ -137,6 +139,13 @@ def search(index, **kwargs):
|
|
|
137
139
|
if not query:
|
|
138
140
|
return bad_request(err="There was no search query.")
|
|
139
141
|
|
|
142
|
+
if (
|
|
143
|
+
"fl" in params
|
|
144
|
+
and index == "user"
|
|
145
|
+
and any(sensitive_field in params["fl"] for sensitive_field in SENSITIVE_USER_FIELDS)
|
|
146
|
+
):
|
|
147
|
+
return forbidden(err="Invalid fields to retrieve.")
|
|
148
|
+
|
|
140
149
|
try:
|
|
141
150
|
metadata = params.pop("metadata", [])
|
|
142
151
|
result = collection().search(query, **params)
|
|
@@ -277,6 +286,13 @@ def eql_search(index, **kwargs):
|
|
|
277
286
|
if not eql_query:
|
|
278
287
|
return bad_request(err="There was no EQL search query.")
|
|
279
288
|
|
|
289
|
+
if (
|
|
290
|
+
"fl" in params
|
|
291
|
+
and index == "user"
|
|
292
|
+
and any(sensitive_field in params["fl"] for sensitive_field in SENSITIVE_USER_FIELDS)
|
|
293
|
+
):
|
|
294
|
+
return forbidden(err="Invalid fields to retrieve.")
|
|
295
|
+
|
|
280
296
|
try:
|
|
281
297
|
return ok(collection().raw_eql_search(**params))
|
|
282
298
|
except (SearchException, BadRequestError) as e:
|
|
@@ -365,6 +381,13 @@ def sigma_search(index, **kwargs):
|
|
|
365
381
|
|
|
366
382
|
lucene_queries = LuceneBackend(index_names=[es_collection.index_name]).convert_rule(rule)
|
|
367
383
|
|
|
384
|
+
if (
|
|
385
|
+
"fl" in params
|
|
386
|
+
and index == "user"
|
|
387
|
+
and any(sensitive_field in params["fl"] for sensitive_field in SENSITIVE_USER_FIELDS)
|
|
388
|
+
):
|
|
389
|
+
return forbidden(err="Invalid fields to retrieve.")
|
|
390
|
+
|
|
368
391
|
try:
|
|
369
392
|
return ok(es_collection.search("*:*", **params, filters=[*params.get("filters", []), *lucene_queries]))
|
|
370
393
|
except (SearchException, BadRequestError) as e:
|
|
@@ -433,6 +456,13 @@ def group_search(index, group_field, **kwargs):
|
|
|
433
456
|
if not group_field:
|
|
434
457
|
return bad_request(err="The field to group on was not specified.")
|
|
435
458
|
|
|
459
|
+
if (
|
|
460
|
+
"fl" in params
|
|
461
|
+
and index == "user"
|
|
462
|
+
and any(sensitive_field in params["fl"] for sensitive_field in SENSITIVE_USER_FIELDS)
|
|
463
|
+
):
|
|
464
|
+
return forbidden(err="Invalid fields to retrieve.")
|
|
465
|
+
|
|
436
466
|
try:
|
|
437
467
|
return ok(collection().grouped_search(group_field, **params))
|
|
438
468
|
except (SearchException, BadRequestError) as e:
|
|
@@ -593,6 +623,9 @@ def facet(index, **kwargs):
|
|
|
593
623
|
logger.warning("Invalid field %s requested for faceting, skipping", field)
|
|
594
624
|
continue
|
|
595
625
|
|
|
626
|
+
if index == "user" and any(sensitive_field in field for sensitive_field in SENSITIVE_USER_FIELDS):
|
|
627
|
+
return forbidden(err="Invalid fields to facet on.")
|
|
628
|
+
|
|
596
629
|
facet_result[field] = collection().facet(field, **params)
|
|
597
630
|
|
|
598
631
|
return ok(facet_result)
|
|
@@ -643,6 +676,9 @@ def facet_field(index, field, **kwargs):
|
|
|
643
676
|
if field_info is None:
|
|
644
677
|
return bad_request(err=f"Field '{field}' is not a valid field in index: {index}")
|
|
645
678
|
|
|
679
|
+
if index == "user" and any(sensitive_field in field for sensitive_field in SENSITIVE_USER_FIELDS):
|
|
680
|
+
return forbidden(err="Invalid field to facet on.")
|
|
681
|
+
|
|
646
682
|
fields = ["query", "mincount", "rows"]
|
|
647
683
|
multi_fields = ["filters"]
|
|
648
684
|
|
|
@@ -422,7 +422,6 @@ class ESCollection(Generic[ModelType]):
|
|
|
422
422
|
res = None
|
|
423
423
|
while res is None:
|
|
424
424
|
attempt = attempt + 1
|
|
425
|
-
logger.warning("Checking status of task %s (Attempt %s)", task["task"], attempt)
|
|
426
425
|
try:
|
|
427
426
|
res = self.with_retries(
|
|
428
427
|
self.datastore.client.tasks.get,
|
|
@@ -443,8 +442,6 @@ class ESCollection(Generic[ModelType]):
|
|
|
443
442
|
|
|
444
443
|
result = res.get("response", res["task"]["status"])
|
|
445
444
|
|
|
446
|
-
logger.info("Task result:\n%s", str(result))
|
|
447
|
-
|
|
448
445
|
return result
|
|
449
446
|
|
|
450
447
|
def _get_current_alias(self, index: str) -> typing.Optional[str]:
|
|
@@ -28,7 +28,7 @@ TRANSPORT_TIMEOUT = int(os.environ.get("HWL_DATASTORE_TRANSPORT_TIMEOUT", "10"))
|
|
|
28
28
|
class LuceneProcessor(TreeVisitor):
|
|
29
29
|
"Tree visitor that evaluates a query on a given object"
|
|
30
30
|
|
|
31
|
-
def visit(self, tree: Any, context: dict[str, Any]) -> bool:
|
|
31
|
+
def visit(self, tree: Any, context: dict[str, Any]) -> bool: # pyright: ignore[reportIncompatibleMethodOverride]
|
|
32
32
|
"Visit each node in a tree"
|
|
33
33
|
return super().visit(tree, context)[0]
|
|
34
34
|
|
|
@@ -252,6 +252,8 @@ def match(lucene: str, obj: dict[str, Any]):
|
|
|
252
252
|
# which means the two are equivalent in elastic, but the second one is a lot less ambiguous to parse.
|
|
253
253
|
normalized_query = cast(str, result["explanations"][0]["explanation"])
|
|
254
254
|
|
|
255
|
+
normalized_query = re.sub(r"IndexOrDocValuesQuery *\(indexQuery=(.+?), dvQuery=.+?\)", r"\1", normalized_query)
|
|
256
|
+
|
|
255
257
|
# Elastic's explanation mangles exists queries. Since we will handle them the normal way, reset their changes
|
|
256
258
|
normalized_query = re.sub(r"FieldExistsQuery *\[.*?field=(.+?)]", r"_exists_:\1", normalized_query)
|
|
257
259
|
normalized_query = re.sub(r"ConstantScore", "", normalized_query)
|
|
@@ -20,7 +20,7 @@ def try_parse_date(date: str) -> Optional[datetime]:
|
|
|
20
20
|
return None
|
|
21
21
|
|
|
22
22
|
|
|
23
|
-
def try_parse_number(number:
|
|
23
|
+
def try_parse_number(number: str | int | float) -> int | float | None:
|
|
24
24
|
"Try and parse a number string into an integer or float type, or infinity. Returns None if string is invalid."
|
|
25
25
|
if isinstance(number, (int, float)):
|
|
26
26
|
return number
|
|
@@ -148,7 +148,7 @@ suppress-none-returning = true
|
|
|
148
148
|
[tool.poetry]
|
|
149
149
|
package-mode = true
|
|
150
150
|
name = "howler-api"
|
|
151
|
-
version = "3.1.
|
|
151
|
+
version = "3.1.1.485"
|
|
152
152
|
description = "Howler - API server"
|
|
153
153
|
authors = [
|
|
154
154
|
"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
|
|
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
|
|
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-3.1.0.dev426 → howler_api-3.1.1.485}/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
|