add username cleanup

This commit is contained in:
sam 2023-09-10 17:44:35 +02:00
parent 153812d79f
commit 2da388df2e
No known key found for this signature in database
GPG key ID: B4EF20DDE721CAA1
2 changed files with 61 additions and 1 deletions

View file

@ -825,3 +825,24 @@ func (db *DB) CleanUser(ctx context.Context, id xid.ID) error {
} }
return nil return nil
} }
const inactiveUsersSQL = `select id, snowflake_id from users
where last_active < now() - '30 days'::interval
and display_name is null and bio is null and timezone is null
and links is null and avatar is null and member_title is null
and names = '[]' and pronouns = '[]'
and (select count(m.id) from members m where user_id = users.id) = 0
and (select count(f.id) from user_fields f where user_id = users.id) = 0;`
// InactiveUsers gets the list of inactive users from the database.
// "Inactive" is defined as:
// - not logged in for 30 days or more
// - no display name, bio, avatar, names, pronouns, profile links, or profile fields
// - no members
func (db *DB) InactiveUsers(ctx context.Context, tx pgx.Tx) (us []User, err error) {
err = pgxscan.Select(ctx, tx, &us, inactiveUsersSQL)
if err != nil {
return nil, errors.Wrap(err, "executing query")
}
return us, nil
}

View file

@ -3,6 +3,7 @@ package cleandb
import ( import (
"context" "context"
"fmt" "fmt"
"os"
"time" "time"
dbpkg "codeberg.org/pronounscc/pronouns.cc/backend/db" dbpkg "codeberg.org/pronounscc/pronouns.cc/backend/db"
@ -25,6 +26,8 @@ func run(c *cli.Context) error {
return err return err
} }
changeUnusedUsernames := os.Getenv("DB_CLEAN_CHANGE_UNUSED_USERNAMES") == "true"
ctx := context.Background() ctx := context.Background()
db, err := dbpkg.New() db, err := dbpkg.New()
@ -66,6 +69,41 @@ func run(c *cli.Context) error {
fmt.Printf("deleted %v expired exports\n", len(exports)) fmt.Printf("deleted %v expired exports\n", len(exports))
if changeUnusedUsernames {
fmt.Println("cleaning unused usernames")
tx, err := db.Begin(ctx)
if err != nil {
fmt.Printf("error starting transaction: %v\n", err)
return err
}
defer tx.Rollback(ctx)
inactiveUsers, err := db.InactiveUsers(ctx, tx)
if err != nil {
fmt.Printf("getting inactive users: %v\n", err)
return err
}
for _, u := range inactiveUsers {
err = db.UpdateUsername(ctx, tx, u.ID, fmt.Sprintf("inactive-user-%v", u.SnowflakeID))
if err != nil {
fmt.Printf("changing username for user %v: %v\n", u.SnowflakeID, err)
return err
}
}
err = tx.Commit(ctx)
if err != nil {
fmt.Printf("committing transaction: %v\n", err)
return err
}
fmt.Printf("changed usernames for %v inactive users\n", len(inactiveUsers))
} else {
fmt.Println("not cleaning unused usernames")
}
var users []dbpkg.User var users []dbpkg.User
err = pgxscan.Select(ctx, db, &users, `SELECT * FROM users WHERE err = pgxscan.Select(ctx, db, &users, `SELECT * FROM users WHERE
deleted_at IS NOT NULL AND deleted_at IS NOT NULL AND
@ -78,7 +116,7 @@ func run(c *cli.Context) error {
} }
if len(users) == 0 { if len(users) == 0 {
fmt.Println("there are no users pending deletion") fmt.Println("there are no users pending deletion\nfinished cleaning database!")
return nil return nil
} }
@ -132,5 +170,6 @@ func run(c *cli.Context) error {
} }
fmt.Printf("deleted %v users!\n", ct.RowsAffected()) fmt.Printf("deleted %v users!\n", ct.RowsAffected())
fmt.Println("finished cleaning database!")
return nil return nil
} }