#!/bin/sh # LOWERLIMIT="'6 months'" or "'24 weeks'" # UPPERLIMIT="'7 months'" or "'28 weeks'" # this defines the range of inactivity where users get notified # before the account will be deleted when UPPERLIMIT is surpassed. LOWERLIMIT="6 months" UPPERLIMIT="7 months" TOOTCTL="~/live/bin/tootctl" set -f # set the following variables accordingly to your site # the admin will get a notification mail in BCC grep -e ^"DB_" -e ^"LOCAL_DOMAIN" /home/mastodon/live/.env.production > /home/mastodon/bin/cleanup-mastodon-users.conf . /home/mastodon/bin/cleanup-mastodon-users.conf # the following lines should be moved to a config file, eg. /usr/local/etc/cleanup_friendica.conf mastodonpath="/home/mastodon/live" #DB_HOST=127.0.0.1 #DB_PORT=6432 #DB_NAME=mastodon #DB_USER=mastodon #DB_PASS= site="Nerdculture.de" siteurl="https://nerdculture.de/" siteadmin="ij@bluespice.org" sitefrom="no-reply@nerdculture.de" protectedusers="ij kirschwipfel xmppcompliance order kirschwipfeltest" sqlprotectedusers="'ij', 'kirschwipfel', 'xmppcompliance', 'order', 'kirschwipfeltest'" limit_delete=2 num_notified=0 num_disabled=0 num_deleted=0 STARTDATE=$(date +"%d.%m.%Y %H:%M:%S") case $1 in "--dry-run") mode="dryrun" ;; "--cron") mode="cron" ;; "--dowhatimean") mode="hotrun" ;; *) echo "Usage: " echo " --dry-run \t: make a dry-run, no deletion will be done, no mails are sent." echo " --cron \t: delete deactivated users in a regularly cron run step by step to avoid mass flooding." echo " --dowhatimean \t: add this option if you really want to delete users." exit 0 ;; esac #. /usr/local/etc/cleanup_friendica.conf # make a list to be used for grep -E protected=$(echo $protectedusers | sed 's/\"//g' | sed 's/\ /\\\|/g') #echo $protected cd ${mastodonpath} || exit 0 # notify the user that s/he needs to re-login after 6 months to prevent account deletion notifyUser () { ( cat < now()-'${UPPERLIMIT}'::interval and username not in ($sqlprotectedusers) limit ${limit_delete}" | tr -d " " ) # when there is less then 1 user to delete (=0) then exit if [ ${num_deactivated_total} -lt 1 ]; then exit 0 fi echo "===================================" echo "Number deactivated accounts: ${num_deactivated_total}" echo "Deleting this many accounts: ${limit_delete}" echo "===================================" for u in $(psql -U ${DB_USER} -w -h ${DB_HOST} -p ${DB_PORT} -t ${DB_NAME} -c "select concat(username||';'||display_name||';'||email||';'||to_char(a.created_at, 'YYYY-MM-DD')||';'||to_char(current_sign_in_at,'YYYY-MM-DD')) from accounts a, users u where disabled is true and a.id=u.account_id and current_sign_in_at > now()-'${UPPERLIMIT}'::interval and username not in ($sqlprotectedusers) order by current_sign_in_at limit ${limit_delete}" | tr -d " " ); do #echo ${u} username=$(echo "${u}" | awk -F ";" '{print $1}') dispname=$(echo "${u}" | awk -F ";" '{print $2}') profileurl="https://nerdculture.de/@${username}" usermail=$(echo "${u}" | awk -F ";" '{print $3}') registered=$(echo "${u}" | awk -F ";" '{print $4}') lastlogin=$(echo "${u}" | awk -F ";" '{print $5}') # delete account when last login is older than 7 months and send mail about deletion # you should copy & paste the text from 6 months for the first runs of this script # and later change the text to a notification that the account has been deleted. # if username is a protected user do nothing, else delete user echo -n "${username} : " ${mastodonpath}/bin/tootctl accounts delete "${username}" notifyUserDeletion num_deleted=$((num_deleted+1)) RND=$(date +%s) sec=$(( $RND %60 )) ms=$(( $RND %23 )) sleep ${sec}.${ms} done ;; *) # find & notify users that didn't logged in >6 months and send mail to log in again#psql -U ${DB_USER} -w -h ${DB_HOST} -p ${DB_PORT} -t ${DB_NAME} -c "select concat(username||';'||email) from accounts a, users u where domain is null and a.id=u.account_id and current_sign_in_at is null and u.created_at < now()-'2 weeks'::interval" | tr -d " " #for username in $(psql -U ${DB_USER} -w -h ${DB_HOST} -p ${DB_PORT} -t ${DB_NAME} -c "select a.id, username, email, current_sign_in_at from accounts a, users u where domain is null and a.id=u.account_id and current_sign_in_at <'2019-01-01'" ) for line in $(psql -U ${DB_USER} -w -h ${DB_HOST} -p ${DB_PORT} -t ${DB_NAME} -c "select concat(username||','||email) from accounts a, users u where domain is null and a.id=u.account_id and current_sign_in_at is null and u.created_at < now()-'2 weeks'::interval and username not in (${sqlprotectedusers})"| tr -d " "); do #echo ${line} username=$(echo ${line} | cut -f1 -d"," ) mail=$(echo ${line} | cut -f2 -d"," ) # if username is a protected user do nothing, else delete user if [ -n "${protectedusers}" ]; then pcheck=0 for s in $(echo ${protectedusers}) ; do if [ "${s}" = "${username}" ]; then pcheck=1 fi done if [ ${pcheck} -eq 0 ]; then echo "Delete unconfirmed user ${username}" if [ "${mode}" = "hotrun" ]; then ${mastodonpath}/bin/tootctl accounts delete "${username}" elif [ "${mode}" = "dryrun" ]; then echo "${username}: skipped because of dryrun." fi fi fi done #for u in $( ${mastodonpath}/bin/console user list active -c 10000 | grep -v '.*---.*' | sed 's/|/;/g' | tr -s "\ " | sed 's/^;\ //g' | sed 's/\ ;\ /;/g' | sed 's/\ /_/g' | tail -n +2 | grep -i -v -E ${protected} ); do for mode2 in $(echo "warn disable"); do #echo "mode2: $mode2" case ${mode2} in "warn") #echo "in warn" SQLSTATE="current_sign_in_at between now()-'${UPPERLIMIT}'::interval and now()-'${LOWERLIMIT}'::interval" ;; "disable") #echo "in disable" SQLSTATE="current_sign_in_at < now()-'${UPPERLIMIT}'::interval" ;; #"delete") # #echo "in delete" # SQLSTATE="current_sign_in_at < now()-'${UPPERLIMIT}'::interval" # ;; esac #echo "SQL: $SQLSTATE" for u in $( psql -U ${DB_USER} -w -h ${DB_HOST} -p ${DB_PORT} -t ${DB_NAME} -c "select concat(username||';'||display_name||';'||email||';'||to_char(a.created_at, 'YYYY-MM-DD')||';'||to_char(current_sign_in_at,'YYYY-MM-DD')) from accounts a, users u where domain is null and a.id=u.account_id and ${SQLSTATE} and username not in ($sqlprotectedusers) order by current_sign_in_at" | tr -d " " ); do #echo ${u} username=$(echo "${u}" | awk -F ";" '{print $1}') dispname=$(echo "${u}" | awk -F ";" '{print $2}') profileurl="https://nerdculture.de/@${username}" usermail=$(echo "${u}" | awk -F ";" '{print $3}') registered=$(echo "${u}" | awk -F ";" '{print $4}') lastlogin=$(echo "${u}" | awk -F ";" '{print $5}') case ${mode2} in "warn") if [ "${mode}" = "hotrun" ]; then #echo -n "hotrun " notifyUser elif [ "${mode}" = "dryrun" ]; then echo "Check ${username}: notify skipped because of dryrun." fi num_notified=$((num_notified+1)) ;; "disable") # delete account when last login is older than 7 months and send mail about deletion # you should copy & paste the text from 6 months for the first runs of this script # and later change the text to a notification that the account has been deleted. # if username is a protected user do nothing, else delete user echo -n "${username} : " if [ "${mode}" = "hotrun" ]; then #echo -n "hotrun " #${mastodonpath}/bin/tootctl accounts delete "${username}" ${mastodonpath}/bin/tootctl accounts modify "${username}" --disable #notifyUserDeletion notifyUserDisable #echo "deleted." elif [ "${mode}" = "dryrun" ]; then echo "will be disabled, but is skipped because of dryrun." fi num_disabled=$((num_disabled+1)) ;; esac RND=$(date +%s) sec=$(( $RND %5 )) ms=$(( $RND %23 )) sleep ${sec}.${ms} done done ;; esac ENDDATE=$(date +"%d.%m.%Y %H:%M:%S") echo "===================================" echo "Starting time : ${STARTDATE}" echo "Ending time : ${ENDDATE}" echo "Notified Users: $num_notified" echo "Disabled Users: $num_disabled" echo "Deleted Users : $num_deleted" echo "==================================="