From 63a26e98ccaad19ac9c4a141a6199d6097dd1cc1 Mon Sep 17 00:00:00 2001 From: Simon Leary Date: Mon, 24 Nov 2025 11:10:50 -0500 Subject: [PATCH 1/4] setup init.php for workers --- workers/clear-audit-log.php | 4 +--- workers/group_user_request_owner_reminder.php | 4 +--- workers/init.php | 17 +++++++++++++++++ workers/remove-users-from-group.php | 17 ++++------------- workers/update-ldap-cache.php | 12 ++++++------ 5 files changed, 29 insertions(+), 25 deletions(-) create mode 100644 workers/init.php diff --git a/workers/clear-audit-log.php b/workers/clear-audit-log.php index c7cfebf8..908fb2ac 100755 --- a/workers/clear-audit-log.php +++ b/workers/clear-audit-log.php @@ -1,8 +1,6 @@ #!/usr/bin/env php exists()) { - _die("No such group '$gid'\n"); + _die("No such group '$gid'\n", 1); } -($handle = fopen($filename, "r")) or _die("Can't open '$filename'\n"); +($handle = fopen($filename, "r")) or _die("Can't open '$filename'\n", 1); while (($line = fgets($handle)) !== false) { $uid = trim($line); $user = new UnityUser($uid, $LDAP, $SQL, $MAILER, $REDIS, $WEBHOOK); diff --git a/workers/update-ldap-cache.php b/workers/update-ldap-cache.php index d4e5c396..124bc40c 100755 --- a/workers/update-ldap-cache.php +++ b/workers/update-ldap-cache.php @@ -1,8 +1,6 @@ #!/usr/bin/env php Date: Mon, 24 Nov 2025 12:36:41 -0500 Subject: [PATCH 2/4] fix return code --- workers/remove-users-from-group.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workers/remove-users-from-group.php b/workers/remove-users-from-group.php index fe816a3a..25142e17 100755 --- a/workers/remove-users-from-group.php +++ b/workers/remove-users-from-group.php @@ -5,7 +5,7 @@ use UnityWebPortal\lib\UnityGroup; if (sizeof($argv) != 3 or in_array($argv, ["-h", "--help"])) { - _die("Usage: $argv[0] group_name filename_of_users_to_remove\n", 0); + _die("Usage: {$argv[0]} group_name filename_of_users_to_remove\n", 1); } $gid = $argv[1]; From 862f597f716800a9df0d9888e1e2a95df6b5f015 Mon Sep 17 00:00:00 2001 From: Simon Leary Date: Wed, 26 Nov 2025 15:05:01 -0500 Subject: [PATCH 3/4] add test for worker remove-users-from-group.php --- .../WorkerRemoveUsersFromGroupTest.php | 70 +++++++++++++++++++ test/phpunit-bootstrap.php | 39 +++++++++++ 2 files changed, 109 insertions(+) create mode 100644 test/functional/WorkerRemoveUsersFromGroupTest.php diff --git a/test/functional/WorkerRemoveUsersFromGroupTest.php b/test/functional/WorkerRemoveUsersFromGroupTest.php new file mode 100644 index 00000000..06bb743e --- /dev/null +++ b/test/functional/WorkerRemoveUsersFromGroupTest.php @@ -0,0 +1,70 @@ +getPIGroup(); + $this->assertTrue($pi->isPI()); + $this->assertEqualsCanonicalizing([$pi->uid], $pi_group->getGroupMemberUIDs(true)); + $this->assertEqualsCanonicalizing([$pi->uid], $pi_group->getGroupMemberUIDs(false)); + $this->assertEqualsCanonicalizing([], $pi_group->getRequests()); + $uids = getSomeUIDsOfQualifiedUsersNotRequestedAccountDeletion(); + $uids_to_remove = array_slice($uids, 0, 3); + $expected_new_uids = array_diff(array_merge([$pi->uid], $uids), $uids_to_remove); + $remove_uids_file = $this->writeLinesToTmpFile($uids_to_remove); + $remove_uids_file_path = stream_get_meta_data($remove_uids_file)["uri"]; + try { + foreach ($uids as $uid) { + $user = new UnityUser($uid, $LDAP, $SQL, $MAILER, $REDIS, $WEBHOOK); + $pi_group->newUserRequest($user, false); + $pi_group->approveUser($user, false); + } + [$_, $output] = executeWorker( + "remove-users-from-group.php", + "$pi_group->gid $remove_uids_file_path", + ); + print implode("\n", $output); + // our $LDAP is not aware of changes made by worker subprocess, so throw it out + unset($GLOBALS["ldapconn"]); + switchUser(...getUserIsPIHasNoMembersNoMemberRequests()); + $pi = $USER; + $pi_group = $USER->getPIGroup(); + $this->assertEqualsCanonicalizing( + $expected_new_uids, + $pi_group->getGroupMemberUIDs(false), + ); + $this->assertEqualsCanonicalizing( + $expected_new_uids, + $pi_group->getGroupMemberUIDs(true), + ); + } finally { + foreach ($uids as $uid) { + $user = new UnityUser($uid, $LDAP, $SQL, $MAILER, $REDIS, $WEBHOOK); + $pi_group->removeUser($user); + } + } + } +} diff --git a/test/phpunit-bootstrap.php b/test/phpunit-bootstrap.php index 2091029e..052b89d5 100644 --- a/test/phpunit-bootstrap.php +++ b/test/phpunit-bootstrap.php @@ -158,6 +158,30 @@ function http_get(string $phpfile, array $get_data = []): void } } +/** + * runs a worker script + * @throws RuntimeException + * @return [return code, output lines] + */ +function executeWorker(string $basename, string $args, bool $doThrowIfNonzero = true): array +{ + $command = sprintf("%s %s/../workers/%s %s 2>&1", PHP_BINARY, __DIR__, $basename, $args); + $output = []; + $rc = null; + exec($command, $output, $rc); + if ($doThrowIfNonzero && $rc !== 0) { + throw new RuntimeException( + sprintf( + "command failed! command='%s' rc=%d output=%s", + $command, + $rc, + jsonEncode($output), + ), + ); + } + return [$rc, $output]; +} + // delete requests made by that user // delete user entry // delete user group entry @@ -216,6 +240,7 @@ function ensureUserNotInPIGroup(UnityGroup $pi_group) $pi_group->removeUser($USER); ensure(!$pi_group->memberExists($USER)); } + // FIXME removeUser already removes the uid from this redis, this shouldn't be necessary $REDIS->removeCacheArray( $pi_group->gid, "members", @@ -338,3 +363,17 @@ function getAdminUser() { return ["user1@org1.test", "foo", "bar", "user1@org1.test"]; } + +function getSomeUIDsOfQualifiedUsersNotRequestedAccountDeletion() +{ + return [ + "user1_org1_test", + "user3_org1_test", + "user6_org1_test", + "user7_org1_test", + "user8_org1_test", + "user9_org3_test", + "user10_org1_test", + "user11_org1_test", + ]; +} From 5f7f35f05a59a070dacea81afa1a11fa18abd9d5 Mon Sep 17 00:00:00 2001 From: Simon Leary Date: Wed, 26 Nov 2025 17:09:13 -0500 Subject: [PATCH 4/4] add broken test --- test/functional/WorkerUpdateLDAPCacheTest.php | 25 +++++++++++++++++++ test/phpunit-bootstrap.php | 2 +- 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 test/functional/WorkerUpdateLDAPCacheTest.php diff --git a/test/functional/WorkerUpdateLDAPCacheTest.php b/test/functional/WorkerUpdateLDAPCacheTest.php new file mode 100644 index 00000000..47837e02 --- /dev/null +++ b/test/functional/WorkerUpdateLDAPCacheTest.php @@ -0,0 +1,25 @@ +getPIGroup()->getGroupMemberUIDs(false); + [$_, $output_lines] = executeWorker("update-ldap-cache.php", "-f"); + error_log(implode("\n", $output_lines)); + // switchUser(...getUserIsPIHasAtLeastOneMember()); // refresh $REDIS + $after_flush_value = $REDIS->getCache($USER->getPIGroup()->gid, "members"); + $this->assertEqualsCanonicalizing([], $after_flush_value); + [$_, $output_lines] = executeWorker("update-ldap-cache.php"); + error_log(implode("\n", $output_lines)); + // switchUser(...getUserIsPIHasAtLeastOneMember()); // refresh $REDIS + $after_update_value = $REDIS->getCache($USER->getPIGroup()->gid, "members"); + $this->assertEqualsCanonicalizing($initial_value, $after_update_value); + } +} diff --git a/test/phpunit-bootstrap.php b/test/phpunit-bootstrap.php index 052b89d5..303d2642 100644 --- a/test/phpunit-bootstrap.php +++ b/test/phpunit-bootstrap.php @@ -163,7 +163,7 @@ function http_get(string $phpfile, array $get_data = []): void * @throws RuntimeException * @return [return code, output lines] */ -function executeWorker(string $basename, string $args, bool $doThrowIfNonzero = true): array +function executeWorker(string $basename, string $args = "", bool $doThrowIfNonzero = true): array { $command = sprintf("%s %s/../workers/%s %s 2>&1", PHP_BINARY, __DIR__, $basename, $args); $output = [];