Files
wurangyu 1e39b6da88 feat: sap-cli skill v2.1.0 — self-contained distributable package
- assets/: sap-cli source (v2.1.0, 26 commands, 16 object types)
- references/: tool constraints + error handling (self-contained)
- scripts/setup.py: one-click install/config/verify
- SKILL.md: full command reference + dual-platform install guide
- VERSION: 2.1.0

Built from D:/Codespace/sap-cli via scripts/pack_skill.py
2026-06-13 20:52:24 +08:00

125 lines
3.5 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""凭证管理模块。
使用 keyring 库安全存储 SAP 密码,优雅降级到 config.ini。
服务名格式: sap-cli:{host}:{client}
"""
from __future__ import annotations
import argparse
import getpass
import logging
# 从独立模块导入,避免与 config 循环 import
from sapcli.password import ( # noqa: F401 re-export
_KEYRING_AVAILABLE,
_keyring,
_keyring_mod,
_service_name,
get_password,
resolve_password,
)
logger = logging.getLogger("sapcli.auth")
def set_password(host: str, client: str, user: str, password: str) -> bool:
"""存储密码到 keyring。
Returns:
是否成功存储
"""
if not _KEYRING_AVAILABLE:
print(" ✗ keyring 库不可用,无法安全存储密码")
print(" 安装方法: pip install keyring")
return False
try:
_keyring.set_password(_service_name(host, client), user, password)
return True
except Exception as e:
print(f" ✗ 存储密码失败: {e}")
return False
def delete_password(host: str, client: str, user: str) -> bool:
"""从 keyring 删除密码。
Returns:
是否成功删除
"""
if not _KEYRING_AVAILABLE:
print(" ✗ keyring 库不可用")
return False
try:
_keyring.delete_password(_service_name(host, client), user)
return True
except _keyring_mod.errors.PasswordDeleteError:
print(" keyring 中未找到该密码")
return False
except Exception as e:
print(f" ✗ 删除密码失败: {e}")
return False
def cmd_auth_login(args: argparse.Namespace, client=None) -> None:
"""auth login: 交互式保存密码到 keyring。"""
import os
from sapcli.config import load_config
try:
cfg, _ = load_config(getattr(args, "config", None))
except Exception as e:
print(f" ✗ 无法加载配置: {e}")
return
print("=" * 60)
print(" sap-cli 密钥登录")
print("=" * 60)
print(f" 主机: {cfg.host}")
print(f" Client: {cfg.client}")
print(f" 用户: {cfg.user}")
password = getpass.getpass(" 请输入密码: ")
if not password:
print(" ✗ 密码不能为空")
return
if set_password(cfg.host, cfg.client, cfg.user, password):
print(f" ✓ 密码已安全存储到 keyring")
print(f" 服务名: {_service_name(cfg.host, cfg.client)}")
else:
print(" ✗ 密码存储失败")
def cmd_auth_logout(args: argparse.Namespace, client=None) -> None:
"""auth logout: 从 keyring 删除密码。"""
from sapcli.config import load_config
try:
cfg, _ = load_config(getattr(args, "config", None))
except Exception as e:
print(f" ✗ 无法加载配置: {e}")
return
if delete_password(cfg.host, cfg.client, cfg.user):
print(" ✓ 密码已从 keyring 删除")
else:
print(" ✗ 删除失败")
def cmd_auth_status(args: argparse.Namespace, client=None) -> None:
"""auth status: 显示 keyring 状态。"""
print("=" * 60)
print(" sap-cli 密钥状态")
print("=" * 60)
if _KEYRING_AVAILABLE:
print(f" keyring: ✓ 可用")
try:
backend = _keyring.get_keyring().__class__.__name__
print(f" 后端: {backend}")
except Exception:
logger.debug("获取 keyring 后端名称失败", exc_info=True)
else:
print(f" keyring: ✗ 不可用")
print(f" 安装方法: pip install keyring")