Coverage for src/alprina_cli/config.py: 25%
56 statements
« prev ^ index » next coverage.py v7.11.3, created at 2025-11-14 11:27 +0100
« prev ^ index » next coverage.py v7.11.3, created at 2025-11-14 11:27 +0100
1"""
2Configuration management for Alprina CLI.
3"""
5import yaml
6import os
7from pathlib import Path
8from rich.console import Console
9from rich.panel import Panel
11console = Console()
13ALPRINA_DIR = Path.home() / ".alprina"
14CONFIG_FILE = ALPRINA_DIR / "config.json"
16DEFAULT_CONFIG = {
17 "version": "0.1.0",
18 "backend_url": "https://api.alprina.ai",
19 "timeout": 30,
20 "max_retries": 3,
21 "log_level": "INFO",
22 "theme": "dark",
23 "memory": {
24 "enabled": True,
25 "api_key": "", # Set via environment variable MEM0_API_KEY
26 "user_id": "default"
27 }
28}
31def load_config() -> dict:
32 """Load configuration from file."""
33 if not CONFIG_FILE.exists():
34 return DEFAULT_CONFIG.copy()
36 try:
37 with open(CONFIG_FILE, "r") as f:
38 import json
39 config = json.load(f)
40 return {**DEFAULT_CONFIG, **config}
41 except Exception as e:
42 console.print(f"[yellow]Warning: Could not load config: {e}[/yellow]")
43 return DEFAULT_CONFIG.copy()
46def save_config(config: dict):
47 """Save configuration to file."""
48 ALPRINA_DIR.mkdir(exist_ok=True)
50 import json
51 with open(CONFIG_FILE, "w") as f:
52 json.dump(config, f, indent=2)
55def is_admin_mode() -> bool:
56 """
57 Check if running in admin/development mode (bypasses authentication).
59 SECURITY: Requires ALPRINA_ADMIN_KEY environment variable with correct secret.
60 This prevents unauthorized users from bypassing authentication even if they
61 know about admin mode.
63 Usage (for Malte only):
64 export ALPRINA_ADMIN_KEY="your-secure-secret-key"
66 To generate a new admin key:
67 python3 -c "import secrets; print(secrets.token_hex(32))"
69 Returns:
70 True if admin mode enabled with correct key, False otherwise
71 """
72 import hashlib
74 # Get admin key from environment
75 admin_key = os.getenv("ALPRINA_ADMIN_KEY", "")
77 if not admin_key:
78 return False
80 # Valid admin keys (SHA256 hashed for security)
81 # To add your key: python3 -c "import hashlib; print(hashlib.sha256(b'YOUR_SECRET').hexdigest())"
82 VALID_ADMIN_KEYS = {
83 # Malte's secure admin key (generated 2025-01-14)
84 "05356d75c4be81c8f528c0c6999aad0d0a3db801036b65ac0801b9137a35a763",
85 }
87 # Hash the provided key
88 key_hash = hashlib.sha256(admin_key.encode()).hexdigest()
90 # Check if valid
91 return key_hash in VALID_ADMIN_KEYS
94def get_api_key() -> str:
95 """
96 Get API key from environment variable or auth file.
98 Returns:
99 API key string or None if not found
100 """
101 # Admin mode - bypass authentication
102 if is_admin_mode():
103 return "admin_bypass_key"
105 # Check environment variable first
106 api_key = os.getenv("ALPRINA_API_KEY")
107 if api_key:
108 return api_key
110 # Check auth file
111 auth_file = ALPRINA_DIR / "auth.json"
112 if auth_file.exists():
113 try:
114 import json
115 with open(auth_file, "r") as f:
116 auth_data = json.load(f)
117 return auth_data.get("api_key")
118 except Exception:
119 pass
121 return None
124def init_config_command():
125 """Initialize default configuration."""
126 if CONFIG_FILE.exists():
127 from rich.prompt import Confirm
128 if not Confirm.ask("Config file already exists. Overwrite?", default=False):
129 return
131 save_config(DEFAULT_CONFIG)
133 console.print(Panel(
134 f"[green]✓ Configuration initialized[/green]\n\n"
135 f"Location: {CONFIG_FILE}\n\n"
136 f"Edit this file to customize Alprina settings.",
137 title="Config Initialized"
138 ))