feat: Enhance file management and user features

- Add file deduplication mechanism based on PhysicalFile reference counting.
- Implement chunked upload support for large files with resumable uploads.
- Update sharing page to automatically render README and preview content.
- Integrate Redis for caching and token storage (optional).
- Refactor project structure to include new models for download tasks, nodes, and tasks.
- Introduce user filtering parameters for admin user management.
- Add CORS middleware for handling cross-origin requests.
- Improve error messages for authentication failures.
- Update user model to include two-factor authentication key management.
- Enhance API documentation and response models for clarity.
- Implement admin checks for user management and permissions.
This commit is contained in:
2026-01-13 15:29:52 +08:00
parent 61ddc96f17
commit b12aad4e73
13 changed files with 467 additions and 4512 deletions

View File

@@ -1,6 +1,6 @@
from datetime import datetime, timedelta
from fastapi import APIRouter, Depends
from fastapi import APIRouter, Depends, status
from loguru import logger as l
from sqlalchemy import and_
@@ -56,6 +56,23 @@ admin_aria2_router = APIRouter(
tags=['admin', 'admin_aria2']
)
@admin_router.get(
path='/',
summary='自己是否为管理员',
dependencies=[Depends(admin_required)],
status_code=status.HTTP_204_NO_CONTENT
)
async def is_admin() -> None:
"""
检查当前用户是否具有管理员权限。
如果用户是管理员,则返回 204 No Content 响应;否则返回 403 Forbidden 错误。
Returns:
None: 无内容响应
"""
return None
@admin_router.get(
path='/summary',
summary='获取站点概况',

View File

@@ -5,14 +5,14 @@ from loguru import logger as l
from sqlalchemy import func, and_
from middleware.auth import admin_required
from middleware.dependencies import SessionDep, TableViewRequestDep
from middleware.dependencies import SessionDep, TableViewRequestDep, UserFilterParamsDep
from models import (
User, ResponseBase, UserPublic, ListResponse,
Group, Object, ObjectType, )
from models.user import (
UserAdminUpdateRequest, UserCalibrateResponse,
)
from utils import Password
from utils import Password, http_exceptions
admin_user_router = APIRouter(
prefix="/user",
@@ -50,15 +50,17 @@ async def router_admin_get_user(session: SessionDep, user_id: int) -> ResponseBa
async def router_admin_get_users(
session: SessionDep,
table_view: TableViewRequestDep,
filter_params: UserFilterParamsDep,
) -> ListResponse[UserPublic]:
"""
获取用户列表,支持分页、排序时间筛选。
获取用户列表,支持分页、排序时间筛选和用户筛选
:param session: 数据库会话依赖项
:param table_view: 分页排序参数依赖
:param filter_params: 用户筛选参数(用户组、用户名、昵称、状态)
:return: 分页用户列表
"""
result = await User.get_with_count(session, table_view=table_view)
result = await User.get_with_count(session, filter_params=filter_params, table_view=table_view)
return ListResponse(
items=[user.to_public() for user in result.items],
count=result.count,
@@ -114,6 +116,10 @@ async def router_admin_update_user(
if not user:
raise HTTPException(status_code=404, detail="用户不存在")
# 默认管理员(用户名为 admin不允许更改用户组
if request.group_id and user.username == "admin" and request.group_id != user.group_id:
http_exceptions.raise_forbidden("默认管理员不允许更改用户组")
# 如果更新用户组,验证新组存在
if request.group_id:
group = await Group.get(session, Group.id == request.group_id)
@@ -127,6 +133,11 @@ async def router_admin_update_user(
elif 'password' in update_data:
del update_data['password'] # 空密码不更新
# 验证两步验证密钥格式(如果提供了值且不为 None长度必须为 32
if 'two_factor' in update_data and update_data['two_factor'] is not None:
if len(update_data['two_factor']) != 32:
raise HTTPException(status_code=400, detail="两步验证密钥必须为32位字符串")
# 更新字段
for key, value in update_data.items():
setattr(user, key, value)