2021-08-05 10:14:46 +02:00
#!/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.
2023-10-25 15:46:46 +02:00
readonly LOWERLIMIT = "6 months" # all accounts below 6 months inactivity are safe, start notifiying them when >6 months
readonly UPPERLIMIT = "7 months" # inactive accounts older than 7 months will be deactivated
readonly DELDELIMIT = "1 year" # all accounts not used within a year will get deleted
readonly LIVE_PATH = " ${ MASTO_PATH } " # Path to live data from mastodon
readonly TOOTCTL = "bin/tootctl"
2021-08-05 10:14:46 +02:00
2023-10-25 15:46:46 +02:00
cd " ${ LIVE_PATH } " || exit
2021-08-05 10:14:46 +02:00
2023-10-25 15:46:46 +02:00
# shellcheck source=/dev/null
source " ${ LIVE_PATH } /.env.production "
2021-08-05 10:14:46 +02:00
2023-10-25 15:46:46 +02:00
run_tootctl( ) {
" ${ TOOTCTL } " " $@ "
}
2023-08-17 19:25:27 +00:00
2023-10-25 15:46:46 +02:00
set -f
# set the following variables accordingly to your site
# the admin will get a notification mail in BCC
2021-08-05 10:14:46 +02:00
# the following lines should be moved to a config file, eg. /usr/local/etc/cleanup_friendica.conf
#DB_HOST=127.0.0.1
#DB_PORT=6432
#DB_NAME=mastodon
#DB_USER=mastodon
#DB_PASS=
2023-08-17 19:25:27 +00:00
site = "Nerdculture.de"
2023-10-25 15:46:46 +02:00
#siteadmin="ij@bluespice.org"
2023-08-17 19:25:27 +00:00
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" )
2021-08-05 10:14:46 +02:00
case $1 in
"--dry-run" )
mode = "dryrun"
; ;
2023-08-17 19:25:27 +00:00
"--cron" )
mode = "cron"
; ;
2021-08-05 10:14:46 +02:00
"--dowhatimean" )
mode = "hotrun"
; ;
*)
echo "Usage: "
echo " --dry-run \t: make a dry-run, no deletion will be done, no mails are sent."
2023-08-17 19:25:27 +00:00
echo " --cron \t: delete deactivated users in a regularly cron run step by step to avoid mass flooding."
2021-08-05 10:14:46 +02:00
echo " --dowhatimean \t: add this option if you really want to delete users."
exit 0
; ;
esac
#. /usr/local/etc/cleanup_friendica.conf
2023-10-25 15:46:46 +02:00
# make a list to be used for grep -E
protected = $( echo " $protectedusers " | sed 's/\"//g' | sed 's/\ /\\\|/g' )
#echo $protected
2021-08-05 10:14:46 +02:00
# notify the user that s/he needs to re-login after 6 months to prevent account deletion
2023-10-25 15:46:46 +02:00
notifyUser( ) {
(
cat <<EOF
Dear ${ dispname } ,
2021-08-05 10:14:46 +02:00
2023-10-25 15:46:46 +02:00
you have registered your account on ${ LOCAL_DOMAIN } at ${ registered } and last time you logged in was at ${ lastlogin } .
2021-08-05 10:14:46 +02:00
2023-10-25 15:46:46 +02:00
If you want to continue to keep your Mastodon account on Nerdculture then please log in at least every 6 months via web browser to keep your account alive. Otherwise we assume that you don' t want to use it anymore and will deactivate your account 7 months after your last login ( and delete it later) .
2021-08-05 10:14:46 +02:00
2023-10-25 15:46:46 +02:00
You can access your profile at ${ profileurl } or you can cancel your account on your own when logged in at ${ LOCAL_DOMAIN } removeme - however we would like to see you become an active user again and contribute to the Fediverse, but of course it' s up to you.
2021-08-05 10:14:46 +02:00
Sincerely,
your ${ site } admins
2023-10-25 15:46:46 +02:00
2021-08-05 10:14:46 +02:00
EOF
2023-10-25 15:46:46 +02:00
) | sed 's/_/\ /g' | /usr/bin/mail -s " The Fediverse misses you, ${ username } ! " -r " ${ SMTP_FROM_ADDRESS } " -- " ${ usermail } "
# add '-b "$siteadmin"' before the "--" above to receive BCC mails
2023-08-17 19:25:27 +00:00
#((num_notified++))
}
# notify user that the account has been deleted because of inactivity
2023-10-25 15:46:46 +02:00
notifyUserDisable( ) {
(
cat <<EOF
Dear ${ dispname } ,
2023-08-17 19:25:27 +00:00
2023-10-25 15:46:46 +02:00
you have registered your account on ${ LOCAL_DOMAIN } at ${ registered } and last time you logged in was at ${ lastlogin } .
2023-08-17 19:25:27 +00:00
2023-10-25 15:46:46 +02:00
Since you haven't reacted to the previous mails and didn' t login again, your account including all your data has now been deactivated and will be deleted at a ( random) later time.
2023-08-17 19:25:27 +00:00
Sincerely,
your ${ site } admins
2023-10-25 15:46:46 +02:00
2023-08-17 19:25:27 +00:00
EOF
2023-10-25 15:46:46 +02:00
) | sed 's/_/\ /g' | /usr/bin/mail -s " Your account ${ username } on ${ site } has been deleted! " -r " ${ SMTP_FROM_ADDRESS } " -- " ${ usermail } "
# add '-b "$siteadmin"' before the "--" above to receive BCC mails
2021-08-05 10:14:46 +02:00
}
# notify user that the account has been deleted because of inactivity
2023-10-25 15:46:46 +02:00
notifyUserDeletion( ) {
(
cat <<EOF
Dear ${ dispname } ,
2021-08-05 10:14:46 +02:00
2023-10-25 15:46:46 +02:00
you have registered your account on ${ LOCAL_DOMAIN } at ${ registered } and last time you logged in was at ${ lastlogin } .
2021-08-05 10:14:46 +02:00
2023-10-25 15:46:46 +02:00
Since you haven't reacted to the previous mails and didn' t login again, your account including all your data has now been deleted.
2021-08-05 10:14:46 +02:00
Sincerely,
your ${ site } admins
2023-10-25 15:46:46 +02:00
2021-08-05 10:14:46 +02:00
EOF
2023-10-25 15:46:46 +02:00
) | sed 's/_/\ /g' | /usr/bin/mail -s " Your account ${ username } on ${ site } has been deleted! " -r " ${ SMTP_FROM_ADDRESS } " -- " ${ usermail } "
# add '-b "$siteadmin"' before the "--" above to receive BCC mails
2021-08-05 10:14:46 +02:00
}
2023-08-17 19:25:27 +00:00
# delete users that never logged in and never posted content
2023-10-25 15:46:46 +02:00
# filtering for "weeks" will result in accounts with 2 weeks old accounts,
2023-08-17 19:25:27 +00:00
# filter for just "week" will do the same after 1 week.
# same should apply to "month" and "months", but untested.
2023-10-25 15:46:46 +02:00
#for username in $( "${TOOTCTL}" user list active -c 10000 | grep 'never.*never' | grep weeks | awk '{print $2}') ; do
2023-08-17 19:25:27 +00:00
# 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'
case ${ mode } in
"cron" )
2023-10-25 15:46:46 +02:00
# get the total number of deactivated accounts
2023-08-17 19:25:27 +00:00
# the intention is that you can better judge how often you need to invoke the cron option
# or by increasing the limit_delete variable
# the backlog queue shouldn't pile up but also not run empty to fast to reduce the load
2023-10-25 15:46:46 +02:00
num_deactivated_overgrace = $( psql -U " ${ DB_USER } " -w -h " ${ DB_HOST } " -p " ${ DB_PORT } " -t " ${ DB_NAME } " -c " select count(username) from accounts a, users u where disabled is true and a.id=u.account_id and current_sign_in_at < now()-' ${ DELDELIMIT } '::interval and username not in ( $sqlprotectedusers ) " | tr -d " " )
num_deactivated_total = $( psql -U " ${ DB_USER } " -w -h " ${ DB_HOST } " -p " ${ DB_PORT } " -t " ${ DB_NAME } " -c " select count(username) from accounts a, users u where disabled is true and a.id=u.account_id and username not in ( $sqlprotectedusers ) " | tr -d " " )
2023-08-17 19:25:27 +00:00
# when there is less then 1 user to delete (=0) then exit
2023-10-25 15:46:46 +02:00
if [ " ${ num_deactivated_overgrace } " -lt 1 ] ; then
2023-08-17 19:25:27 +00:00
exit 0
2021-08-05 10:14:46 +02:00
fi
2023-08-17 19:25:27 +00:00
echo "==================================="
2023-08-20 17:11:49 +00:00
echo " Total deactivated accounts: ${ num_deactivated_total } "
echo " Number deactivated accounts over grace: ${ num_deactivated_overgrace } "
2023-08-17 19:25:27 +00:00
echo " Deleting this many accounts: ${ limit_delete } "
echo "==================================="
2023-10-25 15:46:46 +02:00
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()-' ${ DELDELIMIT } '::interval and username not in ( $sqlprotectedusers ) order by current_sign_in_at limit ${ limit_delete } " | tr -d " " ) ; do
2023-08-17 19:25:27 +00:00
#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
2023-10-25 15:46:46 +02:00
# and later change the text to a notification that the account has been deleted.
2023-08-17 19:25:27 +00:00
# if username is a protected user do nothing, else delete user
echo -n " ${ username } : "
2023-10-25 15:46:46 +02:00
run_tootctl accounts delete " ${ username } "
2023-08-17 19:25:27 +00:00
notifyUserDeletion
num_deleted = $(( num_deleted+1))
RND = $( date +%s)
sec = $(( $RND % 60 ))
ms = $(( $RND % 23 ))
2023-10-25 15:46:46 +02:00
sleep ${ sec } .${ ms }
2023-08-17 19:25:27 +00:00
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'" )
2023-10-25 15:46:46 +02:00
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
2023-08-17 19:25:27 +00:00
#echo ${line}
2023-10-25 15:46:46 +02:00
username = $( echo " ${ line } " | cut -f1 -d"," )
mail = $( echo " ${ line } " | cut -f2 -d"," )
2023-08-17 19:25:27 +00:00
# if username is a protected user do nothing, else delete user
if [ -n " ${ protectedusers } " ] ; then
pcheck = 0
2023-10-25 15:46:46 +02:00
for s in ${ protectedusers } ; do
2023-08-17 19:25:27 +00:00
if [ " ${ s } " = " ${ username } " ] ; then
pcheck = 1
fi
done
if [ ${ pcheck } -eq 0 ] ; then
echo " Delete unconfirmed user ${ username } "
if [ " ${ mode } " = "hotrun" ] ; then
2023-10-25 15:46:46 +02:00
run_tootctl accounts delete " ${ username } "
2023-08-17 19:25:27 +00:00
elif [ " ${ mode } " = "dryrun" ] ; then
echo " ${ username } : skipped because of dryrun. "
fi
2021-08-05 10:14:46 +02:00
fi
2023-08-17 19:25:27 +00:00
fi
done
2023-10-25 15:46:46 +02:00
#for u in $( ${LIVE_PATH}/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
2023-08-17 19:25:27 +00:00
for mode2 in $( echo "warn disable" ) ; do
#echo "mode2: $mode2"
case ${ mode2 } in
"warn" )
#echo "in warn"
2023-10-25 15:46:46 +02:00
SQLSTATE = " current_sign_in_at between now()-' ${ UPPERLIMIT } '::interval and now()-' ${ LOWERLIMIT } '::interval "
2023-08-17 19:25:27 +00:00
; ;
"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"
2023-10-25 15:46:46 +02:00
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
2023-08-17 19:25:27 +00:00
#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
2023-10-25 15:46:46 +02:00
# and later change the text to a notification that the account has been deleted.
2023-08-17 19:25:27 +00:00
# if username is a protected user do nothing, else delete user
echo -n " ${ username } : "
if [ " ${ mode } " = "hotrun" ] ; then
#echo -n "hotrun "
2023-10-25 15:46:46 +02:00
#run_tootctl accounts delete "${username}"
run_tootctl accounts modify " ${ username } " --disable
2023-08-17 19:25:27 +00:00
#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 "==================================="