From c491cc169428cd01db1fffa723e0b75598846731 Mon Sep 17 00:00:00 2001 From: Simon Leary Date: Mon, 15 Dec 2025 13:13:08 -0500 Subject: [PATCH 01/18] 1st draft --- defaults/config.ini.default | 5 ++++- resources/lib/UnityLDAP.php | 38 ++++++++++++++++++++++--------------- resources/lib/UnityUser.php | 13 ++++--------- test/phpunit-bootstrap.php | 14 ++------------ 4 files changed, 33 insertions(+), 37 deletions(-) diff --git a/defaults/config.ini.default b/defaults/config.ini.default index 773013bc..75065505 100644 --- a/defaults/config.ini.default +++ b/defaults/config.ini.default @@ -28,11 +28,14 @@ pass = "password" ; Admin bind password custom_user_mappings_dir = "deployment/custom_user_mappings" ; for internal use only basedn = "dc=unityhpc,dc=test" ; Base search DN user_ou = "ou=users,dc=unityhpc,dc=test" ; User organizational unit (may contain more than user group) -qualified_user_group = "cn=unityusers,dc=unityhpc,dc=test" ; Qualified user group (in at least one PI group) group_ou = "ou=groups,dc=unityhpc,dc=test" ; Group organizational unit pigroup_ou = "ou=pi_groups,dc=unityhpc,dc=test" ; PI Group organizational unit orggroup_ou = "ou=org_groups,dc=unityhpc,dc=test" ; ORG group organizational unit admin_group = "cn=web_admins,dc=unityhpc,dc=test" ; admin dn (members of this group are admins on the web portal) +qualified_user_group = "cn=unityusers,dc=unityhpc,dc=test" ; Qualified user group (in at least one PI group) +locked_user_group = "cn=locked,dc=unityhpc,dc=test" ; locked user group dn +idlelocked_user_group = "cn=idlelocked,dc=unityhpc,dc=test" ; idlelocked user group dn +ghost_user_group = "cn=ghost,dc=unityhpc,dc=test" ; ghost user group dn def_user_shell = "/bin/bash" ; Default shell for new users offset_UIDGID = 1000000 ; start point when allocating new UID/GID pairs for a new user offset_PIGID = 2000000 ; start point when allocating new GID for a new PI group diff --git a/resources/lib/UnityLDAP.php b/resources/lib/UnityLDAP.php index 6752140a..1d395c6a 100644 --- a/resources/lib/UnityLDAP.php +++ b/resources/lib/UnityLDAP.php @@ -5,6 +5,7 @@ use UnityWebPortal\lib\exceptions\EntryNotFoundException; use PHPOpenLDAPer\LDAPConn; use PHPOpenLDAPer\LDAPEntry; +use UnityWebPortal\lib\PosixGroup; /** * An LDAP connection class which extends LDAPConn tailored for the UnityHPC Platform @@ -35,8 +36,12 @@ class UnityLDAP extends LDAPConn private LDAPEntry $groupOU; private LDAPEntry $pi_groupOU; private LDAPEntry $org_groupOU; - private LDAPEntry $adminGroup; - private LDAPEntry $qualifiedUserGroup; + + public PosixGroup $adminGroup; + public PosixGroup $qualifiedUserGroup; + public PosixGroup $lockedUserGroup; + public PosixGroup $idlelockedUserGroup; + public PosixGroup $ghostUserGroup; public function __construct() { @@ -46,8 +51,21 @@ public function __construct() $this->groupOU = $this->getEntry(CONFIG["ldap"]["group_ou"]); $this->pi_groupOU = $this->getEntry(CONFIG["ldap"]["pigroup_ou"]); $this->org_groupOU = $this->getEntry(CONFIG["ldap"]["orggroup_ou"]); - $this->adminGroup = $this->getEntry(CONFIG["ldap"]["admin_group"]); - $this->qualifiedUserGroup = $this->getEntry(CONFIG["ldap"]["qualified_user_group"]); + $this->adminGroup = new PosixGroup( + new LDAPEntry($this->conn, CONFIG["ldap"]["admin_group"]), + ); + $this->qualifiedUserGroup = new PosixGroup( + new LDAPEntry($this->conn, CONFIG["ldap"]["qualified_user_group"]), + ); + $this->lockedUserGroup = new PosixGroup( + new LDAPEntry($this->conn, CONFIG["ldap"]["locked_user_group"]), + ); + $this->idlelockedUserGroup = new PosixGroup( + new LDAPEntry($this->conn, CONFIG["ldap"]["idlelocked_user_group"]), + ); + $this->ghostUserGroup = new PosixGroup( + new LDAPEntry($this->conn, CONFIG["ldap"]["ghost_user_group"]), + ); } public function getUserOU(): LDAPEntry @@ -70,16 +88,6 @@ public function getOrgGroupOU(): LDAPEntry return $this->org_groupOU; } - public function getAdminGroup(): LDAPEntry - { - return $this->adminGroup; - } - - public function getQualifiedUserGroup(): LDAPEntry - { - return $this->qualifiedUserGroup; - } - public function getDefUserShell(): string { return $this->def_user_shell; @@ -191,7 +199,7 @@ public function getQualifiedUsersUIDs(): array { // should not use $user_ou->getChildren or $base_ou->getChildren(objectClass=posixAccount) // qualified users might be outside user ou, and not all users in LDAP tree are qualified users - return $this->qualifiedUserGroup->getAttribute("memberuid"); + return $this->qualifiedUserGroup->getMemberUIDs(); } public function getQualifiedUsers($UnitySQL, $UnityMailer, $UnityWebhook): array diff --git a/resources/lib/UnityUser.php b/resources/lib/UnityUser.php index 16b4514f..d1795097 100644 --- a/resources/lib/UnityUser.php +++ b/resources/lib/UnityUser.php @@ -99,7 +99,7 @@ public function init( public function isQualified(): bool { - return $this->LDAP->getQualifiedUserGroup()->attributeValueExists("memberUid", $this->uid); + return $this->LDAP->qualifiedUserGroup->memberUIDExists($this->uid); } public function setIsQualified(bool $newIsQualified, bool $doSendMail = true): void @@ -109,8 +109,7 @@ public function setIsQualified(bool $newIsQualified, bool $doSendMail = true): v return; } if ($newIsQualified) { - $this->LDAP->getQualifiedUserGroup()->appendAttribute("memberuid", $this->uid); - $this->LDAP->getQualifiedUserGroup()->write(); + $this->LDAP->qualifiedUserGroup->addMemberUID($this->uid); if ($doSendMail) { $this->MAILER->sendMail($this->getMail(), "user_qualified", [ "user" => $this->uid, @@ -118,10 +117,7 @@ public function setIsQualified(bool $newIsQualified, bool $doSendMail = true): v ]); } } else { - $this->LDAP - ->getQualifiedUserGroup() - ->removeAttributeEntryByValue("memberuid", $this->uid); - $this->LDAP->getQualifiedUserGroup()->write(); + $this->LDAP->qualifiedUserGroup->removeMemberUID($this->uid); if ($doSendMail) { $this->MAILER->sendMail($this->getMail(), "user_dequalified", [ "user" => $this->uid, @@ -324,8 +320,7 @@ public function getHomeDir(): string */ public function isAdmin(): bool { - $admins = $this->LDAP->getAdminGroup()->getAttribute("memberuid"); - return in_array($this->uid, $admins); + return $this->LDAP->adminGroup->memberUIDExists($this->uid); } /** diff --git a/test/phpunit-bootstrap.php b/test/phpunit-bootstrap.php index d16a6222..0cece051 100644 --- a/test/phpunit-bootstrap.php +++ b/test/phpunit-bootstrap.php @@ -195,18 +195,8 @@ function ensureUserDoesNotExist() $USER->getGroupEntry()->delete(); ensure(!$USER->getGroupEntry()->exists()); } - $qualified_users_group = $LDAP->getQualifiedUserGroup(); - $all_member_uids = $qualified_users_group->getAttribute("memberuid"); - if (in_array($USER->uid, $all_member_uids)) { - $qualified_users_group->setAttribute( - "memberuid", - // array_diff will break the contiguity of the array indexes - // ldap_mod_replace requires contiguity, array_values restores contiguity - array_values(array_diff($all_member_uids, [$USER->uid])), - ); - $qualified_users_group->write(); - ensure(!in_array($USER->uid, $qualified_users_group->getAttribute("memberuid"))); - } + $USER->setIsQualified(false); + ensure(!$LDAP->qualifiedUserGroup->memberUIDExists($USER->uid)); } function ensureOrgGroupDoesNotExist() From 6493b977433c8dbc189e74c82281081e0c75839f Mon Sep 17 00:00:00 2001 From: Simon Leary Date: Mon, 15 Dec 2025 13:27:28 -0500 Subject: [PATCH 02/18] modifiers --- defaults/config.ini.default | 10 ++++---- resources/init.php | 2 +- resources/lib/UnityGroup.php | 4 ++-- resources/lib/UnityLDAP.php | 27 +++++---------------- resources/lib/UnityUser.php | 30 ++++++++++-------------- test/functional/PIBecomeApproveTest.php | 2 +- test/functional/PiMemberApproveTest.php | 4 ++-- test/functional/ViewAsUserTest.php | 4 ++-- test/phpunit-bootstrap.php | 4 ++-- webroot/admin/ajax/get_group_members.php | 2 +- webroot/admin/ajax/get_page_contents.php | 2 +- webroot/admin/content.php | 2 +- webroot/admin/notices.php | 2 +- webroot/admin/pi-mgmt.php | 2 +- webroot/admin/user-mgmt.php | 2 +- webroot/panel/account.php | 2 +- 16 files changed, 40 insertions(+), 61 deletions(-) diff --git a/defaults/config.ini.default b/defaults/config.ini.default index 75065505..4f216c01 100644 --- a/defaults/config.ini.default +++ b/defaults/config.ini.default @@ -31,15 +31,15 @@ user_ou = "ou=users,dc=unityhpc,dc=test" ; User organizational unit (may contai group_ou = "ou=groups,dc=unityhpc,dc=test" ; Group organizational unit pigroup_ou = "ou=pi_groups,dc=unityhpc,dc=test" ; PI Group organizational unit orggroup_ou = "ou=org_groups,dc=unityhpc,dc=test" ; ORG group organizational unit -admin_group = "cn=web_admins,dc=unityhpc,dc=test" ; admin dn (members of this group are admins on the web portal) -qualified_user_group = "cn=unityusers,dc=unityhpc,dc=test" ; Qualified user group (in at least one PI group) -locked_user_group = "cn=locked,dc=unityhpc,dc=test" ; locked user group dn -idlelocked_user_group = "cn=idlelocked,dc=unityhpc,dc=test" ; idlelocked user group dn -ghost_user_group = "cn=ghost,dc=unityhpc,dc=test" ; ghost user group dn def_user_shell = "/bin/bash" ; Default shell for new users offset_UIDGID = 1000000 ; start point when allocating new UID/GID pairs for a new user offset_PIGID = 2000000 ; start point when allocating new GID for a new PI group offset_ORGGID = 3000000 ; start point when allocating new GID for a new org group +user_modifier_groups[admin] = "cn=web_admins,dc=unityhpc,dc=test" ; admin user group dn +user_modifier_groups[ghost] = "cn=ghost,dc=unityhpc,dc=test" ; ghost user group dn +user_modifier_groups[idlelocked] = "cn=idlelocked,dc=unityhpc,dc=test" ; idlelocked user group dn +user_modifier_groups[locked] = "cn=locked,dc=unityhpc,dc=test" ; locked user group dn +user_modifier_groups[qualified] = "cn=unityusers,dc=unityhpc,dc=test" ; qualified user group (in at least one PI group) [sql] host = "sql" ; mariadb hostname diff --git a/resources/init.php b/resources/init.php index b4c2f20d..54cf53c6 100644 --- a/resources/init.php +++ b/resources/init.php @@ -56,7 +56,7 @@ $_SESSION["SSO"] = $SSO; $OPERATOR = new UnityUser($SSO["user"], $LDAP, $SQL, $MAILER, $WEBHOOK); - $_SESSION["is_admin"] = $OPERATOR->isAdmin(); + $_SESSION["is_admin"] = $OPERATOR->getModifier("admin"); if (isset($_SESSION["viewUser"]) && $_SESSION["is_admin"]) { $USER = new UnityUser($_SESSION["viewUser"], $LDAP, $SQL, $MAILER, $WEBHOOK); diff --git a/resources/lib/UnityGroup.php b/resources/lib/UnityGroup.php index 04f6e8e0..c6ea0f07 100644 --- a/resources/lib/UnityGroup.php +++ b/resources/lib/UnityGroup.php @@ -85,7 +85,7 @@ public function approveGroup(?UnityUser $operator = null, bool $send_mail = true if ($send_mail) { $this->MAILER->sendMail($this->getOwner()->getMail(), "group_created"); } - $this->getOwner()->setIsQualified(true); // having your own group makes you qualified + $this->getOwner()->setModifier("qualified", true); // having your own group makes you qualified } /** @@ -191,7 +191,7 @@ public function approveUser(UnityUser $new_user, bool $send_mail = true): void "org" => $new_user->getOrg(), ]); } - $new_user->setIsQualified(true); // being in a group makes you qualified + $new_user->setModifier("qualified", true); // being in a group makes you qualified } public function denyUser(UnityUser $new_user, bool $send_mail = true): void diff --git a/resources/lib/UnityLDAP.php b/resources/lib/UnityLDAP.php index 1d395c6a..30e04081 100644 --- a/resources/lib/UnityLDAP.php +++ b/resources/lib/UnityLDAP.php @@ -37,11 +37,7 @@ class UnityLDAP extends LDAPConn private LDAPEntry $pi_groupOU; private LDAPEntry $org_groupOU; - public PosixGroup $adminGroup; - public PosixGroup $qualifiedUserGroup; - public PosixGroup $lockedUserGroup; - public PosixGroup $idlelockedUserGroup; - public PosixGroup $ghostUserGroup; + public array $userModifierGroups; public function __construct() { @@ -51,21 +47,10 @@ public function __construct() $this->groupOU = $this->getEntry(CONFIG["ldap"]["group_ou"]); $this->pi_groupOU = $this->getEntry(CONFIG["ldap"]["pigroup_ou"]); $this->org_groupOU = $this->getEntry(CONFIG["ldap"]["orggroup_ou"]); - $this->adminGroup = new PosixGroup( - new LDAPEntry($this->conn, CONFIG["ldap"]["admin_group"]), - ); - $this->qualifiedUserGroup = new PosixGroup( - new LDAPEntry($this->conn, CONFIG["ldap"]["qualified_user_group"]), - ); - $this->lockedUserGroup = new PosixGroup( - new LDAPEntry($this->conn, CONFIG["ldap"]["locked_user_group"]), - ); - $this->idlelockedUserGroup = new PosixGroup( - new LDAPEntry($this->conn, CONFIG["ldap"]["idlelocked_user_group"]), - ); - $this->ghostUserGroup = new PosixGroup( - new LDAPEntry($this->conn, CONFIG["ldap"]["ghost_user_group"]), - ); + $this->userModifierGroups = []; + foreach (CONFIG["ldap"]["user_modifier_groups"] as $gid => $dn) { + $this->userModifierGroups[$gid] = new PosixGroup(new LDAPEntry($this->conn, $dn)); + } } public function getUserOU(): LDAPEntry @@ -199,7 +184,7 @@ public function getQualifiedUsersUIDs(): array { // should not use $user_ou->getChildren or $base_ou->getChildren(objectClass=posixAccount) // qualified users might be outside user ou, and not all users in LDAP tree are qualified users - return $this->qualifiedUserGroup->getMemberUIDs(); + return $this->userModifierGroups["qualified"]->getMemberUIDs(); } public function getQualifiedUsers($UnitySQL, $UnityMailer, $UnityWebhook): array diff --git a/resources/lib/UnityUser.php b/resources/lib/UnityUser.php index d1795097..642332dd 100644 --- a/resources/lib/UnityUser.php +++ b/resources/lib/UnityUser.php @@ -97,31 +97,33 @@ public function init( $this->SQL->addLog($this->uid, $_SERVER["REMOTE_ADDR"], "user_added", $this->uid); } - public function isQualified(): bool + public function getModifier($modifier): bool { - return $this->LDAP->qualifiedUserGroup->memberUIDExists($this->uid); + return $this->LDAP->userModifierGroups[$modifier]->memberUIDExists($this->uid); } - public function setIsQualified(bool $newIsQualified, bool $doSendMail = true): void + public function setModifier($modifier, bool $newValue, bool $doSendMail = true): void { - $oldIsQualified = $this->isQualified(); - if ($oldIsQualified == $newIsQualified) { + $oldValue = $this->getModifier($modifier); + if ($oldValue == $newValue) { return; } - if ($newIsQualified) { - $this->LDAP->qualifiedUserGroup->addMemberUID($this->uid); + if ($newValue) { + $this->LDAP->userModifierGroups[$modifier]->addMemberUID($this->uid); if ($doSendMail) { - $this->MAILER->sendMail($this->getMail(), "user_qualified", [ + $this->MAILER->sendMail($this->getMail(), "user_modifier_added", [ "user" => $this->uid, "org" => $this->getOrg(), + "modifier" => $modifier, ]); } } else { - $this->LDAP->qualifiedUserGroup->removeMemberUID($this->uid); + $this->LDAP->userModifierGroups[$modifier]->removeMemberUID($this->uid); if ($doSendMail) { - $this->MAILER->sendMail($this->getMail(), "user_dequalified", [ + $this->MAILER->sendMail($this->getMail(), "user_modifier_removed", [ "user" => $this->uid, "org" => $this->getOrg(), + "modifier" => $modifier, ]); } } @@ -315,14 +317,6 @@ public function getHomeDir(): string return $this->entry->getAttribute("homedirectory"); } - /** - * Checks if the current account is an admin - */ - public function isAdmin(): bool - { - return $this->LDAP->adminGroup->memberUIDExists($this->uid); - } - /** * Checks if current user is a PI */ diff --git a/test/functional/PIBecomeApproveTest.php b/test/functional/PIBecomeApproveTest.php index afe7a9e3..451853e7 100644 --- a/test/functional/PIBecomeApproveTest.php +++ b/test/functional/PIBecomeApproveTest.php @@ -64,7 +64,7 @@ public function testApprovePI() $this->assertRequestedPIGroup(false); $this->assertTrue($pi_group->exists()); - $this->assertTrue($USER->isQualified()); + $this->assertTrue($USER->getModifier("qualified")); // $third_request_failed = false; // try { diff --git a/test/functional/PiMemberApproveTest.php b/test/functional/PiMemberApproveTest.php index 51e90acb..06639843 100644 --- a/test/functional/PiMemberApproveTest.php +++ b/test/functional/PiMemberApproveTest.php @@ -107,7 +107,7 @@ public function testApproveMemberByPI() $this->assertTrue(!$pi_group->requestExists($USER)); $this->assertRequestedMembership(false, $gid); $this->assertTrue($pi_group->memberUIDExists($USER->uid)); - $this->assertTrue($USER->isQualified()); + $this->assertTrue($USER->getModifier("qualified")); // $third_request_failed = false; // try { @@ -167,7 +167,7 @@ public function testApproveMemberByAdmin() $this->assertTrue(!$pi_group->requestExists($USER)); $this->assertRequestedMembership(false, $gid); $this->assertTrue($pi_group->memberUIDExists($USER->uid)); - $this->assertTrue($USER->isQualified()); + $this->assertTrue($USER->getModifier("qualified")); // $third_request_failed = false; // try { diff --git a/test/functional/ViewAsUserTest.php b/test/functional/ViewAsUserTest.php index 43b1caad..b49a8984 100644 --- a/test/functional/ViewAsUserTest.php +++ b/test/functional/ViewAsUserTest.php @@ -10,7 +10,7 @@ public function _testViewAsUser(array $beforeUser, array $afterUser) switchUser(...$afterUser); $afterUid = $USER->uid; switchUser(...$beforeUser); - // $this->assertTrue($USER->isAdmin()); + // $this->assertTrue($USER->getModifier("admin")); $beforeUid = $USER->uid; // $this->assertNotEquals($afterUid, $beforeUid); http_post(__DIR__ . "/../../webroot/admin/user-mgmt.php", [ @@ -57,7 +57,7 @@ public function testNonAdminViewAsAdmin() global $USER; switchUser(...getAdminUser()); $adminUid = $USER->uid; - $this->assertTrue($USER->isAdmin()); + $this->assertTrue($USER->getModifier("admin")); switchUser(...getNormalUser()); http_post(__DIR__ . "/../../webroot/admin/user-mgmt.php", [ "form_type" => "viewAsUser", diff --git a/test/phpunit-bootstrap.php b/test/phpunit-bootstrap.php index 0cece051..d63c53fa 100644 --- a/test/phpunit-bootstrap.php +++ b/test/phpunit-bootstrap.php @@ -195,8 +195,8 @@ function ensureUserDoesNotExist() $USER->getGroupEntry()->delete(); ensure(!$USER->getGroupEntry()->exists()); } - $USER->setIsQualified(false); - ensure(!$LDAP->qualifiedUserGroup->memberUIDExists($USER->uid)); + $USER->setModifier("qualified", false); + ensure(!$LDAP->userModifierGroups["qualified"]->memberUIDExists($USER->uid)); } function ensureOrgGroupDoesNotExist() diff --git a/webroot/admin/ajax/get_group_members.php b/webroot/admin/ajax/get_group_members.php index e9076043..f815c7c2 100644 --- a/webroot/admin/ajax/get_group_members.php +++ b/webroot/admin/ajax/get_group_members.php @@ -5,7 +5,7 @@ use UnityWebPortal\lib\UnityGroup; use UnityWebPortal\lib\UnityHTTPD; -if (!$USER->isAdmin()) { +if (!$USER->getModifier("admin")) { UnityHTTPD::forbidden("not an admin"); } diff --git a/webroot/admin/ajax/get_page_contents.php b/webroot/admin/ajax/get_page_contents.php index a26a9e59..d9077720 100644 --- a/webroot/admin/ajax/get_page_contents.php +++ b/webroot/admin/ajax/get_page_contents.php @@ -4,7 +4,7 @@ use UnityWebPortal\lib\UnityHTTPD; -if (!$USER->isAdmin()) { +if (!$USER->getModifier("admin")) { UnityHTTPD::forbidden("not an admin"); } diff --git a/webroot/admin/content.php b/webroot/admin/content.php index 7159681d..5c060554 100644 --- a/webroot/admin/content.php +++ b/webroot/admin/content.php @@ -4,7 +4,7 @@ use UnityWebPortal\lib\UnityHTTPD; -if (!$USER->isAdmin()) { +if (!$USER->getModifier("admin")) { UnityHTTPD::forbidden("not an admin"); } diff --git a/webroot/admin/notices.php b/webroot/admin/notices.php index e258670f..e35416d4 100644 --- a/webroot/admin/notices.php +++ b/webroot/admin/notices.php @@ -4,7 +4,7 @@ use UnityWebPortal\lib\UnityHTTPD; -if (!$USER->isAdmin()) { +if (!$USER->getModifier("admin")) { UnityHTTPD::forbidden("not an admin"); } diff --git a/webroot/admin/pi-mgmt.php b/webroot/admin/pi-mgmt.php index ec388b0e..21ad3b97 100644 --- a/webroot/admin/pi-mgmt.php +++ b/webroot/admin/pi-mgmt.php @@ -7,7 +7,7 @@ use UnityWebPortal\lib\UnityHTTPD; use UnityWebPortal\lib\UnitySQL; -if (!$USER->isAdmin()) { +if (!$USER->getModifier("admin")) { UnityHTTPD::forbidden("not an admin"); } diff --git a/webroot/admin/user-mgmt.php b/webroot/admin/user-mgmt.php index e969f9bf..529cd2ce 100644 --- a/webroot/admin/user-mgmt.php +++ b/webroot/admin/user-mgmt.php @@ -4,7 +4,7 @@ use UnityWebPortal\lib\UnityHTTPD; -if (!$USER->isAdmin()) { +if (!$USER->getModifier("admin")) { UnityHTTPD::forbidden("not an admin"); } diff --git a/webroot/panel/account.php b/webroot/panel/account.php index aef71339..2fac54af 100644 --- a/webroot/panel/account.php +++ b/webroot/panel/account.php @@ -130,7 +130,7 @@ echo "

You are curently a principal investigator on the UnityHPC Platform

"; -} elseif ($USER->isQualified()) { +} elseif ($USER->getModifier("qualified")) { echo "

You are curently a qualified user on the UnityHPC Platform

"; } else { $tos_url = CONFIG["site"]["terms_of_service_url"]; From 7ab6665b2b1b83cf44136b45515e50c98c5f8b4a Mon Sep 17 00:00:00 2001 From: Simon Leary Date: Mon, 15 Dec 2025 14:58:27 -0500 Subject: [PATCH 03/18] setup mail templates --- .pre-commit-config.yaml | 3 ++ resources/lib/UnityGroup.php | 3 +- resources/lib/UnityUser.php | 22 +++++++- resources/mail/user_dequalified.php | 10 ---- resources/mail/user_modifier_added.php | 54 +++++++++++++++++++ resources/mail/user_modifier_added_admin.php | 39 ++++++++++++++ resources/mail/user_modifier_removed.php | 44 +++++++++++++++ .../mail/user_modifier_removed_admin.php | 39 ++++++++++++++ resources/mail/user_qualified.php | 22 -------- 9 files changed, 201 insertions(+), 35 deletions(-) delete mode 100644 resources/mail/user_dequalified.php create mode 100644 resources/mail/user_modifier_added.php create mode 100644 resources/mail/user_modifier_added_admin.php create mode 100644 resources/mail/user_modifier_removed.php create mode 100644 resources/mail/user_modifier_removed_admin.php delete mode 100644 resources/mail/user_qualified.php diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b24dd63d..3622c294 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -31,6 +31,7 @@ repos: resources/lib/phpopenldaper/.*| vendor/.*| resources/lib/.*| + resources/mail/.*| )$ - repo: https://github.com/rbubley/mirrors-prettier @@ -47,6 +48,7 @@ repos: vendor/.*| resources/templates/.*| webroot/.*| + resources/mail/.*| )$ # linters (work required) ######################################################################## @@ -81,6 +83,7 @@ repos: resources/lib/phpopenldaper/.*| vendor/.*| resources/lib/.*| + resources/mail/.*| )$ - id: php-l name: php -l diff --git a/resources/lib/UnityGroup.php b/resources/lib/UnityGroup.php index c6ea0f07..38145664 100644 --- a/resources/lib/UnityGroup.php +++ b/resources/lib/UnityGroup.php @@ -191,7 +191,8 @@ public function approveUser(UnityUser $new_user, bool $send_mail = true): void "org" => $new_user->getOrg(), ]); } - $new_user->setModifier("qualified", true); // being in a group makes you qualified + // being in a group makes you qualified + $new_user->setModifier("qualified", true, true, false); } public function denyUser(UnityUser $new_user, bool $send_mail = true): void diff --git a/resources/lib/UnityUser.php b/resources/lib/UnityUser.php index 642332dd..b3395841 100644 --- a/resources/lib/UnityUser.php +++ b/resources/lib/UnityUser.php @@ -102,8 +102,12 @@ public function getModifier($modifier): bool return $this->LDAP->userModifierGroups[$modifier]->memberUIDExists($this->uid); } - public function setModifier($modifier, bool $newValue, bool $doSendMail = true): void - { + public function setModifier( + $modifier, + bool $newValue, + bool $doSendMail = true, + bool $doSendMailAdmin = true, + ): void { $oldValue = $this->getModifier($modifier); if ($oldValue == $newValue) { return; @@ -117,6 +121,13 @@ public function setModifier($modifier, bool $newValue, bool $doSendMail = true): "modifier" => $modifier, ]); } + if ($doSendMailAdmin) { + $this->MAILER->sendMail($this->getMail(), "user_modifier_added_admin", [ + "user" => $this->uid, + "org" => $this->getOrg(), + "modifier" => $modifier, + ]); + } } else { $this->LDAP->userModifierGroups[$modifier]->removeMemberUID($this->uid); if ($doSendMail) { @@ -126,6 +137,13 @@ public function setModifier($modifier, bool $newValue, bool $doSendMail = true): "modifier" => $modifier, ]); } + if ($doSendMailAdmin) { + $this->MAILER->sendMail($this->getMail(), "user_modifier_removed_admin", [ + "user" => $this->uid, + "org" => $this->getOrg(), + "modifier" => $modifier, + ]); + } } } diff --git a/resources/mail/user_dequalified.php b/resources/mail/user_dequalified.php deleted file mode 100644 index 73677ab0..00000000 --- a/resources/mail/user_dequalified.php +++ /dev/null @@ -1,10 +0,0 @@ -Subject = "User Deactivated"; ?> - -

Hello,

- -

Your account on the UnityHPC Platform has been deactivated.

- -

If you believe this to be a mistake, please reply to this email as soon as possible.

diff --git a/resources/mail/user_modifier_added.php b/resources/mail/user_modifier_added.php new file mode 100644 index 00000000..a0839130 --- /dev/null +++ b/resources/mail/user_modifier_added.php @@ -0,0 +1,54 @@ + +Subject = "User Activated"; ?> +

Hello,

+

Your account on the UnityHPC Platform has been activated. Your account details are below:

+

+Username +
+Organization +

+

+See the +">Getting Started +page in our documentation for next steps. +

+

If you believe this to be a mistake, please reply to this email as soon as possible.

+ + + + +Subject = "User Deleted"; ?> +

Hello,

+

Your account on the UnityHPC Platform has been deleted.

+

If you believe this to be a mistake, please reply to this email as soon as possible.

+ + + + +Subject = "User Locked"; ?> +

Hello,

+

Your account on the UnityHPC Platform has been locked.

+

If you believe this to be a mistake, please reply to this email as soon as possible.

+ + + + +Subject = "User Locked"; ?> +

Hello,

+

Your account on the UnityHPC Platform has been locked due to inactivity.

+

If you believe this to be a mistake, please reply to this email as soon as possible.

+ + + + +Subject = "User Promoted"; ?> +

Hello,

+

Your account on the UnityHPC Platform has been promoted to admin.

+

If you believe this to be a mistake, please reply to this email as soon as possible.

+ + + + + + diff --git a/resources/mail/user_modifier_added_admin.php b/resources/mail/user_modifier_added_admin.php new file mode 100644 index 00000000..99cc8691 --- /dev/null +++ b/resources/mail/user_modifier_added_admin.php @@ -0,0 +1,39 @@ + +Subject = "User Qualified"; ?> +

Hello,

+

User "" has been qualified.

+ + + + +Subject = "User Ghosted"; ?> +

Hello,

+

User "" has been marked as ghost.

+ + + + +Subject = "User Locked"; ?> +

Hello,

+

User "" has been locked.

+ + + + +Subject = "User Idle Locked"; ?> +

Hello,

+

User "" has been idle locked.

+ + + + +Subject = "User Promoted"; ?> +

Hello,

+

User "" has been promoted to admin.

+ + + + + + diff --git a/resources/mail/user_modifier_removed.php b/resources/mail/user_modifier_removed.php new file mode 100644 index 00000000..d625445f --- /dev/null +++ b/resources/mail/user_modifier_removed.php @@ -0,0 +1,44 @@ + +Subject = "User Deactivated"; ?> +

Hello,

+

Your account on the UnityHPC Platform has been deactivated.

+

If you believe this to be a mistake, please reply to this email as soon as possible.

+ + + + +Subject = "User Resurrected"; ?> +

Hello,

+

Your account on the UnityHPC Platform has been resurrected.

+

If you believe this to be a mistake, please reply to this email as soon as possible.

+ + + + +Subject = "User Unlocked"; ?> +

Hello,

+

Your account on the UnityHPC Platform has been unlocked.

+

If you believe this to be a mistake, please reply to this email as soon as possible.

+ + + + +Subject = "User Unlocked"; ?> +

Hello,

+

Your account on the UnityHPC Platform has been unlocked.

+

If you believe this to be a mistake, please reply to this email as soon as possible.

+ + + + +Subject = "User Demoted"; ?> +

Hello,

+

Your account on the UnityHPC Platform has been demoted from admin.

+

If you believe this to be a mistake, please reply to this email as soon as possible.

+ + + + + + diff --git a/resources/mail/user_modifier_removed_admin.php b/resources/mail/user_modifier_removed_admin.php new file mode 100644 index 00000000..1aac930d --- /dev/null +++ b/resources/mail/user_modifier_removed_admin.php @@ -0,0 +1,39 @@ + +Subject = "User Dequalified"; ?> +

Hello,

+

User "" has been dequalified.

+ + + + +Subject = "User Resurrected"; ?> +

Hello,

+

User "" has been resurrected (no longer marked as ghost).

+ + + + +Subject = "User Unlocked"; ?> +

Hello,

+

User "" has been unlocked.

+ + + + +Subject = "User Idle Unlocked"; ?> +

Hello,

+

User "" has been idle unlocked.

+ + + + +Subject = "User Demoted"; ?> +

Hello,

+

User "" has been demoted from admin.

+ + + + + + diff --git a/resources/mail/user_qualified.php b/resources/mail/user_qualified.php deleted file mode 100644 index c6739fec..00000000 --- a/resources/mail/user_qualified.php +++ /dev/null @@ -1,22 +0,0 @@ -Subject = "User Activated"; ?> - -

Hello,

- -

Your account on the UnityHPC Platform has been activated. Your account details are below:

- -

-Username -
-Organization -

- -

-See the -">Getting Started -page in our documentation for next steps. -

- -

If you believe this to be a mistake, please reply to this email as soon as possible.

From 080d6170e802240358db96820a834816fc984f24 Mon Sep 17 00:00:00 2001 From: Simon Leary Date: Mon, 15 Dec 2025 15:07:36 -0500 Subject: [PATCH 04/18] explicit --- resources/lib/UnityGroup.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/lib/UnityGroup.php b/resources/lib/UnityGroup.php index 38145664..a5823aed 100644 --- a/resources/lib/UnityGroup.php +++ b/resources/lib/UnityGroup.php @@ -192,7 +192,7 @@ public function approveUser(UnityUser $new_user, bool $send_mail = true): void ]); } // being in a group makes you qualified - $new_user->setModifier("qualified", true, true, false); + $new_user->setModifier("qualified", true, doSendMail: true, doSendMailAdmin: false); } public function denyUser(UnityUser $new_user, bool $send_mail = true): void From 256b5d10e621baacf4abf40d0e470c92137c45a6 Mon Sep 17 00:00:00 2001 From: Simon Leary Date: Mon, 15 Dec 2025 15:12:24 -0500 Subject: [PATCH 05/18] migration instructions --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 8a65ec4c..6728c59d 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,8 @@ rm "$prod" && ln -s "$old" "$prod" ### 1.5.0 -> 1.5.1 - the `[site]getting_started_url` option should be defined +- the `[ldap]admin_group` option has been renamed to `[ldap]user_modifier_groups[admin]` +- the `[ldap]qualified_user_group` option has been renamed to `[ldap]user_modifier_groups[qualified]` ### 1.4 -> 1.5 From d5d03c5e7c4aba058eb97a00893c34c9a938038e Mon Sep 17 00:00:00 2001 From: Simon Leary Date: Mon, 15 Dec 2025 15:15:10 -0500 Subject: [PATCH 06/18] remove unused functions --- resources/lib/UnityLDAP.php | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/resources/lib/UnityLDAP.php b/resources/lib/UnityLDAP.php index 30e04081..76884393 100644 --- a/resources/lib/UnityLDAP.php +++ b/resources/lib/UnityLDAP.php @@ -180,31 +180,11 @@ private function getAllGIDNumbersInUse(): array ); } - public function getQualifiedUsersUIDs(): array - { - // should not use $user_ou->getChildren or $base_ou->getChildren(objectClass=posixAccount) - // qualified users might be outside user ou, and not all users in LDAP tree are qualified users - return $this->userModifierGroups["qualified"]->getMemberUIDs(); - } - - public function getQualifiedUsers($UnitySQL, $UnityMailer, $UnityWebhook): array - { - $out = []; - - $qualifiedUsers = $this->getQualifiedUsersUIDs(); - sort($qualifiedUsers); - foreach ($qualifiedUsers as $user) { - $params = [$user, $this, $UnitySQL, $UnityMailer, $UnityWebhook]; - array_push($out, new UnityUser(...$params)); - } - return $out; - } - public function getQualifiedUsersAttributes( array $attributes, array $default_values = [], ): array { - $include_uids = $this->getQualifiedUsersUIDs(); + $include_uids = $this->userModifierGroups["qualified"]->getMemberUIDs(); $user_attributes = $this->baseOU->getChildrenArrayStrict( $attributes, true, // recursive @@ -301,7 +281,7 @@ public function getAllPIGroupOwnerAttributes( public function getQualifiedUID2PIGIDs(): array { // initialize output so each UID is a key with an empty array as its value - $uids = $this->getQualifiedUsersUIDs(); + $uids = $this->userModifierGroups["qualified"]->getMemberUIDs(); $uid2pigids = array_combine($uids, array_fill(0, count($uids), [])); // for each PI group, append that GID to the member list for each of its member UIDs foreach ( From 3770915d657ec8951d2f82124dc6f4a51b4dc419 Mon Sep 17 00:00:00 2001 From: Simon Leary Date: Mon, 15 Dec 2025 15:23:24 -0500 Subject: [PATCH 07/18] add new posixGroups to LDAP, group OUs together --- tools/docker-dev/identity/bootstrap.ldif | 56 ++++++++++++++++-------- 1 file changed, 37 insertions(+), 19 deletions(-) diff --git a/tools/docker-dev/identity/bootstrap.ldif b/tools/docker-dev/identity/bootstrap.ldif index 3043db2b..535f9d88 100644 --- a/tools/docker-dev/identity/bootstrap.ldif +++ b/tools/docker-dev/identity/bootstrap.ldif @@ -1,3 +1,24 @@ +dn: ou=org_groups,dc=unityhpc,dc=test +objectclass: organizationalUnit +objectclass: top +ou: org_groups + +dn: ou=groups,dc=unityhpc,dc=test +objectclass: organizationalUnit +objectclass: top +ou: groups + +dn: ou=pi_groups,dc=unityhpc,dc=test +objectclass: organizationalUnit +objectclass: top +ou: pi_groups + +dn: ou=users,dc=unityhpc,dc=test +description: Holds all posix accounts. +objectclass: organizationalUnit +objectclass: top +ou: users + dn: dc=unityhpc,dc=test objectClass: top objectClass: dcObject @@ -31,10 +52,23 @@ memberuid: user14_org3_test objectclass: posixGroup objectclass: top -dn: ou=groups,dc=unityhpc,dc=test -objectclass: organizationalUnit +dn: cn=locked,dc=unityhpc,dc=test +cn: locked +gidnumber: 502 +objectclass: posixGroup +objectclass: top + +dn: cn=idlelocked,dc=unityhpc,dc=test +cn: idlelocked +gidnumber: 503 +objectclass: posixGroup +objectclass: top + +dn: cn=ghost,dc=unityhpc,dc=test +cn: ghost +gidnumber: 504 +objectclass: posixGroup objectclass: top -ou: groups dn: cn=unityusers,dc=unityhpc,dc=test cn: unityusers @@ -9183,11 +9217,6 @@ gidnumber: 33130 objectclass: posixGroup objectclass: top -dn: ou=org_groups,dc=unityhpc,dc=test -objectclass: organizationalUnit -objectclass: top -ou: org_groups - dn: cn=org11_test,ou=org_groups,dc=unityhpc,dc=test cn: org11_test gidnumber: 20007 @@ -10577,11 +10606,6 @@ memberuid: user494_org8_test objectclass: posixGroup objectclass: top -dn: ou=pi_groups,dc=unityhpc,dc=test -objectclass: organizationalUnit -objectclass: top -ou: pi_groups - dn: cn=pi_user36_org2_test,ou=pi_groups,dc=unityhpc,dc=test cn: pi_user36_org2_test gidnumber: 10206 @@ -13490,12 +13514,6 @@ memberuid: user1298_org1_test objectclass: posixGroup objectclass: top -dn: ou=users,dc=unityhpc,dc=test -description: Holds all posix accounts. -objectclass: organizationalUnit -objectclass: top -ou: users - dn: cn=user15_org3_test,ou=users,dc=unityhpc,dc=test cn: user15_org3_test gidnumber: 1813 From f55c407a99f8025f4b02b35470702091cfd0efde Mon Sep 17 00:00:00 2001 From: Simon Leary Date: Tue, 16 Dec 2025 08:18:07 -0500 Subject: [PATCH 08/18] add missing semicolon --- resources/mail/user_modifier_added.php | 2 +- resources/mail/user_modifier_added_admin.php | 2 +- resources/mail/user_modifier_removed.php | 2 +- resources/mail/user_modifier_removed_admin.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/mail/user_modifier_added.php b/resources/mail/user_modifier_added.php index a0839130..7431accf 100644 --- a/resources/mail/user_modifier_added.php +++ b/resources/mail/user_modifier_added.php @@ -50,5 +50,5 @@ - + diff --git a/resources/mail/user_modifier_added_admin.php b/resources/mail/user_modifier_added_admin.php index 99cc8691..42034edf 100644 --- a/resources/mail/user_modifier_added_admin.php +++ b/resources/mail/user_modifier_added_admin.php @@ -35,5 +35,5 @@ - + diff --git a/resources/mail/user_modifier_removed.php b/resources/mail/user_modifier_removed.php index d625445f..8ac02020 100644 --- a/resources/mail/user_modifier_removed.php +++ b/resources/mail/user_modifier_removed.php @@ -40,5 +40,5 @@ - + diff --git a/resources/mail/user_modifier_removed_admin.php b/resources/mail/user_modifier_removed_admin.php index 1aac930d..21586baa 100644 --- a/resources/mail/user_modifier_removed_admin.php +++ b/resources/mail/user_modifier_removed_admin.php @@ -35,5 +35,5 @@ - + From 2f75f0ed51daaa2a960b3980aea67a5afe8e4189 Mon Sep 17 00:00:00 2001 From: Simon Leary Date: Tue, 16 Dec 2025 08:18:15 -0500 Subject: [PATCH 09/18] add type declaration --- resources/lib/UnityUser.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/lib/UnityUser.php b/resources/lib/UnityUser.php index b3395841..c51688d8 100644 --- a/resources/lib/UnityUser.php +++ b/resources/lib/UnityUser.php @@ -97,13 +97,13 @@ public function init( $this->SQL->addLog($this->uid, $_SERVER["REMOTE_ADDR"], "user_added", $this->uid); } - public function getModifier($modifier): bool + public function getModifier(string $modifier): bool { return $this->LDAP->userModifierGroups[$modifier]->memberUIDExists($this->uid); } public function setModifier( - $modifier, + string $modifier, bool $newValue, bool $doSendMail = true, bool $doSendMailAdmin = true, From 0e33973a879c3721c2b15d5af22cb3925350087a Mon Sep 17 00:00:00 2001 From: Simon Leary Date: Tue, 16 Dec 2025 08:20:46 -0500 Subject: [PATCH 10/18] fix mail recipient --- resources/lib/UnityUser.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/lib/UnityUser.php b/resources/lib/UnityUser.php index c51688d8..161ba6c1 100644 --- a/resources/lib/UnityUser.php +++ b/resources/lib/UnityUser.php @@ -122,7 +122,7 @@ public function setModifier( ]); } if ($doSendMailAdmin) { - $this->MAILER->sendMail($this->getMail(), "user_modifier_added_admin", [ + $this->MAILER->sendMail("admin", "user_modifier_added_admin", [ "user" => $this->uid, "org" => $this->getOrg(), "modifier" => $modifier, @@ -138,7 +138,7 @@ public function setModifier( ]); } if ($doSendMailAdmin) { - $this->MAILER->sendMail($this->getMail(), "user_modifier_removed_admin", [ + $this->MAILER->sendMail("admin", "user_modifier_removed_admin", [ "user" => $this->uid, "org" => $this->getOrg(), "modifier" => $modifier, From 306a5cf73dc4e97ab0c20f792e533240eb3fac40 Mon Sep 17 00:00:00 2001 From: Simon Leary Date: Tue, 16 Dec 2025 08:28:57 -0500 Subject: [PATCH 11/18] "modifier" -> "flag" --- README.md | 4 +-- defaults/config.ini.default | 10 +++---- resources/init.php | 2 +- resources/lib/UnityGroup.php | 4 +-- resources/lib/UnityLDAP.php | 12 ++++---- resources/lib/UnityUser.php | 30 +++++++++---------- ...modifier_added.php => user_flag_added.php} | 4 +-- ...ed_admin.php => user_flag_added_admin.php} | 4 +-- ...fier_removed.php => user_flag_removed.php} | 4 +-- ..._admin.php => user_flag_removed_admin.php} | 4 +-- test/functional/PIBecomeApproveTest.php | 2 +- test/functional/PiMemberApproveTest.php | 4 +-- test/functional/ViewAsUserTest.php | 4 +-- test/phpunit-bootstrap.php | 4 +-- webroot/admin/ajax/get_group_members.php | 2 +- webroot/admin/ajax/get_page_contents.php | 2 +- webroot/admin/content.php | 2 +- webroot/admin/notices.php | 2 +- webroot/admin/pi-mgmt.php | 2 +- webroot/admin/user-mgmt.php | 2 +- webroot/panel/account.php | 2 +- 21 files changed, 53 insertions(+), 53 deletions(-) rename resources/mail/{user_modifier_added.php => user_flag_added.php} (95%) rename resources/mail/{user_modifier_added_admin.php => user_flag_added_admin.php} (92%) rename resources/mail/{user_modifier_removed.php => user_flag_removed.php} (94%) rename resources/mail/{user_modifier_removed_admin.php => user_flag_removed_admin.php} (92%) diff --git a/README.md b/README.md index 6728c59d..4edbdcc5 100644 --- a/README.md +++ b/README.md @@ -120,8 +120,8 @@ rm "$prod" && ln -s "$old" "$prod" ### 1.5.0 -> 1.5.1 - the `[site]getting_started_url` option should be defined -- the `[ldap]admin_group` option has been renamed to `[ldap]user_modifier_groups[admin]` -- the `[ldap]qualified_user_group` option has been renamed to `[ldap]user_modifier_groups[qualified]` +- the `[ldap]admin_group` option has been renamed to `[ldap]user_flag_groups[admin]` +- the `[ldap]qualified_user_group` option has been renamed to `[ldap]user_flag_groups[qualified]` ### 1.4 -> 1.5 diff --git a/defaults/config.ini.default b/defaults/config.ini.default index 4f216c01..c826c779 100644 --- a/defaults/config.ini.default +++ b/defaults/config.ini.default @@ -35,11 +35,11 @@ def_user_shell = "/bin/bash" ; Default shell for new users offset_UIDGID = 1000000 ; start point when allocating new UID/GID pairs for a new user offset_PIGID = 2000000 ; start point when allocating new GID for a new PI group offset_ORGGID = 3000000 ; start point when allocating new GID for a new org group -user_modifier_groups[admin] = "cn=web_admins,dc=unityhpc,dc=test" ; admin user group dn -user_modifier_groups[ghost] = "cn=ghost,dc=unityhpc,dc=test" ; ghost user group dn -user_modifier_groups[idlelocked] = "cn=idlelocked,dc=unityhpc,dc=test" ; idlelocked user group dn -user_modifier_groups[locked] = "cn=locked,dc=unityhpc,dc=test" ; locked user group dn -user_modifier_groups[qualified] = "cn=unityusers,dc=unityhpc,dc=test" ; qualified user group (in at least one PI group) +user_flag_groups[admin] = "cn=web_admins,dc=unityhpc,dc=test" ; admin user group dn +user_flag_groups[ghost] = "cn=ghost,dc=unityhpc,dc=test" ; ghost user group dn +user_flag_groups[idlelocked] = "cn=idlelocked,dc=unityhpc,dc=test" ; idlelocked user group dn +user_flag_groups[locked] = "cn=locked,dc=unityhpc,dc=test" ; locked user group dn +user_flag_groups[qualified] = "cn=unityusers,dc=unityhpc,dc=test" ; qualified user group (in at least one PI group) [sql] host = "sql" ; mariadb hostname diff --git a/resources/init.php b/resources/init.php index 54cf53c6..bd80319a 100644 --- a/resources/init.php +++ b/resources/init.php @@ -56,7 +56,7 @@ $_SESSION["SSO"] = $SSO; $OPERATOR = new UnityUser($SSO["user"], $LDAP, $SQL, $MAILER, $WEBHOOK); - $_SESSION["is_admin"] = $OPERATOR->getModifier("admin"); + $_SESSION["is_admin"] = $OPERATOR->getFlag("admin"); if (isset($_SESSION["viewUser"]) && $_SESSION["is_admin"]) { $USER = new UnityUser($_SESSION["viewUser"], $LDAP, $SQL, $MAILER, $WEBHOOK); diff --git a/resources/lib/UnityGroup.php b/resources/lib/UnityGroup.php index a5823aed..1f432c8d 100644 --- a/resources/lib/UnityGroup.php +++ b/resources/lib/UnityGroup.php @@ -85,7 +85,7 @@ public function approveGroup(?UnityUser $operator = null, bool $send_mail = true if ($send_mail) { $this->MAILER->sendMail($this->getOwner()->getMail(), "group_created"); } - $this->getOwner()->setModifier("qualified", true); // having your own group makes you qualified + $this->getOwner()->setFlag("qualified", true); // having your own group makes you qualified } /** @@ -192,7 +192,7 @@ public function approveUser(UnityUser $new_user, bool $send_mail = true): void ]); } // being in a group makes you qualified - $new_user->setModifier("qualified", true, doSendMail: true, doSendMailAdmin: false); + $new_user->setFlag("qualified", true, doSendMail: true, doSendMailAdmin: false); } public function denyUser(UnityUser $new_user, bool $send_mail = true): void diff --git a/resources/lib/UnityLDAP.php b/resources/lib/UnityLDAP.php index 76884393..0d60b511 100644 --- a/resources/lib/UnityLDAP.php +++ b/resources/lib/UnityLDAP.php @@ -37,7 +37,7 @@ class UnityLDAP extends LDAPConn private LDAPEntry $pi_groupOU; private LDAPEntry $org_groupOU; - public array $userModifierGroups; + public array $userFlagGroups; public function __construct() { @@ -47,9 +47,9 @@ public function __construct() $this->groupOU = $this->getEntry(CONFIG["ldap"]["group_ou"]); $this->pi_groupOU = $this->getEntry(CONFIG["ldap"]["pigroup_ou"]); $this->org_groupOU = $this->getEntry(CONFIG["ldap"]["orggroup_ou"]); - $this->userModifierGroups = []; - foreach (CONFIG["ldap"]["user_modifier_groups"] as $gid => $dn) { - $this->userModifierGroups[$gid] = new PosixGroup(new LDAPEntry($this->conn, $dn)); + $this->userFlagGroups = []; + foreach (CONFIG["ldap"]["user_flag_groups"] as $gid => $dn) { + $this->userFlagGroups[$gid] = new PosixGroup(new LDAPEntry($this->conn, $dn)); } } @@ -184,7 +184,7 @@ public function getQualifiedUsersAttributes( array $attributes, array $default_values = [], ): array { - $include_uids = $this->userModifierGroups["qualified"]->getMemberUIDs(); + $include_uids = $this->userFlagGroups["qualified"]->getMemberUIDs(); $user_attributes = $this->baseOU->getChildrenArrayStrict( $attributes, true, // recursive @@ -281,7 +281,7 @@ public function getAllPIGroupOwnerAttributes( public function getQualifiedUID2PIGIDs(): array { // initialize output so each UID is a key with an empty array as its value - $uids = $this->userModifierGroups["qualified"]->getMemberUIDs(); + $uids = $this->userFlagGroups["qualified"]->getMemberUIDs(); $uid2pigids = array_combine($uids, array_fill(0, count($uids), [])); // for each PI group, append that GID to the member list for each of its member UIDs foreach ( diff --git a/resources/lib/UnityUser.php b/resources/lib/UnityUser.php index 161ba6c1..604c6c9d 100644 --- a/resources/lib/UnityUser.php +++ b/resources/lib/UnityUser.php @@ -97,51 +97,51 @@ public function init( $this->SQL->addLog($this->uid, $_SERVER["REMOTE_ADDR"], "user_added", $this->uid); } - public function getModifier(string $modifier): bool + public function getFlag(string $flag): bool { - return $this->LDAP->userModifierGroups[$modifier]->memberUIDExists($this->uid); + return $this->LDAP->userFlagGroups[$flag]->memberUIDExists($this->uid); } - public function setModifier( - string $modifier, + public function setFlag( + string $flag, bool $newValue, bool $doSendMail = true, bool $doSendMailAdmin = true, ): void { - $oldValue = $this->getModifier($modifier); + $oldValue = $this->getFlag($flag); if ($oldValue == $newValue) { return; } if ($newValue) { - $this->LDAP->userModifierGroups[$modifier]->addMemberUID($this->uid); + $this->LDAP->userFlagGroups[$flag]->addMemberUID($this->uid); if ($doSendMail) { - $this->MAILER->sendMail($this->getMail(), "user_modifier_added", [ + $this->MAILER->sendMail($this->getMail(), "user_flag_added", [ "user" => $this->uid, "org" => $this->getOrg(), - "modifier" => $modifier, + "flag" => $flag, ]); } if ($doSendMailAdmin) { - $this->MAILER->sendMail("admin", "user_modifier_added_admin", [ + $this->MAILER->sendMail("admin", "user_flag_added_admin", [ "user" => $this->uid, "org" => $this->getOrg(), - "modifier" => $modifier, + "flag" => $flag, ]); } } else { - $this->LDAP->userModifierGroups[$modifier]->removeMemberUID($this->uid); + $this->LDAP->userFlagGroups[$flag]->removeMemberUID($this->uid); if ($doSendMail) { - $this->MAILER->sendMail($this->getMail(), "user_modifier_removed", [ + $this->MAILER->sendMail($this->getMail(), "user_flag_removed", [ "user" => $this->uid, "org" => $this->getOrg(), - "modifier" => $modifier, + "flag" => $flag, ]); } if ($doSendMailAdmin) { - $this->MAILER->sendMail("admin", "user_modifier_removed_admin", [ + $this->MAILER->sendMail("admin", "user_flag_removed_admin", [ "user" => $this->uid, "org" => $this->getOrg(), - "modifier" => $modifier, + "flag" => $flag, ]); } } diff --git a/resources/mail/user_modifier_added.php b/resources/mail/user_flag_added.php similarity index 95% rename from resources/mail/user_modifier_added.php rename to resources/mail/user_flag_added.php index 7431accf..9eb22239 100644 --- a/resources/mail/user_modifier_added.php +++ b/resources/mail/user_flag_added.php @@ -1,4 +1,4 @@ - Subject = "User Activated"; ?>

Hello,

@@ -50,5 +50,5 @@ - + diff --git a/resources/mail/user_modifier_added_admin.php b/resources/mail/user_flag_added_admin.php similarity index 92% rename from resources/mail/user_modifier_added_admin.php rename to resources/mail/user_flag_added_admin.php index 42034edf..d72818e3 100644 --- a/resources/mail/user_modifier_added_admin.php +++ b/resources/mail/user_flag_added_admin.php @@ -1,4 +1,4 @@ - Subject = "User Qualified"; ?>

Hello,

@@ -35,5 +35,5 @@ - + diff --git a/resources/mail/user_modifier_removed.php b/resources/mail/user_flag_removed.php similarity index 94% rename from resources/mail/user_modifier_removed.php rename to resources/mail/user_flag_removed.php index 8ac02020..0122b312 100644 --- a/resources/mail/user_modifier_removed.php +++ b/resources/mail/user_flag_removed.php @@ -1,4 +1,4 @@ - Subject = "User Deactivated"; ?>

Hello,

@@ -40,5 +40,5 @@ - + diff --git a/resources/mail/user_modifier_removed_admin.php b/resources/mail/user_flag_removed_admin.php similarity index 92% rename from resources/mail/user_modifier_removed_admin.php rename to resources/mail/user_flag_removed_admin.php index 21586baa..ec42f8ba 100644 --- a/resources/mail/user_modifier_removed_admin.php +++ b/resources/mail/user_flag_removed_admin.php @@ -1,4 +1,4 @@ - Subject = "User Dequalified"; ?>

Hello,

@@ -35,5 +35,5 @@ - + diff --git a/test/functional/PIBecomeApproveTest.php b/test/functional/PIBecomeApproveTest.php index 451853e7..dae5da5f 100644 --- a/test/functional/PIBecomeApproveTest.php +++ b/test/functional/PIBecomeApproveTest.php @@ -64,7 +64,7 @@ public function testApprovePI() $this->assertRequestedPIGroup(false); $this->assertTrue($pi_group->exists()); - $this->assertTrue($USER->getModifier("qualified")); + $this->assertTrue($USER->getFlag("qualified")); // $third_request_failed = false; // try { diff --git a/test/functional/PiMemberApproveTest.php b/test/functional/PiMemberApproveTest.php index 06639843..dd2a8f43 100644 --- a/test/functional/PiMemberApproveTest.php +++ b/test/functional/PiMemberApproveTest.php @@ -107,7 +107,7 @@ public function testApproveMemberByPI() $this->assertTrue(!$pi_group->requestExists($USER)); $this->assertRequestedMembership(false, $gid); $this->assertTrue($pi_group->memberUIDExists($USER->uid)); - $this->assertTrue($USER->getModifier("qualified")); + $this->assertTrue($USER->getFlag("qualified")); // $third_request_failed = false; // try { @@ -167,7 +167,7 @@ public function testApproveMemberByAdmin() $this->assertTrue(!$pi_group->requestExists($USER)); $this->assertRequestedMembership(false, $gid); $this->assertTrue($pi_group->memberUIDExists($USER->uid)); - $this->assertTrue($USER->getModifier("qualified")); + $this->assertTrue($USER->getFlag("qualified")); // $third_request_failed = false; // try { diff --git a/test/functional/ViewAsUserTest.php b/test/functional/ViewAsUserTest.php index b49a8984..2b49548b 100644 --- a/test/functional/ViewAsUserTest.php +++ b/test/functional/ViewAsUserTest.php @@ -10,7 +10,7 @@ public function _testViewAsUser(array $beforeUser, array $afterUser) switchUser(...$afterUser); $afterUid = $USER->uid; switchUser(...$beforeUser); - // $this->assertTrue($USER->getModifier("admin")); + // $this->assertTrue($USER->getFlag("admin")); $beforeUid = $USER->uid; // $this->assertNotEquals($afterUid, $beforeUid); http_post(__DIR__ . "/../../webroot/admin/user-mgmt.php", [ @@ -57,7 +57,7 @@ public function testNonAdminViewAsAdmin() global $USER; switchUser(...getAdminUser()); $adminUid = $USER->uid; - $this->assertTrue($USER->getModifier("admin")); + $this->assertTrue($USER->getFlag("admin")); switchUser(...getNormalUser()); http_post(__DIR__ . "/../../webroot/admin/user-mgmt.php", [ "form_type" => "viewAsUser", diff --git a/test/phpunit-bootstrap.php b/test/phpunit-bootstrap.php index d63c53fa..c01a5fae 100644 --- a/test/phpunit-bootstrap.php +++ b/test/phpunit-bootstrap.php @@ -195,8 +195,8 @@ function ensureUserDoesNotExist() $USER->getGroupEntry()->delete(); ensure(!$USER->getGroupEntry()->exists()); } - $USER->setModifier("qualified", false); - ensure(!$LDAP->userModifierGroups["qualified"]->memberUIDExists($USER->uid)); + $USER->setFlag("qualified", false); + ensure(!$LDAP->userFlagGroups["qualified"]->memberUIDExists($USER->uid)); } function ensureOrgGroupDoesNotExist() diff --git a/webroot/admin/ajax/get_group_members.php b/webroot/admin/ajax/get_group_members.php index f815c7c2..105009fa 100644 --- a/webroot/admin/ajax/get_group_members.php +++ b/webroot/admin/ajax/get_group_members.php @@ -5,7 +5,7 @@ use UnityWebPortal\lib\UnityGroup; use UnityWebPortal\lib\UnityHTTPD; -if (!$USER->getModifier("admin")) { +if (!$USER->getFlag("admin")) { UnityHTTPD::forbidden("not an admin"); } diff --git a/webroot/admin/ajax/get_page_contents.php b/webroot/admin/ajax/get_page_contents.php index d9077720..bea5752b 100644 --- a/webroot/admin/ajax/get_page_contents.php +++ b/webroot/admin/ajax/get_page_contents.php @@ -4,7 +4,7 @@ use UnityWebPortal\lib\UnityHTTPD; -if (!$USER->getModifier("admin")) { +if (!$USER->getFlag("admin")) { UnityHTTPD::forbidden("not an admin"); } diff --git a/webroot/admin/content.php b/webroot/admin/content.php index 5c060554..d055579b 100644 --- a/webroot/admin/content.php +++ b/webroot/admin/content.php @@ -4,7 +4,7 @@ use UnityWebPortal\lib\UnityHTTPD; -if (!$USER->getModifier("admin")) { +if (!$USER->getFlag("admin")) { UnityHTTPD::forbidden("not an admin"); } diff --git a/webroot/admin/notices.php b/webroot/admin/notices.php index e35416d4..d5ff0635 100644 --- a/webroot/admin/notices.php +++ b/webroot/admin/notices.php @@ -4,7 +4,7 @@ use UnityWebPortal\lib\UnityHTTPD; -if (!$USER->getModifier("admin")) { +if (!$USER->getFlag("admin")) { UnityHTTPD::forbidden("not an admin"); } diff --git a/webroot/admin/pi-mgmt.php b/webroot/admin/pi-mgmt.php index 21ad3b97..c773bf73 100644 --- a/webroot/admin/pi-mgmt.php +++ b/webroot/admin/pi-mgmt.php @@ -7,7 +7,7 @@ use UnityWebPortal\lib\UnityHTTPD; use UnityWebPortal\lib\UnitySQL; -if (!$USER->getModifier("admin")) { +if (!$USER->getFlag("admin")) { UnityHTTPD::forbidden("not an admin"); } diff --git a/webroot/admin/user-mgmt.php b/webroot/admin/user-mgmt.php index 529cd2ce..4dafe8eb 100644 --- a/webroot/admin/user-mgmt.php +++ b/webroot/admin/user-mgmt.php @@ -4,7 +4,7 @@ use UnityWebPortal\lib\UnityHTTPD; -if (!$USER->getModifier("admin")) { +if (!$USER->getFlag("admin")) { UnityHTTPD::forbidden("not an admin"); } diff --git a/webroot/panel/account.php b/webroot/panel/account.php index 2fac54af..f7430099 100644 --- a/webroot/panel/account.php +++ b/webroot/panel/account.php @@ -130,7 +130,7 @@ echo "

You are curently a principal investigator on the UnityHPC Platform

"; -} elseif ($USER->getModifier("qualified")) { +} elseif ($USER->getFlag("qualified")) { echo "

You are curently a qualified user on the UnityHPC Platform

"; } else { $tos_url = CONFIG["site"]["terms_of_service_url"]; From 1e20db048bc21f8584de275b342da9f570c11ca0 Mon Sep 17 00:00:00 2001 From: Simon Leary Date: Tue, 16 Dec 2025 12:55:42 -0500 Subject: [PATCH 12/18] update convention --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4e5c5e1d..034e0bac 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -26,7 +26,7 @@ This will enable strict mode and throw an exception rather than issuing a warning. - `UnityHTTPD`'s user-facing error functionality (ex: `badRequest`) should only be called from `webroot/**/*.php`. `resources/**/*.php` should throw exceptions instead. -- all pages under `webroot/admin/` must check for `$USER->isAdmin()` and call `UnityHTTPD::forbidden()` if not admin. +- all pages under `webroot/admin/` must check for `$USER->getFlag("admin")` and call `UnityHTTPD::forbidden()` if not admin. This repository will automatically check PRs for linting compliance. From db9530e89b7aac144c53c9e1069ccc38c96b73f8 Mon Sep 17 00:00:00 2001 From: Simon Leary Date: Thu, 18 Dec 2025 14:05:02 -0500 Subject: [PATCH 13/18] move to enum --- CONTRIBUTING.md | 2 +- resources/init.php | 3 ++- resources/lib/UnityGroup.php | 4 ++-- resources/lib/UnityLDAP.php | 14 ++++++++++++-- resources/lib/UnityUser.php | 10 +++++----- resources/mail/user_flag_added.php | 11 ++++++----- resources/mail/user_flag_added_admin.php | 11 ++++++----- resources/mail/user_flag_removed.php | 11 ++++++----- resources/mail/user_flag_removed_admin.php | 11 ++++++----- test/functional/PIBecomeApproveTest.php | 5 ++--- test/functional/PiMemberApproveTest.php | 7 +++---- test/functional/ViewAsUserTest.php | 6 +++--- test/phpunit-bootstrap.php | 3 ++- webroot/admin/ajax/get_group_members.php | 2 +- webroot/admin/ajax/get_page_contents.php | 2 +- webroot/admin/content.php | 3 ++- webroot/admin/notices.php | 3 ++- webroot/admin/pi-mgmt.php | 3 ++- webroot/admin/user-mgmt.php | 3 ++- webroot/panel/account.php | 3 ++- 20 files changed, 68 insertions(+), 49 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 034e0bac..4f5e66c5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -26,7 +26,7 @@ This will enable strict mode and throw an exception rather than issuing a warning. - `UnityHTTPD`'s user-facing error functionality (ex: `badRequest`) should only be called from `webroot/**/*.php`. `resources/**/*.php` should throw exceptions instead. -- all pages under `webroot/admin/` must check for `$USER->getFlag("admin")` and call `UnityHTTPD::forbidden()` if not admin. +- all pages under `webroot/admin/` must check for `$USER->getFlag(UserFlag::ADMIN)` and call `UnityHTTPD::forbidden()` if not admin. This repository will automatically check PRs for linting compliance. diff --git a/resources/init.php b/resources/init.php index bd80319a..26918d14 100644 --- a/resources/init.php +++ b/resources/init.php @@ -12,6 +12,7 @@ use UnityWebPortal\lib\UnityWebhook; use UnityWebPortal\lib\UnityGithub; use UnityWebPortal\lib\UnityHTTPD; +use UnityWebPortal\lib\UserFlag; if (CONFIG["site"]["enable_exception_handler"]) { set_exception_handler(["UnityWebPortal\lib\UnityHTTPD", "exceptionHandler"]); @@ -56,7 +57,7 @@ $_SESSION["SSO"] = $SSO; $OPERATOR = new UnityUser($SSO["user"], $LDAP, $SQL, $MAILER, $WEBHOOK); - $_SESSION["is_admin"] = $OPERATOR->getFlag("admin"); + $_SESSION["is_admin"] = $OPERATOR->getFlag(UserFlag::ADMIN); if (isset($_SESSION["viewUser"]) && $_SESSION["is_admin"]) { $USER = new UnityUser($_SESSION["viewUser"], $LDAP, $SQL, $MAILER, $WEBHOOK); diff --git a/resources/lib/UnityGroup.php b/resources/lib/UnityGroup.php index 1f432c8d..3d7ba31b 100644 --- a/resources/lib/UnityGroup.php +++ b/resources/lib/UnityGroup.php @@ -85,7 +85,7 @@ public function approveGroup(?UnityUser $operator = null, bool $send_mail = true if ($send_mail) { $this->MAILER->sendMail($this->getOwner()->getMail(), "group_created"); } - $this->getOwner()->setFlag("qualified", true); // having your own group makes you qualified + $this->getOwner()->setFlag(UserFlag::QUALIFIED, true); // having your own group makes you qualified } /** @@ -192,7 +192,7 @@ public function approveUser(UnityUser $new_user, bool $send_mail = true): void ]); } // being in a group makes you qualified - $new_user->setFlag("qualified", true, doSendMail: true, doSendMailAdmin: false); + $new_user->setFlag(UserFlag::QUALIFIED, true, doSendMail: true, doSendMailAdmin: false); } public function denyUser(UnityUser $new_user, bool $send_mail = true): void diff --git a/resources/lib/UnityLDAP.php b/resources/lib/UnityLDAP.php index 0d60b511..e67c73ed 100644 --- a/resources/lib/UnityLDAP.php +++ b/resources/lib/UnityLDAP.php @@ -7,6 +7,15 @@ use PHPOpenLDAPer\LDAPEntry; use UnityWebPortal\lib\PosixGroup; +enum UserFlag: string +{ + case ADMIN = "admin"; + case GHOST = "ghost"; + case IDLELOCKED = "idlelocked"; + case LOCKED = "locked"; + case QUALIFIED = "qualified"; +} + /** * An LDAP connection class which extends LDAPConn tailored for the UnityHPC Platform */ @@ -48,8 +57,9 @@ public function __construct() $this->pi_groupOU = $this->getEntry(CONFIG["ldap"]["pigroup_ou"]); $this->org_groupOU = $this->getEntry(CONFIG["ldap"]["orggroup_ou"]); $this->userFlagGroups = []; - foreach (CONFIG["ldap"]["user_flag_groups"] as $gid => $dn) { - $this->userFlagGroups[$gid] = new PosixGroup(new LDAPEntry($this->conn, $dn)); + foreach (UserFlag::cases() as $flag) { + $dn = CONFIG["ldap"]["user_flag_groups"][$flag->value]; + $this->userFlagGroups[$flag->value] = new PosixGroup(new LDAPEntry($this->conn, $dn)); } } diff --git a/resources/lib/UnityUser.php b/resources/lib/UnityUser.php index 604c6c9d..9e1b4b48 100644 --- a/resources/lib/UnityUser.php +++ b/resources/lib/UnityUser.php @@ -97,13 +97,13 @@ public function init( $this->SQL->addLog($this->uid, $_SERVER["REMOTE_ADDR"], "user_added", $this->uid); } - public function getFlag(string $flag): bool + public function getFlag(UserFlag $flag): bool { - return $this->LDAP->userFlagGroups[$flag]->memberUIDExists($this->uid); + return $this->LDAP->userFlagGroups[$flag->value]->memberUIDExists($this->uid); } public function setFlag( - string $flag, + UserFlag $flag, bool $newValue, bool $doSendMail = true, bool $doSendMailAdmin = true, @@ -113,7 +113,7 @@ public function setFlag( return; } if ($newValue) { - $this->LDAP->userFlagGroups[$flag]->addMemberUID($this->uid); + $this->LDAP->userFlagGroups[$flag->value]->addMemberUID($this->uid); if ($doSendMail) { $this->MAILER->sendMail($this->getMail(), "user_flag_added", [ "user" => $this->uid, @@ -129,7 +129,7 @@ public function setFlag( ]); } } else { - $this->LDAP->userFlagGroups[$flag]->removeMemberUID($this->uid); + $this->LDAP->userFlagGroups[$flag->value]->removeMemberUID($this->uid); if ($doSendMail) { $this->MAILER->sendMail($this->getMail(), "user_flag_removed", [ "user" => $this->uid, diff --git a/resources/mail/user_flag_added.php b/resources/mail/user_flag_added.php index 9eb22239..268d0e44 100644 --- a/resources/mail/user_flag_added.php +++ b/resources/mail/user_flag_added.php @@ -1,5 +1,6 @@ + +case UserFlag::QUALIFIED: ?> Subject = "User Activated"; ?>

Hello,

Your account on the UnityHPC Platform has been activated. Your account details are below:

@@ -17,7 +18,7 @@ - + Subject = "User Deleted"; ?>

Hello,

Your account on the UnityHPC Platform has been deleted.

@@ -25,7 +26,7 @@ - + Subject = "User Locked"; ?>

Hello,

Your account on the UnityHPC Platform has been locked.

@@ -33,7 +34,7 @@ - + Subject = "User Locked"; ?>

Hello,

Your account on the UnityHPC Platform has been locked due to inactivity.

@@ -41,7 +42,7 @@ - + Subject = "User Promoted"; ?>

Hello,

Your account on the UnityHPC Platform has been promoted to admin.

diff --git a/resources/mail/user_flag_added_admin.php b/resources/mail/user_flag_added_admin.php index d72818e3..3a40153e 100644 --- a/resources/mail/user_flag_added_admin.php +++ b/resources/mail/user_flag_added_admin.php @@ -1,33 +1,34 @@ + +case UserFlag::QUALIFIED: ?> Subject = "User Qualified"; ?>

Hello,

User "" has been qualified.

- + Subject = "User Ghosted"; ?>

Hello,

User "" has been marked as ghost.

- + Subject = "User Locked"; ?>

Hello,

User "" has been locked.

- + Subject = "User Idle Locked"; ?>

Hello,

User "" has been idle locked.

- + Subject = "User Promoted"; ?>

Hello,

User "" has been promoted to admin.

diff --git a/resources/mail/user_flag_removed.php b/resources/mail/user_flag_removed.php index 0122b312..dbd40b27 100644 --- a/resources/mail/user_flag_removed.php +++ b/resources/mail/user_flag_removed.php @@ -1,5 +1,6 @@ + +case UserFlag::QUALIFIED: ?> Subject = "User Deactivated"; ?>

Hello,

Your account on the UnityHPC Platform has been deactivated.

@@ -7,7 +8,7 @@ - + Subject = "User Resurrected"; ?>

Hello,

Your account on the UnityHPC Platform has been resurrected.

@@ -15,7 +16,7 @@ - + Subject = "User Unlocked"; ?>

Hello,

Your account on the UnityHPC Platform has been unlocked.

@@ -23,7 +24,7 @@ - + Subject = "User Unlocked"; ?>

Hello,

Your account on the UnityHPC Platform has been unlocked.

@@ -31,7 +32,7 @@ - + Subject = "User Demoted"; ?>

Hello,

Your account on the UnityHPC Platform has been demoted from admin.

diff --git a/resources/mail/user_flag_removed_admin.php b/resources/mail/user_flag_removed_admin.php index ec42f8ba..9df4d136 100644 --- a/resources/mail/user_flag_removed_admin.php +++ b/resources/mail/user_flag_removed_admin.php @@ -1,33 +1,34 @@ + +case UserFlag::QUALIFIED: ?> Subject = "User Dequalified"; ?>

Hello,

User "" has been dequalified.

- + Subject = "User Resurrected"; ?>

Hello,

User "" has been resurrected (no longer marked as ghost).

- + Subject = "User Unlocked"; ?>

Hello,

User "" has been unlocked.

- + Subject = "User Idle Unlocked"; ?>

Hello,

User "" has been idle unlocked.

- + Subject = "User Demoted"; ?>

Hello,

User "" has been demoted from admin.

diff --git a/test/functional/PIBecomeApproveTest.php b/test/functional/PIBecomeApproveTest.php index dae5da5f..8515372a 100644 --- a/test/functional/PIBecomeApproveTest.php +++ b/test/functional/PIBecomeApproveTest.php @@ -1,7 +1,6 @@ assertRequestedPIGroup(false); $this->assertTrue($pi_group->exists()); - $this->assertTrue($USER->getFlag("qualified")); + $this->assertTrue($USER->getFlag(UserFlag::QUALIFIED)); // $third_request_failed = false; // try { diff --git a/test/functional/PiMemberApproveTest.php b/test/functional/PiMemberApproveTest.php index dd2a8f43..e12d3098 100644 --- a/test/functional/PiMemberApproveTest.php +++ b/test/functional/PiMemberApproveTest.php @@ -1,7 +1,6 @@ assertTrue(!$pi_group->requestExists($USER)); $this->assertRequestedMembership(false, $gid); $this->assertTrue($pi_group->memberUIDExists($USER->uid)); - $this->assertTrue($USER->getFlag("qualified")); + $this->assertTrue($USER->getFlag(UserFlag::QUALIFIED)); // $third_request_failed = false; // try { @@ -167,7 +166,7 @@ public function testApproveMemberByAdmin() $this->assertTrue(!$pi_group->requestExists($USER)); $this->assertRequestedMembership(false, $gid); $this->assertTrue($pi_group->memberUIDExists($USER->uid)); - $this->assertTrue($USER->getFlag("qualified")); + $this->assertTrue($USER->getFlag(UserFlag::QUALIFIED)); // $third_request_failed = false; // try { diff --git a/test/functional/ViewAsUserTest.php b/test/functional/ViewAsUserTest.php index 2b49548b..3177d41a 100644 --- a/test/functional/ViewAsUserTest.php +++ b/test/functional/ViewAsUserTest.php @@ -1,6 +1,6 @@ uid; switchUser(...$beforeUser); - // $this->assertTrue($USER->getFlag("admin")); + // $this->assertTrue($USER->getFlag(UserFlag::ADMIN)); $beforeUid = $USER->uid; // $this->assertNotEquals($afterUid, $beforeUid); http_post(__DIR__ . "/../../webroot/admin/user-mgmt.php", [ @@ -57,7 +57,7 @@ public function testNonAdminViewAsAdmin() global $USER; switchUser(...getAdminUser()); $adminUid = $USER->uid; - $this->assertTrue($USER->getFlag("admin")); + $this->assertTrue($USER->getFlag(UserFlag::ADMIN)); switchUser(...getNormalUser()); http_post(__DIR__ . "/../../webroot/admin/user-mgmt.php", [ "form_type" => "viewAsUser", diff --git a/test/phpunit-bootstrap.php b/test/phpunit-bootstrap.php index c01a5fae..81056d98 100644 --- a/test/phpunit-bootstrap.php +++ b/test/phpunit-bootstrap.php @@ -30,6 +30,7 @@ use UnityWebPortal\lib\CSRFToken; use UnityWebPortal\lib\UnityGroup; use UnityWebPortal\lib\UnityHTTPD; +use UnityWebPortal\lib\UserFlag; use UnityWebPortal\lib\UnitySQL; use UnityWebPortal\lib\UnityHTTPDMessageLevel; use PHPUnit\Framework\TestCase; @@ -195,7 +196,7 @@ function ensureUserDoesNotExist() $USER->getGroupEntry()->delete(); ensure(!$USER->getGroupEntry()->exists()); } - $USER->setFlag("qualified", false); + $USER->setFlag(UserFlag::QUALIFIED, false); ensure(!$LDAP->userFlagGroups["qualified"]->memberUIDExists($USER->uid)); } diff --git a/webroot/admin/ajax/get_group_members.php b/webroot/admin/ajax/get_group_members.php index 105009fa..02dc3233 100644 --- a/webroot/admin/ajax/get_group_members.php +++ b/webroot/admin/ajax/get_group_members.php @@ -5,7 +5,7 @@ use UnityWebPortal\lib\UnityGroup; use UnityWebPortal\lib\UnityHTTPD; -if (!$USER->getFlag("admin")) { +if (!$USER->getFlag(UserFlag::ADMIN)) { UnityHTTPD::forbidden("not an admin"); } diff --git a/webroot/admin/ajax/get_page_contents.php b/webroot/admin/ajax/get_page_contents.php index bea5752b..f384c1de 100644 --- a/webroot/admin/ajax/get_page_contents.php +++ b/webroot/admin/ajax/get_page_contents.php @@ -4,7 +4,7 @@ use UnityWebPortal\lib\UnityHTTPD; -if (!$USER->getFlag("admin")) { +if (!$USER->getFlag(UserFlag::ADMIN)) { UnityHTTPD::forbidden("not an admin"); } diff --git a/webroot/admin/content.php b/webroot/admin/content.php index d055579b..6285ea23 100644 --- a/webroot/admin/content.php +++ b/webroot/admin/content.php @@ -3,8 +3,9 @@ require_once __DIR__ . "/../../resources/autoload.php"; use UnityWebPortal\lib\UnityHTTPD; +use UnityWebPortal\lib\UserFlag; -if (!$USER->getFlag("admin")) { +if (!$USER->getFlag(UserFlag::ADMIN)) { UnityHTTPD::forbidden("not an admin"); } diff --git a/webroot/admin/notices.php b/webroot/admin/notices.php index d5ff0635..eec54cd2 100644 --- a/webroot/admin/notices.php +++ b/webroot/admin/notices.php @@ -3,8 +3,9 @@ require_once __DIR__ . "/../../resources/autoload.php"; use UnityWebPortal\lib\UnityHTTPD; +use UnityWebPortal\lib\UserFlag; -if (!$USER->getFlag("admin")) { +if (!$USER->getFlag(UserFlag::ADMIN)) { UnityHTTPD::forbidden("not an admin"); } diff --git a/webroot/admin/pi-mgmt.php b/webroot/admin/pi-mgmt.php index c773bf73..75b128b2 100644 --- a/webroot/admin/pi-mgmt.php +++ b/webroot/admin/pi-mgmt.php @@ -6,8 +6,9 @@ use UnityWebPortal\lib\UnityGroup; use UnityWebPortal\lib\UnityHTTPD; use UnityWebPortal\lib\UnitySQL; +use UnityWebPortal\lib\UserFlag; -if (!$USER->getFlag("admin")) { +if (!$USER->getFlag(UserFlag::ADMIN)) { UnityHTTPD::forbidden("not an admin"); } diff --git a/webroot/admin/user-mgmt.php b/webroot/admin/user-mgmt.php index 4dafe8eb..9032a4b9 100644 --- a/webroot/admin/user-mgmt.php +++ b/webroot/admin/user-mgmt.php @@ -3,8 +3,9 @@ require_once __DIR__ . "/../../resources/autoload.php"; use UnityWebPortal\lib\UnityHTTPD; +use UnityWebPortal\lib\UserFlag; -if (!$USER->getFlag("admin")) { +if (!$USER->getFlag(UserFlag::ADMIN)) { UnityHTTPD::forbidden("not an admin"); } diff --git a/webroot/panel/account.php b/webroot/panel/account.php index f7430099..3ab19508 100644 --- a/webroot/panel/account.php +++ b/webroot/panel/account.php @@ -2,6 +2,7 @@ require_once __DIR__ . "/../../resources/autoload.php"; +use UnityWebPortal\lib\UserFlag; use UnityWebPortal\lib\UnityHTTPD; use UnityWebPortal\lib\exceptions\EncodingUnknownException; use UnityWebPortal\lib\exceptions\EncodingConversionException; @@ -130,7 +131,7 @@ echo "

You are curently a principal investigator on the UnityHPC Platform

"; -} elseif ($USER->getFlag("qualified")) { +} elseif ($USER->getFlag(UserFlag::QUALIFIED)) { echo "

You are curently a qualified user on the UnityHPC Platform

"; } else { $tos_url = CONFIG["site"]["terms_of_service_url"]; From 1000e4e5b454c43251e3736c85b18f6c49a80d51 Mon Sep 17 00:00:00 2001 From: Simon Leary Date: Thu, 18 Dec 2025 14:17:18 -0500 Subject: [PATCH 14/18] fix phpunit notice --- test/functional/SSHKeyAddTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/functional/SSHKeyAddTest.php b/test/functional/SSHKeyAddTest.php index e6593e4f..8d5fb009 100644 --- a/test/functional/SSHKeyAddTest.php +++ b/test/functional/SSHKeyAddTest.php @@ -2,9 +2,9 @@ use UnityWebPortal\lib\UnityGithub; use PHPUnit\Framework\Attributes\DataProvider; -use PHPUnit\Framework\MockObject\MockBuilder; use PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations; +#[AllowMockObjectsWithoutExpectations] class SSHKeyAddTest extends UnityWebPortalTestCase { private function addSshKeysPaste(array $keys): void From 33f9573e01152d944dfab29c0a7193758f023016 Mon Sep 17 00:00:00 2001 From: simonLeary42 <71396965+simonLeary42@users.noreply.github.com> Date: Thu, 18 Dec 2025 14:22:42 -0500 Subject: [PATCH 15/18] Update resources/lib/UnityLDAP.php Co-authored-by: bryank-cs --- resources/lib/UnityLDAP.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/lib/UnityLDAP.php b/resources/lib/UnityLDAP.php index e67c73ed..64c42efe 100644 --- a/resources/lib/UnityLDAP.php +++ b/resources/lib/UnityLDAP.php @@ -291,7 +291,7 @@ public function getAllPIGroupOwnerAttributes( public function getQualifiedUID2PIGIDs(): array { // initialize output so each UID is a key with an empty array as its value - $uids = $this->userFlagGroups["qualified"]->getMemberUIDs(); + $uids = $this->userFlagGroups[UserFlag::QUALIFIED]->getMemberUIDs(); $uid2pigids = array_combine($uids, array_fill(0, count($uids), [])); // for each PI group, append that GID to the member list for each of its member UIDs foreach ( From a0a5037a0f7c0d53fb38e3f85594d30baa6a13f1 Mon Sep 17 00:00:00 2001 From: simonLeary42 <71396965+simonLeary42@users.noreply.github.com> Date: Thu, 18 Dec 2025 14:22:50 -0500 Subject: [PATCH 16/18] Update resources/lib/UnityLDAP.php Co-authored-by: bryank-cs --- resources/lib/UnityLDAP.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/lib/UnityLDAP.php b/resources/lib/UnityLDAP.php index 64c42efe..4a9b6878 100644 --- a/resources/lib/UnityLDAP.php +++ b/resources/lib/UnityLDAP.php @@ -194,7 +194,7 @@ public function getQualifiedUsersAttributes( array $attributes, array $default_values = [], ): array { - $include_uids = $this->userFlagGroups["qualified"]->getMemberUIDs(); + $include_uids = $this->userFlagGroups[UserFlag::QUALIFIED]->getMemberUIDs(); $user_attributes = $this->baseOU->getChildrenArrayStrict( $attributes, true, // recursive From ec00742a0e3ce75646d417db967b05eec9b47aa1 Mon Sep 17 00:00:00 2001 From: simonLeary42 <71396965+simonLeary42@users.noreply.github.com> Date: Thu, 18 Dec 2025 14:22:56 -0500 Subject: [PATCH 17/18] Update test/phpunit-bootstrap.php Co-authored-by: bryank-cs --- test/phpunit-bootstrap.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/phpunit-bootstrap.php b/test/phpunit-bootstrap.php index 81056d98..2d64892a 100644 --- a/test/phpunit-bootstrap.php +++ b/test/phpunit-bootstrap.php @@ -197,7 +197,7 @@ function ensureUserDoesNotExist() ensure(!$USER->getGroupEntry()->exists()); } $USER->setFlag(UserFlag::QUALIFIED, false); - ensure(!$LDAP->userFlagGroups["qualified"]->memberUIDExists($USER->uid)); + ensure(!$LDAP->userFlagGroups[UserFlag::QUALIFIED]->memberUIDExists($USER->uid)); } function ensureOrgGroupDoesNotExist() From ee017458f217212dffee0ad403403470aaa27678 Mon Sep 17 00:00:00 2001 From: Simon Leary Date: Thu, 18 Dec 2025 14:26:36 -0500 Subject: [PATCH 18/18] get value of enum --- resources/lib/UnityLDAP.php | 4 ++-- test/phpunit-bootstrap.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/lib/UnityLDAP.php b/resources/lib/UnityLDAP.php index 4a9b6878..139ede5a 100644 --- a/resources/lib/UnityLDAP.php +++ b/resources/lib/UnityLDAP.php @@ -194,7 +194,7 @@ public function getQualifiedUsersAttributes( array $attributes, array $default_values = [], ): array { - $include_uids = $this->userFlagGroups[UserFlag::QUALIFIED]->getMemberUIDs(); + $include_uids = $this->userFlagGroups[UserFlag::QUALIFIED->value]->getMemberUIDs(); $user_attributes = $this->baseOU->getChildrenArrayStrict( $attributes, true, // recursive @@ -291,7 +291,7 @@ public function getAllPIGroupOwnerAttributes( public function getQualifiedUID2PIGIDs(): array { // initialize output so each UID is a key with an empty array as its value - $uids = $this->userFlagGroups[UserFlag::QUALIFIED]->getMemberUIDs(); + $uids = $this->userFlagGroups[UserFlag::QUALIFIED->value]->getMemberUIDs(); $uid2pigids = array_combine($uids, array_fill(0, count($uids), [])); // for each PI group, append that GID to the member list for each of its member UIDs foreach ( diff --git a/test/phpunit-bootstrap.php b/test/phpunit-bootstrap.php index 2d64892a..5b1bd315 100644 --- a/test/phpunit-bootstrap.php +++ b/test/phpunit-bootstrap.php @@ -197,7 +197,7 @@ function ensureUserDoesNotExist() ensure(!$USER->getGroupEntry()->exists()); } $USER->setFlag(UserFlag::QUALIFIED, false); - ensure(!$LDAP->userFlagGroups[UserFlag::QUALIFIED]->memberUIDExists($USER->uid)); + ensure(!$LDAP->userFlagGroups[UserFlag::QUALIFIED->value]->memberUIDExists($USER->uid)); } function ensureOrgGroupDoesNotExist()