Tighten upload validation and transactions
This commit is contained in:
35
back/main.py
35
back/main.py
@@ -3,9 +3,11 @@
|
||||
from flask import Flask, jsonify, request, abort, send_from_directory
|
||||
from flask_cors import CORS
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
from sqlalchemy.orm import foreign
|
||||
import os
|
||||
import uuid
|
||||
import json
|
||||
import imghdr
|
||||
from datetime import datetime
|
||||
|
||||
app = Flask(__name__)
|
||||
@@ -62,9 +64,10 @@ class Submission(db.Model):
|
||||
comments = db.relationship('Comment', backref='submission', lazy=True, cascade='all, delete-orphan')
|
||||
hashtags = db.relationship(
|
||||
'Hashtag',
|
||||
primaryjoin="and_(Hashtag.type==0, Hashtag.target_id==Submission.id)",
|
||||
primaryjoin="and_(Hashtag.type==0, foreign(Hashtag.target_id)==Submission.id)",
|
||||
cascade='all, delete-orphan',
|
||||
lazy=True
|
||||
lazy=True,
|
||||
overlaps="hashtags"
|
||||
)
|
||||
|
||||
class Comment(db.Model):
|
||||
@@ -78,9 +81,10 @@ class Comment(db.Model):
|
||||
parent_comment_id = db.Column(db.Integer, db.ForeignKey('comments.id'), nullable=True)
|
||||
hashtags = db.relationship(
|
||||
'Hashtag',
|
||||
primaryjoin="and_(Hashtag.type==1, Hashtag.target_id==Comment.id)",
|
||||
primaryjoin="and_(Hashtag.type==1, foreign(Hashtag.target_id)==Comment.id)",
|
||||
cascade='all, delete-orphan',
|
||||
lazy=True
|
||||
lazy=True,
|
||||
overlaps="hashtags"
|
||||
)
|
||||
|
||||
class Report(db.Model):
|
||||
@@ -207,7 +211,6 @@ def save_hashtags(tag_type, target_id, hashtopic):
|
||||
name=tag
|
||||
)
|
||||
db.session.add(new_tag)
|
||||
db.session.commit()
|
||||
|
||||
# --- 用户普通api端点 ---
|
||||
@app.route('/api/settings', methods=['GET'])
|
||||
@@ -345,14 +348,16 @@ def submit_post():
|
||||
updated_at=now,
|
||||
)
|
||||
db.session.add(new_post)
|
||||
db.session.commit()
|
||||
db.session.flush()
|
||||
|
||||
# 保存 Hashtags
|
||||
save_hashtags(0, new_post.id, hashtopic)
|
||||
db.session.commit()
|
||||
|
||||
code = 1002 if new_post.status == 'Pending' else 1001
|
||||
return jsonify({"code": code, "data": {"id": new_post.id}})
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
return jsonify({"code": 2003, "data": f"投稿失败: {str(e)}"})
|
||||
|
||||
@app.route('/api/comment', methods=['POST'])
|
||||
@@ -398,13 +403,15 @@ def submit_comment():
|
||||
parent_comment_id=None if parent_comment_id == 0 else parent_comment_id
|
||||
)
|
||||
db.session.add(new_comment)
|
||||
db.session.commit()
|
||||
db.session.flush()
|
||||
|
||||
# 保存 Hashtags
|
||||
save_hashtags(1, new_comment.id, hashtopic)
|
||||
db.session.commit()
|
||||
|
||||
return jsonify({"code": 1001, "data": {"id": new_comment.id}})
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
return jsonify({"code": 2003, "data": f"评论失败: {str(e)}"})
|
||||
|
||||
@app.route('/api/report', methods=['POST'])
|
||||
@@ -498,6 +505,20 @@ def upload_pic():
|
||||
if not ext or (FILE_FORMATS and ext not in FILE_FORMATS):
|
||||
return jsonify({"code": 2007, "data": "上传的文件类型不支持"})
|
||||
|
||||
header = file.read(512)
|
||||
file.seek(0)
|
||||
detected = imghdr.what(None, header)
|
||||
ext_map = {
|
||||
'jpg': 'jpeg',
|
||||
'jpeg': 'jpeg',
|
||||
'png': 'png',
|
||||
'gif': 'gif',
|
||||
'webp': 'webp',
|
||||
}
|
||||
expected = ext_map.get(ext)
|
||||
if not expected or detected != expected:
|
||||
return jsonify({"code": 2007, "data": "上传的文件类型不支持"})
|
||||
|
||||
filename = f"{uuid.uuid4().hex}.{ext}"
|
||||
filepath = os.path.join(IMG_DIR, filename)
|
||||
file.save(filepath)
|
||||
|
||||
Reference in New Issue
Block a user