fix: 改密计入锁定并清理过期管理员会话

This commit is contained in:
Nixevol
2026-09-30 16:22:48 +08:00
parent b3787a0471
commit 1cb562fb71
4 changed files with 108 additions and 2 deletions
+75
View File
@@ -0,0 +1,75 @@
package admin_test
import (
"context"
"database/sql"
"net/http"
"net/http/cookiejar"
"net/http/httptest"
"path/filepath"
"testing"
"git.asio.asia/nixevol/NixMsg/internal/admin"
"git.asio.asia/nixevol/NixMsg/internal/auth"
"git.asio.asia/nixevol/NixMsg/internal/store"
)
func TestPasswordWrongOldLocksAfterTen(t *testing.T) {
_, srv, client, _ := setup(t)
login(t, client, srv.URL)
base := srv.URL
var last *http.Response
var env envelope
for i := 0; i < 10; i++ {
last = postJSON(t, client, base+"/api/admin/password",
`{"old_password":"not-the-password","new_password":"new-password-12"}`,
map[string]string{"X-Nixmsg-Request": "1"})
env = decodeEnv(t, last)
}
if last.StatusCode != http.StatusTooManyRequests {
t.Fatalf("want 429 after 10 wrong old passwords, got %d %+v", last.StatusCode, env)
}
if env.Error == nil || env.Error.Code != "rate_limited" {
t.Fatalf("want rate_limited got %+v", env.Error)
}
}
func TestLoginDeletesExpiredAdminSessions(t *testing.T) {
dir := t.TempDir()
db, err := store.Open(filepath.Join(dir, "data"), "FULL")
if err != nil {
t.Fatal(err)
}
t.Cleanup(func() { _ = db.Close() })
hash := auth.NewStubHashPool()
if seedErr := admin.SeedAdminPassword(context.Background(), db, hash, testPassword); seedErr != nil {
t.Fatal(seedErr)
}
h := admin.New(admin.Deps{
DB: db,
Hash: hash,
Tokens: admin.NewRandomAPITokens(),
Locks: admin.NewMemoryLoginLocks(),
})
srv := httptest.NewServer(h)
t.Cleanup(srv.Close)
if err := db.Queue.Do(context.Background(), func(tx *sql.Tx) error {
_, e := tx.Exec(`INSERT INTO admin_sessions(token_hash, created_at, expires_at) VALUES ('expired-hash', 1, 1)`)
return e
}); err != nil {
t.Fatal(err)
}
jar, err := cookiejar.New(nil)
if err != nil {
t.Fatal(err)
}
client := &http.Client{Jar: jar}
login(t, client, srv.URL)
var n int
if err := db.Read.QueryRow(`SELECT COUNT(*) FROM admin_sessions WHERE token_hash = 'expired-hash'`).Scan(&n); err != nil {
t.Fatal(err)
}
if n != 0 {
t.Fatalf("expired session still present, count=%d", n)
}
}