| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556 |
- package service
- import (
- "context"
- "database/sql"
- "github.com/lib/pq"
- )
- // Preserve a private recovery snapshot before releasing canonical login bindings.
- // This reproduces UserRepository.deleteUser's binding cleanup while preserving all
- // source rows internally; regular users and admin result DTOs cannot read the archive.
- func cleanupArchiveIdentities(ctx context.Context, tx *sql.Tx, ids []int64, previewID string) error {
- for _, query := range []string{
- `SELECT id FROM auth_identities WHERE user_id=ANY($1) ORDER BY id FOR UPDATE`,
- `SELECT c.id FROM auth_identity_channels c JOIN auth_identities a ON a.id=c.identity_id WHERE a.user_id=ANY($1) ORDER BY c.id FOR UPDATE OF c`,
- `SELECT d.id FROM identity_adoption_decisions d JOIN auth_identities a ON a.id=d.identity_id WHERE a.user_id=ANY($1) ORDER BY d.id FOR UPDATE OF d`,
- } {
- rows, err := tx.QueryContext(ctx, query, pq.Array(ids))
- if err != nil {
- return err
- }
- for rows.Next() {
- var id int64
- if err := rows.Scan(&id); err != nil {
- _ = rows.Close()
- return err
- }
- }
- err = rows.Err()
- _ = rows.Close()
- if err != nil {
- return err
- }
- }
- _, err := tx.ExecContext(ctx, `
- INSERT INTO user_cleanup_identity_archives(preview_id,user_id,identities,channels,adoption_decisions)
- SELECT $2::uuid,u.id,
- COALESCE((SELECT jsonb_agg(to_jsonb(a) ORDER BY a.id) FROM auth_identities a WHERE a.user_id=u.id),'[]'::jsonb),
- COALESCE((SELECT jsonb_agg(to_jsonb(c) ORDER BY c.id) FROM auth_identity_channels c JOIN auth_identities a ON a.id=c.identity_id WHERE a.user_id=u.id),'[]'::jsonb),
- COALESCE((SELECT jsonb_agg(to_jsonb(d) ORDER BY d.id) FROM identity_adoption_decisions d JOIN auth_identities a ON a.id=d.identity_id WHERE a.user_id=u.id),'[]'::jsonb)
- FROM users u WHERE u.id=ANY($1)`, pq.Array(ids), previewID)
- if err != nil {
- return err
- }
- for _, query := range []string{
- `UPDATE identity_adoption_decisions SET identity_id=NULL WHERE identity_id IN (SELECT id FROM auth_identities WHERE user_id=ANY($1))`,
- `DELETE FROM auth_identity_channels WHERE identity_id IN (SELECT id FROM auth_identities WHERE user_id=ANY($1))`,
- `DELETE FROM auth_identities WHERE user_id=ANY($1)`,
- } {
- if _, err := tx.ExecContext(ctx, query, pq.Array(ids)); err != nil {
- return err
- }
- }
- return nil
- }
|