From a5d44df5059b04aafe06f0d746c429ce273fc414 Mon Sep 17 00:00:00 2001 From: weichen Date: Mon, 12 Oct 2026 05:24:02 +0000 Subject: [PATCH] Clear must_change before API-key use in multi-instance U7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Why: Backend login_keys gate blocks Key traffic while must_change_password is set; U7 failed on PUT settings/user 403. Evidence: go test -c multi-instance compiles; CI test-pg will GATE. Impact: loginAlice does session password change alicePass0→alicePass. Refs: Dev PR #426; Backend #170 pin e7b70c2 Co-authored-by: Cursor --- .../multi-instance/multi_instance_test.go | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/tests/integration/multi-instance/multi_instance_test.go b/tests/integration/multi-instance/multi_instance_test.go index f9e54ec5..6cba49bf 100644 --- a/tests/integration/multi-instance/multi_instance_test.go +++ b/tests/integration/multi-instance/multi_instance_test.go @@ -21,6 +21,7 @@ import ( "io" "net" "net/http" + "net/http/cookiejar" "net/url" "os" "os/exec" @@ -370,9 +371,24 @@ func (e *env) killNine(t *testing.T, inst *instance) { // loginAlice 引导 alice 账号并发放 API key(CLI 直连测试库;key 存共享 PG, // 对两实例同时有效——程序化验收的首选凭证,SSE 亦可用 ?key= 兜底)。 +// 建号后 must_change=1:API Key 在改密完成前不能走业务接口(login_keys 门禁), +// 故先经会话完成 alicePass0→alicePass,再发 Key。 func (e *env) loginAlice(t *testing.T) *userClient { t.Helper() - e.cli(t, "user", "create", "--dsn", e.dbDSN, "--owner", aliceOwner, "--name", "Alice", "--password", alicePass) + e.cli(t, "user", "create", "--dsn", e.dbDSN, "--owner", aliceOwner, "--name", "Alice", "--password", alicePass0) + jar, err := cookiejar.New(nil) + if err != nil { + t.Fatal(err) + } + sess := &http.Client{Timeout: httpWait, Jar: jar} + // e.uc 尚未赋值 → baseFor 走 A;会话 cookie 落 jar 后改密清 must_change。 + e.do(t, sess, "POST", "/api/auth/login", map[string]any{ + "owner": aliceOwner, "password": alicePass0, + }, nil) + e.do(t, sess, "POST", "/api/auth/password", map[string]any{ + "current": alicePass0, "next": alicePass, + }, nil) + key := e.cliOut(t, "apikey", "create", "--dsn", e.dbDSN, "--owner", aliceOwner, "--name", "mi-acceptance") uc := &userClient{ api: &http.Client{Timeout: httpWait, Transport: bearerRT{key: key}},