From b92a02a770c7463b1b13551d0c587f8525bd1edf Mon Sep 17 00:00:00 2001 From: Dobromir Popov Date: Fri, 13 Feb 2026 11:26:47 +0200 Subject: [PATCH] fix gitea db --- gitea/delete-users-by-creation-date.sh | 54 +++++++++++++++++++++++++ gitea/fix-postgres-collation-version.sh | 48 ++++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 gitea/delete-users-by-creation-date.sh create mode 100644 gitea/fix-postgres-collation-version.sh diff --git a/gitea/delete-users-by-creation-date.sh b/gitea/delete-users-by-creation-date.sh new file mode 100644 index 0000000..7598335 --- /dev/null +++ b/gitea/delete-users-by-creation-date.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash +# Mark Gitea users for deletion by creation date (e.g. after a hack/spam wave). +# Users created ON or AFTER the cutoff date will be marked inactive; then run +# Gitea admin task "Delete all unactivated accounts" to remove them. +# +# Usage: +# ./delete-users-by-creation-date.sh 2025-02-01 +# ./delete-users-by-creation-date.sh "2025-02-10 14:00" +# ./delete-users-by-creation-date.sh 2025-02-01 --whitelist "admin,myuser" +# +# Steps after running this script: +# 1. Backup your Gitea database. +# 2. Run the generated SQL against your DB (PostgreSQL or SQLite). +# 3. In Gitea: Site Administration -> Maintenance -> "Delete all unactivated accounts". +# 4. Consider DISABLE_REGISTRATION = true in app.ini if registration was abused. + +set -e +CUTOFF_DATE="${1:?Usage: $0 YYYY-MM-DD [--whitelist user1,user2]}" +WHITELIST="" +if [[ "$2" == "--whitelist" && -n "$3" ]]; then + WHITELIST="$3" +fi + +# Convert cutoff to Unix timestamp (GNU date on Linux) +CUTOFF_UNIX=$(date -d "$CUTOFF_DATE" +%s 2>/dev/null) || true +if [[ -z "$CUTOFF_UNIX" ]]; then + echo "Invalid date: $CUTOFF_DATE (use YYYY-MM-DD or \"YYYY-MM-DD HH:MM\")" + echo "Run this script on the Gitea server (Linux) or pass the Unix timestamp manually." + exit 1 +fi + +echo "# Cutoff: $CUTOFF_DATE -> Unix $CUTOFF_UNIX (users created on or after this will be marked inactive)" +echo "# Backup your database before running any of the below." +echo "" + +if [[ -n "$WHITELIST" ]]; then + # Build NOT IN list for SQL + WL=$(echo "$WHITELIST" | sed "s/,/','/g" | sed "s/^/'/; s/$/'/") + WHERE_EXTRA=" AND name NOT IN ($WL)" + WHERE_EXTRA_PG=" AND name NOT IN ($WL)" +else + WHERE_EXTRA="" + WHERE_EXTRA_PG="" +fi + +echo "# --- PostgreSQL (table: public.user) ---" +echo "UPDATE public.user SET is_active = false WHERE created_unix >= $CUTOFF_UNIX${WHERE_EXTRA_PG};" +echo "" + +echo "# --- SQLite / MySQL (table: user) ---" +echo "UPDATE user SET is_active = 0 WHERE created_unix >= $CUTOFF_UNIX${WHERE_EXTRA};" +echo "" + +echo "# Then in Gitea: Site Administration -> Maintenance -> 'Delete all unactivated accounts'" diff --git a/gitea/fix-postgres-collation-version.sh b/gitea/fix-postgres-collation-version.sh new file mode 100644 index 0000000..2f5b4b4 --- /dev/null +++ b/gitea/fix-postgres-collation-version.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +# Fix PostgreSQL "collation version mismatch" (e.g. DB created with 2.36, OS provides 2.41). +# Reindexes then refreshes collation version. REINDEX will be canceled if Gitea (or other +# clients) keep using the DB, so either stop Gitea first or use --terminate-connections. +# +# Usage (from host): +# ./fix-postgres-collation-version.sh +# ./fix-postgres-collation-version.sh gitea +# ./fix-postgres-collation-version.sh gitea --terminate-connections +# +# Option: --terminate-connections Terminate all other sessions on the DB so REINDEX can +# run without being canceled. Gitea will disconnect; restart it after. + + +# REINDEX DATABASE gitea; +# ALTER DATABASE gitea REFRESH COLLATION VERSION; + + +set -e +CONTAINER="${1:?Usage: $0 [database_name] [--terminate-connections]}" +DB="${2:-gitea}" +TERMINATE="" +if [[ "$2" == "--terminate-connections" ]]; then + TERMINATE=1 + DB="gitea" +elif [[ "$3" == "--terminate-connections" ]]; then + TERMINATE=1 +fi + +if [[ -z "$TERMINATE" ]]; then + echo "Stop the Gitea container (and any other app using database $DB) before continuing," + echo "otherwise REINDEX may be canceled. Press Enter when ready, or Ctrl+C to abort." + read -r +fi + +if [[ -n "$TERMINATE" ]]; then + echo "Terminating other connections to $DB..." + docker exec "$CONTAINER" psql -U postgres -d "$DB" -c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = '$DB' AND pid <> pg_backend_pid();" || true + sleep 2 +fi + +echo "Reindexing database $DB (may take a while)..." +docker exec "$CONTAINER" psql -U postgres -d "$DB" -c "REINDEX DATABASE $DB;" + +echo "Refreshing collation version..." +docker exec "$CONTAINER" psql -U postgres -d "$DB" -c "ALTER DATABASE $DB REFRESH COLLATION VERSION;" + +echo "Done. Start Gitea again if you stopped it or used --terminate-connections."