mirror of
https://github.com/PR0M3TH3AN/SeedPass.git
synced 2026-10-27 07:52:03 +00:00
89 lines
2.9 KiB
Python
89 lines
2.9 KiB
Python
from __future__ import annotations
|
|
|
|
from typing import Optional
|
|
|
|
import click
|
|
import typer
|
|
import uvicorn
|
|
|
|
from .. import api as api_module
|
|
from seedpass.core.auth_broker import AuthBrokerError, resolve_password as resolve_broker_password
|
|
|
|
app = typer.Typer(help="Run the API server")
|
|
|
|
|
|
@app.command("start")
|
|
def api_start(
|
|
ctx: typer.Context,
|
|
host: str = "127.0.0.1",
|
|
port: int = 8000,
|
|
unlock: bool = typer.Option(
|
|
False, "--unlock", help="Unlock vault during startup using the selected auth broker"
|
|
),
|
|
auth_broker: str = typer.Option(
|
|
"prompt",
|
|
"--auth-broker",
|
|
help="Password source when --unlock is used (prompt|env|keyring|command)",
|
|
click_type=click.Choice(["prompt", "env", "keyring", "command"], case_sensitive=False),
|
|
),
|
|
password_env: str = typer.Option(
|
|
"SEEDPASS_PASSWORD", "--password-env", help="Env var used when --auth-broker=env"
|
|
),
|
|
broker_service: str = typer.Option(
|
|
"seedpass",
|
|
"--broker-service",
|
|
help="Keyring service name when --auth-broker=keyring",
|
|
),
|
|
broker_account: Optional[str] = typer.Option(
|
|
None,
|
|
"--broker-account",
|
|
help="Keyring account (defaults to active fingerprint when available)",
|
|
),
|
|
broker_command: Optional[str] = typer.Option(
|
|
None,
|
|
"--broker-command",
|
|
help="Command that prints password to stdout for --auth-broker=command",
|
|
),
|
|
) -> None:
|
|
"""Start the SeedPass API server."""
|
|
unlock_password: str | None = None
|
|
if unlock:
|
|
if auth_broker.lower() == "prompt":
|
|
unlock_password = typer.prompt("Master password", hide_input=True)
|
|
else:
|
|
account = broker_account or str((ctx.obj or {}).get("fingerprint") or "default")
|
|
try:
|
|
unlock_password = resolve_broker_password(
|
|
broker=auth_broker,
|
|
password_env=password_env,
|
|
broker_service=broker_service,
|
|
broker_account=account,
|
|
broker_command=broker_command,
|
|
)
|
|
except AuthBrokerError as exc:
|
|
raise typer.BadParameter(str(exc)) from exc
|
|
token = api_module.start_server(ctx.obj.get("fingerprint"), unlock_password)
|
|
typer.echo(
|
|
f"API token: {token}\nWARNING: Store this token securely; it cannot be recovered."
|
|
)
|
|
uvicorn.run(api_module.app, host=host, port=port)
|
|
|
|
|
|
@app.command("stop")
|
|
def api_stop(
|
|
token: str = typer.Option(..., help="API token"),
|
|
host: str = "127.0.0.1",
|
|
port: int = 8000,
|
|
) -> None:
|
|
"""Stop the SeedPass API server."""
|
|
import requests
|
|
|
|
try:
|
|
requests.post(
|
|
f"http://{host}:{port}/api/v1/shutdown",
|
|
headers={"Authorization": f"Bearer {token}"},
|
|
timeout=2,
|
|
)
|
|
except Exception as exc: # pragma: no cover - best effort
|
|
typer.echo(f"Failed to stop server: {exc}")
|