Report token scan results in tables

This commit is contained in:
mpabi
2026-04-26 15:23:33 +02:00
parent a84b0e1fbd
commit 2b672d2137
4 changed files with 116 additions and 29 deletions
+3
View File
@@ -149,6 +149,9 @@ Podstawowe komendy tokenow:
./rvctl tokens stats --repo ~/dev/workspace/rv/series/inf/03 ./rvctl tokens stats --repo ~/dev/workspace/rv/series/inf/03
``` ```
`tokens scan` wypisuje tabele TSV. Remote bez `LOGIN:TOKEN@` bedzie pokazany
jako `url_kind=plain` i `result=no_credentials`.
## Fetch i switch ## Fetch i switch
Domyslna galaz launchera to `main`. Domyslna galaz launchera to `main`.
+12 -5
View File
@@ -276,13 +276,20 @@ Przelaczniki:
Typowy wynik: Typowy wynik:
```text ```text
repo_root<TAB>... summary
scanned<TAB>1 repo_root<TAB>remotes<TAB>urls<TAB>scanned<TAB>auth_urls<TAB>plain_urls<TAB>unsupported_urls<TAB>found<TAB>added<TAB>servers<TAB>token_path
added<TAB>1 ...<TAB>1<TAB>1<TAB>1<TAB>1<TAB>0<TAB>0<TAB>1<TAB>1<TAB>1<TAB>...
servers<TAB>1
token_path<TAB>... remotes
remote<TAB>endpoint<TAB>type<TAB>url_kind<TAB>user<TAB>result
r1<TAB>http://77.90.8.171:3001<TAB>gitea<TAB>auth<TAB>u1<TAB>added
``` ```
Jesli remote istnieje, ale ma URL bez `LOGIN:TOKEN@`, wynik bedzie mial
`plain_urls=1`, `auth_urls=0`, `found=0`, `added=0`, a w tabeli `remotes`
pojawi sie `url_kind=plain` i `result=no_credentials`. To znaczy, ze `scan`
sprawdzil remote, ale nie znalazl sekretu do zapisania.
Przyklad: Przyklad:
```bash ```bash
+10
View File
@@ -84,6 +84,16 @@ Dzialanie:
- skanuje remote URL-e w repo - skanuje remote URL-e w repo
- zapisuje znalezione tokeny do `tokens.json` - zapisuje znalezione tokeny do `tokens.json`
- zapisuje je per endpoint serwera - zapisuje je per endpoint serwera
- wypisuje wynik jako tabele TSV: `summary` oraz `remotes`
Kolumny w tabeli `remotes`:
- `remote` - nazwa remote, na przyklad `r1`
- `endpoint` - serwer bez sekretu, na przyklad `http://77.90.8.171:3001`
- `type` - typ serwera, na przyklad `gitea`
- `url_kind` - `auth`, `plain` albo `unsupported`
- `user` - login odczytany z URL, tylko dla `auth`
- `result` - `added`, `existing`, `no_credentials` albo `ignored`
Przyklad: Przyklad:
+91 -24
View File
@@ -425,45 +425,98 @@ def sync_tokens_from_repo(config: WorkspaceConfig, repo_path: Path) -> dict:
if repo_root is None: if repo_root is None:
return { return {
"repo_root": None, "repo_root": None,
"remotes": 0,
"urls": 0,
"scanned": 0, "scanned": 0,
"auth_urls": 0,
"plain_urls": 0,
"unsupported_urls": 0,
"found": 0,
"added": 0, "added": 0,
"servers": 0, "servers": 0,
"remote_rows": [],
"changed": False, "changed": False,
} }
found_credentials: list[tuple[dict, str, str]] = [] found_credentials: list[tuple[int, dict, str, str]] = []
for remote_url in remote_urls(repo_root): remote_entries = remote_name_urls(repo_root)
remote_names = {remote_name for remote_name, _ in remote_entries}
touched_servers: set[str] = set()
remote_rows: list[dict[str, str]] = []
auth_urls = 0
plain_urls = 0
unsupported_urls = 0
for remote_name, remote_url in remote_entries:
server_info = server_info_from_url(config, remote_url) server_info = server_info_from_url(config, remote_url)
credentials = remote_credentials(remote_url) if server_info is None:
if server_info is not None and credentials is not None: unsupported_urls += 1
user_name, token_value = credentials remote_rows.append(
found_credentials.append((server_info, user_name, token_value)) {
"remote": remote_name,
"endpoint": "",
"type": "unsupported",
"url_kind": "unsupported",
"user": "",
"result": "ignored",
}
)
continue
if not found_credentials: touched_servers.add(server_info["endpoint"])
return { credentials = remote_credentials(remote_url)
"repo_root": repo_root, if credentials is None:
"scanned": 0, plain_urls += 1
"added": 0, remote_rows.append(
"servers": 0, {
"changed": False, "remote": remote_name,
} "endpoint": server_info["endpoint"],
"type": server_info["type"],
"url_kind": "plain",
"user": "",
"result": "no_credentials",
}
)
continue
auth_urls += 1
user_name, token_value = credentials
row_index = len(remote_rows)
remote_rows.append(
{
"remote": remote_name,
"endpoint": server_info["endpoint"],
"type": server_info["type"],
"url_kind": "auth",
"user": user_name,
"result": "found",
}
)
found_credentials.append((row_index, server_info, user_name, token_value))
token_data = load_token_store(config) token_data = load_token_store(config)
added = 0 added = 0
touched_servers: set[str] = set() for row_index, server_info, user_name, token_value in found_credentials:
for server_info, user_name, token_value in found_credentials:
touched_servers.add(server_info["endpoint"])
if register_token(token_data, server_info, user_name, token_value): if register_token(token_data, server_info, user_name, token_value):
added += 1 added += 1
remote_rows[row_index]["result"] = "added"
else:
remote_rows[row_index]["result"] = "existing"
if added or not config.token_path.exists(): if found_credentials and (added or not config.token_path.exists()):
write_token_store(config, token_data) write_token_store(config, token_data)
return { return {
"repo_root": repo_root, "repo_root": repo_root,
"scanned": len(found_credentials), "remotes": len(remote_names),
"urls": len(remote_entries),
"scanned": auth_urls + plain_urls,
"auth_urls": auth_urls,
"plain_urls": plain_urls,
"unsupported_urls": unsupported_urls,
"found": len(found_credentials),
"added": added, "added": added,
"servers": len(touched_servers), "servers": len(touched_servers),
"remote_rows": remote_rows,
"changed": added > 0, "changed": added > 0,
} }
@@ -656,11 +709,25 @@ def resolve_repo_argument(repo_arg: str | None) -> Path:
def run_tokens_scan(config: WorkspaceConfig, args: argparse.Namespace) -> None: def run_tokens_scan(config: WorkspaceConfig, args: argparse.Namespace) -> None:
report = sync_tokens_from_repo(config, resolve_repo_argument(args.repo)) report = sync_tokens_from_repo(config, resolve_repo_argument(args.repo))
repo_root = report["repo_root"] repo_root = report["repo_root"]
print(f"repo_root\t{repo_root or ''}") print("summary")
print(f"scanned\t{report['scanned']}") print(
print(f"added\t{report['added']}") "repo_root\tremotes\turls\tscanned\tauth_urls\tplain_urls\t"
print(f"servers\t{report['servers']}") "unsupported_urls\tfound\tadded\tservers\ttoken_path"
print(f"token_path\t{config.token_path}") )
print(
f"{repo_root or ''}\t{report['remotes']}\t{report['urls']}\t"
f"{report['scanned']}\t{report['auth_urls']}\t{report['plain_urls']}\t"
f"{report['unsupported_urls']}\t{report['found']}\t{report['added']}\t"
f"{report['servers']}\t{config.token_path}"
)
print()
print("remotes")
print("remote\tendpoint\ttype\turl_kind\tuser\tresult")
for row in report["remote_rows"]:
print(
f"{row['remote']}\t{row['endpoint']}\t{row['type']}\t"
f"{row['url_kind']}\t{row['user']}\t{row['result']}"
)
def run_tokens_read(config: WorkspaceConfig, args: argparse.Namespace) -> None: def run_tokens_read(config: WorkspaceConfig, args: argparse.Namespace) -> None: