keys.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. """
  2. 密钥管理接口
  3. """
  4. from fastapi import APIRouter, Depends
  5. from sqlalchemy.orm import Session
  6. from fastapi import Body
  7. from app.database import get_db
  8. from app.api.deps import get_current_admin
  9. from app.models.api_key import APIKey
  10. from app.models.key_rotation_config import KeyRotationConfig
  11. from app.core.encrypt import encryptor
  12. from datetime import datetime, timedelta
  13. from app.config import settings
  14. router = APIRouter()
  15. @router.get("/current")
  16. async def get_current_key(
  17. db: Session = Depends(get_db),
  18. current_admin = Depends(get_current_admin)
  19. ):
  20. """获取当前密钥"""
  21. key = db.query(APIKey).filter(APIKey.is_active == 1).order_by(APIKey.key_version.desc()).first()
  22. if not key:
  23. return {"code": 404, "msg": "未找到激活的密钥"}
  24. return {
  25. "code": 200,
  26. "msg": "成功",
  27. "data": {
  28. "public_key": key.public_key,
  29. "private_key": key.private_key,
  30. "key_version": key.key_version,
  31. "expire_at": key.expire_at.isoformat() if key.expire_at else None
  32. }
  33. }
  34. @router.get("/history")
  35. async def get_key_history(
  36. db: Session = Depends(get_db),
  37. current_admin = Depends(get_current_admin)
  38. ):
  39. """获取历史密钥"""
  40. keys = db.query(APIKey).order_by(APIKey.key_version.desc()).all()
  41. return {
  42. "code": 200,
  43. "msg": "成功",
  44. "data": [
  45. {
  46. "id": k.id,
  47. "key_version": k.key_version,
  48. "is_active": bool(k.is_active),
  49. "created_at": k.created_at.isoformat() if k.created_at else None,
  50. "expire_at": k.expire_at.isoformat() if k.expire_at else None
  51. }
  52. for k in keys
  53. ]
  54. }
  55. @router.post("/rotate")
  56. async def rotate_key(
  57. db: Session = Depends(get_db),
  58. current_admin = Depends(get_current_admin)
  59. ):
  60. """立即更新密钥"""
  61. # 获取当前激活的密钥
  62. current_key = db.query(APIKey).filter(APIKey.is_active == 1).order_by(APIKey.key_version.desc()).first()
  63. # 生成新密钥
  64. new_key_pair = encryptor.generate_key_pair()
  65. new_version = (current_key.key_version + 1) if current_key else 1
  66. # 获取配置,确定过期时间
  67. config = db.query(KeyRotationConfig).first()
  68. rotation_days = config.rotation_days if config else settings.KEY_ROTATION_DAYS
  69. expire_at = datetime.now() + timedelta(days=rotation_days)
  70. # 禁用旧密钥
  71. if current_key:
  72. current_key.is_active = 0
  73. current_key.updated_at = datetime.now()
  74. # 创建新密钥
  75. new_key = APIKey(
  76. public_key=new_key_pair['public_key'],
  77. private_key=new_key_pair['private_key'],
  78. key_version=new_version,
  79. is_active=1,
  80. expire_at=expire_at,
  81. created_at=datetime.now(),
  82. updated_at=datetime.now()
  83. )
  84. db.add(new_key)
  85. db.commit()
  86. return {
  87. "code": 200,
  88. "msg": "密钥更新成功",
  89. "data": {
  90. "public_key": new_key.public_key,
  91. "private_key": new_key.private_key,
  92. "key_version": new_key.key_version,
  93. "expire_at": new_key.expire_at.isoformat() if new_key.expire_at else None
  94. }
  95. }
  96. @router.put("/cycle")
  97. async def update_key_cycle(
  98. req: dict = Body(...),
  99. db: Session = Depends(get_db),
  100. current_admin = Depends(get_current_admin)
  101. ):
  102. """更新密钥轮换周期"""
  103. rotation_days = req.get("rotation_days")
  104. if not rotation_days or rotation_days < 1:
  105. return {"code": 400, "msg": "轮换周期必须大于0"}
  106. # 获取或创建配置
  107. config = db.query(KeyRotationConfig).first()
  108. if not config:
  109. config = KeyRotationConfig(
  110. rotation_days=rotation_days,
  111. is_auto_rotate=1,
  112. updated_at=datetime.now()
  113. )
  114. db.add(config)
  115. else:
  116. config.rotation_days = rotation_days
  117. config.updated_at = datetime.now()
  118. db.commit()
  119. return {"code": 200, "msg": "更新成功"}