From e4cd9ea8d8c4abba35c2987cefa52a69374de620 Mon Sep 17 00:00:00 2001 From: tvv28669 Date: Wed, 20 Oct 2021 17:43:17 +0100 Subject: [PATCH 01/17] Init script to remove inactive users --- resources/RemoveInactiveUsersRunner.php | 60 +++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 resources/RemoveInactiveUsersRunner.php diff --git a/resources/RemoveInactiveUsersRunner.php b/resources/RemoveInactiveUsersRunner.php new file mode 100644 index 000000000..c81c3b2a8 --- /dev/null +++ b/resources/RemoveInactiveUsersRunner.php @@ -0,0 +1,60 @@ +createQuery($dql)->getResult(); + +echo "Scanning user login dates in database at: ".date('D, d M Y H:i:s')."\n"; + +$today = new DateTime(); +echo $today->format('Y-m-d H:i:s'); + +foreach ($users as $user) { + echo 'User ID: ' . $user->getId() . "\n"; + + $CreationDate = $user->getCreationDate(); + $CreationStr = $CreationDate->format('Y-m-d H:i:s'); + + $lastLoginDate = $user->getLastLoginDate(); + + if ($lastLoginDate){ // null lastLoginDate check + $interval = $today->diff($lastLoginDate); + } else { // This might only be run once, since new users always have field filled. + echo "User has no lastLoginDate (it may have been a very long time.)\n"; + echo "Deleting user.\n"; + deleteUser($user, $em); + echo "\n"; + return; + } + + $elapsedMonths = (int) $interval->format('%a') / 30; + echo 'Months elapsed since last login: ' . $elapsedMonths . "\n"; + + if ($elapsedMonths > 18){ // Delete user + echo "Deleting user\n"; + deleteUser($user); + } + elseif ($elapsedMonths > 17){ // Warn user + echo "Requesting user warning email.\n"; + sendWarningEmail($user); + } + elseif ($elapsedMonths < 17){ // Do Nothing + echo "Doing nothing.\n"; + } + + echo "\n\n"; +} + +$em->flush(); +echo "Completed ok: ".date('D, d M Y H:i:s'); + +function deleteUser($user){ + echo "User deleted."; +} + +function sendWarningEmail($user){ + echo "Email sent."; +} From 43a341ac413cab1bd0ccf282b782bdfbce0bfadd Mon Sep 17 00:00:00 2001 From: tvv28669 Date: Wed, 20 Oct 2021 16:00:52 +0100 Subject: [PATCH 02/17] Email handling function --- resources/RemoveInactiveUsersRunner.php | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/resources/RemoveInactiveUsersRunner.php b/resources/RemoveInactiveUsersRunner.php index c81c3b2a8..203d78dc7 100644 --- a/resources/RemoveInactiveUsersRunner.php +++ b/resources/RemoveInactiveUsersRunner.php @@ -2,6 +2,7 @@ require_once dirname(__FILE__) . "/../lib/Doctrine/bootstrap.php"; require dirname(__FILE__) . '/../lib/Doctrine/bootstrap_doctrine.php'; require_once dirname(__FILE__) . '/../lib/Gocdb_Services/User.php'; +require_once dirname(__FILE__) . '/../lib/Gocdb_Services/Factory.php'; $em = $entityManager; $dql = "SELECT u FROM User u"; @@ -56,5 +57,23 @@ function deleteUser($user){ } function sendWarningEmail($user){ - echo "Email sent."; + $emailAddress = $user->getEmail(); + $certDn = $user->getCertificateDn(); + + // Email content + $headers = "From: no-reply@goc.egi.eu"; + $subject = "GocDB: User account deletion notice"; + + //$webPortalURL = "gocdb-portal-address"; + $localInfoLocation = __DIR__ . "/../config/local_info.xml"; + $localInfoXML = simplexml_load_file ( $localInfoLocation ); + $webPortalURL = $localInfoXML->local_info->web_portal_url; + + $body = "Dear GOCDB User,\n\n" . "Your account (ID:". $certDn .") has not" + . "signed in for the past 17 months and is due for deletion in 30" + . "days.\n\n" . "You can prevent this by visiting" . $webPortalURL + . "while authenticated with the above credential.\n\n"; + + // Handle all mail related printing/debugging + \Factory::getEmailService()->send($emailAddress, $subject, $body, $headers); } From 6d2a69db9ec1079729d35e1fa24c4f5ae80777ab Mon Sep 17 00:00:00 2001 From: tvv28669 Date: Thu, 28 Oct 2021 12:11:11 +0100 Subject: [PATCH 03/17] Delete user function --- resources/RemoveInactiveUsersRunner.php | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/resources/RemoveInactiveUsersRunner.php b/resources/RemoveInactiveUsersRunner.php index 203d78dc7..73b9787e9 100644 --- a/resources/RemoveInactiveUsersRunner.php +++ b/resources/RemoveInactiveUsersRunner.php @@ -36,7 +36,7 @@ if ($elapsedMonths > 18){ // Delete user echo "Deleting user\n"; - deleteUser($user); + deleteUser($user, $em); } elseif ($elapsedMonths > 17){ // Warn user echo "Requesting user warning email.\n"; @@ -52,8 +52,19 @@ $em->flush(); echo "Completed ok: ".date('D, d M Y H:i:s'); -function deleteUser($user){ - echo "User deleted."; +function deleteUser($user, $em){ + $em->getConnection()->beginTransaction(); + try { + $em->remove($user); + $em->flush(); + $em->getConnection()->commit(); + echo "User deleted.\n"; + } catch (\Exception $e) { + $em->getConnection()->rollback(); + $em->close(); + echo "User not deleted.\n"; + throw $e; + } } function sendWarningEmail($user){ From a00be3582f2d05b71ff7d2e0d39a5a8f39096522 Mon Sep 17 00:00:00 2001 From: gregcorbett Date: Fri, 27 May 2022 09:43:35 +0000 Subject: [PATCH 04/17] Remove trailing whitespace --- resources/RemoveInactiveUsersRunner.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/resources/RemoveInactiveUsersRunner.php b/resources/RemoveInactiveUsersRunner.php index 73b9787e9..17e237acc 100644 --- a/resources/RemoveInactiveUsersRunner.php +++ b/resources/RemoveInactiveUsersRunner.php @@ -37,11 +37,11 @@ if ($elapsedMonths > 18){ // Delete user echo "Deleting user\n"; deleteUser($user, $em); - } + } elseif ($elapsedMonths > 17){ // Warn user echo "Requesting user warning email.\n"; sendWarningEmail($user); - } + } elseif ($elapsedMonths < 17){ // Do Nothing echo "Doing nothing.\n"; } @@ -51,7 +51,7 @@ $em->flush(); echo "Completed ok: ".date('D, d M Y H:i:s'); - + function deleteUser($user, $em){ $em->getConnection()->beginTransaction(); try { @@ -79,12 +79,12 @@ function sendWarningEmail($user){ $localInfoLocation = __DIR__ . "/../config/local_info.xml"; $localInfoXML = simplexml_load_file ( $localInfoLocation ); $webPortalURL = $localInfoXML->local_info->web_portal_url; - + $body = "Dear GOCDB User,\n\n" . "Your account (ID:". $certDn .") has not" . "signed in for the past 17 months and is due for deletion in 30" . "days.\n\n" . "You can prevent this by visiting" . $webPortalURL . "while authenticated with the above credential.\n\n"; - + // Handle all mail related printing/debugging \Factory::getEmailService()->send($emailAddress, $subject, $body, $headers); } From 1428e6aff01e5eb6165c387991711aa7d1cb32e5 Mon Sep 17 00:00:00 2001 From: gregcorbett Date: Fri, 27 May 2022 09:47:05 +0000 Subject: [PATCH 05/17] Fix indentation --- resources/RemoveInactiveUsersRunner.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/RemoveInactiveUsersRunner.php b/resources/RemoveInactiveUsersRunner.php index 17e237acc..a15fa194e 100644 --- a/resources/RemoveInactiveUsersRunner.php +++ b/resources/RemoveInactiveUsersRunner.php @@ -26,7 +26,7 @@ } else { // This might only be run once, since new users always have field filled. echo "User has no lastLoginDate (it may have been a very long time.)\n"; echo "Deleting user.\n"; - deleteUser($user, $em); + deleteUser($user, $em); echo "\n"; return; } @@ -36,11 +36,11 @@ if ($elapsedMonths > 18){ // Delete user echo "Deleting user\n"; - deleteUser($user, $em); + deleteUser($user, $em); } elseif ($elapsedMonths > 17){ // Warn user echo "Requesting user warning email.\n"; - sendWarningEmail($user); + sendWarningEmail($user); } elseif ($elapsedMonths < 17){ // Do Nothing echo "Doing nothing.\n"; From b0b0a78a2b3a1b299624c76350fabb397ad33022 Mon Sep 17 00:00:00 2001 From: gregcorbett Date: Fri, 27 May 2022 09:49:53 +0000 Subject: [PATCH 06/17] Change email address used in "From" header - GOCDB admins email is better because it doesn't matter what view the user uses. - it's also consistent with other mails sent (e.g. role requests, ID linking). --- resources/RemoveInactiveUsersRunner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/RemoveInactiveUsersRunner.php b/resources/RemoveInactiveUsersRunner.php index a15fa194e..4ea22f0d6 100644 --- a/resources/RemoveInactiveUsersRunner.php +++ b/resources/RemoveInactiveUsersRunner.php @@ -72,7 +72,7 @@ function sendWarningEmail($user){ $certDn = $user->getCertificateDn(); // Email content - $headers = "From: no-reply@goc.egi.eu"; + $headers = "From: GOCDB "; $subject = "GocDB: User account deletion notice"; //$webPortalURL = "gocdb-portal-address"; From d17e715eec6d18ad14e31570b032ff5cb867d554 Mon Sep 17 00:00:00 2001 From: gregcorbett Date: Fri, 27 May 2022 09:52:04 +0000 Subject: [PATCH 07/17] Change capitalisation of GOCDB - to be more consistent with itself and other emails sent --- resources/RemoveInactiveUsersRunner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/RemoveInactiveUsersRunner.php b/resources/RemoveInactiveUsersRunner.php index 4ea22f0d6..e7560f166 100644 --- a/resources/RemoveInactiveUsersRunner.php +++ b/resources/RemoveInactiveUsersRunner.php @@ -73,7 +73,7 @@ function sendWarningEmail($user){ // Email content $headers = "From: GOCDB "; - $subject = "GocDB: User account deletion notice"; + $subject = "GOCDB: User account deletion notice"; //$webPortalURL = "gocdb-portal-address"; $localInfoLocation = __DIR__ . "/../config/local_info.xml"; From 54754168f505d33d316eea87ae50f0b34a6175ea Mon Sep 17 00:00:00 2001 From: gregcorbett Date: Fri, 27 May 2022 10:05:11 +0000 Subject: [PATCH 08/17] Address low hanging code climate fruit --- resources/RemoveInactiveUsersRunner.php | 37 ++++++++++++------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/resources/RemoveInactiveUsersRunner.php b/resources/RemoveInactiveUsersRunner.php index e7560f166..3248c2812 100644 --- a/resources/RemoveInactiveUsersRunner.php +++ b/resources/RemoveInactiveUsersRunner.php @@ -4,7 +4,6 @@ require_once dirname(__FILE__) . '/../lib/Gocdb_Services/User.php'; require_once dirname(__FILE__) . '/../lib/Gocdb_Services/Factory.php'; -$em = $entityManager; $dql = "SELECT u FROM User u"; $users = $entityManager->createQuery($dql)->getResult(); @@ -21,12 +20,12 @@ $lastLoginDate = $user->getLastLoginDate(); - if ($lastLoginDate){ // null lastLoginDate check + if ($lastLoginDate) { // null lastLoginDate check $interval = $today->diff($lastLoginDate); } else { // This might only be run once, since new users always have field filled. echo "User has no lastLoginDate (it may have been a very long time.)\n"; echo "Deleting user.\n"; - deleteUser($user, $em); + deleteUser($user, $entityManager); echo "\n"; return; } @@ -34,40 +33,40 @@ $elapsedMonths = (int) $interval->format('%a') / 30; echo 'Months elapsed since last login: ' . $elapsedMonths . "\n"; - if ($elapsedMonths > 18){ // Delete user + if ($elapsedMonths > 18) { // Delete user echo "Deleting user\n"; - deleteUser($user, $em); - } - elseif ($elapsedMonths > 17){ // Warn user + deleteUser($user, $entityManager); + } elseif ($elapsedMonths > 17) { // Warn user echo "Requesting user warning email.\n"; sendWarningEmail($user); - } - elseif ($elapsedMonths < 17){ // Do Nothing + } elseif ($elapsedMonths < 17) { // Do Nothing echo "Doing nothing.\n"; } echo "\n\n"; } -$em->flush(); +$entityManager->flush(); echo "Completed ok: ".date('D, d M Y H:i:s'); -function deleteUser($user, $em){ - $em->getConnection()->beginTransaction(); +function deleteUser($user, $entityManager) +{ + $entityManager->getConnection()->beginTransaction(); try { - $em->remove($user); - $em->flush(); - $em->getConnection()->commit(); + $entityManager->remove($user); + $entityManager->flush(); + $entityManager->getConnection()->commit(); echo "User deleted.\n"; } catch (\Exception $e) { - $em->getConnection()->rollback(); - $em->close(); + $entityManager->getConnection()->rollback(); + $entityManager->close(); echo "User not deleted.\n"; throw $e; } } -function sendWarningEmail($user){ +function sendWarningEmail($user) +{ $emailAddress = $user->getEmail(); $certDn = $user->getCertificateDn(); @@ -77,7 +76,7 @@ function sendWarningEmail($user){ //$webPortalURL = "gocdb-portal-address"; $localInfoLocation = __DIR__ . "/../config/local_info.xml"; - $localInfoXML = simplexml_load_file ( $localInfoLocation ); + $localInfoXML = simplexml_load_file($localInfoLocation); $webPortalURL = $localInfoXML->local_info->web_portal_url; $body = "Dear GOCDB User,\n\n" . "Your account (ID:". $certDn .") has not" From 3c9995b481ded167fbbe15823b60cc9f77fab37c Mon Sep 17 00:00:00 2001 From: gregcorbett Date: Fri, 27 May 2022 11:11:08 +0000 Subject: [PATCH 09/17] Rework email generation to list all identifiers --- resources/RemoveInactiveUsersRunner.php | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/resources/RemoveInactiveUsersRunner.php b/resources/RemoveInactiveUsersRunner.php index 3248c2812..684107a01 100644 --- a/resources/RemoveInactiveUsersRunner.php +++ b/resources/RemoveInactiveUsersRunner.php @@ -68,21 +68,26 @@ function deleteUser($user, $entityManager) function sendWarningEmail($user) { $emailAddress = $user->getEmail(); - $certDn = $user->getCertificateDn(); // Email content $headers = "From: GOCDB "; $subject = "GOCDB: User account deletion notice"; - //$webPortalURL = "gocdb-portal-address"; - $localInfoLocation = __DIR__ . "/../config/local_info.xml"; - $localInfoXML = simplexml_load_file($localInfoLocation); - $webPortalURL = $localInfoXML->local_info->web_portal_url; + $body = "Dear ". $user->getForename() .",\n\n" . + "Your GOCDB account, associated with the following identifiers, " . + "has not been signed into during the last 17 months and is due " . + "for deletion in 30 days.\n\n"; + + $body .= "Identifiers:\n"; + foreach ($user->getUserIdentifiers() as $identifier) { + $body .= " - " . $identifier->getKeyName() .": " . $identifier->getKeyValue(). "\n"; + } + + $body .= "\n"; + $body .= "You can prevent the deletion of this account by visiting the " . + "GOCDB portal while authenticated with one of the above " . + "identifiers.\n"; - $body = "Dear GOCDB User,\n\n" . "Your account (ID:". $certDn .") has not" - . "signed in for the past 17 months and is due for deletion in 30" - . "days.\n\n" . "You can prevent this by visiting" . $webPortalURL - . "while authenticated with the above credential.\n\n"; // Handle all mail related printing/debugging \Factory::getEmailService()->send($emailAddress, $subject, $body, $headers); From 7b719131157d059cd229b8bc18d08a74aa933697 Mon Sep 17 00:00:00 2001 From: gregcorbett Date: Fri, 27 May 2022 11:12:01 +0000 Subject: [PATCH 10/17] Change variables to camelCase - for consistency and PSR-12 compliance --- resources/RemoveInactiveUsersRunner.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/RemoveInactiveUsersRunner.php b/resources/RemoveInactiveUsersRunner.php index 684107a01..37683000c 100644 --- a/resources/RemoveInactiveUsersRunner.php +++ b/resources/RemoveInactiveUsersRunner.php @@ -15,8 +15,8 @@ foreach ($users as $user) { echo 'User ID: ' . $user->getId() . "\n"; - $CreationDate = $user->getCreationDate(); - $CreationStr = $CreationDate->format('Y-m-d H:i:s'); + $creationDate = $user->getCreationDate(); + $creationStr = $creationDate->format('Y-m-d H:i:s'); $lastLoginDate = $user->getLastLoginDate(); From d8248b3e37a7c3423a0019fff217e604aef7a7b1 Mon Sep 17 00:00:00 2001 From: gregcorbett Date: Fri, 27 May 2022 11:13:00 +0000 Subject: [PATCH 11/17] Remove duplicate time echo - as the time this script starts is already captured above. --- resources/RemoveInactiveUsersRunner.php | 1 - 1 file changed, 1 deletion(-) diff --git a/resources/RemoveInactiveUsersRunner.php b/resources/RemoveInactiveUsersRunner.php index 37683000c..73a97aeee 100644 --- a/resources/RemoveInactiveUsersRunner.php +++ b/resources/RemoveInactiveUsersRunner.php @@ -10,7 +10,6 @@ echo "Scanning user login dates in database at: ".date('D, d M Y H:i:s')."\n"; $today = new DateTime(); -echo $today->format('Y-m-d H:i:s'); foreach ($users as $user) { echo 'User ID: ' . $user->getId() . "\n"; From ed42ea345ddd0ebecbbc25b41ad252a0ac4e456e Mon Sep 17 00:00:00 2001 From: gregcorbett Date: Fri, 27 May 2022 11:14:18 +0000 Subject: [PATCH 12/17] Bug fix when handling users with no lastLoginDate - we don't want to return here (and skip the rest of the users), we want to continue on to the next user. --- resources/RemoveInactiveUsersRunner.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/RemoveInactiveUsersRunner.php b/resources/RemoveInactiveUsersRunner.php index 73a97aeee..b3815c23b 100644 --- a/resources/RemoveInactiveUsersRunner.php +++ b/resources/RemoveInactiveUsersRunner.php @@ -26,7 +26,8 @@ echo "Deleting user.\n"; deleteUser($user, $entityManager); echo "\n"; - return; + // Move onto the next users. + continue; } $elapsedMonths = (int) $interval->format('%a') / 30; From 6107b64e7cb18f282aa5e2745b1a5489b5f12326 Mon Sep 17 00:00:00 2001 From: gregcorbett Date: Fri, 27 May 2022 11:15:13 +0000 Subject: [PATCH 13/17] Slight tweaks to printed output --- resources/RemoveInactiveUsersRunner.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/resources/RemoveInactiveUsersRunner.php b/resources/RemoveInactiveUsersRunner.php index b3815c23b..b36b6d128 100644 --- a/resources/RemoveInactiveUsersRunner.php +++ b/resources/RemoveInactiveUsersRunner.php @@ -37,13 +37,11 @@ echo "Deleting user\n"; deleteUser($user, $entityManager); } elseif ($elapsedMonths > 17) { // Warn user - echo "Requesting user warning email.\n"; + echo "Sending user warning email.\n"; sendWarningEmail($user); } elseif ($elapsedMonths < 17) { // Do Nothing echo "Doing nothing.\n"; } - - echo "\n\n"; } $entityManager->flush(); From bdeba7e88a22bdee95e6a0727e768925587c2013 Mon Sep 17 00:00:00 2001 From: gregcorbett Date: Fri, 27 May 2022 13:26:25 +0000 Subject: [PATCH 14/17] Be less specific about account deletion - As this script is stateless and might be run weekly, hence a used will get ~4 warnings and we don't want each one saying "30 days". --- resources/RemoveInactiveUsersRunner.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/RemoveInactiveUsersRunner.php b/resources/RemoveInactiveUsersRunner.php index b36b6d128..86f8086f9 100644 --- a/resources/RemoveInactiveUsersRunner.php +++ b/resources/RemoveInactiveUsersRunner.php @@ -73,8 +73,8 @@ function sendWarningEmail($user) $body = "Dear ". $user->getForename() .",\n\n" . "Your GOCDB account, associated with the following identifiers, " . - "has not been signed into during the last 17 months and is due " . - "for deletion in 30 days.\n\n"; + "has not been signed into during the last 17 months and will be " . + "when this period of inactivity reaches 18 months.\n\n"; $body .= "Identifiers:\n"; foreach ($user->getUserIdentifiers() as $identifier) { From f16cbeca542f062b79f3c3650147d6e8360b71de Mon Sep 17 00:00:00 2001 From: gregcorbett Date: Thu, 7 Jul 2022 08:31:15 +0100 Subject: [PATCH 15/17] Add missing word to account deletion email Co-authored-by: ineilson --- resources/RemoveInactiveUsersRunner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/RemoveInactiveUsersRunner.php b/resources/RemoveInactiveUsersRunner.php index 86f8086f9..f3b22f9a7 100644 --- a/resources/RemoveInactiveUsersRunner.php +++ b/resources/RemoveInactiveUsersRunner.php @@ -74,7 +74,7 @@ function sendWarningEmail($user) $body = "Dear ". $user->getForename() .",\n\n" . "Your GOCDB account, associated with the following identifiers, " . "has not been signed into during the last 17 months and will be " . - "when this period of inactivity reaches 18 months.\n\n"; + "deleted when this period of inactivity reaches 18 months.\n\n"; $body .= "Identifiers:\n"; foreach ($user->getUserIdentifiers() as $identifier) { From e86f594c02013afadd35d9ba6f89ae82b6fe155b Mon Sep 17 00:00:00 2001 From: gregcorbett Date: Fri, 29 Jul 2022 14:49:15 +0000 Subject: [PATCH 16/17] Softcode thresholds for warning and deletion - so that they can be changed in production based on how frequently the script runs. --- resources/RemoveInactiveUsersRunner.php | 63 +++++++++++++++++++++---- 1 file changed, 55 insertions(+), 8 deletions(-) diff --git a/resources/RemoveInactiveUsersRunner.php b/resources/RemoveInactiveUsersRunner.php index f3b22f9a7..560960437 100644 --- a/resources/RemoveInactiveUsersRunner.php +++ b/resources/RemoveInactiveUsersRunner.php @@ -4,6 +4,34 @@ require_once dirname(__FILE__) . '/../lib/Gocdb_Services/User.php'; require_once dirname(__FILE__) . '/../lib/Gocdb_Services/Factory.php'; +// Configure script options +$longOptions = array( + // Required Option. After this many months, users will receive email warnings. + "warning_threshold:", + // Required Option. After this many months, users will be deleted. + "deletion_threshold:", +); + +$options = getopt("", $longOptions); + +// Handle the cases where options were not passed. + +if (isset($options["warning_threshold"])) { + $warningThreshold = $options["warning_threshold"]; +} else { + echo "Error: warning_threshold option must be set.\n"; + usage(); + return; +}; + +if (isset($options["deletion_threshold"])) { + $deletionThreshold = $options["deletion_threshold"]; +} else { + echo "Error: deletion_threshold option must be set.\n"; + usage(); + return; +}; + $dql = "SELECT u FROM User u"; $users = $entityManager->createQuery($dql)->getResult(); @@ -33,13 +61,13 @@ $elapsedMonths = (int) $interval->format('%a') / 30; echo 'Months elapsed since last login: ' . $elapsedMonths . "\n"; - if ($elapsedMonths > 18) { // Delete user + if ($elapsedMonths > $deletionThreshold) { // Delete user echo "Deleting user\n"; deleteUser($user, $entityManager); - } elseif ($elapsedMonths > 17) { // Warn user + } elseif ($elapsedMonths > $warningThreshold) { // Warn user echo "Sending user warning email.\n"; - sendWarningEmail($user); - } elseif ($elapsedMonths < 17) { // Do Nothing + sendWarningEmail($user, $elapsedMonths, $deletionThreshold); + } elseif ($elapsedMonths < $warningThreshold) { // Do Nothing echo "Doing nothing.\n"; } } @@ -47,6 +75,23 @@ $entityManager->flush(); echo "Completed ok: ".date('D, d M Y H:i:s'); +function usage() { + echo "Usage: " . + "RemoveInactiveUsersRunner.php " . + "--warning_threshold X " . + "--deletion_threshold Y" . + "\n\n"; + echo "Options:\n\n"; + echo "--warning_threshold X " . + " After this many months, users will receive email warnings." . + "\n"; + echo "--deletion_threshold Y" . + " After this many months, users will be deleted." . + "\n"; + + echo "\n"; +}; + function deleteUser($user, $entityManager) { $entityManager->getConnection()->beginTransaction(); @@ -63,7 +108,7 @@ function deleteUser($user, $entityManager) } } -function sendWarningEmail($user) +function sendWarningEmail($user, $elapsedMonths, $deletionThreshold) { $emailAddress = $user->getEmail(); @@ -72,9 +117,11 @@ function sendWarningEmail($user) $subject = "GOCDB: User account deletion notice"; $body = "Dear ". $user->getForename() .",\n\n" . - "Your GOCDB account, associated with the following identifiers, " . - "has not been signed into during the last 17 months and will be " . - "deleted when this period of inactivity reaches 18 months.\n\n"; + "Your GOCDB account, associated with the following " . + "identifiers, has not been signed into during the last " . + floor($elapsedMonths) . " months and will be deleted when " . + "this period of inactivity reaches " . + $deletionThreshold . " months.\n\n"; $body .= "Identifiers:\n"; foreach ($user->getUserIdentifiers() as $identifier) { From a97fc223c7aa7dbb18dda27b06279ac9e2a621bc Mon Sep 17 00:00:00 2001 From: gregcorbett Date: Fri, 29 Jul 2022 14:57:03 +0000 Subject: [PATCH 17/17] Skip users with API credentials - to prevent deleting the user and creating orphaned API credentials. --- resources/RemoveInactiveUsersRunner.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/resources/RemoveInactiveUsersRunner.php b/resources/RemoveInactiveUsersRunner.php index 560960437..dd7065589 100644 --- a/resources/RemoveInactiveUsersRunner.php +++ b/resources/RemoveInactiveUsersRunner.php @@ -47,6 +47,13 @@ $lastLoginDate = $user->getLastLoginDate(); + if (!$user->getAPIAuthenticationEntities()->isEmpty()) { + // Prevent creating orphaned API credentials. + echo "Cannot delete a user with attached API credentials.\n"; + // Move onto the next users. + continue; + } + if ($lastLoginDate) { // null lastLoginDate check $interval = $today->diff($lastLoginDate); } else { // This might only be run once, since new users always have field filled.