Skip to content

Conversation

@simonLeary42
Copy link
Collaborator

@simonLeary42 simonLeary42 commented Jan 12, 2026

Closes #392

Puts back the old "disband PI" functionality (removed in #207) using the term "disable" instead of "disband". A PI group can now have the isDisabled attribute set to "TRUE" and it will be ignored by the portal. If a PI is once again approved for a PI group, the old group will have isDisabled set to "FALSE" or unset.

Note: Disabled PI groups should have no members.

Note: I used OIDs 1.1.1 and 1.1.2 for my new LDAP stuff. 1.1 is documented as a "dead namespace" in OID land and is advisable for "private experiments". copilot doesn't like that I did this.

Note: if a large PI group is disabled, while updating the qualified status of each member, the portal will query for the members' attributes one-at-a-time and then do $user->getPIGroupGIDs() one-at-a-time, which is a lot of LDAP queries. I implemented an optimized version of this, but it's very ugly.

Test cases added:

  • UnityGroup->setIsDisabled() changes return value of future UnityGroup->getIsDisabled()
  • wen user is re-approved and old disabled group is re-enabled, $user->isPI() returns true
  • when PI group is disabled by an admin in pi-mgmt.php, $group->getIsDisabled() returns true and $owner->isPI() returns false
  • when PI group is disabled voluntarily by the owner in pi.php, $group->getIsDisabled() returns true and $owner->isPI() returns false
  • groups with isDisabled unset and groups with isDisabled = "FALSE" are both displayed in pi-mgmt.php

@simonLeary42 simonLeary42 force-pushed the disband branch 3 times, most recently from b4f49d4 to 8b797d7 Compare January 12, 2026 20:44
@simonLeary42 simonLeary42 changed the title disband, reinstate disband, reinstate PI groups Jan 12, 2026
@simonLeary42 simonLeary42 force-pushed the disband branch 2 times, most recently from 6da966d to a8dcf02 Compare January 12, 2026 21:05
@simonLeary42 simonLeary42 force-pushed the disband branch 2 times, most recently from 9c25537 to 7b65b64 Compare January 13, 2026 17:01
@simonLeary42 simonLeary42 force-pushed the disband branch 2 times, most recently from 5bbab62 to 0d8a076 Compare January 14, 2026 18:33
@simonLeary42 simonLeary42 requested a review from Copilot January 14, 2026 19:05
@simonLeary42 simonLeary42 marked this pull request as ready for review January 14, 2026 19:05
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request restores the ability to disable and re-enable PI groups (previously called "disband"), using new terminology and implementing it via an LDAP attribute rather than deleting the group. When a PI group is disabled, it's marked with an isDisabled attribute in LDAP and is excluded from most portal operations.

Changes:

  • Adds a new LDAP schema with isDisabled attribute and unityClusterPIGroup object class
  • Implements disable(), reenable(), getIsDisabled(), and setIsDisabled() methods in UnityGroup
  • Updates all LDAP queries to filter out disabled PI groups using a new NON_DEFUNCT_FILTER
  • Adds UI controls in pi-mgmt.php and pi.php for disabling groups
  • Updates email templates to reflect "disabled" terminology instead of "disbanded"
  • Adds comprehensive test coverage for disable/reenable functionality

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 17 comments.

Show a summary per file
File Description
tools/docker-dev/identity/unity-cluster-schema.ldif New LDAP schema defining isDisabled attribute and unityClusterPIGroup object class
tools/docker-dev/identity/bootstrap.ldif Adds unityClusterPIGroup object class to all PI groups and creates test disabled groups
tools/docker-dev/identity/Dockerfile Loads the new LDAP schema during Docker build
resources/lib/UnityGroup.php Core disable/reenable logic, getIsDisabled/setIsDisabled methods, updated approveGroup to handle re-enabling
resources/lib/UnityLDAP.php Renamed methods to getAllNonDisabledPIGroups variants, added NON_DEFUNCT_FILTER
resources/lib/UnityUser.php Updated isPI() to check disabled status, changed objectclass arrays
resources/lib/UnityOrg.php Updated objectclass array from constant to inline
webroot/admin/pi-mgmt.php Added disable action and UI button
webroot/panel/pi.php Added disable action and "Danger Zone" UI section
webroot/panel/modal/pi_search.php Uses getAllNonDisabledPIGroups
workers/group_user_request_owner_reminder.php Uses getAllNonDisabledPIGroups
resources/mail/group_disabled.php Updated template for disabled (not disbanded)
resources/mail/group_reenabled.php New template for re-enabled groups
resources/mail/user_flag_removed.php Changed "Deactivated" to "Disabled"
test/functional/PIDisableTest.php New comprehensive tests for disable functionality
test/functional/PIBecomeApproveTest.php Added testReenableGroup
test/functional/RegisterUserTest.php Removed unused import
test/phpunit-bootstrap.php Uses getNonDisabledPIGroupGIDsWithMemberUID
README.md Added upgrade instructions for LDAP schema
LDAP.md Added disabled group terminology
Comments suppressed due to low confidence (3)

resources/mail/group_disabled.php:9

  • The email message states "Any jobs associated with this PI account have been killed." However, there's no code in the disable method that actually kills jobs. This message may be misleading to users if job killing is not implemented. Either implement job killing in the disable method or update this message to reflect what actually happens.
    resources/lib/UnityGroup.php:131
  • In approveGroup, when re-enabling a disabled group, the email template "group_created" is sent. This is misleading since the group is being re-enabled, not created for the first time. Either use the "group_reenabled" template when re-enabling (which is what reenable() already does), or send the "group_created" email only when actually creating a new group. Currently, the user would receive both "group_reenabled" (from reenable()) and "group_created" (from approveGroup()) which is redundant.
    public function approveGroup(bool $send_mail = true): void
    {
        $uid = $this->getOwner()->uid;
        $request = $this->SQL->getRequest($uid, UnitySQL::REQUEST_BECOME_PI);
        \ensure($this->getOwner()->exists());
        if (!$this->entry->exists()) {
            $this->init();
        } elseif ($this->getIsDisabled()) {
            $this->reenable();
        } else {
            throw new Exception("cannot approve group that already exists and is not disabled");
        }
        $this->SQL->removeRequest($this->getOwner()->uid, UnitySQL::REQUEST_BECOME_PI);
        $this->SQL->addLog("approved_group", $this->getOwner()->uid);
        if ($send_mail) {
            $this->MAILER->sendMail($this->getOwner()->getMail(), "group_created");
        }
        // having your own group makes you qualified
        $this->getOwner()->setFlag(UserFlag::QUALIFIED, true);
    }

resources/mail/group_disabled.php:11

  • The sentence is missing a period at the end. Should be "If you believe this to be a mistake, please reply to this email."

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@simonLeary42 simonLeary42 force-pushed the disband branch 3 times, most recently from 66f42fb to 6b306ac Compare January 15, 2026 22:16
@simonLeary42 simonLeary42 marked this pull request as draft January 15, 2026 22:18
@simonLeary42 simonLeary42 force-pushed the disband branch 2 times, most recently from 6ed7483 to 0936727 Compare January 16, 2026 15:11
@simonLeary42 simonLeary42 marked this pull request as ready for review January 16, 2026 15:12
@simonLeary42 simonLeary42 force-pushed the disband branch 2 times, most recently from 3aab9a8 to 994be0d Compare January 16, 2026 19:23
@simonLeary42 simonLeary42 force-pushed the disband branch 2 times, most recently from f0970ce to 322378f Compare January 21, 2026 13:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

put back "disband PI" functionality

3 participants