Files
moss-ai/mcp/didatodolist-mcp/scripts/oauth_authenticate.py
雷雨 8635b84b2d init
2025-12-15 22:05:56 +08:00

147 lines
4.3 KiB
Python
Raw 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.
#!/usr/bin/env python3
"""
滴答清单 OAuth 完整认证流程(.env-only
功能:
1. 启动本地回调服务器
2. 生成并显示授权URL
3. 接收授权码
4. 交换访问令牌
5. 测试API调用
6. 将令牌写入 .envDIDA_ACCESS_TOKEN / DIDA_REFRESH_TOKEN
使用:
python scripts/oauth_authenticate.py
python scripts/oauth_authenticate.py --port 38000
"""
import sys
import argparse
from pathlib import Path
# 添加项目根目录到路径
sys.path.insert(0, str(Path(__file__).parent.parent))
import os
import json
import dotenv
from utils.oauth_auth import DidaOAuthClient
def write_env_tokens(env_path: Path, access_token: str, refresh_token: str | None):
"""将令牌写入 .env若存在则更新相关行"""
lines = []
if env_path.exists():
with open(env_path, "r", encoding="utf-8") as f:
lines = f.read().splitlines()
def upsert(key: str, value: str | None):
nonlocal lines
# 删除旧行
lines = [ln for ln in lines if not ln.startswith(f"{key}=")]
if value is not None:
lines.append(f"{key}={value}")
upsert("DIDA_ACCESS_TOKEN", access_token)
upsert("DIDA_REFRESH_TOKEN", refresh_token or "")
content = "\n".join(lines) + ("\n" if not content_endswith_newline(lines) else "")
with open(env_path, "w", encoding="utf-8") as f:
f.write(content)
def content_endswith_newline(lines: list[str]) -> bool:
if not lines:
return False
return lines[-1].endswith("\n")
def main():
# 加载 .env确保 DIDA_CLIENT_ID/SECRET 可被读取
dotenv.load_dotenv()
parser = argparse.ArgumentParser(description="滴答清单OAuth认证.env-only")
parser.add_argument(
"--port",
type=int,
default=38000,
help="回调服务器端口"
)
args = parser.parse_args()
print("\n" + "="*70)
print("滴答清单OAuth 2.0 认证")
print("="*70 + "\n")
# 仅使用 .env 环境变量
client_id = os.environ.get("DIDA_CLIENT_ID")
client_secret = os.environ.get("DIDA_CLIENT_SECRET")
redirect_uri = os.environ.get("DIDA_REDIRECT_URI", f"http://localhost:{args.port}/callback")
if not client_id or not client_secret:
print("❌ 未检测到环境变量 DIDA_CLIENT_ID / DIDA_CLIENT_SECRET")
print("请在 .env 中设置以下变量后重试:\n")
example = {
"DIDA_CLIENT_ID": "YOUR_CLIENT_ID",
"DIDA_CLIENT_SECRET": "YOUR_CLIENT_SECRET",
"DIDA_REDIRECT_URI": f"http://localhost:{args.port}/callback"
}
print(json.dumps(example, indent=2))
sys.exit(1)
if not client_id or not client_secret:
print("❌ 配置文件缺少 client_id 或 client_secret")
sys.exit(1)
# 创建OAuth客户端
oauth_client = DidaOAuthClient(
client_id=client_id,
client_secret=client_secret,
redirect_uri=redirect_uri
)
# 执行授权流程
print("步骤1: 启动本地回调服务器")
print(f"端口: {args.port}\n")
success = oauth_client.authorize(auto_open_browser=False)
if success:
# 写入 .env不会加入版本控制
env_path = Path(".env")
write_env_tokens(env_path, oauth_client.access_token, oauth_client.refresh_token)
print(f"\n已写入 .env: DIDA_ACCESS_TOKEN / DIDA_REFRESH_TOKEN")
print("\n" + "="*70)
print("✅ OAuth认证成功!")
print("="*70)
print(f"Access Token: {oauth_client.access_token[:30]}...")
# 测试API
print("\n正在测试API...")
try:
import requests
headers = oauth_client.get_headers()
response = requests.get(
"https://api.dida365.com/open/v1/project",
headers=headers,
timeout=10
)
if response.status_code == 200:
projects = response.json()
print(f"✅ API测试成功! 找到 {len(projects)} 个项目\n")
else:
print(f"⚠️ API测试失败: HTTP {response.status_code}\n")
except Exception as e:
print(f"⚠️ API测试失败: {str(e)}\n")
else:
print("\n❌ OAuth认证失败")
sys.exit(1)
if __name__ == "__main__":
main()