feat: 更新验证码请求模型,添加 Google reCAPTCHA 和 Cloudflare Turnstile 验证功能

refactor: 修改用户状态字段类型,优化用户模型
fix: 修复启动服务的错误提示信息
refactor: 统一认证依赖,替换为 AuthRequired
docs: 添加用户会话刷新接口
This commit is contained in:
2025-12-25 10:26:45 +08:00
parent 16cec42181
commit 44a8959aa5
21 changed files with 138 additions and 83 deletions

View File

@@ -259,7 +259,6 @@ async def init_default_user() -> None:
admin_user = User(
username="admin",
nickname="admin",
status=True,
group_id=admin_group.id,
password=hashed_admin_password,
)

View File

@@ -5,6 +5,12 @@ from sqlmodel import Field
from .base import SQLModelBase
class ResponseBase(SQLModelBase):
"""通用响应模型"""
instance_id: uuid.UUID = Field(default_factory=uuid.uuid4)
"""实例ID用于标识请求的唯一性"""
class MCPMethod(StrEnum):
"""MCP 方法枚举"""
@@ -30,10 +36,4 @@ class MCPResponseBase(MCPBase):
"""MCP 响应模型基础类"""
result: str
"""方法返回结果"""
class ResponseBase(SQLModelBase):
"""通用响应模型"""
instance_id: uuid.UUID = Field(default_factory=uuid.uuid4)
"""实例ID用于标识请求的唯一性"""
"""方法返回结果"""

View File

@@ -69,10 +69,10 @@ class ObjectBase(SQLModelBase):
"""对象名称(文件名或目录名)"""
type: ObjectType
"""对象类型file 或 folder"""
"""对象类型"""
size: int = 0
"""文件大小(字节),目录为 0"""
size: int | None = None
"""文件大小(字节),目录为 None"""
# ==================== DTO 模型 ====================
@@ -93,7 +93,7 @@ class DirectoryCreateRequest(SQLModelBase):
class ObjectMoveRequest(SQLModelBase):
"""移动对象请求 DTO"""
src_ids: list[UUID]
src_ids: UUID | list[UUID]
"""源对象UUID列表"""
dst_id: UUID
@@ -103,7 +103,7 @@ class ObjectMoveRequest(SQLModelBase):
class ObjectDeleteRequest(SQLModelBase):
"""删除对象请求 DTO"""
ids: list[UUID]
ids: UUID | list[UUID]
"""待删除对象UUID列表"""

View File

@@ -1,11 +1,16 @@
from typing import Literal
from enum import StrEnum
from sqlmodel import Field, UniqueConstraint
from sqlmodel import UniqueConstraint
from .base import SQLModelBase
from .mixin import TableBaseMixin
from .user import UserResponse
class CaptchaType(StrEnum):
"""验证码类型枚举"""
DEFAULT = "default"
GCAPTCHA = "gcaptcha"
CLOUD_FLARE_TURNSTILE = "cloudflare turnstile"
# ==================== DTO 模型 ====================
@@ -24,7 +29,7 @@ class SiteConfigResponse(SQLModelBase):
site_notice: str | None = None
"""网站公告"""
user: dict[str, str | int | bool] = {}
user: UserResponse
"""用户信息"""
logo_light: str | None = None
@@ -33,7 +38,7 @@ class SiteConfigResponse(SQLModelBase):
logo_dark: str | None = None
"""网站Logo URL深色模式"""
captcha_type: Literal["none", "default", "gcaptcha", "cloudflare turnstile"] = "none"
captcha_type: CaptchaType | None = None
"""验证码类型"""
captcha_key: str | None = None
@@ -104,6 +109,11 @@ class Setting(SQLModelBase, TableBaseMixin):
__table_args__ = (UniqueConstraint("type", "name", name="uq_setting_type_name"),)
type: SettingsType = Field(max_length=255, description="设置类型/分组")
name: str = Field(max_length=255, description="设置项名称")
value: str | None = Field(default=None, description="设置值")
type: SettingsType
"""设置类型/分组"""
name: str
"""设置项名称"""
value: str | None
"""设置值"""

View File

@@ -6,6 +6,7 @@ from uuid import UUID
from sqlmodel import Field, Relationship
from .base import SQLModelBase
from .model_base import ResponseBase
from .mixin import UUIDTableBaseMixin
if TYPE_CHECKING:
@@ -110,7 +111,7 @@ class WebAuthnInfo(SQLModelBase):
"""支持的传输方式"""
class TokenResponse(SQLModelBase):
class TokenResponse(ResponseBase):
"""访问令牌响应 DTO"""
access_expires: datetime
@@ -126,7 +127,7 @@ class TokenResponse(SQLModelBase):
"""刷新令牌"""
class UserResponse(UserBase):
class UserResponse(ResponseBase):
"""用户响应 DTO"""
id: UUID
@@ -215,7 +216,7 @@ class UserAdminUpdateRequest(SQLModelBase):
group_id: UUID | None = None
"""用户组UUID"""
status: bool | None = None
status: UserStatus = UserStatus.ACTIVE
"""用户状态"""
score: int | None = Field(default=None, ge=0)
@@ -286,8 +287,8 @@ class User(UserBase, UUIDTableBaseMixin):
password: str = Field(max_length=255)
"""用户密码(加密后)"""
status: bool = Field(default=True, sa_column_kwargs={"server_default": "true"})
"""用户状态: True=正常, False=封禁"""
status: UserStatus = UserStatus.ACTIVE
"""用户状态"""
storage: int = Field(default=0, sa_column_kwargs={"server_default": "0"}, ge=0)
"""已用存储空间(字节)"""
@@ -350,7 +351,10 @@ class User(UserBase, UUIDTableBaseMixin):
)
objects: list["Object"] = Relationship(
back_populates="owner",
sa_relationship_kwargs={"cascade": "all, delete-orphan"}
sa_relationship_kwargs={
"cascade": "all, delete-orphan",
"foreign_keys": "[Object.owner_id]"
}
)
"""用户的所有对象(文件和目录)"""
orders: list["Order"] = Relationship(