MCPcopy Create free account
hub / github.com/FSoft-AI4Code/CodeWiki / ConfigManager

Class ConfigManager

codewiki/cli/config_manager.py:34–332  ·  view source on GitHub ↗

Manages CodeWiki configuration with secure keyring storage for API keys. Storage: - API key: System keychain via keyring (macOS Keychain, Windows Credential Manager, Linux Secret Service) - Fallback: ~/.codewiki/credentials.json when keyring is unavailable

Source from the content-addressed store, hash-verified

32
33
34class ConfigManager:
35 """
36 Manages CodeWiki configuration with secure keyring storage for API keys.
37
38 Storage:
39 - API key: System keychain via keyring (macOS Keychain, Windows Credential Manager,
40 Linux Secret Service)
41 - Fallback: ~/.codewiki/credentials.json when keyring is unavailable
42 - Other settings: ~/.codewiki/config.json
43
44 Set CODEWIKI_NO_KEYRING=1 to skip keyring and use file-based storage.
45 """
46
47 def __init__(self):
48 """Initialize the configuration manager."""
49 self._api_key: Optional[str] = None
50 self._config: Optional[Configuration] = None
51 self._force_no_keyring = os.environ.get("CODEWIKI_NO_KEYRING", "").strip() in (
52 "1",
53 "true",
54 "yes",
55 )
56 self._keyring_available = self._check_keyring_available()
57
58 def _check_keyring_available(self) -> bool:
59 """Check if system keyring is available."""
60 if self._force_no_keyring:
61 logger.debug("Keyring disabled via CODEWIKI_NO_KEYRING")
62 return False
63 try:
64 # Try to get/set a test value
65 keyring.get_password(KEYRING_SERVICE, "__test__")
66 return True
67 except (KeyringError, Exception):
68 return False
69
70 def _load_api_key_from_file(self) -> Optional[str]:
71 """Load API key from fallback credentials file."""
72 if not CREDENTIALS_FILE.exists():
73 return None
74 try:
75 content = safe_read(CREDENTIALS_FILE)
76 data = json.loads(content)
77 return data.get("api_key")
78 except (json.JSONDecodeError, FileSystemError):
79 return None
80
81 def _save_api_key_to_file(self, api_key: str):
82 """Save API key to fallback credentials file (plaintext)."""
83 ensure_directory(CONFIG_DIR)
84 data = {"api_key": api_key}
85 safe_write(CREDENTIALS_FILE, json.dumps(data, indent=2))
86 # Restrict file permissions (owner read/write only)
87 try:
88 CREDENTIALS_FILE.chmod(0o600)
89 except OSError:
90 pass
91

Callers 6

config_setFunction · 0.90
config_showFunction · 0.90
config_validateFunction · 0.90
config_agentFunction · 0.90
generate_commandFunction · 0.90
_load_configFunction · 0.90

Calls

no outgoing calls

Tested by

no test coverage detected