Skip to content

Commit 6293bee

Browse files
committed
Backend: Update management models, API endpoints, and Protobuf schema
1 parent 5ec3426 commit 6293bee

70 files changed

Lines changed: 1520 additions & 481 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

APIDocument.md

Lines changed: 244 additions & 212 deletions
Large diffs are not rendered by default.

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ class YourModel(Base):
128128

129129
```bash
130130
uv run python -m grpc_tools.protoc \
131-
-I. \
131+
-Iapi/ \
132132
--python_out=app/grpc \
133133
--grpc_python_out=app/grpc \
134134
--pyi_out=app/grpc \

DEVELOPMENT.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ uv run cims
114114

115115
```bash
116116
uv run python -m grpc_tools.protoc \
117-
-I. \
117+
-Iapi/ \
118118
--python_out=app/grpc \
119119
--grpc_python_out=app/grpc \
120120
--pyi_out=app/grpc \

NewAPI.md

Lines changed: 0 additions & 137 deletions
This file was deleted.

app/api/admin/approval_routes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
_sa = require_role(100)
2222

2323

24-
@router.post("/list", response_model=list[UserOut])
24+
@router.get("/list", response_model=list[UserOut])
2525
async def get_pending_users(
2626
offset: int = 0,
2727
limit: int = 50,

app/api/admin/settings.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
"""系统设置路由。
22
33
提供平台级系统设置的读取和修改。
4+
仅允许白名单内的配置项写入。
45
"""
56

67
from datetime import datetime, timezone
78

89
from fastapi import APIRouter, Depends, HTTPException
9-
from pydantic import BaseModel
1010
from sqlalchemy import select
1111
from sqlalchemy.ext.asyncio import AsyncSession
1212

1313
from app.core.auth.dependencies import require_role
1414
from app.models.session import get_db
1515
from app.models.system_config import SystemConfig
16+
from app.api.schemas.settings import SettingsUpdate
1617

1718
router = APIRouter()
1819
_sa = require_role(100)
@@ -30,13 +31,13 @@ async def get_settings(
3031

3132
@router.post("")
3233
async def update_settings(
33-
body: dict,
34+
body: SettingsUpdate,
3435
db: AsyncSession = Depends(get_db),
3536
_user=Depends(_sa),
3637
):
37-
"""修改系统设置(键值对)。"""
38+
"""修改系统设置(仅白名单键)。"""
3839
now = datetime.now(timezone.utc)
39-
for key, value in body.items():
40+
for key, value in body.items.items():
4041
stmt = select(SystemConfig).where(SystemConfig.key == key)
4142
cfg = (await db.execute(stmt)).scalar_one_or_none()
4243
if cfg:

app/api/admin/totp_routes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@
55

66
from fastapi import APIRouter
77

8-
router = APIRouter(prefix="/auth/2fa", tags=["2fa"])
8+
router = APIRouter(tags=["2fa"])

app/api/admin/user_delete.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,12 @@
1313
_sa = require_role(100)
1414

1515

16-
@router.post("/{user_id}/delete")
16+
class RenameRequest(BaseModel):
17+
"""重命名请求体。"""
18+
name: str = Field(..., min_length=1, max_length=64)
19+
20+
21+
@router.delete("/{user_id}")
1722
async def delete_user(
1823
user_id: str,
1924
db: AsyncSession = Depends(get_db),
@@ -28,3 +33,22 @@ async def delete_user(
2833
await db.delete(user)
2934
await db.commit()
3035
return {"message": "用户已删除"}
36+
37+
38+
@router.post("/{user_id}/rename")
39+
async def rename_user(
40+
user_id: str,
41+
body: RenameRequest,
42+
db: AsyncSession = Depends(get_db),
43+
_user=Depends(_sa),
44+
):
45+
"""重命名用户。"""
46+
user = (
47+
await db.execute(select(User).where(User.id == user_id))
48+
).scalar_one_or_none()
49+
if not user:
50+
raise HTTPException(status_code=404, detail="用户不存在")
51+
user.username = body.name
52+
await db.commit()
53+
return {"message": "已重命名"}
54+

app/api/admin/user_password.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,23 @@ async def reset_password(
3030
user.hashed_password = hash_password(body.new_password)
3131
await db.commit()
3232
return {"message": "密码已重置"}
33+
34+
35+
@router.post("/{user_id}/password/change")
36+
async def change_password(
37+
user_id: str,
38+
body: PasswordChange,
39+
db: AsyncSession = Depends(get_db),
40+
_user=Depends(_sa),
41+
):
42+
"""超管修改用户密码(需验证旧密码)。"""
43+
user = (
44+
await db.execute(select(User).where(User.id == user_id))
45+
).scalar_one_or_none()
46+
if not user:
47+
raise HTTPException(404, "用户不存在")
48+
if not verify_password(body.old_password, user.hashed_password):
49+
raise HTTPException(400, "旧密码错误")
50+
user.hashed_password = hash_password(body.new_password)
51+
await db.commit()
52+
return {"message": "密码已修改"}

app/api/admin/user_routes.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
_sa = require_role(100)
1818

1919

20-
@router.post("/list", response_model=list[UserOut])
20+
@router.get("/list", response_model=list[UserOut])
2121
async def list_all_users(
2222
offset: int = 0,
2323
limit: int = 20,
@@ -29,7 +29,7 @@ async def list_all_users(
2929
return [_to_out(u) for u in users]
3030

3131

32-
@router.post("/search", response_model=list[UserOut])
32+
@router.get("/search", response_model=list[UserOut])
3333
async def search_users(
3434
q: str = "",
3535
db: AsyncSession = Depends(get_db),

0 commit comments

Comments
 (0)