11 KiB
11 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, user_setup, must_haves
| phase | plan | type | wave | depends_on | files_modified | autonomous | requirements | user_setup | must_haves | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 07-login-auth | 03 | execute | 2 |
|
|
false |
|
|
Purpose: 整合登录功能到 CLI,支持 Cookie 验证和状态查询 Output: 完整的 login 命令 + Cookie 验证 + 端到端测试
<execution_context> @/home/starmen1265/.claude/get-shit-done/workflows/execute-plan.md @/home/starmen1265/.claude/get-shit-done/templates/summary.md </execution_context>
@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/07-login-auth/07-CONTEXT.md @.planning/phases/07-login-auth/07-RESEARCH.md @.planning/phases/07-login-auth/07-01-PLAN.md @.planning/phases/07-login-auth/07-02-PLAN.mdFrom kb_workflow/auth/zhihu_login.py (Plan 01):
class ZhihuLogin:
async def login_by_qrcode(self) -> ZhihuLoginResult
async def check_login_cookie(self) -> bool
async def get_cookies_str(self) -> str
From kb_workflow/auth/cookie_manager.py (Plan 02):
def parse_json_cookies(json_path: str) -> str
class CookieManager:
def save_cookie(self, cookie_str: str) -> None
def load_cookie(self) -> str
From kb_workflow/kb_workflow.py (existing):
def process_command(url: str, ...) -> Dict[str, Any]
def main():
subparsers = parser.add_subparsers(dest='command')
# 添加 login 子命令到此处
知乎 API:
- 验证接口: GET https://www.zhihu.com/api/v4/me
- 成功返回: {"id": 123, "name": "用户名", ...}
- 失败返回: 401 状态码
- 添加
CookieValidationResultPydantic model:
from pydantic import BaseModel
from typing import Optional
class CookieValidationResult(BaseModel):
"""Cookie 验证结果"""
valid: bool
username: Optional[str] = None
user_id: Optional[str] = None
reason: Optional[str] = None
- 在
ZhihuLogin类中添加验证方法:
VALIDATION_URL = "https://www.zhihu.com/api/v4/me"
async def validate_cookie(self, cookie_str: str = None) -> CookieValidationResult:
"""验证 Cookie 有效性
通过请求知乎用户信息接口检测 Cookie 是否有效。
Args:
cookie_str: 要验证的 Cookie 字符串,为空时使用已加载的 Cookie
Returns:
CookieValidationResult 包含验证状态和用户信息
"""
# 如果提供了 cookie_str,需要重新启动浏览器并设置 Cookie
if cookie_str:
if self.browser.browser:
self.browser.close()
self.browser.start(cookie=cookie_str)
elif not self.browser.page:
return CookieValidationResult(valid=False, reason="No cookie provided")
try:
# 使用 Playwright 的 request API
response = await self.browser.page.request.get(self.VALIDATION_URL)
if response.status == 200:
user_info = await response.json()
return CookieValidationResult(
valid=True,
username=user_info.get("name", ""),
user_id=str(user_info.get("id", ""))
)
elif response.status == 401:
return CookieValidationResult(valid=False, reason="Cookie expired")
else:
return CookieValidationResult(
valid=False,
reason=f"Validation failed with status {response.status}"
)
except Exception as e:
return CookieValidationResult(valid=False, reason=str(e))
- 创建
tests/test_auth/test_cookie_validation.py:
- 使用 mock 模拟 page.request.get() 返回不同状态码
- 测试有效、过期、空、格式错误等场景
pytest tests/test_auth/test_cookie_validation.py -x -v
- validate_cookie 方法可用
- 4 个单元测试全部通过
- 返回 CookieValidationResult 结构
- 添加 login_command 函数:
def login_command(
import_cookie: Optional[str] = None,
status: bool = False
) -> Dict[str, Any]:
"""Execute login command
Args:
import_cookie: Path to JSON cookie file
status: Check current cookie status
Returns:
Dictionary with login result
"""
try:
from kb_workflow.auth import ZhihuLogin
from kb_workflow.auth.cookie_manager import CookieManager, parse_json_cookies
from kb_workflow.pipeline.config import get_settings
settings = get_settings()
manager = CookieManager()
# 检查 Cookie 状态
if status:
current_cookie = settings.zhihu_cookie.get_secret_value()
if not current_cookie:
return {"valid": False, "reason": "No cookie found in ~/.kb_env"}
async def check_status():
login = ZhihuLogin(intermediate_path=settings.intermediate_path)
try:
login.browser.start(cookie=current_cookie)
return await login.validate_cookie(current_cookie)
finally:
login.browser.close()
result = asyncio.run(check_status())
return result.model_dump()
# 导入 Cookie
if import_cookie:
cookie_str = parse_json_cookies(import_cookie)
manager.save_cookie(cookie_str)
return {"success": True, "message": f"Cookie imported from {import_cookie}"}
# 二维码登录
async def qrcode_login():
login = ZhihuLogin(intermediate_path=settings.intermediate_path)
try:
result = await login.login_by_qrcode()
if result.success and result.cookie_str:
manager.save_cookie(result.cookie_str)
return result.model_dump()
finally:
if login.browser.browser:
login.browser.close()
result = asyncio.run(qrcode_login())
return result
except Exception as e:
return {"success": False, "error": str(e)}
- 在 main() 函数中添加 login 子命令:
# Login subcommand
login_parser = subparsers.add_parser('login', help='Zhihu login authentication')
login_parser.add_argument('--import-cookie', '-i', type=str,
help='Import cookie from JSON file')
login_parser.add_argument('--status', action='store_true',
help='Check current cookie status')
# Handle login subcommand
if args.command == 'login':
result = login_command(
import_cookie=args.import_cookie,
status=args.status
)
print(json.dumps(result, ensure_ascii=False, indent=2))
- 创建
tests/test_auth/test_cli_login.py:
- 使用 mock 模拟 ZhihuLogin 和 CookieManager
- 测试各种命令行参数组合
pytest tests/test_auth/test_cli_login.py -x -v
- login 子命令可用
- 支持 --import-cookie 和 --status 参数
- 4 个单元测试全部通过
<success_criteria>
- 用户可以通过命令行扫码登录知乎
- 扫码成功后 Cookie 自动保存
- 用户可以手动导入 JSON Cookie
- 用户可以查看 Cookie 状态
- Cookie 过期时系统提示重新登录
- 所有单元测试通过 (18+ tests)
- 手动验证登录流程成功 </success_criteria>