增加API鉴权
This commit is contained in:
@@ -3,7 +3,7 @@ from api import devices, contents, todos
|
||||
|
||||
api_router = APIRouter()
|
||||
|
||||
# 注册所有路由
|
||||
api_router.include_router(devices.router)
|
||||
api_router.include_router(contents.router)
|
||||
api_router.include_router(todos.router)
|
||||
# 注册所有路由,并添加全局安全要求
|
||||
api_router.include_router(devices.router, prefix="/devices")
|
||||
api_router.include_router(contents.router, prefix="/contents")
|
||||
api_router.include_router(todos.router, prefix="/todos")
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,4 +1,4 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException, status, Query, File, UploadFile
|
||||
from fastapi import APIRouter, Depends, HTTPException, status, Query, File, UploadFile, Security
|
||||
from sqlalchemy.orm import Session
|
||||
from sqlalchemy import func
|
||||
from typing import List, Optional
|
||||
@@ -11,13 +11,13 @@ from models import Content as ContentModel, Device as DeviceModel
|
||||
from mqtt_manager import mqtt_manager
|
||||
from image_processor import image_processor
|
||||
from config import settings
|
||||
from auth import get_api_key
|
||||
|
||||
router = APIRouter(
|
||||
prefix="/api",
|
||||
tags=["contents"]
|
||||
)
|
||||
|
||||
@router.post("/devices/{device_id}/content", response_model=ContentSchema, status_code=status.HTTP_201_CREATED)
|
||||
@router.post("/devices/{device_id}/content", response_model=ContentSchema, status_code=status.HTTP_201_CREATED, dependencies=[Depends(get_api_key)])
|
||||
async def create_content(
|
||||
device_id: str,
|
||||
content: ContentCreate,
|
||||
@@ -60,7 +60,7 @@ async def create_content(
|
||||
|
||||
return db_content
|
||||
|
||||
@router.get("/devices/{device_id}/content", response_model=List[ContentSchema])
|
||||
@router.get("/devices/{device_id}/content", response_model=List[ContentSchema], dependencies=[Depends(get_api_key)])
|
||||
async def list_content(
|
||||
device_id: str,
|
||||
skip: int = 0,
|
||||
@@ -87,7 +87,7 @@ async def list_content(
|
||||
contents = query.order_by(ContentModel.version.desc()).offset(skip).limit(limit).all()
|
||||
return contents
|
||||
|
||||
@router.get("/devices/{device_id}/content/{version}", response_model=ContentResponse)
|
||||
@router.get("/devices/{device_id}/content/{version}", response_model=ContentResponse, dependencies=[Depends(get_api_key)])
|
||||
async def get_content(
|
||||
device_id: str,
|
||||
version: int,
|
||||
@@ -141,7 +141,7 @@ async def get_content(
|
||||
created_at=content.created_at
|
||||
)
|
||||
|
||||
@router.put("/devices/{device_id}/content/{version}", response_model=ContentSchema)
|
||||
@router.put("/devices/{device_id}/content/{version}", response_model=ContentSchema, dependencies=[Depends(get_api_key)])
|
||||
async def update_content(
|
||||
device_id: str,
|
||||
version: int,
|
||||
@@ -176,7 +176,7 @@ async def update_content(
|
||||
|
||||
return content
|
||||
|
||||
@router.delete("/devices/{device_id}/content/{version}", status_code=status.HTTP_204_NO_CONTENT)
|
||||
@router.delete("/devices/{device_id}/content/{version}", status_code=status.HTTP_204_NO_CONTENT, dependencies=[Depends(get_api_key)])
|
||||
async def delete_content(
|
||||
device_id: str,
|
||||
version: int,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from fastapi import APIRouter, Depends, HTTPException, status, Security
|
||||
from sqlalchemy.orm import Session
|
||||
from typing import List, Optional
|
||||
from datetime import datetime
|
||||
@@ -9,13 +9,13 @@ from schemas import Device as DeviceSchema, DeviceCreate, DeviceUpdate, Bootstra
|
||||
from models import Device as DeviceModel
|
||||
from database import Content as ContentModel
|
||||
from mqtt_manager import mqtt_manager
|
||||
from auth import get_api_key
|
||||
|
||||
router = APIRouter(
|
||||
prefix="/api/devices",
|
||||
tags=["devices"]
|
||||
)
|
||||
|
||||
@router.post("/", response_model=DeviceSchema, status_code=status.HTTP_201_CREATED)
|
||||
@router.post("/", response_model=DeviceSchema, status_code=status.HTTP_201_CREATED, dependencies=[Depends(get_api_key)])
|
||||
async def create_device(device: DeviceCreate, db: Session = Depends(get_db)):
|
||||
"""
|
||||
注册新设备
|
||||
@@ -46,7 +46,7 @@ async def create_device(device: DeviceCreate, db: Session = Depends(get_db)):
|
||||
|
||||
return db_device
|
||||
|
||||
@router.get("/", response_model=List[DeviceSchema])
|
||||
@router.get("/", response_model=List[DeviceSchema], dependencies=[Depends(get_api_key)])
|
||||
async def list_devices(
|
||||
skip: int = 0,
|
||||
limit: int = 100,
|
||||
@@ -68,7 +68,7 @@ async def list_devices(
|
||||
devices = query.offset(skip).limit(limit).all()
|
||||
return devices
|
||||
|
||||
@router.get("/{device_id}", response_model=DeviceSchema)
|
||||
@router.get("/{device_id}", response_model=DeviceSchema, dependencies=[Depends(get_api_key)])
|
||||
async def get_device(device_id: str, db: Session = Depends(get_db)):
|
||||
"""
|
||||
获取设备详情
|
||||
@@ -81,7 +81,7 @@ async def get_device(device_id: str, db: Session = Depends(get_db)):
|
||||
)
|
||||
return device
|
||||
|
||||
@router.put("/{device_id}", response_model=DeviceSchema)
|
||||
@router.put("/{device_id}", response_model=DeviceSchema, dependencies=[Depends(get_api_key)])
|
||||
async def update_device(
|
||||
device_id: str,
|
||||
device_update: DeviceUpdate,
|
||||
@@ -108,7 +108,7 @@ async def update_device(
|
||||
|
||||
return device
|
||||
|
||||
@router.delete("/{device_id}", status_code=status.HTTP_204_NO_CONTENT)
|
||||
@router.delete("/{device_id}", status_code=status.HTTP_204_NO_CONTENT, dependencies=[Depends(get_api_key)])
|
||||
async def delete_device(device_id: str, db: Session = Depends(get_db)):
|
||||
"""
|
||||
删除设备
|
||||
@@ -126,11 +126,12 @@ async def delete_device(device_id: str, db: Session = Depends(get_db)):
|
||||
db.delete(device)
|
||||
db.commit()
|
||||
|
||||
@router.get("/{device_id}/bootstrap", response_model=BootstrapResponse)
|
||||
async def device_bootstrap(device_id: str, db: Session = Depends(get_db)):
|
||||
@router.post("/{device_id}/bootstrap", response_model=BootstrapResponse, dependencies=[Depends(get_api_key)])
|
||||
async def bootstrap_device(device_id: str, db: Session = Depends(get_db)):
|
||||
"""
|
||||
设备启动获取当前版本信息
|
||||
设备引导 - 获取设备配置和内容
|
||||
"""
|
||||
# 验证设备是否存在
|
||||
device = db.query(DeviceModel).filter(DeviceModel.device_id == device_id).first()
|
||||
if not device:
|
||||
raise HTTPException(
|
||||
@@ -138,29 +139,19 @@ async def device_bootstrap(device_id: str, db: Session = Depends(get_db)):
|
||||
detail="设备不存在"
|
||||
)
|
||||
|
||||
# 更新设备最后在线时间
|
||||
device.last_online = datetime.utcnow()
|
||||
db.commit()
|
||||
|
||||
# 获取最新的活跃内容
|
||||
latest_content = db.query(ContentModel).filter(
|
||||
ContentModel.device_id == device_id,
|
||||
ContentModel.is_active == True
|
||||
).order_by(ContentModel.version.desc()).first()
|
||||
# 获取设备场景的内容
|
||||
contents = db.query(ContentModel).filter(ContentModel.scene == device.scene).all()
|
||||
|
||||
# 构建响应
|
||||
response = BootstrapResponse(
|
||||
device_id=device_id,
|
||||
timezone=latest_content.timezone if latest_content else "Asia/Shanghai",
|
||||
time_format=latest_content.time_format if latest_content else "%Y-%m-%d %H:%M"
|
||||
scene=device.scene,
|
||||
contents=contents
|
||||
)
|
||||
|
||||
if latest_content:
|
||||
response.content_version = latest_content.version
|
||||
response.last_updated = latest_content.created_at
|
||||
|
||||
return response
|
||||
|
||||
@router.get("/{device_id}/status")
|
||||
@router.get("/{device_id}/status", dependencies=[Depends(get_api_key)])
|
||||
async def get_device_status(device_id: str, db: Session = Depends(get_db)):
|
||||
"""
|
||||
获取设备状态
|
||||
|
||||
18
api/todos.py
18
api/todos.py
@@ -1,4 +1,4 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from fastapi import APIRouter, Depends, HTTPException, status, Security
|
||||
from sqlalchemy.orm import Session
|
||||
from typing import List, Optional
|
||||
from datetime import datetime
|
||||
@@ -7,13 +7,13 @@ from database import get_db
|
||||
from schemas import Todo as TodoSchema, TodoCreate, TodoUpdate
|
||||
from models import Todo as TodoModel
|
||||
from database import Device as DeviceModel
|
||||
from auth import get_api_key
|
||||
|
||||
router = APIRouter(
|
||||
prefix="/api/todos",
|
||||
tags=["todos"]
|
||||
)
|
||||
|
||||
@router.post("/", response_model=TodoSchema, status_code=status.HTTP_201_CREATED)
|
||||
@router.post("/", response_model=TodoSchema, status_code=status.HTTP_201_CREATED, dependencies=[Depends(get_api_key)])
|
||||
async def create_todo(todo: TodoCreate, db: Session = Depends(get_db)):
|
||||
"""
|
||||
创建新的待办事项
|
||||
@@ -40,7 +40,7 @@ async def create_todo(todo: TodoCreate, db: Session = Depends(get_db)):
|
||||
|
||||
return db_todo
|
||||
|
||||
@router.get("/", response_model=List[TodoSchema])
|
||||
@router.get("/", response_model=List[TodoSchema], dependencies=[Depends(get_api_key)])
|
||||
async def list_todos(
|
||||
skip: int = 0,
|
||||
limit: int = 100,
|
||||
@@ -62,7 +62,7 @@ async def list_todos(
|
||||
todos = query.order_by(TodoModel.created_at.desc()).offset(skip).limit(limit).all()
|
||||
return todos
|
||||
|
||||
@router.get("/{todo_id}", response_model=TodoSchema)
|
||||
@router.get("/{todo_id}", response_model=TodoSchema, dependencies=[Depends(get_api_key)])
|
||||
async def get_todo(todo_id: int, db: Session = Depends(get_db)):
|
||||
"""
|
||||
获取待办事项详情
|
||||
@@ -75,7 +75,7 @@ async def get_todo(todo_id: int, db: Session = Depends(get_db)):
|
||||
)
|
||||
return todo
|
||||
|
||||
@router.put("/{todo_id}", response_model=TodoSchema)
|
||||
@router.put("/{todo_id}", response_model=TodoSchema, dependencies=[Depends(get_api_key)])
|
||||
async def update_todo(
|
||||
todo_id: int,
|
||||
todo_update: TodoUpdate,
|
||||
@@ -110,7 +110,7 @@ async def update_todo(
|
||||
|
||||
return todo
|
||||
|
||||
@router.delete("/{todo_id}", status_code=status.HTTP_204_NO_CONTENT)
|
||||
@router.delete("/{todo_id}", status_code=status.HTTP_204_NO_CONTENT, dependencies=[Depends(get_api_key)])
|
||||
async def delete_todo(todo_id: int, db: Session = Depends(get_db)):
|
||||
"""
|
||||
删除待办事项
|
||||
@@ -125,7 +125,7 @@ async def delete_todo(todo_id: int, db: Session = Depends(get_db)):
|
||||
db.delete(todo)
|
||||
db.commit()
|
||||
|
||||
@router.post("/{todo_id}/complete", response_model=TodoSchema)
|
||||
@router.post("/{todo_id}/complete", response_model=TodoSchema, dependencies=[Depends(get_api_key)])
|
||||
async def complete_todo(todo_id: int, db: Session = Depends(get_db)):
|
||||
"""
|
||||
标记待办事项为完成
|
||||
@@ -146,7 +146,7 @@ async def complete_todo(todo_id: int, db: Session = Depends(get_db)):
|
||||
|
||||
return todo
|
||||
|
||||
@router.post("/{todo_id}/incomplete", response_model=TodoSchema)
|
||||
@router.post("/{todo_id}/incomplete", response_model=TodoSchema, dependencies=[Depends(get_api_key)])
|
||||
async def incomplete_todo(todo_id: int, db: Session = Depends(get_db)):
|
||||
"""
|
||||
标记待办事项为未完成
|
||||
|
||||
Reference in New Issue
Block a user