91e75e620b
CI: cua-driver distro-compat matrix / debian:12 (glibc 2.36) (push) Has been cancelled
CI: SPDX Headers / Check SPDX headers (warn-only) (push) Has been cancelled
CD: Docs MCP Server / build (linux/amd64) (push) Has been cancelled
CD: Docs MCP Server / build (linux/arm64) (push) Has been cancelled
CD: Docs MCP Server / merge (push) Has been cancelled
CI: cua-driver distro-compat matrix / Resolve release version (push) Has been cancelled
CI: cua-driver distro-compat matrix / fedora:41 (glibc 2.40) (push) Has been cancelled
CI: cua-driver distro-compat matrix / rockylinux:9 (glibc 2.34) (push) Has been cancelled
CI: cua-driver distro-compat matrix / ubuntu:22.04 (glibc 2.35) (push) Has been cancelled
CI: cua-driver distro-compat matrix / ubuntu:24.04 (glibc 2.39) (push) Has been cancelled
CI: cua-driver distro-compat matrix / Distro compat summary (push) Has been cancelled
CI: Rust Linux unit / Rust Linux unit and compile (push) Has been cancelled
CI: Rust Windows unit / Rust Windows unit and compile (push) Has been cancelled
CI: Nix Linux Rust source / Nix / compositor build (push) Has been cancelled
CI: Nix Linux Rust source / Nix / driver package (push) Has been cancelled
CI: Nix Linux Rust source / Nix / Rust unit tests (push) Has been cancelled
68 lines
2.1 KiB
Python
68 lines
2.1 KiB
Python
"""Authentication — login(), whoami(), credential storage.
|
|
|
|
login() opens a Clerk browser redirect and stores the resulting token
|
|
in ~/.cua/credentials. OAuth device flow deferred to a later stage.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import webbrowser
|
|
from pathlib import Path
|
|
from typing import Any, Dict, Optional
|
|
|
|
import httpx
|
|
from cua_sandbox._config import get_api_key, get_base_url
|
|
|
|
_CUA_DIR = Path.home() / ".cua"
|
|
_CREDENTIALS_FILE = _CUA_DIR / "credentials"
|
|
|
|
|
|
def login(*, base_url: Optional[str] = None) -> None:
|
|
"""Open the CUA login page in a browser and store credentials.
|
|
|
|
This initiates a Clerk-based browser authentication flow.
|
|
The user completes login in their browser, and the resulting
|
|
API key is stored in ~/.cua/credentials.
|
|
"""
|
|
url = base_url or get_base_url()
|
|
login_url = f"{url}/auth/login"
|
|
print(f"Opening {login_url} in your browser...")
|
|
webbrowser.open(login_url)
|
|
print("Complete the login in your browser.")
|
|
print("Then paste the API key you receive below.")
|
|
api_key = input("API key: ").strip()
|
|
if not api_key:
|
|
print("No API key provided. Aborting.")
|
|
return
|
|
_save_credentials(api_key=api_key)
|
|
print("Credentials saved to ~/.cua/credentials")
|
|
|
|
|
|
def whoami(*, api_key: Optional[str] = None) -> Dict[str, Any]:
|
|
"""Return info about the authenticated user.
|
|
|
|
Returns:
|
|
Dict with user info (id, email, etc.) from the CUA API.
|
|
"""
|
|
key = get_api_key(api_key)
|
|
if not key:
|
|
raise RuntimeError("Not authenticated. Run cua_sandbox.login() or set CUA_API_KEY.")
|
|
resp = httpx.get(
|
|
f"{get_base_url()}/v1/whoami",
|
|
headers={"Authorization": f"Bearer {key}"},
|
|
timeout=10,
|
|
)
|
|
resp.raise_for_status()
|
|
return resp.json()
|
|
|
|
|
|
def _save_credentials(*, api_key: str) -> None:
|
|
"""Write credentials to ~/.cua/credentials."""
|
|
_CUA_DIR.mkdir(parents=True, exist_ok=True)
|
|
_CREDENTIALS_FILE.write_text(f"api_key={api_key}\n")
|
|
# Restrict permissions on Unix
|
|
try:
|
|
_CREDENTIALS_FILE.chmod(0o600)
|
|
except OSError:
|
|
pass
|