Files
daniel156161 7fe0e27fec
Testing / remote-protocol-compat (0.9.3) (push) Successful in 46s
Testing / remote-protocol-compat (0.9.5) (push) Successful in 47s
Testing / test (push) Successful in 36s
feat(auth): add interactive key policy editing
- Add auth policy to update existing authorized_keys allow policies locally or over remote serve.
- Support key lookup by public key or exact name, with safe, all, server-default, and category-based modes.
- Add questionary-powered interactive key selection and checkbox policy editing with current policy preselected.
- Show policy descriptions in auth keys output so each capability is easier to understand.
- Gate the new remote control command behind the existing keys policy category and include protocol routing/compat updates.
- Bump real-browser-cli to 0.16.2 and lock the new questionary dependency.
- Cover local, remote, validation, and policy-category behavior in tests.
2026-06-18 15:02:18 +02:00

51 lines
2.0 KiB
Python

"""
Auth-field normalizers — applied to the raw incoming message *before* the
auth check runs. Protocol fields (pubkey, sig, …) are still present here.
Add one entry per breaking auth-field change:
("X.Y.Z", transformer_fn)
Entries must stay in ascending version order.
"""
from __future__ import annotations
from typing import Callable
from browser_cli.version_manager import parse_version
# ── v0.9.3 ────────────────────────────────────────────────────────────────────
def _auth_0_9_3(msg: dict) -> dict:
"""pubkey validation tightened to lowercase hex; normalize for older clients."""
changed: dict = {}
pk = msg.get("pubkey")
if isinstance(pk, str) and pk:
changed["pubkey"] = pk.lower()
if msg.get("command") in {"browser-cli.auth.trust", "browser-cli.auth.policy"}:
args = msg.get("args") or {}
trust_pk = args.get("pubkey")
identifier = args.get("identifier")
patched = dict(args)
if isinstance(trust_pk, str) and trust_pk:
patched["pubkey"] = trust_pk.lower()
if isinstance(identifier, str) and identifier and len(identifier) == 64:
patched["identifier"] = identifier.lower()
if patched != args:
changed["args"] = patched
return {**msg, **changed} if changed else msg
# ── registry ──────────────────────────────────────────────────────────────────
_AUTH_COMPAT: list[tuple[str, Callable[[dict], dict]]] = [
("0.9.3", _auth_0_9_3),
]
def adapt_auth(msg: dict, client_version: str) -> dict:
"""Apply all auth normalizers needed to bring msg up to the current format."""
cv = parse_version(client_version)
for version, fn in _AUTH_COMPAT:
if cv < parse_version(version):
msg = fn(msg)
return msg