package integration import ( "context" "errors" "testing" "time" "git.sundynix.cn/Blizzard/Veyra/internal/apperror" "git.sundynix.cn/Blizzard/Veyra/internal/model" "git.sundynix.cn/Blizzard/Veyra/internal/repository" "git.sundynix.cn/Blizzard/Veyra/internal/service" "github.com/google/uuid" "github.com/jackc/pgx/v5/pgxpool" ) func testAdminCredentialChange(t *testing.T, ctx context.Context, pool *pgxpool.Pool, auth *service.AuthService) { t.Helper() repo := repository.NewIdentityRepository(pool) previous, credential, err := repo.FindCredential(ctx, "admin") if err != nil { t.Fatal(err) } oldSession, err := auth.Login(ctx, "admin", "an-admin-test-password", "admin") if err != nil { t.Fatal(err) } password := "test1234" updater := service.NewAdminCredentialService(repo, true) if _, err := service.NewAdminCredentialService(repo, false).Set(ctx, "admin", "operator", password); !errors.Is(err, apperror.ErrForbidden) { t.Fatal("production credential setup allowed") } if _, err := updater.Set(ctx, "alice", "operator", password); !errors.Is(err, apperror.ErrForbidden) { t.Fatal("ordinary user promoted by credential command") } if _, err := updater.Set(ctx, "admin", "bob", password); !errors.Is(err, apperror.ErrConflict) { t.Fatal("duplicate login accepted") } if _, err := auth.Authenticate(ctx, oldSession.Token, "admin"); err != nil { t.Fatal("failed update revoked existing session") } userID, err := updater.Set(ctx, "admin", "operator", password) if err != nil || userID != previous.ID { t.Fatal("administrator identity was not preserved") } if _, err := auth.Authenticate(ctx, oldSession.Token, "admin"); !errors.Is(err, apperror.ErrUnauthenticated) { t.Fatal("old session survived password change") } if _, err := auth.Login(ctx, "admin", "an-admin-test-password", "admin"); !errors.Is(err, apperror.ErrUnauthenticated) { t.Fatal("old login survived update") } login, err := auth.Login(ctx, "operator", password, "admin") if err != nil || login.User.ID != previous.ID { t.Fatal("new credentials failed") } _, updated, err := repo.FindCredential(ctx, "operator") if err != nil || updated.PasswordHash == password || updated.PasswordHash == credential.PasswordHash { t.Fatal("new password was not hashed") } stale := model.Session{ID: uuid.NewString(), UserID: previous.ID, TokenHash: service.TokenHash(uuid.NewString()), Audience: "admin", ExpiresAt: time.Now().Add(time.Hour)} if err := repo.CreateSession(ctx, stale, credential.PasswordHash); !errors.Is(err, apperror.ErrUnauthenticated) { t.Fatal("stale password verification created a new session") } }