mirror of
https://github.com/handsomezhuzhu/QQuiz.git
synced 2026-02-20 12:00:14 +00:00
安全修复和管理员账号密码自定义
This commit is contained in:
@@ -86,6 +86,11 @@ async def init_default_config(db: AsyncSession):
|
||||
"ai_provider": os.getenv("AI_PROVIDER", "openai"),
|
||||
}
|
||||
|
||||
# Validate admin credentials
|
||||
admin_username = os.getenv("ADMIN_USERNAME", "admin")
|
||||
if not admin_username or len(admin_username) < 3:
|
||||
raise ValueError("ADMIN_USERNAME must be at least 3 characters long")
|
||||
|
||||
admin_password = os.getenv("ADMIN_PASSWORD")
|
||||
if not admin_password or len(admin_password) < 12:
|
||||
raise ValueError("ADMIN_PASSWORD must be set and at least 12 characters long")
|
||||
@@ -99,15 +104,15 @@ async def init_default_config(db: AsyncSession):
|
||||
db.add(config)
|
||||
print(f"✅ Created default config: {key} = {value}")
|
||||
|
||||
# Create default admin user if not exists
|
||||
result = await db.execute(select(User).where(User.username == "admin"))
|
||||
# Create or update default admin user
|
||||
result = await db.execute(select(User).where(User.username == admin_username))
|
||||
admin = result.scalar_one_or_none()
|
||||
|
||||
default_admin_id = admin.id if admin else None
|
||||
|
||||
if not admin:
|
||||
admin_user = User(
|
||||
username="admin",
|
||||
username=admin_username,
|
||||
hashed_password=pwd_context.hash(admin_password),
|
||||
is_admin=True
|
||||
)
|
||||
@@ -115,8 +120,12 @@ async def init_default_config(db: AsyncSession):
|
||||
await db.commit()
|
||||
await db.refresh(admin_user)
|
||||
default_admin_id = admin_user.id
|
||||
print("✅ Created default admin user (username: admin)")
|
||||
print(f"✅ Created default admin user (username: {admin_username})")
|
||||
else:
|
||||
# Update password if it has changed (verify current password doesn't match)
|
||||
if not pwd_context.verify(admin_password, admin.hashed_password):
|
||||
admin.hashed_password = pwd_context.hash(admin_password)
|
||||
print(f"🔄 Updated default admin password (username: {admin_username})")
|
||||
await db.commit()
|
||||
|
||||
if default_admin_id is not None:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""
|
||||
Authentication Router
|
||||
"""
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from fastapi import APIRouter, Depends, HTTPException, status, Request
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import select
|
||||
from datetime import timedelta
|
||||
@@ -66,6 +66,7 @@ async def register(
|
||||
@router.post("/login", response_model=Token)
|
||||
@limiter.limit("5/minute")
|
||||
async def login(
|
||||
request: Request,
|
||||
user_data: UserLogin,
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""
|
||||
Exam Router - Handles exam creation, file upload, and deduplication
|
||||
"""
|
||||
from fastapi import APIRouter, Depends, HTTPException, status, UploadFile, File, Form, BackgroundTasks
|
||||
from fastapi import APIRouter, Depends, HTTPException, status, UploadFile, File, Form, BackgroundTasks, Request
|
||||
from fastapi.responses import StreamingResponse
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import select, func, and_
|
||||
@@ -537,6 +537,7 @@ async def async_parse_and_save(
|
||||
@router.post("/create", response_model=ExamUploadResponse, status_code=status.HTTP_201_CREATED)
|
||||
@limiter.limit("10/minute")
|
||||
async def create_exam_with_upload(
|
||||
request: Request,
|
||||
background_tasks: BackgroundTasks,
|
||||
title: str = Form(...),
|
||||
file: UploadFile = File(...),
|
||||
@@ -587,6 +588,7 @@ async def create_exam_with_upload(
|
||||
@router.post("/{exam_id}/append", response_model=ExamUploadResponse)
|
||||
@limiter.limit("10/minute")
|
||||
async def append_document_to_exam(
|
||||
request: Request,
|
||||
exam_id: int,
|
||||
background_tasks: BackgroundTasks,
|
||||
file: UploadFile = File(...),
|
||||
|
||||
Reference in New Issue
Block a user