audit-labs/audit-tools
A collection of scripts, queries, and other goodies you can use in an audit.
clone: git clone https://gitbay.org/audit-labs/audit-tools.git
1"""
2Platform descriptors that let the TUI drive any collector runner.
3
4Each Platform declares its connection form (``fields``), its checks, and how to
5compute the output directory and run the audit. The screens in app.py are
6written against this interface, so adding a platform is data, not new UI.
7"""
8
9import os
10from collections.abc import Callable
11from dataclasses import dataclass, field
12
13from tui import aws_runner, github_runner, gitlab_runner
14from tui.common import Check
15
16
17@dataclass(frozen=True)
18class Field:
19 """One input on the connection screen."""
20
21 key: str
22 label: str
23 placeholder: str = ""
24 default: str = ""
25 password: bool = False
26 required: bool = False
27 env: str | None = None # environment variable used to pre-fill the value
28
29
30@dataclass(frozen=True)
31class Platform:
32 key: str
33 label: str
34 subject: Callable[
35 [dict], str
36 ] # (settings) -> audit subject shown on the run screen
37 fields: list[Field]
38 checks: list[Check]
39 default_selection: list[str]
40 output_dir: Callable[[dict], str] # (settings) -> path
41 run: Callable[..., object] # (settings, output_dir, selected_keys, on_event)
42 enabled: bool = True
43 note: str = field(default="")
44
45
46# Shared connection fields reused across platforms.
47_OUT_FIELD = Field("out", "Output directory", default="./output")
48
49
50def _prefill(f: Field) -> str:
51 if f.env:
52 value = os.environ.get(f.env, "").strip()
53 if value:
54 return value
55 return f.default
56
57
58def _github_output_dir(s: dict) -> str:
59 return github_runner.default_output_dir(s["out"], s["org"])
60
61
62def _github_run(s: dict, output_dir, selected_keys, on_event):
63 return github_runner.run_audit(
64 org=s["org"],
65 token=s["token"],
66 output_dir=output_dir,
67 branch=s["branch"],
68 selected_keys=selected_keys,
69 on_event=on_event,
70 )
71
72
73def _gitlab_output_dir(s: dict) -> str:
74 return gitlab_runner.default_output_dir(s["out"], s["group"])
75
76
77def _gitlab_run(s: dict, output_dir, selected_keys, on_event):
78 return gitlab_runner.run_audit(
79 group=s["group"],
80 token=s["token"],
81 base_url=s["base_url"],
82 output_dir=output_dir,
83 selected_keys=selected_keys,
84 on_event=on_event,
85 )
86
87
88def _aws_output_dir(s: dict) -> str:
89 return aws_runner.default_output_dir(s["out"], s["profile"])
90
91
92def _aws_run(s: dict, output_dir, selected_keys, on_event):
93 return aws_runner.run_audit(
94 profile=s["profile"],
95 region=s["region"],
96 account=s["account"],
97 output_dir=output_dir,
98 selected_keys=selected_keys,
99 on_event=on_event,
100 )
101
102
103GITHUB = Platform(
104 key="github",
105 label="GitHub",
106 subject=lambda s: s["org"],
107 fields=[
108 Field("org", "Organization", "my-org", required=True, env="GITHUB_ORG"),
109 Field(
110 "token",
111 "Personal access token",
112 "ghp_… (read:org, repo)",
113 password=True,
114 required=True,
115 env="GITHUB_TOKEN",
116 ),
117 _OUT_FIELD,
118 Field("branch", "Branch (for commit history)", default="main"),
119 ],
120 checks=github_runner.CHECKS,
121 default_selection=github_runner.DEFAULT_SELECTION,
122 output_dir=_github_output_dir,
123 run=_github_run,
124)
125
126GITLAB = Platform(
127 key="gitlab",
128 label="GitLab",
129 subject=lambda s: s["group"],
130 fields=[
131 Field(
132 "group",
133 "Group ID or path",
134 "e.g. 1234567 or my-group",
135 required=True,
136 env="GITLAB_GROUP",
137 ),
138 Field(
139 "token",
140 "Personal access token",
141 "glpat-… (read_api)",
142 password=True,
143 required=True,
144 env="GITLAB_TOKEN",
145 ),
146 Field(
147 "base_url",
148 "API base URL (self-hosted)",
149 default="https://gitlab.com/api/v4",
150 env="GITLAB_URL",
151 ),
152 _OUT_FIELD,
153 ],
154 checks=gitlab_runner.CHECKS,
155 default_selection=gitlab_runner.DEFAULT_SELECTION,
156 output_dir=_gitlab_output_dir,
157 run=_gitlab_run,
158)
159
160AWS = Platform(
161 key="aws",
162 label="AWS",
163 subject=lambda s: s["profile"] or "default",
164 fields=[
165 Field(
166 "profile",
167 "AWS profile",
168 "default chain, or a named / SSO profile",
169 env="AWS_PROFILE",
170 ),
171 Field("region", "Region", "e.g. us-east-1", env="AWS_DEFAULT_REGION"),
172 Field(
173 "account",
174 "Account name (SSO check only)",
175 "optional; defaults to current account",
176 env="AWS_AUDIT_ACCOUNT",
177 ),
178 _OUT_FIELD,
179 ],
180 checks=aws_runner.CHECKS,
181 default_selection=aws_runner.DEFAULT_SELECTION,
182 output_dir=_aws_output_dir,
183 run=_aws_run,
184)
185
186PLATFORMS = [GITHUB, GITLAB, AWS]
187
188
189def prefill(f: Field) -> str:
190 """Public accessor for a field's pre-filled value (env var or default)."""
191 return _prefill(f)