完善客服操作台权限与绑定二维码
This commit is contained in:
@@ -57,6 +57,42 @@ def _visible_task_accounts_query(db: Session, current: User):
|
||||
raise HTTPException(status_code=403, detail="无权查看斗鱼账号")
|
||||
|
||||
|
||||
def _visible_tasks_query(db: Session, current: User):
|
||||
"""返回当前用户可查看的斗鱼任务查询。"""
|
||||
query = db.query(DouyuTask).options(joinedload(DouyuTask.account))
|
||||
if _can_view_all(current):
|
||||
return query
|
||||
if user_has_permission(current, "account:view_assigned"):
|
||||
return query.join(DouyuTask.account).filter(Account.assigned_to == current.id)
|
||||
raise HTTPException(status_code=403, detail="无权查看斗鱼任务")
|
||||
|
||||
|
||||
def _require_task_account_access(db: Session, current: User, account_ids: list[int]) -> None:
|
||||
"""确保任务只会提交到当前用户可操作的账号。"""
|
||||
requested_ids = set(account_ids)
|
||||
query = db.query(Account.id).filter(Account.id.in_(requested_ids))
|
||||
if not _can_view_all(current):
|
||||
if not user_has_permission(current, "account:view_assigned"):
|
||||
raise HTTPException(status_code=403, detail="无权操作斗鱼账号")
|
||||
query = query.filter(Account.assigned_to == current.id)
|
||||
allowed_ids = {account_id for account_id, in query.all()}
|
||||
if allowed_ids != requested_ids:
|
||||
raise HTTPException(status_code=403, detail="包含无权操作的斗鱼账号")
|
||||
|
||||
|
||||
def _require_batch_owner(db: Session, current: User, batch_id: str) -> None:
|
||||
"""客服只能停止或订阅自己创建的任务批次。"""
|
||||
if _can_view_all(current):
|
||||
return
|
||||
exists = (
|
||||
db.query(DouyuTask.id)
|
||||
.filter(DouyuTask.batch_id == batch_id, DouyuTask.created_by == current.id)
|
||||
.first()
|
||||
)
|
||||
if not exists:
|
||||
raise HTTPException(status_code=403, detail="无权操作该斗鱼任务批次")
|
||||
|
||||
|
||||
def _account_out(account: Account) -> DouyuTaskAccountOut:
|
||||
return DouyuTaskAccountOut(
|
||||
id=account.id,
|
||||
@@ -187,6 +223,7 @@ async def create_task_batch(
|
||||
"""创建斗鱼任务记录并启动后台执行器。"""
|
||||
if not req.account_ids:
|
||||
raise HTTPException(status_code=400, detail="请选择斗鱼账号")
|
||||
_require_task_account_access(db, current, req.account_ids)
|
||||
|
||||
cleanup_orphan_douyu_tasks(
|
||||
db,
|
||||
@@ -241,7 +278,7 @@ def list_tasks(
|
||||
statuses=("pending", "running"),
|
||||
message="任务已中断(无执行器接管)",
|
||||
)
|
||||
query = db.query(DouyuTask).options(joinedload(DouyuTask.account))
|
||||
query = _visible_tasks_query(db, current)
|
||||
if batch_id:
|
||||
query = query.filter(DouyuTask.batch_id == batch_id)
|
||||
rows = query.order_by(DouyuTask.id.desc()).limit(300).all()
|
||||
@@ -255,12 +292,7 @@ def get_task(
|
||||
current: User = Depends(require_permission("douyu:task")),
|
||||
):
|
||||
"""获取单条斗鱼任务详情。"""
|
||||
task = (
|
||||
db.query(DouyuTask)
|
||||
.options(joinedload(DouyuTask.account))
|
||||
.filter(DouyuTask.id == task_id)
|
||||
.first()
|
||||
)
|
||||
task = _visible_tasks_query(db, current).filter(DouyuTask.id == task_id).first()
|
||||
if not task:
|
||||
raise HTTPException(status_code=404, detail="任务不存在")
|
||||
return _task_out(task)
|
||||
@@ -273,6 +305,7 @@ def stop_batch(
|
||||
current: User = Depends(require_permission("douyu:task")),
|
||||
):
|
||||
"""停止正在运行的斗鱼批次。"""
|
||||
_require_batch_owner(db, current, batch_id)
|
||||
batch = douyu_batch_registry.get(batch_id)
|
||||
if batch:
|
||||
if batch.get("finished"):
|
||||
@@ -297,6 +330,17 @@ async def ws_douyu_logs(websocket: WebSocket, batch_id: str):
|
||||
if not user:
|
||||
await websocket.close(code=1008, reason="未授权")
|
||||
return
|
||||
if not user_has_permission(user, "douyu:task"):
|
||||
await websocket.close(code=1008, reason="无权限")
|
||||
return
|
||||
db = SessionLocal()
|
||||
try:
|
||||
_require_batch_owner(db, user, batch_id)
|
||||
except HTTPException:
|
||||
await websocket.close(code=1008, reason="无权访问该任务批次")
|
||||
return
|
||||
finally:
|
||||
db.close()
|
||||
await websocket.accept()
|
||||
|
||||
batch = douyu_batch_registry.get(batch_id)
|
||||
|
||||
Reference in New Issue
Block a user