# ============================================================================= # 企微IT智能服务台 — 开发模式 Mock 登录 # ============================================================================= # ⚠️ 警告:此模块只在 DEV_MODE=true 时可用 # - 仅供本地开发 / 集成测试使用 # - 生产环境(DEV_MODE 未设置或 false)会直接 403 # - 部署前必须确认 .env / .env.production 没有 DEV_MODE=true # 用法: # GET /api/dev/login?userid=dev-user-001&name=测试&role=user # GET /api/dev/users # 列出所有预设 dev 用户 # ============================================================================= import logging import os from typing import Optional import redis.asyncio as aioredis from fastapi import APIRouter, Depends, HTTPException, Query from app.config import settings from app.dependencies import get_redis from app.services.token_service import TokenService logger = logging.getLogger(__name__) router = APIRouter(prefix="/api/dev", tags=["dev-mock"]) def _dev_mode_enabled() -> bool: """检查是否启用了开发模式。 三个检查源(任一为 true 即启用): 1. 环境变量 DEV_MODE=true 2. settings.dev_mode(从 .env.dev 读) 3. DEBUG 模式 + 本地主机(最严格) """ env_val = os.getenv("DEV_MODE", "false").lower() == "true" if env_val: return True # 兜底:从 settings 读 if hasattr(settings, "dev_mode") and getattr(settings, "dev_mode", False): return True return False # ----------------------------------------------------------------------------- # 预设 dev 用户(便于测试不同角色) # ----------------------------------------------------------------------------- PRESET_DEV_USERS = [ {"userid": "dev-user-001", "name": "张三(普通员工)", "role": "user", "department": "财务部"}, {"userid": "dev-agent-001", "name": "李四(IT 坐席)", "role": "agent", "department": "信息技术部"}, {"userid": "dev-supervisor-001", "name": "王五(部门主管)", "role": "supervisor", "department": "信息技术部"}, {"userid": "dev-security-001", "name": "赵六(安全团队)", "role": "security", "department": "信息安全部"}, {"userid": "dev-admin-001", "name": "钱七(系统管理员)", "role": "admin", "department": "信息技术部"}, {"userid": "dev-multi-001", "name": "周八(多角色测试)", "role": "user,agent,supervisor", "department": "测试部"}, ] # ----------------------------------------------------------------------------- # GET /api/dev/login — Mock 登录(返回 token) # ----------------------------------------------------------------------------- @router.get("/login") async def dev_login( userid: str = Query("dev-user-001", description="用户 ID(模拟企微 userid)"), name: str = Query("开发测试用户", description="用户姓名"), role: str = Query("user", description="角色:user/agent/admin/supervisor/security,多个用逗号分隔"), department: str = Query("信息技术部", description="部门"), avatar: Optional[str] = Query(None, description="头像 URL(可选)"), redis: aioredis.Redis = Depends(get_redis), ): """开发模式 Mock 登录。 用法: GET /api/dev/login?userid=dev-agent-001&name=李四&role=agent 返回: { "code": 0, "data": { "token": "abc123...", "user": { "userid": "...", "name": "...", "roles": [...] } } } """ if not _dev_mode_enabled(): logger.warning("🚨 /api/dev/login 被调用但 DEV_MODE 未启用,返回 403") raise HTTPException( status_code=403, detail="DEV_MODE not enabled. Set DEV_MODE=true in .env.dev to use this endpoint." ) # 解析多角色 roles = [r.strip() for r in role.split(",") if r.strip()] if not roles: roles = ["user"] # 调 TokenService 创建 token(走完全真实的 token 流程) token_service = TokenService(redis) token = await token_service.create_token( employee_id=userid, name=name, roles=roles, department=department, avatar=avatar or "", login_source="dev", ) logger.info(f"🧪 [DEV] Mock 登录成功: userid={userid}, roles={roles}") return { "code": 0, "message": "ok", "data": { "token": token, "user": { "userid": userid, "name": name, "department": department, "avatar": avatar or "", "roles": roles, "login_source": "dev", }, }, } # ----------------------------------------------------------------------------- # GET /api/dev/users — 列出所有预设 dev 用户 # ----------------------------------------------------------------------------- @router.get("/users") async def dev_list_users(): """列出所有预设 dev 用户(便于前端测试用)。""" if not _dev_mode_enabled(): raise HTTPException(status_code=403, detail="DEV_MODE not enabled") return { "code": 0, "message": "ok", "data": PRESET_DEV_USERS, } # ----------------------------------------------------------------------------- # GET /api/dev/health — 检查 dev 模式状态 # ----------------------------------------------------------------------------- @router.get("/health") async def dev_health(): """检查 dev 模式是否启用 + 关键依赖。""" if not _dev_mode_enabled(): raise HTTPException(status_code=403, detail="DEV_MODE not enabled") return { "code": 0, "data": { "dev_mode": True, "env": os.getenv("APP_ENV", "unknown"), "database_url": os.getenv("DATABASE_URL", "not set")[:50] + "...", "redis_url": os.getenv("REDIS_URL", "not set"), "preset_users": len(PRESET_DEV_USERS), }, }