feat: add secure secret provider
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import getpass
|
||||
import sys
|
||||
from collections.abc import Callable, Sequence
|
||||
|
||||
@@ -16,6 +17,7 @@ from javis.memory.sqlite_store import (
|
||||
)
|
||||
from javis.providers.base import ProviderError
|
||||
from javis.providers.ollama import OllamaProvider
|
||||
from javis.security.secrets import SecretProvider, SecretStoreError
|
||||
|
||||
InputFunction = Callable[[str], str]
|
||||
OutputFunction = Callable[[str], None]
|
||||
@@ -34,9 +36,49 @@ def build_parser() -> argparse.ArgumentParser:
|
||||
subparsers = parser.add_subparsers(dest="command", required=True)
|
||||
chat_parser = subparsers.add_parser("chat", help="lokalen Textchat starten")
|
||||
chat_parser.add_argument("--session", help="vorhandene Sitzungs-ID laden")
|
||||
secrets_parser = subparsers.add_parser("secrets", help="lokale Geheimwerte sicher verwalten")
|
||||
secret_subparsers = secrets_parser.add_subparsers(dest="secret_action", required=True)
|
||||
set_parser = secret_subparsers.add_parser("set", help="Geheimwert verdeckt setzen")
|
||||
set_parser.add_argument("secret_name", choices=["gemini"])
|
||||
secret_subparsers.add_parser("status", help="nur Verfügbarkeit anzeigen")
|
||||
delete_parser = secret_subparsers.add_parser("delete", help="Geheimwert löschen")
|
||||
delete_parser.add_argument("secret_name", choices=["gemini"])
|
||||
return parser
|
||||
|
||||
|
||||
def run_secrets(
|
||||
action: str,
|
||||
*,
|
||||
provider: SecretProvider | None = None,
|
||||
password_fn: Callable[[str], str] = getpass.getpass,
|
||||
output: OutputFunction = print,
|
||||
) -> int:
|
||||
secret_provider = provider or SecretProvider()
|
||||
try:
|
||||
if action == "status":
|
||||
state = "verfügbar" if secret_provider.gemini_key_available() else "nicht verfügbar"
|
||||
output(f"Gemini-Schlüssel: {state}")
|
||||
return 0
|
||||
if action == "set":
|
||||
value = password_fn("Gemini API-Key: ")
|
||||
secret_provider.set_gemini_key(value)
|
||||
output("Gemini-Schlüssel wurde sicher gespeichert.")
|
||||
return 0
|
||||
if action == "delete":
|
||||
deleted = secret_provider.delete_gemini_key()
|
||||
output(
|
||||
"Gemini-Schlüssel wurde gelöscht."
|
||||
if deleted
|
||||
else "Gemini-Schlüssel war nicht verfügbar."
|
||||
)
|
||||
return 0
|
||||
except SecretStoreError as exc:
|
||||
output(f"Fehler: {exc}")
|
||||
return 2
|
||||
output("Unbekannte Secret-Aktion.")
|
||||
return 2
|
||||
|
||||
|
||||
def _show_history(service: ChatService, session_id: str, output: OutputFunction) -> None:
|
||||
loaded = service.load_session(session_id)
|
||||
if not loaded.messages:
|
||||
@@ -155,6 +197,12 @@ def main(
|
||||
output: OutputFunction = print,
|
||||
) -> int:
|
||||
args = build_parser().parse_args(argv)
|
||||
if args.command == "secrets":
|
||||
return run_secrets(
|
||||
args.secret_action,
|
||||
password_fn=input_fn if input_fn is not input else getpass.getpass,
|
||||
output=output,
|
||||
)
|
||||
if args.command != "chat":
|
||||
return 2
|
||||
|
||||
|
||||
Reference in New Issue
Block a user