hmn/src/migration/migrations/2021-08-08T134655Z_DeleteIn...

120 lines
3.3 KiB
Go

package migrations
import (
"context"
"fmt"
"time"
"git.handmade.network/hmn/hmn/src/migration/types"
"git.handmade.network/hmn/hmn/src/oops"
"github.com/jackc/pgx/v5"
)
func init() {
registerMigration(DeleteInactiveUsers{})
}
type DeleteInactiveUsers struct{}
func (m DeleteInactiveUsers) Version() types.MigrationVersion {
return types.MigrationVersion(time.Date(2021, 8, 8, 13, 46, 55, 0, time.UTC))
}
func (m DeleteInactiveUsers) Name() string {
return "DeleteInactiveUsers"
}
func (m DeleteInactiveUsers) Description() string {
return "Delete inactive users and expired onetimetokens"
}
func (m DeleteInactiveUsers) Up(ctx context.Context, tx pgx.Tx) error {
var err error
res, err := tx.Exec(ctx,
`
DELETE FROM handmade_passwordresetrequest
USING handmade_onetimetoken
WHERE handmade_onetimetoken.expires < $1 AND handmade_passwordresetrequest.confirmation_token_id = handmade_onetimetoken.id;
`,
time.Now(),
)
if err != nil {
return oops.New(err, "failed to delete password reset requests")
}
fmt.Printf("Deleted %v expired password reset requests.\n", res.RowsAffected())
fmt.Printf("Deleting inactive users. This might take a minute.\n")
res, err = tx.Exec(ctx,
`
DELETE FROM auth_user
WHERE status = 1 AND date_joined < $1;
`,
time.Now().Add(-(time.Hour * 24 * 7)),
)
if err != nil {
return oops.New(err, "failed to delete inactive users")
}
fmt.Printf("Deleted %v inactive users.\n", res.RowsAffected())
_, err = tx.Exec(ctx, `
ALTER TABLE handmade_onetimetoken
DROP used;
ALTER TABLE handmade_onetimetoken
ADD owner_id INT REFERENCES auth_user(id) ON DELETE CASCADE;
ALTER TABLE handmade_userpending
DROP CONSTRAINT handma_activation_token_id_0b4a4b06_fk_handmade_onetimetoken_id;
`)
_, err = tx.Exec(ctx, `
UPDATE handmade_userpending
SET activation_token_id = NULL
WHERE (SELECT count(*) AS ct FROM handmade_onetimetoken WHERE id = activation_token_id) = 0;
`)
res, err = tx.Exec(ctx,
`
DELETE FROM handmade_onetimetoken
WHERE expires < $1
`,
time.Now(),
)
if err != nil {
return oops.New(err, "failed to delete expired tokens")
}
fmt.Printf("Deleted %v expired tokens.\n", res.RowsAffected())
fmt.Printf("Setting owner_id on onetimetoken\n")
_, err = tx.Exec(ctx, `
UPDATE handmade_onetimetoken
SET owner_id = (SELECT id FROM auth_user WHERE username = (SELECT username FROM handmade_userpending WHERE activation_token_id = handmade_onetimetoken.id LIMIT 1))
WHERE token_type = 1;
`)
if err != nil {
return oops.New(err, "failed to set owner_id on onetimetoken")
}
_, err = tx.Exec(ctx, `
UPDATE handmade_onetimetoken
SET owner_id = (SELECT user_id FROM handmade_passwordresetrequest WHERE confirmation_token_id = handmade_onetimetoken.id)
WHERE token_type = 2;
`)
if err != nil {
return oops.New(err, "failed to set owner_id on onetimetoken")
}
fmt.Printf("Setting registration_ip on auth_user\n")
_, err = tx.Exec(ctx, `
UPDATE auth_user
SET registration_ip = (SELECT ip FROM handmade_userpending WHERE handmade_userpending.username = auth_user.username LIMIT 1);
`)
if err != nil {
return oops.New(err, "failed to set owner_id on onetimetoken")
}
return nil
}
func (m DeleteInactiveUsers) Down(ctx context.Context, tx pgx.Tx) error {
panic("Implement me")
}