From 6e065dbd08635c1b0e4597376387b8607be8f0df Mon Sep 17 00:00:00 2001 From: mpabi Date: Sun, 26 Apr 2026 20:52:44 +0200 Subject: [PATCH] Add token validity and endpoint columns --- README.md | 1 + doc/rvctl.md | 13 +++++++------ doc/tokens.md | 3 +++ rvctl.py | 21 +++++++++++++++++++-- 4 files changed, 30 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index ab42b92..c58a00d 100644 --- a/README.md +++ b/README.md @@ -161,6 +161,7 @@ Podstawowe komendy tokenow: remote i `tokens.json` sa zgodne oraz uprawnienia zostaly wczytane, `R` oznacza token tylko w remote, a `S` token tylko w `tokens.json`. Kolumny `scope`, `org` i `repo` sa maskami uprawnien; bez `*` maja wartosc `?????` albo `????`. +Kolumna `valid` oznacza, czy token zostal zaakceptowany przez API teraz. ## Fetch i switch diff --git a/doc/rvctl.md b/doc/rvctl.md index 7023313..07a4c05 100644 --- a/doc/rvctl.md +++ b/doc/rvctl.md @@ -304,9 +304,9 @@ Typowy wynik: ```text tokens -item server host org repo user remote token_ref token scope org repo ----- ------ ------------- --------- ----------- ---- ------ --------- ------------ ------ ------ ------ -1 gitea 77.90.8.171 edu-tools rv-launcher u1 r1 t1 * e59cc...13be +---+ +++++ ++++ +item server proto host port org repo user remote token_ref token valid scope org repo +---- ------ ----- ------------- ----- --------- ----------- ---- ------ --------- ------------ ----- awrop- oawrc- oawr-- +1 gitea http 77.90.8.171 3001 edu-tools rv-launcher u1 r1 t1 * e59cc...13be + +---+ +++++ ++++ ``` `token_ref` jest komorka stalej szerokosci: nazwa tokena jest po lewej, a marker @@ -320,6 +320,7 @@ Maski uprawnien: - `org` ma pozycje `oawrc`: owner, admin, write, read, create repo - `repo` ma pozycje `oawr`: owner, admin, write, read - `+` oznacza wlaczone, `-` wylaczone, `?` nie wczytano, `!` blad wczytania +- `valid` oznacza wynik sprawdzenia tokena przez API: `+` dziala, `-` odrzucony, `?` nie sprawdzono, `!` blad Przyklad: @@ -382,9 +383,9 @@ repo_root... token_path... tokens -item server host org repo user remote token_ref token scope org repo ----- ------ ------------- --------- ----------- ---- ------ --------- ------------ ------ ------ ------ -1 gitea 77.90.8.171 edu-tools rv-launcher u1 r1 t1 * e59cc...13be +---+ +++++ ++++ +item server proto host port org repo user remote token_ref token valid scope org repo +---- ------ ----- ------------- ----- --------- ----------- ---- ------ --------- ------------ ----- awrop- oawrc- oawr-- +1 gitea http 77.90.8.171 3001 edu-tools rv-launcher u1 r1 t1 * e59cc...13be + +---+ +++++ ++++ status itemvalue diff --git a/doc/tokens.md b/doc/tokens.md index 803b254..670b96a 100644 --- a/doc/tokens.md +++ b/doc/tokens.md @@ -104,13 +104,16 @@ Kolumny w tabeli `tokens`: - `item` - numer wiersza tokena - `server` - typ serwera, na przyklad `gitea` +- `proto` - protokol endpointu, na przyklad `http` - `host` - host endpointu, na przyklad `77.90.8.171` +- `port` - port endpointu, na przyklad `3001` - `org` - organizacja z remote URL - `repo` - repo z remote URL - `user` - login wlasciciela tokena - `remote` - nazwa remota, na przyklad `r1` - `token_ref` - nazwa tokena z markerem po prawej stronie - `token` - zamaskowana wartosc tokena +- `valid` - wynik sprawdzenia tokena przez API: `+` dziala, `-` odrzucony, `?` nie sprawdzono, `!` blad - `scope` - maska scope tokena `awrop` - `org` - maska praw w organizacji `oawrc` - `repo` - maska praw w repo `oawr` diff --git a/rvctl.py b/rvctl.py index 50604d7..367fb31 100644 --- a/rvctl.py +++ b/rvctl.py @@ -716,18 +716,27 @@ TOKEN_REF_WIDTH = 9 TOKEN_COLUMNS = [ ("item", "item", 4), ("server", "server", 6), + ("proto", "proto", 5), ("host", "host", 13), + ("port", "port", 5), ("owner", "org", 9), ("repo_name", "repo", 11), ("user", "user", 4), ("remote", "remote", 6), ("token_ref", "token_ref", TOKEN_REF_WIDTH), ("token", "token", 12), + ("valid", "valid", 5), ("scope_mask", "scope", 6), ("org_mask", "org", 6), ("repo_mask", "repo", 6), ] +TOKEN_SEPARATOR_OVERRIDES = { + "scope_mask": "awrop-", + "org_mask": "oawrc-", + "repo_mask": "oawr--", +} + def fit_cell(value: str, width: int) -> str: if len(value) <= width: @@ -740,7 +749,7 @@ def fit_cell(value: str, width: int) -> str: def print_fixed_table(title: str, columns: list[tuple[str, str, int]], rows: list[dict[str, str]]) -> None: print(title) print(" ".join(fit_cell(label, width) for _, label, width in columns).rstrip()) - print(" ".join("-" * width for _, _, width in columns).rstrip()) + print(" ".join(fit_cell(TOKEN_SEPARATOR_OVERRIDES.get(name, "-" * width), width) for name, _, width in columns).rstrip()) for row in rows: print(" ".join(fit_cell(row.get(name, ""), width) for name, _, width in columns).rstrip()) @@ -928,6 +937,7 @@ def load_gitea_authz(endpoint: str, user_name: str, token_name: str, token_value api_base = endpoint.rstrip("/") + "/api/v1" result = { "ok": False, + "valid": "!", "scope_mask": "!!!!!", "org_mask": "!!!!!", "repo_mask": "!!!!", @@ -936,6 +946,7 @@ def load_gitea_authz(endpoint: str, user_name: str, token_name: str, token_value try: tokens_url = f"{api_base}/users/{quote(user_name, safe='')}/tokens" token_list = api_get_json(tokens_url, token_value, user_name=user_name, basic=True) + result["valid"] = "+" token_last8 = token_value[-8:] token_entry = next( ( @@ -967,7 +978,10 @@ def load_gitea_authz(endpoint: str, user_name: str, token_name: str, token_value result["ok"] = True return result - except (OSError, ValueError, urlerror.URLError, urlerror.HTTPError): + except urlerror.HTTPError as error: + result["valid"] = "-" if error.code in {401, 403} else "!" + return result + except (OSError, ValueError, urlerror.URLError): return result @@ -1016,13 +1030,16 @@ def print_token_item_rows( { "item": str(len(token_rows) + 1), "server": endpoint_values["server"], + "proto": endpoint_values["scheme"], "host": endpoint_values["host"], + "port": endpoint_values["port"], "owner": owner, "repo_name": repo_name, "user": user_name, "remote": remote_name, "token_ref": format_token_ref(token_name, marker), "token": short_secret(token_value), + "valid": authz.get("valid", "?") if authz else "?", "scope_mask": authz.get("scope_mask", "?????") if authz else "?????", "org_mask": authz.get("org_mask", "?????") if authz else "?????", "repo_mask": authz.get("repo_mask", "????") if authz else "????",