审计修复:后端(安全 / 数据一致性 / 性能)
audit-2026-09-21.md 里的后端条目落地。每条都配了回归守卫,并逐条做过变异验证 (注入原 bug → 确认按正确理由变红 → 还原 → 变绿)。 安全 - CSRF 只加同源 Origin/Referer 守卫(csrf.go),不动模板 - 会话 cookie 的 Secure 按请求判断;两步验证两闸(loginGuard + 验证码一次性) - 跳转收口到 safeInternalPath;clientIP 只认 XFF 最后一段 - GPX 按属主圈定且查 RowsAffected;下载名走 downloadDisposition - 上传口统一 MaxBytesReader;落盘后的失败路径清掉半成品 数据一致性 - 区域判定两端各过一遍再 AND(apiTrack 与 movementsWhere 对齐) - Filter.Verdict 全域一致(下推到 visitsWhere);聚合刷新必须返回 error - 附属数据改挂坐标键,Go 与 SQL 两套表达式逐位一致 - 脏备份的伪时间/越界坐标不再进领域模型;rows 循环统一 drainRows - 合并与导出:writeRawRow 上抛错误、悬空引用清理、原生列补全 性能 - placeCols 相关子查询带 dataset_id 前导列;findSourceArchive 先按大小筛 - 批量勾选改 ANY($3::bigint[]);fillupCache 加上限;同一查询不再查两遍 另:新增「全新库」冒烟测试 —— 空库跑完 Migrate 再用应用侧读查询真打一遍, 迁移块排到依赖表之前这种错只有新库会炸,老库毫无症状。
This commit is contained in:
@@ -87,10 +87,37 @@ func visitCounts(t *testing.T, page string) (added, gone, clash int) {
|
||||
return
|
||||
}
|
||||
|
||||
// shiftSrcPKs 把库里的编号整体平移,模拟「这份数据其实来自另一份编号完全不同的备份」。
|
||||
//
|
||||
// 这不是臆造的场景:rond 每次导出/同步都会重排 Z_PK,所以「把本地和后来新增的备份合并」
|
||||
// 时,两边编号一定对不上,唯一稳定的键只有到访 `ZIDENTIFIER_` / 活动 `ZUID_`。
|
||||
// 夹具导入的就是 ROND_SRC 本身,编号与备份逐条相同(实测 823/823),
|
||||
// 所以不平移的话,比对会走「编号直接命中的快路径」,UUID 对齐这条真正在用的路径反而测不到。
|
||||
//
|
||||
// 平移量取得足够大(远超库里最大编号),单条 UPDATE 就不会在语句中途撞上唯一约束;
|
||||
// 同时把指向到访编号的外键(movements.from/to_visit_src、weather.visit_src)和留档一起挪。
|
||||
func (f *movementFixture) shiftSrcPKs(t *testing.T, delta int) {
|
||||
t.Helper()
|
||||
for _, q := range []string{
|
||||
`UPDATE visits SET src_pk = src_pk + $2 WHERE dataset_id=$1`,
|
||||
`UPDATE places SET src_pk = src_pk + $2 WHERE dataset_id=$1`,
|
||||
`UPDATE activities SET src_pk = src_pk + $2 WHERE dataset_id=$1`,
|
||||
`UPDATE movements SET src_pk = src_pk + $2,
|
||||
from_visit_src = from_visit_src + $2, to_visit_src = to_visit_src + $2 WHERE dataset_id=$1`,
|
||||
`UPDATE weather SET src_pk = src_pk + $2, visit_src = visit_src + $2 WHERE dataset_id=$1`,
|
||||
`UPDATE entity_raw SET src_pk = src_pk + $2 WHERE dataset_id=$1`,
|
||||
} {
|
||||
if _, err := f.pg.ExecContext(f.ctx, q, f.dsID, delta); err != nil {
|
||||
t.Fatalf("平移编号失败: %v\n%s", err, q)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 同一份备份再传一次:UUID 对得上、字段也没变,到访应当一条不差。
|
||||
//
|
||||
// 这条也顺带钉住「按 UUID 而不是编号对齐」:库内那些行的编号与备份里完全不同
|
||||
// (rond 重排过),只按编号比会让 800 多条全变冲突。
|
||||
// ⚠️ 注意这条用例**没有**验证「按 UUID 对齐」:夹具导入的就是 f.src 本身,
|
||||
// 库里的 src_pk 与备份的 Z_PK 逐条相同(实测 823/823),它是靠编号直接命中的。
|
||||
// 真正钉住 UUID 对齐的是 TestBackupDiffAlignsByUUIDNotSrcPK / TestBackupMergeRenumberedBackup。
|
||||
//
|
||||
// 只断言到访,不断言「完全一致」整句:导入后站点会反查补全地点(改名称/地址),
|
||||
// 地点层面因此真的存在差异,那是预期行为,不该由这个用例来管。
|
||||
@@ -102,6 +129,22 @@ func TestBackupDiffIdentical(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// 编号全被平移后(= 数据来自另一份重排过 Z_PK 的备份),同一份内容再比一次仍须零差异。
|
||||
//
|
||||
// 这是「本地 + 后来新增的备份」合并的真正前提:rond 每次导出都重排编号,
|
||||
// 若比对退回按编号对齐,这里会报成「几百条备份新增 + 几百条仅站内有」,
|
||||
// 勾一下「并进来」就会把整份足迹**复制一遍**。
|
||||
func TestBackupDiffAlignsByUUIDNotSrcPK(t *testing.T) {
|
||||
f := newMovementFixture(t)
|
||||
f.shiftSrcPKs(t, 500000)
|
||||
|
||||
page := previewBackup(t, f, f.src)
|
||||
if a, g, c := visitCounts(t, page); a != 0 || g != 0 || c != 0 {
|
||||
t.Fatalf("编号平移后内容其实没变,差异应为 0;实际 新增 %d 仅站内有 %d 冲突 %d"+
|
||||
" ⇒ 比对是靠编号对齐的,跨备份合并会把足迹复制一遍", a, g, c)
|
||||
}
|
||||
}
|
||||
|
||||
// 站内改过备注、又补录了一条到访,差异页要把这两件事分别认出来。
|
||||
//
|
||||
// 这里的关键是「按 UUID 对齐」:库里那些行的 Z_PK 与备份里完全不同
|
||||
|
||||
Reference in New Issue
Block a user