72 lines
3.4 KiB
Go
72 lines
3.4 KiB
Go
package httpapi
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"git.nianxx.cn/wangxuming/NianAIGC/backend/internal/identity"
|
|
)
|
|
|
|
type passwordChangerStub struct {
|
|
command identity.PasswordChangeCommand
|
|
session identity.Session
|
|
err error
|
|
}
|
|
|
|
func (s *passwordChangerStub) Change(_ context.Context, command identity.PasswordChangeCommand) (identity.Session, error) {
|
|
s.command = command
|
|
return s.session, s.err
|
|
}
|
|
|
|
func TestAuthPasswordChangeReplacesSignedSessionCookie(t *testing.T) {
|
|
secret := "password-change-secret-with-enough-entropy"
|
|
now := time.Now().UTC().Truncate(time.Second)
|
|
version := 4
|
|
changer := &passwordChangerStub{session: identity.Session{Version: 1, AuthMode: identity.AuthModeUser, IssuedAt: now.Unix(), ExpiresAt: now.Add(time.Hour).Unix(), SessionVersion: &version, User: identity.User{ID: "u", Subject: "u", Phone: "13800138000", DisplayName: "User", ClientID: "platform", Role: "user", Status: "active", Authorities: []string{"ROLE_USER"}, Scope: []string{}}}}
|
|
resolver := &platformSessionResolverStub{outcome: "authenticated", session: identity.Session{AuthMode: identity.AuthModeUser, User: identity.User{ID: "u", Role: "user"}}}
|
|
authorizer, _ := NewPlatformAuthorizer(AuthState{Required: true, Configured: true}, resolver)
|
|
handler, err := NewAuthPasswordChangeHandler(PasswordChangeConfig{SessionSecret: secret}, authorizer, changer)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
r := httptest.NewRequest(http.MethodPost, "https://app.test/api/auth/password/change", strings.NewReader(`{"currentPassword":" current-password ","newPassword":"next-password","confirmPassword":"next-password"}`))
|
|
r.AddCookie(&http.Cookie{Name: identity.SessionCookieName, Value: "existing"})
|
|
w := httptest.NewRecorder()
|
|
handler.ServeHTTP(w, r)
|
|
if w.Code != http.StatusOK || changer.command.AccountID != "u" || changer.command.CurrentPassword != "current-password" {
|
|
t.Fatalf("status=%d command=%+v body=%q", w.Code, changer.command, w.Body.String())
|
|
}
|
|
cookies := w.Result().Cookies()
|
|
if len(cookies) != identity.CookieMaxChunks {
|
|
t.Fatalf("cookies=%d", len(cookies))
|
|
}
|
|
signed := cookies[0].Value
|
|
parsed, err := identity.Parse(signed, secret, now)
|
|
if err != nil || parsed.SessionVersion == nil || *parsed.SessionVersion != 4 {
|
|
t.Fatalf("parse=%+v err=%v", parsed, err)
|
|
}
|
|
var body map[string]any
|
|
if err := json.Unmarshal(w.Body.Bytes(), &body); err != nil || body["ok"] != true {
|
|
t.Fatalf("body=%q err=%v", w.Body.String(), err)
|
|
}
|
|
}
|
|
|
|
func TestAuthPasswordChangeValidatesConfirmation(t *testing.T) {
|
|
resolver := &platformSessionResolverStub{outcome: "authenticated", session: identity.Session{AuthMode: identity.AuthModeUser, User: identity.User{ID: "u", Role: "user"}}}
|
|
authorizer, _ := NewPlatformAuthorizer(AuthState{Required: true, Configured: true}, resolver)
|
|
changer := &passwordChangerStub{}
|
|
handler, _ := NewAuthPasswordChangeHandler(PasswordChangeConfig{SessionSecret: "secret"}, authorizer, changer)
|
|
r := httptest.NewRequest(http.MethodPost, "/api/auth/password/change", strings.NewReader(`{"currentPassword":"old-password","newPassword":"new-password","confirmPassword":"different"}`))
|
|
r.AddCookie(&http.Cookie{Name: identity.SessionCookieName, Value: "cookie"})
|
|
w := httptest.NewRecorder()
|
|
handler.ServeHTTP(w, r)
|
|
if w.Code != http.StatusBadRequest || changer.command.AccountID != "" {
|
|
t.Fatalf("status=%d command=%+v", w.Code, changer.command)
|
|
}
|
|
}
|