feat: toggle all-certs view with A key (load_all_certs, Action.TOGGLE_ALL)

This commit is contained in:
Vlad Doloman
2026-06-24 02:36:32 +03:00
parent 629095e0d8
commit 1222fb46a4
3 changed files with 100 additions and 8 deletions

View File

@@ -124,6 +124,25 @@ def load_expiring_certs(
return results
def load_all_certs(pki_dir: str) -> list[CertInfo]:
"""Return all valid (V-status) certs, sorted by expiry date."""
now = datetime.now(tz=timezone.utc)
results: list[CertInfo] = []
with open(os.path.join(pki_dir, "index.txt")) as fh:
for line in fh:
parsed = _parse_index_line(line)
if parsed is None:
continue
cn, expiry = parsed
results.append(CertInfo(
cn=cn,
expires=expiry,
days_left=(expiry - now).days,
))
results.sort(key=lambda c: c.expires)
return results
# ============================================================
# === PASSWORD ===
# ============================================================
@@ -609,6 +628,7 @@ class Action(Enum):
NEW_CERT = auto()
REGEN_CRL = auto()
REVOKE = auto()
TOGGLE_ALL = auto()
EXIT = auto()
@@ -632,7 +652,9 @@ def _expiry_label(c: CertInfo) -> str:
return f"[exp in {c.days_left}d] "
def show_main_screen(stdscr, certs: list[CertInfo]) -> ScreenResult:
def show_main_screen(
stdscr, certs: list[CertInfo], show_all: bool = False
) -> ScreenResult:
"""Display cert selection list. Returns when user activates an action."""
init_colors()
curses.curs_set(0)
@@ -649,8 +671,9 @@ def show_main_screen(stdscr, certs: list[CertInfo]) -> ScreenResult:
stdscr.clear()
sh, sw = stdscr.getmaxyx()
# Header bar
hdr = " openvpncertupdate — VPN Certificate Manager "
# Header bar — shows current filter mode
mode = "ALL certs" if show_all else "expiring/expired"
hdr = f" openvpncertupdate — VPN Certificate Manager [{mode}] "
try:
stdscr.addstr(0, 0, hdr.ljust(sw)[:sw],
curses.color_pair(COLOR_TITLE) | curses.A_BOLD)
@@ -658,7 +681,7 @@ def show_main_screen(stdscr, certs: list[CertInfo]) -> ScreenResult:
pass
# Footer hint
hint = " ↑↓:Navigate Space:Check Enter:Confirm R:Revoke Q:Quit"
hint = " ↑↓:Navigate Space:Check Enter:Confirm R:Revoke A:Toggle view Q:Quit"
try:
stdscr.addstr(sh - 1, 0, hint[:sw], curses.color_pair(COLOR_DISABLED))
except curses.error:
@@ -737,6 +760,9 @@ def show_main_screen(stdscr, certs: list[CertInfo]) -> ScreenResult:
return ScreenResult(action=Action.EXIT)
# _MENU_NEW when checked → grayed, ignore
elif key in (ord("a"), ord("A")):
return ScreenResult(action=Action.TOGGLE_ALL)
elif key in (ord("r"), ord("R")) and is_cert(cursor):
cert = certs[cursor]
if show_confirm(
@@ -759,19 +785,25 @@ class CursesApp:
curses.curs_set(0)
init_colors()
show_all = False
while True:
try:
certs = load_expiring_certs(
EASYRSA_PKI_DIR, DAYS_PAST, DAYS_AHEAD,
certs = (
load_all_certs(EASYRSA_PKI_DIR)
if show_all
else load_expiring_certs(EASYRSA_PKI_DIR, DAYS_PAST, DAYS_AHEAD)
)
except FileNotFoundError as exc:
self._fatal(stdscr, f"Cannot read PKI index.txt:\n{exc}")
return
result = show_main_screen(stdscr, certs)
result = show_main_screen(stdscr, certs, show_all=show_all)
if result.action == Action.EXIT:
return
elif result.action == Action.TOGGLE_ALL:
show_all = not show_all
elif result.action == Action.REGEN_CRL:
self._regen_crl(stdscr)
elif result.action == Action.REVOKE: