feat: /download 下载端点 download_project.dspy + RBAC 权限注册
This commit is contained in:
parent
4be75e1f6a
commit
1403bced52
@ -104,6 +104,7 @@ PATHS_LOGINED = [
|
||||
f"/{MOD}/api/workspace_files.dspy",
|
||||
f"/{MOD}/api/workspace_open.dspy",
|
||||
f"/{MOD}/api/workspace_file.dspy",
|
||||
f"/{MOD}/api/download_project.dspy",
|
||||
f"/{MOD}/api/workspace_upload.dspy",
|
||||
f"/{MOD}/api/workspace_delete.dspy",
|
||||
f"/{MOD}/api/workspace_popup.dspy",
|
||||
|
||||
26
wwwroot/api/download_project.dspy
Normal file
26
wwwroot/api/download_project.dspy
Normal file
@ -0,0 +1,26 @@
|
||||
# download_project.dspy - 下载项目备份 tgz 文件(/download 命令生成下载链接)
|
||||
import os
|
||||
from urllib.parse import quote
|
||||
from aiohttp.web_fileresponse import FileResponse
|
||||
|
||||
path = (params_kw or {}).get('path', '').strip()
|
||||
|
||||
uid = await get_user()
|
||||
if not uid:
|
||||
return {"widgettype": "Message", "options": {"title": "错误", "message": "请先登录"}}
|
||||
|
||||
# 安全校验:只允许 _archive 备份归档目录下的 .tgz 文件
|
||||
if not path or not path.endswith('.tgz'):
|
||||
return {"widgettype": "Message", "options": {"title": "错误", "message": "非法文件(仅支持 .tgz 备份文件)"}}
|
||||
|
||||
real = os.path.realpath(path)
|
||||
if '/_archive/' not in real:
|
||||
return {"widgettype": "Message", "options": {"title": "错误", "message": "非法路径(仅允许 _archive 备份归档目录)"}}
|
||||
|
||||
if not os.path.isfile(path):
|
||||
return {"widgettype": "Message", "options": {"title": "错误", "message": "文件不存在"}}
|
||||
|
||||
filename = os.path.basename(path)
|
||||
safe_name = quote(filename)
|
||||
headers = {'Content-Disposition': 'attachment; filename="%s"; filename*=UTF-8\'\'%s' % (filename, safe_name)}
|
||||
return FileResponse(path, headers=headers)
|
||||
Loading…
x
Reference in New Issue
Block a user