3.8 KiB
3.8 KiB
AM Downloader 多用户 V1 方案
目标
在现有 Go + Gin + GORM + SQLite + 下载队列 + WebDAV 架构上增量加入多用户、权限、下载额度和兑换码,不推倒重写现有 Downloader。
角色与权限
admin:全部权限;用户、兑换码、系统设置、日志、全局 WebDAV Storage 管理。privileged:普通下载能力 + WebDAV;可以配置自己的 WebDAV。user:下载、历史、兑换额度;不能访问 WebDAV、系统设置或其他用户。- 底层使用 capability:
download、redeem、webdav、webdav_config、api、advanced_download,避免以后扩展时绑定死角色。
设置隔离
- 用户设置:账户、外观;特权用户额外有自己的 WebDAV。
- 管理设置:
/admin/*,只有管理员可见且后端强制校验。 - 现有全局 AM API、下载目录、默认音质、WebDAV Storage 等属于管理员配置。
- 前端隐藏不是安全措施;API 必须返回 401/403。
WebDAV
- 管理员定义 Storage Root,例如
/data/webdav。 - 特权用户拥有自己的 WebDAV 配置和独立根目录
/data/webdav/{user_id}/。 - 禁止用户通过
..、绝对路径等逃逸 Storage Root。 - WebDAV 权限和 WebDAV 配置权限分离,方便以后扩展。
- 现有全局 WebDAV 继续作为系统级远程 Storage,逐步迁移为管理员配置。
Credits
- 一首实际成功下载的歌曲消耗 1 credit。
- 已存在且可复用的文件不扣 credit。
- 新下载创建任务时预留 credit;成功 commit,失败 refund。
- 同一任务重试不能重复扣费。
- 批量任务按实际成功数量结算。
- 所有额度变化进入不可变流水,不允许直接改余额。
Redeem Code
- 管理员可按批次批量生成兑换码。
- 每个兑换码可以有自定义 credits、有效期、备注。
- 状态:
unused、used、expired、revoked。 - 数据库只保存 code hash;生成后提供复制/导出明文。
- 兑换必须事务化,防止并发双兑。
- 管理员可以作废兑换码、查看批次统计和兑换记录。
数据模型
usersuser_permissionscredit_accountscredit_transactionscredit_reservationsredeem_batchesredeem_codesredeem_recordswebdav_configsaudit_logssessions- 现有
tasks增加user_id、credit_reservation_id,继续保留全局资源去重索引。 settings继续保存管理员系统设置。
下载与去重
不要简单把现有唯一键改成 user_id + source + rid + quality。用户任务与全局资源/文件应逻辑分离:同一资源可以被多个用户请求,但每个用户拥有自己的任务、额度流水和访问边界。第一阶段保持现有 Task 模型兼容,再逐步增加资源复用层。
API 分层
/api/auth/*:登录、登出、当前用户。/api/tasks:当前用户任务;所有查询按 user_id 隔离。/api/credits/*:余额、流水、兑换。/api/webdav/*:仅拥有 webdav 权限的用户。/api/admin/users/*:管理员。/api/admin/redeem/*:管理员。/api/admin/settings/*:管理员。/api/admin/audit/*:管理员。
安全
- 密码只保存强哈希。
- Session 使用随机不可预测 token,数据库保存 hash。
- 登录限速。
- 管理员敏感操作记录 audit log。
- 额度操作必须事务化。
- 兑换码不可明文持久化。
- WebDAV 路径必须做目录边界校验。
- 用户绝不能通过 API 读取其他用户 Task、Credit、WebDAV 配置。
实施顺序
- 数据模型与数据库迁移
- Session/Auth
- 权限中间件
- Task 用户隔离
- Credit Ledger + Reservation
- 下载成功/失败扣退额度
- Redeem Code
- WebDAV 特权用户隔离
- 管理后台 API
- 前端用户/特权/管理员界面
- 测试、迁移兼容性、备份与部署