User account creation date

Hello there,

I’m trying to set a kind of expiration date on user accounts (I want to auto-remove users account created more than 1 month ago for example)

Many subjects but not really answers, such as Is it possible to set expiration date/time on user accounts? - #6 by JimmyKater

So I want to work on something new, but it seems, there is no way to get the user account creation date (not stored in database today). is it stored somewhere and i missed it?

Otherwise I was thinking of adding a column in the associated mysql table using migrations so that it resists updates. Is this a possible idea?

Thanks for your help,

Kindly,
Florian

Hey there…

in the meanwhile there should be an app available where you can purge user-accounts. I never used it. but it looks like it already exists, maybe you wanna check it out yourself?

I noticed that this app’s purge functionality is based on the most recent login.

However, in my specific use case, users log in daily. I would like to implement an account disabling feature based on the account creation date instead.

But this date seems not stored anywhere

I see the difference now. And I’m afraid I can’t help you here.
But maybe you can go another way.
Like on account creation give them a somehow hidden file and don’t let them execute nor touch nor delete it. So you would have a date on which the account was created, which is stored in the metadata of that special file. you can read that out once/day and then decide what to do with that info.
Of course that’s only possible for newly created accounts. With old accounts you need to check if they still have one of the “default”-files that were created within skeleton–directory. Or maybe the setup–date of one of the originally created directories would still show the date of first login (this is when everything gets created)

What I’m using for this task is an external script and a csv file, which stores every single user creation, with user metadata and expiration date. All my users are created from csv files using bash scripting and occ cli so it’s easy to keep a log file with that data.
Then a daily cronjob checks the csv user creation log, looking for expiring dates and blocking user in case. Also adds a recordo to the same csv file to confirm when cancellation has been run and sends an email)

csv file looks like this:

timestamp;username;email;name;group;quota;lang;expiration_date;disabled_on
2024-04-26 10:18:34;accountA@domain.es;accountA@domain.es;Username A;Internal team;2GB;es;
2024-04-30 11:20:33;account2expire@domain.es;account2expire@domain.es;Account to expire;Temporary accounts;2GB;es;2024-04-30;2024-04-30 10:00:03
2024-05-02 09:31:07;accountB@domain.es;accountB@domain.es;Username B;Internal team; 2GB;es;;
2024-05-30 11:20:33;account2expireB@domain.es;account2expireB@domain.es;Account to expire;Temporary accounts;2GB;es;2025-04-30;

accountA and accountB are active accounts withou expiration date
account2expire is already expired
account2expireB will expire on 2025-04-30

And command nextcloud_check_expired_accounts that runs on a daily basis…

#!/bin/bash
# comando para la expiraciĂłn de cuentas en nextcloud
# este comando se ejecutará en el servidor de nextcloud diariamente mediante un cron
# revisará el archivo csv indicado por parámetros y comprobará si hay cuentas que han expirado las cuales inhabilitará
# la primera lĂ­nea del archivo csv debe ser la cabecera con los nombres de las columnas
# las columnas deben ser: timestamp;username;email;name;group;quota;lang;expiration_date;disabled_on
# la columan username contiene el nombre de usuario
# la columna expiration_date contiene la fecha de expiraciĂłn de la cuenta y puede estar vacĂ­a, el formato de la fecha de expiraciĂłn debe ser: YYYY-MM-DD
# por cada registro en archivo csv que tenga la fecha de expiración anterior a la fecha actual se comprobará si la cuenta está activa y si lo está se deshabilitará
# y modificará la líena de la columna disabled_on del csv con el timestamp de la fecha de deshabilitación.

# v0.1 - 2024-04-26 first version
# v0.2 - 2024-04-27 added email notification

_usage="Usage: nextcloud_check_expired_accounts <csv_file> (--send_notification_to=email@domain.com)"

_csv_file="${1:?$_usage}"


# check if second parameter is --send_notification_to and configure email notification
if [ -z "$2" ]
then
    _email_notification=false
elif [ "$2" == "--email-notification" ]
then
    echo "Email notification is enabled but no email recipients specified"
    echo $_usage
    exit 1
elif [[ "$2" == --send_notification_to=* ]]
then
    _email_notification=true
    _email_recipients=$(echo $2 | cut -d'=' -f2)
else
    echo "Invalid second parameter"
    echo $_usage
    exit 1
fi

# check if csv file exists
if [ ! -f $_csv_file ]
then
  echo "File $_csv_file does not exist"
  echo $_usage
  exit 1
fi

# check if csv file is writable
if [ ! -w $_csv_file ]
then
  echo "File $_csv_file is not writable"
  echo $_usage
  exit 1
fi

# check if csv file has header
header=$(head -n 1 $_csv_file)
if [ "$header" != "timestamp;username;email;name;group;quota;lang;expiration_date;disabled_on" ]
then
  echo "File $_csv_file does not have header"
  echo $_usage
  exit 1
fi

# check if csv file has at least one record
records=$(tail -n +2 $_csv_file)
if [ -z "$records" ]
then
  echo "File $_csv_file does not have records"
  echo $_usage
  exit 1
fi

# read csv file and check if any account has expired (discard first line)
while IFS=';' read -r timestamp username email name group quota lang expiration_date disabled_on
do
    # if $timestamp is "timestamp" then skip line
    if [ "$timestamp" == "timestamp" ]
    then
        continue
    fi

    # check if expiration_date is empty
    if [ -z "$expiration_date" ]
    then
        echo "Expiration date is empty for user ${username}"
        continue
    fi

    # check if expiration_date is in the correct format
    if ! date -d "$expiration_date" > /dev/null 2>&1
    then
        echo "Expiration date is not in the correct format for user ${username}"
        continue
    fi

    # check if expiration_date is in the future
    if [ $(date -d "$expiration_date" +%s) -gt $(date +%s) ]
    then
        echo "Expiration date is in the future for user ${username}. Nothing to do"
        continue
    else
        echo "Expiration date is in the past for user ${username}. Disabling account... if not already disabled"
    fi

    # check if user exists with occ
    /usr/local/sbin/occ "user:info ${username}" > /dev/null 2>&1
    status=$?
    if [ $status -ne 0 ]
    then
        echo "User ${username} does not exist"
        continue
    fi

    # check if user is enabled
    /usr/local/sbin/occ "user:setting ${username} core enabled" | grep -q "false"
    status=$?
    if [ $status -eq 0 ]
    then
        echo "User ${username} is already disabled. Nothing to do"
        continue
    fi

    # disable user
    /usr/local/sbin/occ "user:disable ${username}"
    status=$?
    if [ $status -ne 0 ]
    then
        echo "Failed to disable user ${username}"
        continue
    else
        echo "User ${username} disabled at $(date '+%Y-%m-%d %H:%M:%S')"
        # send email notification
        if [ $_email_notification == true ]
        then
            echo "Sending email notification to $_email_recipients"
            echo "User ${username} has been disabled at $(date '+%Y-%m-%d %H:%M:%S')" | mail -s "Nextcloud account disabled" $_email_recipients
        fi
    fi

    # set disabled_on column on csv file
    sed -i "s/^$timestamp;$username;$email;$name;$group;$quota;$lang;$expiration_date;$disabled_on$/$timestamp;$username;$email;$name;$group;$quota;$lang;$expiration_date;$(date '+%Y-%m-%d %H:%M:%S')/" $_csv_file


done < $_csv_file