package logic import ( "context" "net/http" "testing" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/net/ghttp" "github.com/gogf/gf/v2/os/gcfg" "tool-api/internal/consts" ) // ============================================================================ // 订单越权回归(真库 IT,IT_DB 门控) // // 两步式(N1)下,订单归属校验必须发生在「详情」与「支付」两条链路: // 访问**他人**订单的 out_trade_no → 一律 4015(订单不存在 / 不属于当前用户)。 // 运行:$env:IT_DB=1; go test ./internal/logic/ -run TestOrderOwnership4015 -count=1 -v // ============================================================================ // ctxWithUser 构造带登录用户 id 的最小请求上下文(CtxUserId 依赖 g.RequestFromCtx)。 func ctxWithUser(userId int64) context.Context { req := &ghttp.Request{Request: &http.Request{}} req.SetCtxVar(consts.CtxUserId, userId) return req.Context() } // ensureXPayConfig 注入最小可用的 wx.pay 配置,使 buildPayParams 越过「未配置」闸门, // 从而真正走到「支付人 = 登录人」的越权校验(本用例的目的:验证 4015,而非支付配置)。 func ensureXPayConfig(t *testing.T) { t.Helper() if xpayConfig(context.Background()).Configured() { return } adapter, err := gcfg.NewAdapterFile() if err != nil { t.Fatalf("创建配置适配器失败: %v", err) } adapter.SetContent( "wx:\n appId: \"probe\"\n appSecret: \"probe\"\n pay:\n offerId: \"probe\"\n appKey: \"probe\"\n env: 0\n", ) g.Cfg().SetAdapter(adapter) if !xpayConfig(context.Background()).Configured() { t.Fatalf("wx.pay 配置注入后仍未生效") } } // TestOrderOwnership4015 越权访问他人订单:详情 / 支付均须 4015。 func TestOrderOwnership4015(t *testing.T) { ctx := requireOrderIT(t) p := setupOrderProbe(ctx, t) defer p.cleanup(ctx) res := createMemberOrder(ctx, t, p) // 属于 p.userId 的待支付单 other := ctxWithUser(p.userId + 1) if _, err := MemberOrderDetail(other, res.OutTradeNo); err == nil { t.Fatalf("/member/order/detail 他人订单应 4015,实得 nil") } else if codeOf(err) != consts.CodeOrderInvalid { t.Fatalf("/member/order/detail 他人订单应 4015,实得 code=%d err=%v", codeOf(err), err) } ensureXPayConfig(t) if _, err := MemberOrderPay(other, res.OutTradeNo, "probe-code"); err == nil { t.Fatalf("/member/order/pay 他人订单应 4015,实得 nil") } else if codeOf(err) != consts.CodeOrderInvalid { t.Fatalf("/member/order/pay 他人订单应 4015,实得 code=%d err=%v", codeOf(err), err) } // 反证:本人取详情应放行 if _, err := MemberOrderDetail(ctxWithUser(p.userId), res.OutTradeNo); err != nil { t.Fatalf("本人订单详情应放行,实得 err=%v", err) } }