测试项目管理与登出部分的接口 #20

Merged
hnu202326010318 merged 3 commits from liguolin_branch into develop 2 months ago

@ -56,7 +56,7 @@ async def update_project_info(
current_user: Any = Depends(deps.get_current_active_user),
) -> Any:
try:
return await project_service.update_project_info_service(db, project_id, current_user.user_id, data.model_dump(exclude_unset=True))
return await project_service.update_project_info_service(db, project_id, current_user.user_id, update_data.model_dump(exclude_unset=True))
except ItemNotFoundException:
raise HTTPException(status_code=404, detail="Not found")

@ -11,6 +11,8 @@ from pydantic import BaseModel
from core.config import config
from core.exceptions import TokenInvalidException
from core.log import log
# 导入 Redis 获取函数
from redis.redis import get_redis
# 密码哈希上下文
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
@ -81,12 +83,27 @@ def create_access_token(data: dict) -> str:
# 5. 获取当前活跃用户 ID (依赖注入用)
async def get_current_active_user(
token: str = Depends(oauth2_scheme)
token: str = Depends(oauth2_scheme)
) -> int:
"""
负责解析 Token检查是否过期/无效返回 user_id
注意此函数不查数据库只解密 Token查库逻辑请在 deps.py 中基于此 user_id 进行
"""
# 检查 Token 是否在 Redis 白名单中
redis = get_redis()
if redis:
# 这里的 key 格式必须与 user_service.service_save_token_in_redis 保持一致
token_key = f"token:{token}"
is_valid = await redis.get(token_key)
if not is_valid:
log.warning(f"Token invalid (logged out or expired in redis): {token[:10]}...")
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Token has been revoked (logged out)",
headers={"WWW-Authenticate": "Bearer"},
)
try:
user_id = decode_jwt_token(token)
return user_id

@ -3,6 +3,7 @@
from typing import Optional, Dict, Any
from sqlalchemy.ext.asyncio import AsyncSession as Session
from datetime import datetime, timedelta, timezone
from jose import jwt, JWTError # 新增
# 隐式绝对导入
from crud.crud_project import crud_project
@ -21,11 +22,27 @@ from core.config import config
# --- 辅助函数 ---
async def _verify_delete_token(token: str, user_id: int, project_id: int) -> bool:
try:
payload = decode_jwt_token(token)
if payload.get("sub") != str(user_id) or payload.get("project_id") != project_id:
# 直接使用 jwt.decode 获取完整 payload而不是用 auth.decode_jwt_token
payload = jwt.decode(
token,
config.jwt.secret_key,
algorithms=[config.jwt.algorithm]
)
token_sub = payload.get("sub")
token_pid = payload.get("project_id")
# 1. 验证是否属于当前用户
if str(token_sub) != str(user_id):
return False
# 2. 验证是否针对当前项目
if token_pid is None or int(token_pid) != int(project_id):
return False
return True
except Exception:
except (JWTError, ValueError, TypeError, AttributeError):
# 任何解码错误或类型转换错误都视为验证失败
return False
@ -40,10 +57,15 @@ async def create_project_service(
# 1. 创建关联的 DatabaseInstance (占位)
# 必须先创建它,否则 Project 的 instance_id 外键会报错
# 使用合法的占位数据 (非空字符串非0端口)
new_instance = await crud_database_instance.create(
db,
db_type=db_type,
db_host="", db_port=0, db_name="pending", db_username="", db_password="",
db_host="127.0.0.1", # TODO:后续改成真实的ip地址修改使用本地回环地址占位
db_port=3306, # 修改:使用标准端口占位
db_name="pending_init", # TODO:修改:更有意义的占位名
db_username="pending_user", # TODO:修改:非空用户名
db_password="pending_password", # TODO:修改:非空密码
status="inactive"
)

Loading…
Cancel
Save