clue-api 1.0.0.dev14__tar.gz → 1.0.0.dev34__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.
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/PKG-INFO +2 -3
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/models/config.py +0 -1
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/plugin/interactive.py +0 -8
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/security/obo.py +5 -13
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/pyproject.toml +2 -4
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/LICENSE +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/README.md +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/.gitignore +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/__init__.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/api/__init__.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/api/base.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/api/v1/__init__.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/api/v1/actions.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/api/v1/auth.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/api/v1/configs.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/api/v1/fetchers.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/api/v1/lookup.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/api/v1/registration.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/api/v1/static.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/app.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/cache/__init__.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/common/__init__.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/common/classification.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/common/classification.yml +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/common/dict_utils.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/common/exceptions.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/common/forge.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/common/json_utils.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/common/list_utils.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/common/logging/__init__.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/common/logging/audit.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/common/logging/format.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/common/regex.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/common/str_utils.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/common/swagger.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/common/uid.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/config.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/constants/__init__.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/constants/supported_types.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/cronjobs/__init__.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/cronjobs/plugins.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/error.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/gunicorn_config.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/healthz.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/helper/discover.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/helper/headers.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/helper/oauth.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/models/__init__.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/models/actions.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/models/fetchers.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/models/graph.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/models/model_list.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/models/network.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/models/results/__init__.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/models/results/base.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/models/results/graph.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/models/results/image.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/models/results/status.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/models/results/validation.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/models/selector.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/models/utils.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/models/validators.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/patched.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/plugin/__init__.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/plugin/helpers/__init__.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/plugin/helpers/central_server.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/plugin/helpers/email_render.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/plugin/helpers/token.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/plugin/helpers/trino.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/plugin/models.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/plugin/utils.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/remote/__init__.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/remote/datatypes/__init__.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/remote/datatypes/cache.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/remote/datatypes/events.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/remote/datatypes/hash.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/remote/datatypes/queues/__init__.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/remote/datatypes/queues/comms.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/remote/datatypes/set.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/remote/datatypes/user_quota_tracker.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/security/__init__.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/security/utils.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/services/action_service.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/services/auth_service.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/services/config_service.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/services/fetcher_service.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/services/jwt_service.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/services/lookup_service.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/services/type_service.py +0 -0
- {clue_api-1.0.0.dev14 → clue_api-1.0.0.dev34}/clue/services/user_service.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: clue-api
|
|
3
|
-
Version: 1.0.0.
|
|
3
|
+
Version: 1.0.0.dev34
|
|
4
4
|
Summary: Clue distributed enrichment service
|
|
5
5
|
License: MIT
|
|
6
6
|
License-File: LICENSE
|
|
@@ -31,9 +31,8 @@ Requires-Dist: flask-caching (>=2.1.0,<3.0.0)
|
|
|
31
31
|
Requires-Dist: flask-cors (>=4.0.1,<5.0.0) ; extra == "server"
|
|
32
32
|
Requires-Dist: gevent (>=24.2.1,<25.0.0)
|
|
33
33
|
Requires-Dist: geventhttpclient (>=2.3.1,<3.0.0)
|
|
34
|
-
Requires-Dist: gunicorn (>=22
|
|
34
|
+
Requires-Dist: gunicorn (>=22,<24)
|
|
35
35
|
Requires-Dist: imgkit (>=1.2.3,<2.0.0)
|
|
36
|
-
Requires-Dist: netifaces (>=0.11.0,<0.12.0) ; extra == "server"
|
|
37
36
|
Requires-Dist: passlib (>=1.7.4,<2.0.0) ; extra == "server"
|
|
38
37
|
Requires-Dist: pillow (>=11.1.0,<12.0.0)
|
|
39
38
|
Requires-Dist: prometheus-client (>=0.20.0,<0.21.0) ; extra == "server"
|
|
@@ -378,7 +378,6 @@ class API(BaseModel):
|
|
|
378
378
|
validate_session_xsrf_token: bool = Field(
|
|
379
379
|
description="Validate if the XSRF token matches the randomly generated token for the session", default=True
|
|
380
380
|
)
|
|
381
|
-
vault_url: str = Field(default="https://vault.vault.svc.cluster.local:8200")
|
|
382
381
|
|
|
383
382
|
|
|
384
383
|
root_path = Path("/etc") / APP_NAME
|
|
@@ -229,14 +229,6 @@ def main(): # noqa: C901
|
|
|
229
229
|
Environment variable CLUE_ACCESS_TOKEN not set!
|
|
230
230
|
|
|
231
231
|
It is highly likely your plugin will not work if it connects to an external service.
|
|
232
|
-
|
|
233
|
-
You'll need to generate a matching token. If on jupyhub, run:
|
|
234
|
-
|
|
235
|
-
export CLUE_ACCESS_TOKEN=$(python -c "from hogwarts.auth.vault.credentials import ClueTokenCredential; print(ClueTokenCredential().get_token().token)")
|
|
236
|
-
|
|
237
|
-
If you need a different token use the corresponding credential (i.e., trino -> TrinoTokenCredential, howler -> HowlerTokenCredential).
|
|
238
|
-
|
|
239
|
-
If you're developing on your local machine, talk to Matthew Rafuse <Matthew.Rafuse@cyber.gc.ca> on Teams.
|
|
240
232
|
""").strip() # noqa: E501
|
|
241
233
|
)
|
|
242
234
|
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
from datetime import datetime
|
|
2
2
|
from typing import Optional
|
|
3
3
|
|
|
4
|
-
# from hogwarts.auth.vault.exceptions import VaultRequestException
|
|
5
|
-
# from hogwarts.auth.vault.vault_client import VaultClient
|
|
6
4
|
from clue.common.exceptions import InvalidDataException
|
|
7
5
|
from clue.common.logging import get_logger
|
|
8
6
|
from clue.config import config, get_redis
|
|
@@ -34,7 +32,7 @@ def _get_token_raw(service: str, user: str) -> Optional[str]:
|
|
|
34
32
|
|
|
35
33
|
|
|
36
34
|
def get_obo_token(service: str, access_token: str, user: str, force_refresh: bool = False):
|
|
37
|
-
"""Gets an On-Behalf-Of token from either the Redis cache or from the
|
|
35
|
+
"""Gets an On-Behalf-Of token from either the Redis cache or from the provided authentication plugin.
|
|
38
36
|
|
|
39
37
|
Args:
|
|
40
38
|
service (str): The target application we want a token for.
|
|
@@ -71,13 +69,7 @@ def get_obo_token(service: str, access_token: str, user: str, force_refresh: boo
|
|
|
71
69
|
if obo_access_token is None:
|
|
72
70
|
logger.info(f"Fetching OBO token for user {user} to service {service}")
|
|
73
71
|
|
|
74
|
-
|
|
75
|
-
# vault_client = VaultClient(url=config.api.vault_url)
|
|
76
|
-
# obo_access_token, _ = vault_client.on_behalf_of(
|
|
77
|
-
# config.api.obo_targets[service].scope,
|
|
78
|
-
# access_token,
|
|
79
|
-
# token_client_name=APP_NAME.replace("-dev", ""),
|
|
80
|
-
# )
|
|
72
|
+
# TODO: figure out plugin-based OBO system
|
|
81
73
|
obo_access_token = None
|
|
82
74
|
|
|
83
75
|
if obo_access_token:
|
|
@@ -85,11 +77,11 @@ def get_obo_token(service: str, access_token: str, user: str, force_refresh: boo
|
|
|
85
77
|
service_token_store.pop_all()
|
|
86
78
|
service_token_store.add(obo_access_token)
|
|
87
79
|
else:
|
|
88
|
-
logger.error("
|
|
80
|
+
logger.error("OBO failed, no token received.")
|
|
89
81
|
else:
|
|
90
82
|
logger.debug("Using cached OBO token")
|
|
91
83
|
|
|
92
84
|
return obo_access_token
|
|
93
85
|
except Exception:
|
|
94
|
-
|
|
95
|
-
|
|
86
|
+
logger.exception("Exception on OBO:")
|
|
87
|
+
return None
|
|
@@ -164,7 +164,7 @@ log_cli_level = "INFO"
|
|
|
164
164
|
[tool.poetry]
|
|
165
165
|
package-mode = true
|
|
166
166
|
name = "clue-api"
|
|
167
|
-
version = "1.0.0.
|
|
167
|
+
version = "1.0.0.dev34"
|
|
168
168
|
description = "Clue distributed enrichment service"
|
|
169
169
|
authors = ["Canadian Centre for Cyber Security <contact@cyber.gc.ca>"]
|
|
170
170
|
license = "MIT"
|
|
@@ -199,7 +199,7 @@ python = "^3.12"
|
|
|
199
199
|
elastic-apm = "^6.22.0"
|
|
200
200
|
flask = "<3.0.0"
|
|
201
201
|
flask-caching = "^2.1.0"
|
|
202
|
-
gunicorn = "
|
|
202
|
+
gunicorn = ">=22,<24"
|
|
203
203
|
gevent = "^24.2.1"
|
|
204
204
|
pydantic = "^2.7.1"
|
|
205
205
|
geventhttpclient = "^2.3.1"
|
|
@@ -217,7 +217,6 @@ Werkzeug = { version = "^3.0.2", optional = true }
|
|
|
217
217
|
bcrypt = { version = "^4.1.2", optional = true }
|
|
218
218
|
PyYAML = { version = "^6.0.1", optional = true }
|
|
219
219
|
python-baseconv = { version = "^1.2.2", optional = true }
|
|
220
|
-
netifaces = { version = "^0.11.0", optional = true }
|
|
221
220
|
pyroute2 = { version = "^0.7.12", optional = true }
|
|
222
221
|
pyjwt = { version = "^2.8.0", optional = true }
|
|
223
222
|
prometheus-client = { version = "^0.20.0", optional = true }
|
|
@@ -235,7 +234,6 @@ server = [
|
|
|
235
234
|
"bcrypt",
|
|
236
235
|
"PyYAML",
|
|
237
236
|
"python-baseconv",
|
|
238
|
-
"netifaces",
|
|
239
237
|
"pyroute2",
|
|
240
238
|
"pyjwt",
|
|
241
239
|
"prometheus-client",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|