fluidattacks_core_models 14.5.0__tar.gz → 14.7.0__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.
- {fluidattacks_core_models-14.5.0 → fluidattacks_core_models-14.7.0}/.gitignore +1 -1
- {fluidattacks_core_models-14.5.0 → fluidattacks_core_models-14.7.0}/PKG-INFO +1 -1
- {fluidattacks_core_models-14.5.0 → fluidattacks_core_models-14.7.0}/fluidattacks_core/models/scanners/__init__.py +2 -0
- {fluidattacks_core_models-14.5.0 → fluidattacks_core_models-14.7.0}/fluidattacks_core/models/scanners/sspm_config.py +13 -0
- {fluidattacks_core_models-14.5.0 → fluidattacks_core_models-14.7.0}/fluidattacks_core/models/state_machines/types.py +1 -0
- {fluidattacks_core_models-14.5.0 → fluidattacks_core_models-14.7.0}/pyproject.toml +1 -1
- fluidattacks_core_models-14.7.0/tests/test_sspm_config.py +84 -0
- {fluidattacks_core_models-14.5.0 → fluidattacks_core_models-14.7.0}/tests/test_state_machines.py +15 -0
- {fluidattacks_core_models-14.5.0 → fluidattacks_core_models-14.7.0}/uv.lock +1 -1
- fluidattacks_core_models-14.5.0/tests/test_sspm_config.py +0 -38
- {fluidattacks_core_models-14.5.0 → fluidattacks_core_models-14.7.0}/.envrc +0 -0
- {fluidattacks_core_models-14.5.0 → fluidattacks_core_models-14.7.0}/fluidattacks_core/models/__init__.py +0 -0
- {fluidattacks_core_models-14.5.0 → fluidattacks_core_models-14.7.0}/fluidattacks_core/models/py.typed +0 -0
- {fluidattacks_core_models-14.5.0 → fluidattacks_core_models-14.7.0}/fluidattacks_core/models/scanners/apk_config.py +0 -0
- {fluidattacks_core_models-14.5.0 → fluidattacks_core_models-14.7.0}/fluidattacks_core/models/scanners/common_config.py +0 -0
- {fluidattacks_core_models-14.5.0 → fluidattacks_core_models-14.7.0}/fluidattacks_core/models/scanners/containers_sca_config.py +0 -0
- {fluidattacks_core_models-14.5.0 → fluidattacks_core_models-14.7.0}/fluidattacks_core/models/scanners/cspm_config.py +0 -0
- {fluidattacks_core_models-14.5.0 → fluidattacks_core_models-14.7.0}/fluidattacks_core/models/scanners/dast_config.py +0 -0
- {fluidattacks_core_models-14.5.0 → fluidattacks_core_models-14.7.0}/fluidattacks_core/models/scanners/loader.py +0 -0
- {fluidattacks_core_models-14.5.0 → fluidattacks_core_models-14.7.0}/fluidattacks_core/models/scanners/resolves_config.py +0 -0
- {fluidattacks_core_models-14.5.0 → fluidattacks_core_models-14.7.0}/fluidattacks_core/models/scanners/sast_config.py +0 -0
- {fluidattacks_core_models-14.5.0 → fluidattacks_core_models-14.7.0}/fluidattacks_core/models/scanners/sbom_config.py +0 -0
- {fluidattacks_core_models-14.5.0 → fluidattacks_core_models-14.7.0}/fluidattacks_core/models/scanners/sca_config.py +0 -0
- {fluidattacks_core_models-14.5.0 → fluidattacks_core_models-14.7.0}/fluidattacks_core/models/scanners/scan_config.py +0 -0
- {fluidattacks_core_models-14.5.0 → fluidattacks_core_models-14.7.0}/fluidattacks_core/models/scanners/sniffs_config.py +0 -0
- {fluidattacks_core_models-14.5.0 → fluidattacks_core_models-14.7.0}/fluidattacks_core/models/state_machines/__init__.py +0 -0
- {fluidattacks_core_models-14.5.0 → fluidattacks_core_models-14.7.0}/fluidattacks_core/models/state_machines/component_orchestrator.py +0 -0
- {fluidattacks_core_models-14.5.0 → fluidattacks_core_models-14.7.0}/fluidattacks_core/models/state_machines/root_scanner.py +0 -0
- {fluidattacks_core_models-14.5.0 → fluidattacks_core_models-14.7.0}/import-linter.cfg +0 -0
- {fluidattacks_core_models-14.5.0 → fluidattacks_core_models-14.7.0}/mypy.ini +0 -0
- {fluidattacks_core_models-14.5.0 → fluidattacks_core_models-14.7.0}/ruff.toml +0 -0
- {fluidattacks_core_models-14.5.0 → fluidattacks_core_models-14.7.0}/tests/__init__.py +0 -0
- {fluidattacks_core_models-14.5.0 → fluidattacks_core_models-14.7.0}/tests/test_component_orchestrator.py +0 -0
- {fluidattacks_core_models-14.5.0 → fluidattacks_core_models-14.7.0}/tests/test_loader_env.py +0 -0
- {fluidattacks_core_models-14.5.0 → fluidattacks_core_models-14.7.0}/tests/test_model_scanner.py +0 -0
- {fluidattacks_core_models-14.5.0 → fluidattacks_core_models-14.7.0}/tests/test_root_scanner.py +0 -0
|
@@ -37,6 +37,7 @@ from fluidattacks_core.models.scanners.sspm_config import (
|
|
|
37
37
|
AzureDevopsPat,
|
|
38
38
|
GithubApp,
|
|
39
39
|
GithubPat,
|
|
40
|
+
N8nApiKey,
|
|
40
41
|
SspmConfig,
|
|
41
42
|
)
|
|
42
43
|
|
|
@@ -60,6 +61,7 @@ __all__ = [
|
|
|
60
61
|
"GithubApp",
|
|
61
62
|
"GithubPat",
|
|
62
63
|
"LocalesEnum",
|
|
64
|
+
"N8nApiKey",
|
|
63
65
|
"OutputConfig",
|
|
64
66
|
"OutputFormat",
|
|
65
67
|
"ResolvesConfig",
|
|
@@ -41,7 +41,20 @@ class AzureDevopsPat(BaseModel):
|
|
|
41
41
|
return resolve_env_var(v, info)
|
|
42
42
|
|
|
43
43
|
|
|
44
|
+
class N8nApiKey(BaseModel):
|
|
45
|
+
model_config = {"extra": "forbid"}
|
|
46
|
+
base_url: str
|
|
47
|
+
api_key: str = Field(repr=False)
|
|
48
|
+
environment_id: str | None = None
|
|
49
|
+
|
|
50
|
+
@field_validator("api_key", mode="before")
|
|
51
|
+
@classmethod
|
|
52
|
+
def _resolve_credentials(cls, v: object, info: LoaderValidationInfo) -> object:
|
|
53
|
+
return resolve_env_var(v, info)
|
|
54
|
+
|
|
55
|
+
|
|
44
56
|
class SspmConfig(BaseModel):
|
|
45
57
|
model_config = {"extra": "forbid"}
|
|
46
58
|
github_credentials: list[GithubPat | GithubApp] = []
|
|
47
59
|
azure_devops_credentials: list[AzureDevopsPat] = []
|
|
60
|
+
n8n_credentials: list[N8nApiKey] = []
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from pydantic import ValidationError
|
|
3
|
+
|
|
4
|
+
from fluidattacks_core.models.scanners import AzureDevopsPat, GithubPat, N8nApiKey, SspmConfig
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def test_azure_devops_credential_resolves_its_token(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
8
|
+
monkeypatch.setenv("AZURE_TOKEN", "resolved-value")
|
|
9
|
+
cfg = SspmConfig.model_validate(
|
|
10
|
+
{
|
|
11
|
+
"azure_devops_credentials": [
|
|
12
|
+
{"organization": "acme", "pat_token": "${AZURE_TOKEN}"},
|
|
13
|
+
],
|
|
14
|
+
},
|
|
15
|
+
context={"resolve_env": True},
|
|
16
|
+
)
|
|
17
|
+
assert cfg.azure_devops_credentials == [
|
|
18
|
+
AzureDevopsPat(organization="acme", pat_token="resolved-value"), # noqa: S106
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def test_azure_devops_and_github_credentials_stay_independent(
|
|
23
|
+
monkeypatch: pytest.MonkeyPatch,
|
|
24
|
+
) -> None:
|
|
25
|
+
monkeypatch.setenv("GH_TOKEN", "gh-value")
|
|
26
|
+
monkeypatch.setenv("AZ_TOKEN", "az-value")
|
|
27
|
+
cfg = SspmConfig.model_validate(
|
|
28
|
+
{
|
|
29
|
+
"github_credentials": [{"organization": "gh-org", "pat_token": "${GH_TOKEN}"}],
|
|
30
|
+
"azure_devops_credentials": [{"organization": "az-org", "pat_token": "${AZ_TOKEN}"}],
|
|
31
|
+
},
|
|
32
|
+
context={"resolve_env": True},
|
|
33
|
+
)
|
|
34
|
+
assert cfg.github_credentials == [
|
|
35
|
+
GithubPat(organization="gh-org", pat_token="gh-value"), # noqa: S106
|
|
36
|
+
]
|
|
37
|
+
assert cfg.azure_devops_credentials == [
|
|
38
|
+
AzureDevopsPat(organization="az-org", pat_token="az-value"), # noqa: S106
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def test_n8n_credentials_resolve_their_key_and_keep_it_out_of_the_repr(
|
|
43
|
+
monkeypatch: pytest.MonkeyPatch,
|
|
44
|
+
) -> None:
|
|
45
|
+
monkeypatch.setenv("N8N_KEY", "resolved-value")
|
|
46
|
+
cfg = SspmConfig.model_validate(
|
|
47
|
+
{
|
|
48
|
+
"n8n_credentials": [
|
|
49
|
+
{
|
|
50
|
+
"base_url": "https://n8n.example.com",
|
|
51
|
+
"api_key": "${N8N_KEY}",
|
|
52
|
+
"environment_id": "env-1",
|
|
53
|
+
},
|
|
54
|
+
{"base_url": "https://n8n.example.com/${N8N_KEY}", "api_key": "${N8N_KEY}"},
|
|
55
|
+
],
|
|
56
|
+
},
|
|
57
|
+
context={"resolve_env": True},
|
|
58
|
+
)
|
|
59
|
+
assert cfg.n8n_credentials == [
|
|
60
|
+
N8nApiKey(
|
|
61
|
+
base_url="https://n8n.example.com",
|
|
62
|
+
api_key="resolved-value",
|
|
63
|
+
environment_id="env-1",
|
|
64
|
+
),
|
|
65
|
+
N8nApiKey(base_url="https://n8n.example.com/${N8N_KEY}", api_key="resolved-value"),
|
|
66
|
+
]
|
|
67
|
+
assert "resolved-value" not in repr(cfg)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
@pytest.mark.parametrize(
|
|
71
|
+
("credential", "error"),
|
|
72
|
+
[
|
|
73
|
+
(
|
|
74
|
+
{"base_url": "https://n8n.example.com", "api_key": "key", "organization": "acme"},
|
|
75
|
+
r"n8n_credentials\.0\.organization\n Extra inputs are not permitted",
|
|
76
|
+
),
|
|
77
|
+
({"base_url": "https://n8n.example.com"}, r"n8n_credentials\.0\.api_key\n Field required"),
|
|
78
|
+
({"api_key": "key"}, r"n8n_credentials\.0\.base_url\n Field required"),
|
|
79
|
+
],
|
|
80
|
+
ids=["unknown_key", "no_api_key", "no_base_url"],
|
|
81
|
+
)
|
|
82
|
+
def test_n8n_credential_refuses_what_flags_refuses(credential: dict[str, str], error: str) -> None:
|
|
83
|
+
with pytest.raises(ValidationError, match=error):
|
|
84
|
+
SspmConfig.model_validate({"n8n_credentials": [credential]})
|
{fluidattacks_core_models-14.5.0 → fluidattacks_core_models-14.7.0}/tests/test_state_machines.py
RENAMED
|
@@ -68,6 +68,21 @@ def test_state_machine_cloning_input_cloning_job_queue() -> None:
|
|
|
68
68
|
assert dumped["cloningJobQueue"] == "clones_warp"
|
|
69
69
|
|
|
70
70
|
|
|
71
|
+
def test_state_machine_cloning_input_bulk_sync_trigger() -> None:
|
|
72
|
+
with patch("fluidattacks_core.models.state_machines.types.uuid4", return_value=_FIXED_UUID):
|
|
73
|
+
machine_input = StateMachineCloningInput(
|
|
74
|
+
group_name="group1",
|
|
75
|
+
roots=["root1", "root2"],
|
|
76
|
+
user_email="user@example.com",
|
|
77
|
+
trigger="sync_git_roots_mutation",
|
|
78
|
+
execute_sifts=True,
|
|
79
|
+
)
|
|
80
|
+
dumped = machine_input.model_dump(by_alias=True, mode="json")
|
|
81
|
+
machine_name = machine_input.get_machine_name()
|
|
82
|
+
assert dumped["trigger"] == "sync_git_roots_mutation"
|
|
83
|
+
assert machine_name == f"group1_sync_git_roots_mutation-{_FIXED_UUID_TIME}"
|
|
84
|
+
|
|
85
|
+
|
|
71
86
|
def test_state_machine_execute_scanner_input() -> None:
|
|
72
87
|
with patch("fluidattacks_core.models.state_machines.types.uuid4", return_value=_FIXED_UUID):
|
|
73
88
|
machine_input = StateMachineExecuteScannerInput(
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import pytest
|
|
2
|
-
|
|
3
|
-
from fluidattacks_core.models.scanners import AzureDevopsPat, GithubPat, SspmConfig
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
def test_azure_devops_credential_resolves_its_token(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
7
|
-
monkeypatch.setenv("AZURE_TOKEN", "resolved-value")
|
|
8
|
-
cfg = SspmConfig.model_validate(
|
|
9
|
-
{
|
|
10
|
-
"azure_devops_credentials": [
|
|
11
|
-
{"organization": "acme", "pat_token": "${AZURE_TOKEN}"},
|
|
12
|
-
],
|
|
13
|
-
},
|
|
14
|
-
context={"resolve_env": True},
|
|
15
|
-
)
|
|
16
|
-
assert cfg.azure_devops_credentials == [
|
|
17
|
-
AzureDevopsPat(organization="acme", pat_token="resolved-value"), # noqa: S106
|
|
18
|
-
]
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
def test_azure_devops_and_github_credentials_stay_independent(
|
|
22
|
-
monkeypatch: pytest.MonkeyPatch,
|
|
23
|
-
) -> None:
|
|
24
|
-
monkeypatch.setenv("GH_TOKEN", "gh-value")
|
|
25
|
-
monkeypatch.setenv("AZ_TOKEN", "az-value")
|
|
26
|
-
cfg = SspmConfig.model_validate(
|
|
27
|
-
{
|
|
28
|
-
"github_credentials": [{"organization": "gh-org", "pat_token": "${GH_TOKEN}"}],
|
|
29
|
-
"azure_devops_credentials": [{"organization": "az-org", "pat_token": "${AZ_TOKEN}"}],
|
|
30
|
-
},
|
|
31
|
-
context={"resolve_env": True},
|
|
32
|
-
)
|
|
33
|
-
assert cfg.github_credentials == [
|
|
34
|
-
GithubPat(organization="gh-org", pat_token="gh-value"), # noqa: S106
|
|
35
|
-
]
|
|
36
|
-
assert cfg.azure_devops_credentials == [
|
|
37
|
-
AzureDevopsPat(organization="az-org", pat_token="az-value"), # noqa: S106
|
|
38
|
-
]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fluidattacks_core_models-14.5.0 → fluidattacks_core_models-14.7.0}/tests/test_loader_env.py
RENAMED
|
File without changes
|
{fluidattacks_core_models-14.5.0 → fluidattacks_core_models-14.7.0}/tests/test_model_scanner.py
RENAMED
|
File without changes
|
{fluidattacks_core_models-14.5.0 → fluidattacks_core_models-14.7.0}/tests/test_root_scanner.py
RENAMED
|
File without changes
|