@@ -21,7 +21,7 @@ func newTestAuth(t *testing.T) *AuthService {
|
||||
if err != nil {
|
||||
t.Fatalf("open in-memory sqlite: %v", err)
|
||||
}
|
||||
if err := db.AutoMigrate(&model.User{}); err != nil {
|
||||
if err := db.AutoMigrate(&model.User{}, &model.UserSession{}); err != nil {
|
||||
t.Fatalf("auto migrate: %v", err)
|
||||
}
|
||||
return NewAuthService(db, "test-jwt-secret")
|
||||
@@ -32,7 +32,7 @@ func TestEnsureAdminCreatesUser(t *testing.T) {
|
||||
if err := auth.EnsureAdmin("admin", "pass123"); err != nil {
|
||||
t.Fatalf("EnsureAdmin: %v", err)
|
||||
}
|
||||
if _, _, err := auth.Login(context.Background(), "admin", "pass123", "127.0.0.1", ""); err != nil {
|
||||
if _, _, err := auth.Login(context.Background(), "admin", "pass123", "", SessionMeta{ClientIP: "127.0.0.1"}); err != nil {
|
||||
t.Errorf("Login after EnsureAdmin: %v", err)
|
||||
}
|
||||
}
|
||||
@@ -45,10 +45,10 @@ func TestEnsureAdminDoesNotResetPassword(t *testing.T) {
|
||||
if err := auth.EnsureAdmin("admin", "second"); err != nil {
|
||||
t.Fatalf("EnsureAdmin twice: %v", err)
|
||||
}
|
||||
if _, _, err := auth.Login(context.Background(), "admin", "first", "127.0.0.1", ""); err != nil {
|
||||
if _, _, err := auth.Login(context.Background(), "admin", "first", "", SessionMeta{ClientIP: "127.0.0.1"}); err != nil {
|
||||
t.Errorf("Login with original password: %v", err)
|
||||
}
|
||||
if _, _, err := auth.Login(context.Background(), "admin", "second", "127.0.0.1", ""); !errors.Is(err, ErrInvalidCredentials) {
|
||||
if _, _, err := auth.Login(context.Background(), "admin", "second", "", SessionMeta{ClientIP: "127.0.0.1"}); !errors.Is(err, ErrInvalidCredentials) {
|
||||
t.Errorf("Login with new password: got %v, want ErrInvalidCredentials", err)
|
||||
}
|
||||
}
|
||||
@@ -89,7 +89,7 @@ func TestLoginFailures(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
_, _, err := auth.Login(context.Background(), tt.username, tt.password, "127.0.0.1", "")
|
||||
_, _, err := auth.Login(context.Background(), tt.username, tt.password, "", SessionMeta{ClientIP: "127.0.0.1"})
|
||||
if !errors.Is(err, ErrInvalidCredentials) {
|
||||
t.Errorf("Login(%q, %q) error = %v, want ErrInvalidCredentials", tt.username, tt.password, err)
|
||||
}
|
||||
@@ -102,7 +102,7 @@ func TestTokenRoundTrip(t *testing.T) {
|
||||
if err := auth.EnsureAdmin("admin", "pass123"); err != nil {
|
||||
t.Fatalf("EnsureAdmin: %v", err)
|
||||
}
|
||||
token, expires, err := auth.Login(context.Background(), "admin", "pass123", "127.0.0.1", "")
|
||||
token, expires, err := auth.Login(context.Background(), "admin", "pass123", "", SessionMeta{ClientIP: "127.0.0.1"})
|
||||
if err != nil {
|
||||
t.Fatalf("Login: %v", err)
|
||||
}
|
||||
@@ -125,7 +125,7 @@ func TestParseTokenRejectsForged(t *testing.T) {
|
||||
if err := other.EnsureAdmin("admin", "pass"); err != nil {
|
||||
t.Fatalf("EnsureAdmin: %v", err)
|
||||
}
|
||||
forged, _, err := other.Login(context.Background(), "admin", "pass", "127.0.0.1", "")
|
||||
forged, _, err := other.Login(context.Background(), "admin", "pass", "", SessionMeta{ClientIP: "127.0.0.1"})
|
||||
if err != nil {
|
||||
t.Fatalf("Login: %v", err)
|
||||
}
|
||||
@@ -143,21 +143,21 @@ func TestLogoutRevokesToken(t *testing.T) {
|
||||
if err := auth.EnsureAdmin("admin", "pass123"); err != nil {
|
||||
t.Fatalf("EnsureAdmin: %v", err)
|
||||
}
|
||||
token, _, err := auth.signToken("admin", 0)
|
||||
token, _, _, err := auth.signToken("admin", 0)
|
||||
if err != nil {
|
||||
t.Fatalf("signToken: %v", err)
|
||||
}
|
||||
if _, err := auth.ParseToken(context.Background(), token); err != nil {
|
||||
t.Fatalf("ParseToken before logout: %v", err)
|
||||
}
|
||||
auth.Logout(token)
|
||||
auth.Logout(context.Background(), token)
|
||||
if _, err := auth.ParseToken(context.Background(), token); err == nil {
|
||||
t.Error("ParseToken after logout: got nil error, want revoked")
|
||||
}
|
||||
// 幂等:重复登出与无效令牌登出都不应 panic,也不影响其他令牌
|
||||
auth.Logout(token)
|
||||
auth.Logout("not.a.token")
|
||||
fresh, _, err := auth.signToken("admin", 0)
|
||||
auth.Logout(context.Background(), token)
|
||||
auth.Logout(context.Background(), "not.a.token")
|
||||
fresh, _, _, err := auth.signToken("admin", 0)
|
||||
if err != nil {
|
||||
t.Fatalf("signToken fresh: %v", err)
|
||||
}
|
||||
@@ -174,13 +174,13 @@ func TestTokenVersionInvalidatesOldToken(t *testing.T) {
|
||||
t.Fatalf("EnsureAdmin: %v", err)
|
||||
}
|
||||
ctx := context.Background()
|
||||
old, _, err := auth.Login(ctx, "admin", "pass123", "127.0.0.1", "")
|
||||
old, _, err := auth.Login(ctx, "admin", "pass123", "", SessionMeta{ClientIP: "127.0.0.1"})
|
||||
if err != nil {
|
||||
t.Fatalf("Login: %v", err)
|
||||
}
|
||||
finalName, err := auth.UpdateCredentials(ctx, "admin", UpdateCredentialsInput{
|
||||
NewPassword: "changed-456", CurrentPassword: "pass123",
|
||||
})
|
||||
}, proofOf(t, auth.db, "admin"))
|
||||
if err != nil {
|
||||
t.Fatalf("UpdateCredentials: %v", err)
|
||||
}
|
||||
@@ -203,11 +203,11 @@ func TestRevokeSessions(t *testing.T) {
|
||||
t.Fatalf("EnsureAdmin: %v", err)
|
||||
}
|
||||
ctx := context.Background()
|
||||
old, _, err := auth.Login(ctx, "admin", "pass123", "127.0.0.1", "")
|
||||
old, _, err := auth.Login(ctx, "admin", "pass123", "", SessionMeta{ClientIP: "127.0.0.1"})
|
||||
if err != nil {
|
||||
t.Fatalf("Login: %v", err)
|
||||
}
|
||||
fresh, _, err := auth.RevokeSessions(ctx, "admin")
|
||||
fresh, _, err := auth.RevokeSessions(ctx, "admin", "", SessionMeta{}, proofOf(t, auth.db, "admin"))
|
||||
if err != nil {
|
||||
t.Fatalf("RevokeSessions: %v", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user