mirror of
https://github.com/wangdage12/Snap.Server.git
synced 2026-02-17 08:52:10 +08:00
初始提交
This commit is contained in:
12
routes/announcement.py
Normal file
12
routes/announcement.py
Normal file
@@ -0,0 +1,12 @@
|
||||
from flask import Blueprint, jsonify
|
||||
from services.announcement_service import get_announcements
|
||||
|
||||
announcement_bp = Blueprint("announcement", __name__)
|
||||
|
||||
@announcement_bp.route("/List", methods=["POST"])
|
||||
def list_announcements():
|
||||
return jsonify({
|
||||
"code": 0,
|
||||
"message": "OK",
|
||||
"data": get_announcements()
|
||||
})
|
||||
241
routes/auth.py
Normal file
241
routes/auth.py
Normal file
@@ -0,0 +1,241 @@
|
||||
from flask import Blueprint, request, jsonify, session
|
||||
from app.utils.jwt_utils import create_token, verify_token
|
||||
from services.auth_service import (
|
||||
decrypt_data, send_verification_email, verify_user_credentials,
|
||||
create_user_account, get_user_by_id
|
||||
)
|
||||
from app.extensions import generate_code, logger
|
||||
|
||||
auth_bp = Blueprint("auth", __name__)
|
||||
|
||||
|
||||
@auth_bp.route('/Passport/v2/Verify', methods=['POST'])
|
||||
def passport_verify():
|
||||
"""获取验证码"""
|
||||
data = request.get_json()
|
||||
encrypted_email = data.get('UserName', '')
|
||||
|
||||
try:
|
||||
decrypted_email = decrypt_data(encrypted_email)
|
||||
logger.debug(f"Decrypted email: {decrypted_email}")
|
||||
except Exception as e:
|
||||
logger.error(f"Decryption error: {e}")
|
||||
return jsonify({
|
||||
"retcode": 1,
|
||||
"message": f"Invalid encrypted email: {str(e)}",
|
||||
"data": None
|
||||
})
|
||||
|
||||
# 生成验证码
|
||||
code = generate_code(6)
|
||||
session['verification_code'] = code
|
||||
session['email'] = decrypted_email
|
||||
|
||||
# 发送邮件
|
||||
if send_verification_email(decrypted_email, code):
|
||||
return jsonify({
|
||||
"retcode": 0,
|
||||
"message": "success",
|
||||
"l10nKey": "ViewDialogUserAccountVerificationEmailCaptchaSent"
|
||||
})
|
||||
else:
|
||||
return jsonify({
|
||||
"retcode": 1,
|
||||
"message": "Failed to send email",
|
||||
"data": None
|
||||
}), 500
|
||||
|
||||
|
||||
@auth_bp.route('/Passport/v2/Register', methods=['POST'])
|
||||
def passport_register():
|
||||
"""用户注册"""
|
||||
data = request.get_json()
|
||||
encrypted_email = data.get('UserName', '')
|
||||
encrypted_password = data.get('Password', '')
|
||||
encrypted_code = data.get('VerifyCode', '')
|
||||
|
||||
try:
|
||||
decrypted_email = decrypt_data(encrypted_email)
|
||||
decrypted_password = decrypt_data(encrypted_password)
|
||||
decrypted_code = decrypt_data(encrypted_code)
|
||||
|
||||
logger.debug(f"Decrypted registration data: email={decrypted_email}, code={decrypted_code}")
|
||||
except Exception as e:
|
||||
logger.warning(f"Decryption error: {e}")
|
||||
return jsonify({
|
||||
"retcode": 1,
|
||||
"message": f"Invalid encrypted data: {str(e)}",
|
||||
"data": None
|
||||
}), 400
|
||||
|
||||
# 验证验证码
|
||||
if (session.get('verification_code') != decrypted_code or
|
||||
session.get('email') != decrypted_email):
|
||||
logger.warning("Invalid verification code")
|
||||
return jsonify({
|
||||
"retcode": 2,
|
||||
"message": "Invalid verification code",
|
||||
"data": None
|
||||
})
|
||||
|
||||
# 创建新用户
|
||||
new_user = create_user_account(decrypted_email, decrypted_password)
|
||||
if not new_user:
|
||||
logger.warning(f"User already exists: {decrypted_email}")
|
||||
return jsonify({
|
||||
"retcode": 3,
|
||||
"message": "User already exists",
|
||||
"data": None
|
||||
})
|
||||
|
||||
# 删除session中的验证码和邮箱
|
||||
session.pop('verification_code', None)
|
||||
session.pop('email', None)
|
||||
|
||||
# 创建token
|
||||
access_token = create_token(str(new_user['_id']))
|
||||
logger.info(f"User registered: {decrypted_email}")
|
||||
|
||||
return jsonify({
|
||||
"retcode": 0,
|
||||
"message": "success",
|
||||
"data": {
|
||||
"AccessToken": access_token,
|
||||
"RefreshToken": access_token,
|
||||
"ExpiresIn": 3600
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@auth_bp.route('/Passport/v2/Login', methods=['POST'])
|
||||
def passport_login():
|
||||
"""用户登录"""
|
||||
data = request.get_json()
|
||||
encrypted_email = data.get('UserName', '')
|
||||
encrypted_password = data.get('Password', '')
|
||||
|
||||
try:
|
||||
decrypted_email = decrypt_data(encrypted_email)
|
||||
decrypted_password = decrypt_data(encrypted_password)
|
||||
|
||||
logger.debug(f"Decrypted login data: email={decrypted_email}")
|
||||
except Exception as e:
|
||||
logger.warning(f"Decryption error: {e}")
|
||||
return jsonify({
|
||||
"retcode": 1,
|
||||
"message": f"Invalid encrypted data: {str(e)}",
|
||||
"data": None
|
||||
}), 400
|
||||
|
||||
# 验证用户凭据
|
||||
user = verify_user_credentials(decrypted_email, decrypted_password)
|
||||
if not user:
|
||||
logger.warning(f"Invalid login attempt for email: {decrypted_email}")
|
||||
return jsonify({
|
||||
"retcode": 2,
|
||||
"message": "Invalid email or password",
|
||||
"data": None
|
||||
})
|
||||
|
||||
# 创建token
|
||||
access_token = create_token(str(user['_id']))
|
||||
logger.info(f"User logged in: {decrypted_email}")
|
||||
|
||||
return jsonify({
|
||||
"retcode": 0,
|
||||
"message": "success",
|
||||
"l10nKey": "ServerPassportLoginSucceed",
|
||||
"data": {
|
||||
"AccessToken": access_token,
|
||||
"RefreshToken": access_token,
|
||||
"ExpiresIn": 3600
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@auth_bp.route('/Passport/v2/UserInfo', methods=['GET'])
|
||||
def passport_userinfo():
|
||||
"""获取用户信息"""
|
||||
token = request.headers.get('Authorization', '').replace('Bearer ', '')
|
||||
user_id = verify_token(token)
|
||||
|
||||
if not user_id:
|
||||
logger.warning("Invalid or expired token")
|
||||
return jsonify({
|
||||
"retcode": 1,
|
||||
"message": "Invalid or expired token",
|
||||
"data": None
|
||||
}), 401
|
||||
|
||||
user = get_user_by_id(user_id)
|
||||
if not user:
|
||||
logger.warning(f"User not found: {user_id}")
|
||||
return jsonify({
|
||||
"retcode": 2,
|
||||
"message": "User not found",
|
||||
"data": None
|
||||
})
|
||||
|
||||
logger.info(f"User info retrieved: {user['email']}")
|
||||
return jsonify({
|
||||
"retcode": 0,
|
||||
"message": "success",
|
||||
"data": {
|
||||
"NormalizedUserName": user['NormalizedUserName'],
|
||||
"UserName": user['UserName'],
|
||||
"IsLicensedDeveloper": user['IsLicensedDeveloper'],
|
||||
"IsMaintainer": user['IsMaintainer'],
|
||||
"GachaLogExpireAt": user['GachaLogExpireAt'],
|
||||
"CdnExpireAt": user['CdnExpireAt']
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@auth_bp.route('/Passport/v2/RefreshToken', methods=['POST'])
|
||||
def passport_refresh_token():
|
||||
"""刷新Token"""
|
||||
data = request.get_json()
|
||||
refresh_token = data.get('RefreshToken', '')
|
||||
|
||||
try:
|
||||
decrypted_refresh_token = decrypt_data(refresh_token)
|
||||
except Exception as e:
|
||||
logger.error(f"Decryption error: {e}")
|
||||
return jsonify({
|
||||
"retcode": 1,
|
||||
"message": f"Invalid encrypted refresh token: {str(e)}",
|
||||
"data": None
|
||||
}), 400
|
||||
|
||||
user_id = verify_token(decrypted_refresh_token)
|
||||
if not user_id:
|
||||
logger.warning("Invalid or expired refresh token")
|
||||
return jsonify({
|
||||
"retcode": 1,
|
||||
"message": "Invalid or expired refresh token",
|
||||
"data": None
|
||||
})
|
||||
|
||||
access_token = create_token(user_id)
|
||||
logger.info(f"Token refreshed for user_id: {user_id}")
|
||||
|
||||
return jsonify({
|
||||
"retcode": 0,
|
||||
"message": "success",
|
||||
"data": {
|
||||
"AccessToken": access_token,
|
||||
"RefreshToken": access_token,
|
||||
"ExpiresIn": 3600
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@auth_bp.route('/Passport/v2/RevokeToken', methods=['POST'])
|
||||
def passport_revoke_token():
|
||||
"""注销Token"""
|
||||
logger.info("Token revoked")
|
||||
return jsonify({
|
||||
"retcode": 0,
|
||||
"message": "Token revoked successfully",
|
||||
"data": None
|
||||
})
|
||||
160
routes/gacha_log.py
Normal file
160
routes/gacha_log.py
Normal file
@@ -0,0 +1,160 @@
|
||||
from flask import Blueprint, request, jsonify
|
||||
from app.utils.jwt_utils import verify_token
|
||||
from services.gacha_log_service import (
|
||||
get_gacha_log_entries, get_gacha_log_end_ids, upload_gacha_log,
|
||||
retrieve_gacha_log, delete_gacha_log
|
||||
)
|
||||
from app.extensions import logger
|
||||
|
||||
gacha_log_bp = Blueprint("gacha_log", __name__)
|
||||
|
||||
|
||||
@gacha_log_bp.route('/GachaLog/Statistics/Distribution/<distributionType>', methods=['GET'])
|
||||
def gacha_log_statistics_distribution(distributionType):
|
||||
"""获取祈愿记录统计分布"""
|
||||
return jsonify({
|
||||
"retcode": 0,
|
||||
"message": "success",
|
||||
"data": {}
|
||||
})
|
||||
|
||||
|
||||
@gacha_log_bp.route('/GachaLog/Entries', methods=['GET'])
|
||||
def gacha_log_entries():
|
||||
"""获取用户的祈愿记录条目列表"""
|
||||
token = request.headers.get('Authorization', '').replace('Bearer ', '')
|
||||
user_id = verify_token(token)
|
||||
|
||||
if not user_id:
|
||||
logger.warning("Invalid or expired token")
|
||||
return jsonify({
|
||||
"retcode": 1,
|
||||
"message": "Invalid or expired token",
|
||||
"data": None
|
||||
}), 401
|
||||
|
||||
entries = get_gacha_log_entries(user_id)
|
||||
logger.info(f"Gacha log entries retrieved for user_id: {user_id}")
|
||||
logger.debug(f"Entries: {entries}")
|
||||
|
||||
return jsonify({
|
||||
"retcode": 0,
|
||||
"message": "success",
|
||||
"data": entries
|
||||
})
|
||||
|
||||
|
||||
@gacha_log_bp.route('/GachaLog/EndIds', methods=['GET'])
|
||||
def gacha_log_end_ids():
|
||||
"""获取指定 UID 用户的祈愿记录最新 ID"""
|
||||
token = request.headers.get('Authorization', '').replace('Bearer ', '')
|
||||
user_id = verify_token(token)
|
||||
|
||||
if not user_id:
|
||||
logger.warning("Invalid or expired token")
|
||||
return jsonify({
|
||||
"retcode": 1,
|
||||
"message": "Invalid or expired token",
|
||||
"data": None
|
||||
}), 401
|
||||
|
||||
uid = request.args.get('Uid', '')
|
||||
end_ids = get_gacha_log_end_ids(user_id, uid)
|
||||
|
||||
logger.info(f"Gacha log end IDs retrieved for user_id: {user_id}, uid: {uid}")
|
||||
logger.debug(f"End IDs: {end_ids}")
|
||||
|
||||
return jsonify({
|
||||
"retcode": 0,
|
||||
"message": "success",
|
||||
"data": end_ids
|
||||
})
|
||||
|
||||
|
||||
@gacha_log_bp.route('/GachaLog/Upload', methods=['POST'])
|
||||
def gacha_log_upload():
|
||||
"""上传祈愿记录"""
|
||||
token = request.headers.get('Authorization', '').replace('Bearer ', '')
|
||||
user_id = verify_token(token)
|
||||
|
||||
if not user_id:
|
||||
logger.warning("Invalid or expired token")
|
||||
return jsonify({
|
||||
"retcode": 1,
|
||||
"message": "Invalid or expired token",
|
||||
"data": None
|
||||
}), 401
|
||||
|
||||
data = request.get_json()
|
||||
uid = data.get('Uid', '')
|
||||
items = data.get('Items', [])
|
||||
|
||||
message = upload_gacha_log(user_id, uid, items)
|
||||
logger.info(f"Gacha log upload for user_id: {user_id}, uid: {uid}")
|
||||
|
||||
return jsonify({
|
||||
"retcode": 0,
|
||||
"message": message,
|
||||
"data": None
|
||||
})
|
||||
|
||||
|
||||
@gacha_log_bp.route('/GachaLog/Retrieve', methods=['POST'])
|
||||
def gacha_log_retrieve():
|
||||
"""从云端检索用户的祈愿记录数据"""
|
||||
token = request.headers.get('Authorization', '').replace('Bearer ', '')
|
||||
user_id = verify_token(token)
|
||||
|
||||
if not user_id:
|
||||
logger.warning("Invalid or expired token")
|
||||
return jsonify({
|
||||
"retcode": 1,
|
||||
"message": "Invalid or expired token",
|
||||
"data": None
|
||||
}), 401
|
||||
|
||||
data = request.get_json()
|
||||
uid = data.get('Uid', '')
|
||||
end_ids = data.get('EndIds', {})
|
||||
|
||||
filtered_items = retrieve_gacha_log(user_id, uid, end_ids)
|
||||
logger.info(f"Gacha log retrieved for user_id: {user_id}, uid: {uid}, items count: {len(filtered_items)}")
|
||||
|
||||
return jsonify({
|
||||
"retcode": 0,
|
||||
"message": f"success, retrieved {len(filtered_items)} items",
|
||||
"data": filtered_items
|
||||
})
|
||||
|
||||
|
||||
@gacha_log_bp.route('/GachaLog/Delete', methods=['GET'])
|
||||
def gacha_log_delete():
|
||||
"""删除用户的祈愿记录"""
|
||||
token = request.headers.get('Authorization', '').replace('Bearer ', '')
|
||||
user_id = verify_token(token)
|
||||
|
||||
if not user_id:
|
||||
logger.warning("Invalid or expired token")
|
||||
return jsonify({
|
||||
"retcode": 1,
|
||||
"message": "Invalid or expired token",
|
||||
"data": None
|
||||
}), 401
|
||||
|
||||
uid = request.args.get('Uid', '')
|
||||
success = delete_gacha_log(user_id, uid)
|
||||
|
||||
if success:
|
||||
logger.info(f"Gacha log deleted for user_id: {user_id}, uid: {uid}")
|
||||
return jsonify({
|
||||
"retcode": 0,
|
||||
"message": "success, gacha log deleted",
|
||||
"data": None
|
||||
})
|
||||
else:
|
||||
logger.info(f"No gacha log found to delete for user_id: {user_id}, uid: {uid}")
|
||||
return jsonify({
|
||||
"retcode": 2,
|
||||
"message": "no gacha log found to delete",
|
||||
"data": None
|
||||
})
|
||||
69
routes/misc.py
Normal file
69
routes/misc.py
Normal file
@@ -0,0 +1,69 @@
|
||||
from flask import Blueprint, request, jsonify, send_file
|
||||
from app.extensions import logger, client
|
||||
from app.config import Config
|
||||
|
||||
misc_bp = Blueprint("misc", __name__)
|
||||
|
||||
|
||||
@misc_bp.route('/patch/hutao', methods=['GET'])
|
||||
def patch_hutao():
|
||||
"""获取新版本信息"""
|
||||
return {
|
||||
"code": 0,
|
||||
"message": "OK",
|
||||
"data": {
|
||||
"validation": "",
|
||||
"version": "1.0.0",
|
||||
"mirrors": []
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@misc_bp.route('/git-repository/all', methods=['GET'])
|
||||
def git_repository_all():
|
||||
"""获取所有Git仓库"""
|
||||
if Config.ISTEST_MODE:
|
||||
# 覆盖元数据仓库列表,测试用
|
||||
repositories = [
|
||||
{
|
||||
"name": "test",
|
||||
"https_url": "http://server.wdg.cloudns.ch:3000/wdg1122/Snap.Metadata.Test.git",
|
||||
"web_url": "http://server.wdg.cloudns.ch:3000/wdg1122/Snap.Metadata.Test",
|
||||
"type": "Public"
|
||||
}
|
||||
]
|
||||
return jsonify({
|
||||
"code": 0,
|
||||
"message": "OK",
|
||||
"data": repositories
|
||||
})
|
||||
|
||||
# 从数据库获取 Git 仓库列表
|
||||
git_repositories = list(client.ht_server.git_repository.find({}))
|
||||
|
||||
for repo in git_repositories:
|
||||
repo.pop('_id', None)
|
||||
|
||||
logger.debug(f"Git repositories: {git_repositories}")
|
||||
|
||||
return jsonify({
|
||||
"code": 0,
|
||||
"message": "OK",
|
||||
"data": git_repositories
|
||||
})
|
||||
|
||||
|
||||
@misc_bp.route('/static/raw/<category>/<fileName>', methods=['GET'])
|
||||
def get_image(category, fileName):
|
||||
"""获取图片资源,弃用,请使用额外的文件服务器"""
|
||||
return jsonify({"code": 1, "message": "Image not found"}), 404
|
||||
|
||||
|
||||
@misc_bp.route('/mgnt/am-i-banned', methods=['GET'])
|
||||
def mgnt_am_i_banned():
|
||||
"""检查游戏账户是否禁用注入,目前直接返回成功的响应即可"""
|
||||
return jsonify({
|
||||
"retcode": 0,
|
||||
"message": "OK",
|
||||
"data": {}
|
||||
})
|
||||
246
routes/web_api.py
Normal file
246
routes/web_api.py
Normal file
@@ -0,0 +1,246 @@
|
||||
import datetime
|
||||
from bson import ObjectId
|
||||
from flask import Blueprint, request, jsonify
|
||||
from app.utils.jwt_utils import verify_token, create_token
|
||||
from services.auth_service import verify_user_credentials, get_users_with_search
|
||||
from app.decorators import require_maintainer_permission
|
||||
from app.extensions import generate_numeric_id, client, logger
|
||||
|
||||
web_api_bp = Blueprint("web_api", __name__)
|
||||
|
||||
|
||||
@web_api_bp.route('/web-api/login', methods=['POST'])
|
||||
def web_api_login():
|
||||
"""Web管理端登录"""
|
||||
data = request.get_json()
|
||||
email = data.get('email', '')
|
||||
password = data.get('password', '')
|
||||
|
||||
# 验证用户凭据
|
||||
user = verify_user_credentials(email, password)
|
||||
|
||||
if not user:
|
||||
logger.warning(f"Invalid web login attempt for email: {email}")
|
||||
return jsonify({
|
||||
"code": 1,
|
||||
"message": "Invalid email or password",
|
||||
"data": None
|
||||
})
|
||||
|
||||
# 创建token
|
||||
access_token = create_token(str(user['_id']))
|
||||
logger.info(f"Web user logged in: {email}")
|
||||
|
||||
return jsonify({
|
||||
"code": 0,
|
||||
"message": "success",
|
||||
"data": {
|
||||
"access_token": access_token,
|
||||
"expires_in": 3600
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
# 公告管理API
|
||||
|
||||
@web_api_bp.route('/web-api/announcement', methods=['POST'])
|
||||
@require_maintainer_permission
|
||||
def web_api_create_announcement():
|
||||
"""创建公告"""
|
||||
data = request.get_json()
|
||||
|
||||
# 验证必需字段
|
||||
if not all(k in data for k in ['Title', 'Content', 'Locale']):
|
||||
return jsonify({
|
||||
"code": 1,
|
||||
"message": "Missing required fields: Title, Content, Locale",
|
||||
"data": None
|
||||
}), 400
|
||||
|
||||
# 生成公告ID
|
||||
announcement_id = int(generate_numeric_id(8))
|
||||
|
||||
# 创建公告对象
|
||||
announcement = {
|
||||
"Id": announcement_id,
|
||||
"Title": data['Title'],
|
||||
"Content": data['Content'],
|
||||
"Severity": data.get('Severity', 0), # 默认为Informational
|
||||
"Link": data.get('Link', ''),
|
||||
"Locale": data['Locale'],
|
||||
"LastUpdateTime": int(datetime.datetime.now().timestamp()),
|
||||
"MaxPresentVersion": data.get('MaxPresentVersion', None),
|
||||
"CreatedBy": str(request.current_user['_id']),
|
||||
"CreatedAt": datetime.datetime.utcnow()
|
||||
}
|
||||
|
||||
# 插入数据库
|
||||
result = client.ht_server.announcement.insert_one(announcement)
|
||||
|
||||
if result.inserted_id:
|
||||
logger.info(f"Announcement created with ID: {announcement_id} by user: {request.current_user['email']}")
|
||||
return jsonify({
|
||||
"code": 0,
|
||||
"message": "Announcement created successfully",
|
||||
"data": {
|
||||
"Id": announcement_id
|
||||
}
|
||||
})
|
||||
else:
|
||||
logger.error("Failed to create announcement")
|
||||
return jsonify({
|
||||
"code": 2,
|
||||
"message": "Failed to create announcement",
|
||||
"data": None
|
||||
}), 500
|
||||
|
||||
|
||||
@web_api_bp.route('/web-api/announcement/<int:announcement_id>', methods=['PUT'])
|
||||
@require_maintainer_permission
|
||||
def web_api_update_announcement(announcement_id):
|
||||
"""编辑公告"""
|
||||
data = request.get_json()
|
||||
|
||||
# 检查公告是否存在
|
||||
existing_announcement = client.ht_server.announcement.find_one({"Id": announcement_id})
|
||||
if not existing_announcement:
|
||||
return jsonify({
|
||||
"code": 1,
|
||||
"message": "Announcement not found",
|
||||
"data": None
|
||||
}), 404
|
||||
|
||||
# 更新字段
|
||||
update_data = {
|
||||
"LastUpdateTime": int(datetime.datetime.now().timestamp()),
|
||||
"UpdatedBy": str(request.current_user['_id']),
|
||||
"UpdatedAt": datetime.datetime.utcnow()
|
||||
}
|
||||
|
||||
# 只更新提供的字段
|
||||
if 'Title' in data:
|
||||
update_data["Title"] = data['Title']
|
||||
if 'Content' in data:
|
||||
update_data["Content"] = data['Content']
|
||||
if 'Severity' in data:
|
||||
update_data["Severity"] = data['Severity']
|
||||
if 'Link' in data:
|
||||
update_data["Link"] = data['Link']
|
||||
if 'Locale' in data:
|
||||
update_data["Locale"] = data['Locale']
|
||||
if 'MaxPresentVersion' in data:
|
||||
update_data["MaxPresentVersion"] = data['MaxPresentVersion']
|
||||
|
||||
# 执行更新
|
||||
result = client.ht_server.announcement.update_one(
|
||||
{"Id": announcement_id},
|
||||
{"$set": update_data}
|
||||
)
|
||||
|
||||
if result.modified_count > 0:
|
||||
logger.info(f"Announcement {announcement_id} updated by user: {request.current_user['email']}")
|
||||
return jsonify({
|
||||
"code": 0,
|
||||
"message": "Announcement updated successfully",
|
||||
"data": None
|
||||
})
|
||||
else:
|
||||
logger.warning(f"No changes made to announcement {announcement_id}")
|
||||
return jsonify({
|
||||
"code": 2,
|
||||
"message": "No changes made",
|
||||
"data": None
|
||||
})
|
||||
|
||||
|
||||
@web_api_bp.route('/web-api/announcement/<int:announcement_id>', methods=['DELETE'])
|
||||
@require_maintainer_permission
|
||||
def web_api_delete_announcement(announcement_id):
|
||||
"""删除公告"""
|
||||
# 检查公告是否存在
|
||||
existing_announcement = client.ht_server.announcement.find_one({"Id": announcement_id})
|
||||
if not existing_announcement:
|
||||
return jsonify({
|
||||
"code": 1,
|
||||
"message": "Announcement not found",
|
||||
"data": None
|
||||
}), 404
|
||||
|
||||
# 执行删除
|
||||
result = client.ht_server.announcement.delete_one({"Id": announcement_id})
|
||||
|
||||
if result.deleted_count > 0:
|
||||
logger.info(f"Announcement {announcement_id} deleted by user: {request.current_user['email']}")
|
||||
return jsonify({
|
||||
"code": 0,
|
||||
"message": "Announcement deleted successfully",
|
||||
"data": None
|
||||
})
|
||||
else:
|
||||
logger.error(f"Failed to delete announcement {announcement_id}")
|
||||
return jsonify({
|
||||
"code": 2,
|
||||
"message": "Failed to delete announcement",
|
||||
"data": None
|
||||
}), 500
|
||||
|
||||
|
||||
@web_api_bp.route('/web-api/announcement/<int:announcement_id>', methods=['GET'])
|
||||
@require_maintainer_permission
|
||||
def web_api_get_announcement(announcement_id):
|
||||
"""获取单个公告详情"""
|
||||
# 查询公告
|
||||
announcement = client.ht_server.announcement.find_one({"Id": announcement_id})
|
||||
|
||||
if not announcement:
|
||||
return jsonify({
|
||||
"code": 1,
|
||||
"message": "Announcement not found",
|
||||
"data": None
|
||||
}), 404
|
||||
|
||||
# 移除MongoDB的_id字段
|
||||
announcement.pop('_id', None)
|
||||
|
||||
return jsonify({
|
||||
"code": 0,
|
||||
"message": "success",
|
||||
"data": announcement
|
||||
})
|
||||
|
||||
|
||||
@web_api_bp.route('/web-api/users', methods=['GET'])
|
||||
def web_api_get_users():
|
||||
"""获取所有用户列表,需要验证token,并且需要高权限"""
|
||||
# 获取用户信息
|
||||
token = request.headers.get('Authorization', '').replace('Bearer ', '')
|
||||
user_id = verify_token(token)
|
||||
|
||||
if not user_id:
|
||||
logger.warning("Invalid or expired token")
|
||||
return jsonify({
|
||||
"code": 1,
|
||||
"message": "Invalid or expired token",
|
||||
"data": None
|
||||
}), 401
|
||||
|
||||
# 检查用户是否具有高权限
|
||||
user = client.ht_server.users.find_one({"_id": ObjectId(user_id)})
|
||||
if not user or not (user.get("IsMaintainer", False) and user.get("IsLicensedDeveloper", False)):
|
||||
logger.warning(f"User {user_id} does not have required permissions")
|
||||
logger.debug(f"User details: {user}")
|
||||
return jsonify({
|
||||
"code": 2,
|
||||
"message": "Insufficient permissions",
|
||||
"data": None
|
||||
}), 403
|
||||
|
||||
# 获取搜索参数
|
||||
q = request.args.get("q", "").strip()
|
||||
users = get_users_with_search(q)
|
||||
|
||||
return jsonify({
|
||||
"code": 0,
|
||||
"message": "success",
|
||||
"data": users
|
||||
})
|
||||
Reference in New Issue
Block a user