ZHIWEI666 commited on
Commit
7afc96b
·
verified ·
1 Parent(s): 83b860f

提升帖子更新安全

Browse files
Files changed (2) hide show
  1. router_comments.py +8 -4
  2. router_posts.py +33 -23
router_comments.py CHANGED
@@ -82,14 +82,16 @@ async def soft_delete_comment(item_id: str, comment_id: str, account: str = Depe
82
  item_comments = comments_db.get(item_id, [])
83
  target_comment = None
84
 
85
- def find_comment(comments_list):
86
  """查找目标评论"""
 
 
87
  nonlocal target_comment
88
  for c in comments_list:
89
  if c["id"] == comment_id:
90
  target_comment = c
91
  return True
92
- if "replies" in c and find_comment(c["replies"]):
93
  return True
94
  return False
95
 
@@ -129,13 +131,15 @@ async def soft_delete_comment(item_id: str, comment_id: str, account: str = Depe
129
  raise HTTPException(status_code=403, detail="无权删除此评论")
130
 
131
  # 执行软删除
132
- def mark_deleted(comments_list):
 
 
133
  for c in comments_list:
134
  if c["id"] == comment_id:
135
  c["isDeleted"] = True
136
  c["content"] = ""
137
  return True
138
- if "replies" in c and mark_deleted(c["replies"]):
139
  return True
140
  return False
141
 
 
82
  item_comments = comments_db.get(item_id, [])
83
  target_comment = None
84
 
85
+ def find_comment(comments_list, depth=0):
86
  """查找目标评论"""
87
+ if depth > 20: # 防止极端嵌套导致栈溢出
88
+ return False
89
  nonlocal target_comment
90
  for c in comments_list:
91
  if c["id"] == comment_id:
92
  target_comment = c
93
  return True
94
+ if "replies" in c and find_comment(c["replies"], depth + 1):
95
  return True
96
  return False
97
 
 
131
  raise HTTPException(status_code=403, detail="无权删除此评论")
132
 
133
  # 执行软删除
134
+ def mark_deleted(comments_list, depth=0):
135
+ if depth > 20: # 防止极端嵌套导致栈溢出
136
+ return False
137
  for c in comments_list:
138
  if c["id"] == comment_id:
139
  c["isDeleted"] = True
140
  c["content"] = ""
141
  return True
142
+ if "replies" in c and mark_deleted(c["replies"], depth + 1):
143
  return True
144
  return False
145
 
router_posts.py CHANGED
@@ -180,32 +180,42 @@ async def create_post(post: PostCreate, current_user: str = Depends(require_auth
180
  @router.put("/api/posts/{post_id}")
181
  async def update_post(post_id: str, update_data: PostUpdate, current_user: str = Depends(require_auth)):
182
  """
183
- 更新帖子(仅作者可操作)
184
  """
185
- posts_db = db.load_data("posts.json", default_data=[])
186
 
187
- for post in posts_db:
188
- if post["id"] == post_id:
189
- if post.get("author") != current_user:
190
- raise HTTPException(status_code=403, detail="无权修改他人帖子")
191
-
192
- if update_data.title is not None:
193
- post["title"] = update_data.title
194
- if update_data.content is not None:
195
- post["content"] = update_data.content
196
- if update_data.cover_image is not None:
197
- post["cover_image"] = update_data.cover_image
198
- if update_data.images is not None:
199
- post["images"] = update_data.images[:9]
200
- if update_data.is_original is not None:
201
- post["is_original"] = update_data.is_original # 🎨 更新原创作品标记
202
-
203
- db.save_data("posts.json", posts_db)
204
- # 🗂️ 清除排序缓存
205
- sort_cache.invalidate("posts:")
206
- return {"status": "success"}
 
207
 
208
- raise HTTPException(status_code=404, detail="帖子不存在")
 
 
 
 
 
 
 
 
 
209
 
210
  @router.delete("/api/posts/{post_id}")
211
  async def delete_post(post_id: str, current_user: str = Depends(require_auth)):
 
180
  @router.put("/api/posts/{post_id}")
181
  async def update_post(post_id: str, update_data: PostUpdate, current_user: str = Depends(require_auth)):
182
  """
183
+ 更新帖子(仅作者可操作,原子操作,并发安全
184
  """
185
+ result_holder = {}
186
 
187
+ def updater(data):
188
+ for post in data:
189
+ if post["id"] == post_id:
190
+ if post.get("author") != current_user:
191
+ result_holder["error"] = "forbidden"
192
+ return False
193
+ # 更新字段
194
+ if update_data.title is not None:
195
+ post["title"] = update_data.title
196
+ if update_data.content is not None:
197
+ post["content"] = update_data.content
198
+ if update_data.cover_image is not None:
199
+ post["cover_image"] = update_data.cover_image
200
+ if update_data.images is not None:
201
+ post["images"] = update_data.images[:9]
202
+ if update_data.is_original is not None:
203
+ post["is_original"] = update_data.is_original # 🎨 更新原创作品标记
204
+ result_holder["post"] = post
205
+ return True
206
+ result_holder["error"] = "not_found"
207
+ return False
208
 
209
+ db.atomic_update("posts.json", updater, default_data=[])
210
+
211
+ if result_holder.get("error") == "forbidden":
212
+ raise HTTPException(status_code=403, detail="无权修改他人帖子")
213
+ if result_holder.get("error") == "not_found":
214
+ raise HTTPException(status_code=404, detail="帖子不存在")
215
+
216
+ # 🗂️ 清除排序缓存
217
+ sort_cache.invalidate("posts:")
218
+ return {"status": "success"}
219
 
220
  @router.delete("/api/posts/{post_id}")
221
  async def delete_post(post_id: str, current_user: str = Depends(require_auth)):