@@ -40,7 +40,7 @@ public function __toString(): string
4040 public function requestGroup (?bool $ send_mail_to_admins = null , bool $ send_mail = true ): void
4141 {
4242 $ send_mail_to_admins ??= CONFIG ["mail " ]["send_pimesg_to_admins " ];
43- if ($ this ->exists ()) {
43+ if ($ this ->exists () && ! $ this -> getIsDisabled () ) {
4444 return ;
4545 }
4646 if ($ this ->SQL ->accDeletionRequestExists ($ this ->getOwner ()->uid )) {
@@ -63,18 +63,70 @@ public function requestGroup(?bool $send_mail_to_admins = null, bool $send_mail
6363 }
6464 }
6565
66+ public function disable (bool $ send_mail = true ): void
67+ {
68+ if ($ this ->getIsDisabled ()) {
69+ throw new Exception ("cannot disable an already disabled group " );
70+ }
71+ $ this ->SQL ->addLog ("disable_pi_group " , $ this ->gid );
72+ $ memberuids = $ this ->getMemberUIDs ();
73+ if ($ send_mail ) {
74+ $ member_attributes = $ this ->LDAP ->getUsersAttributes ($ memberuids , ["mail " ]);
75+ $ member_mails = array_map (fn ($ x ) => (string ) $ x ["mail " ][0 ], $ member_attributes );
76+ if (count ($ member_mails ) > 0 ) {
77+ $ this ->MAILER ->sendMail ($ member_mails , "group_disabled " , [
78+ "group_name " => $ this ->gid ,
79+ ]);
80+ }
81+ }
82+ $ this ->setIsDisabled (true );
83+ if (count ($ memberuids ) > 0 ) {
84+ $ this ->entry ->setAttribute ("memberuid " , []);
85+ }
86+ // TODO optimize
87+ // UnityUser::__construct() makes one LDAP query for each user
88+ // updateIsQualified() makes one LDAP query for each member
89+ // if user is no longer in any PI group, disqualify them
90+ foreach ($ memberuids as $ uid ) {
91+ $ user = new UnityUser ($ uid , $ this ->LDAP , $ this ->SQL , $ this ->MAILER , $ this ->WEBHOOK );
92+ $ user ->updateIsQualified ($ send_mail );
93+ }
94+ }
95+
96+ private function reenable (bool $ send_mail = true ): void
97+ {
98+ if (!$ this ->getIsDisabled ()) {
99+ throw new Exception ("cannot re-enable a group that is not disabled " );
100+ }
101+ $ this ->SQL ->addLog ("reenabled_pi_group " , $ this ->gid );
102+ if ($ send_mail ) {
103+ $ this ->MAILER ->sendMail ($ this ->getOwner ()->getMail (), "group_reenabled " , [
104+ "group_name " => $ this ->gid ,
105+ ]);
106+ }
107+ $ this ->setIsDisabled (false );
108+ $ owner_uid = $ this ->getOwner ()->uid ;
109+ if (!$ this ->memberUIDExists ($ owner_uid )) {
110+ $ this ->addMemberUID ($ owner_uid );
111+ }
112+ $ this ->getOwner ()->updateIsQualified ($ send_mail );
113+ }
114+
66115 /**
67116 * This method will create the group (this is what is executed when an admin approved the group)
68117 */
69118 public function approveGroup (bool $ send_mail = true ): void
70119 {
71120 $ uid = $ this ->getOwner ()->uid ;
72121 $ request = $ this ->SQL ->getRequest ($ uid , UnitySQL::REQUEST_BECOME_PI );
73- if ($ this ->exists ()) {
74- return ;
75- }
76122 \ensure ($ this ->getOwner ()->exists ());
77- $ this ->init ();
123+ if (!$ this ->entry ->exists ()) {
124+ $ this ->init ();
125+ } elseif ($ this ->getIsDisabled ()) {
126+ $ this ->reenable ();
127+ } else {
128+ throw new Exception ("cannot approve group that already exists and is not disabled " );
129+ }
78130 $ this ->SQL ->removeRequest ($ this ->getOwner ()->uid , UnitySQL::REQUEST_BECOME_PI );
79131 $ this ->SQL ->addLog ("approved_group " , $ this ->getOwner ()->uid );
80132 if ($ send_mail ) {
@@ -126,42 +178,6 @@ public function cancelGroupJoinRequest(UnityUser $user, bool $send_mail = true):
126178 }
127179 }
128180
129- // /**
130- // * This method will delete the group, either by admin action or PI action
131- // */
132- // public function removeGroup($send_mail = true)
133- // {
134- // // remove any pending requests
135- // // this will silently fail if the request doesn't exist (which is what we want)
136- // $this->SQL->removeRequests($this->gid);
137-
138- // // we don't need to do anything extra if the group is already deleted
139- // if (!$this->exists()) {
140- // return;
141- // }
142-
143- // // first, we must record the users in the group currently
144- // $users = $this->getGroupMembers();
145-
146- // // now we delete the ldap entry
147- // $this->entry->ensureExists();
148- // $this->entry->delete();
149-
150- // // Logs the change
151- // $this->SQL->addLog("removed_group", $this->gid);
152-
153- // // send email to every user of the now deleted PI group
154- // if ($send_mail) {
155- // foreach ($users as $user) {
156- // $this->MAILER->sendMail(
157- // $user->getMail(),
158- // "group_disband",
159- // array("group_name" => $this->gid)
160- // );
161- // }
162- // }
163- // }
164-
165181 /**
166182 * This method is executed when a user is approved to join the group
167183 * (either by admin or the group owner)
@@ -220,7 +236,7 @@ public function removeUser(UnityUser $new_user, bool $send_mail = true): void
220236 return ;
221237 }
222238 if ($ new_user ->uid == $ this ->getOwner ()->uid ) {
223- throw new Exception ("Cannot delete group owner from group. Disband group instead " );
239+ throw new Exception ("Cannot delete group owner from group. Disable group instead " );
224240 }
225241 $ this ->removeMemberUID ($ new_user ->uid );
226242 $ this ->SQL ->addLog (
@@ -326,7 +342,7 @@ private function init(): void
326342 \ensure (!$ this ->entry ->exists ());
327343 $ nextGID = $ this ->LDAP ->getNextPIGIDNumber ();
328344 $ this ->entry ->create ([
329- "objectclass " => UnityLDAP:: POSIX_GROUP_CLASS ,
345+ "objectclass " => [ " unityClusterPIGroup " , " posixGroup " , " top " ] ,
330346 "gidnumber " => strval ($ nextGID ),
331347 "memberuid " => [$ owner ->uid ],
332348 ]);
@@ -376,4 +392,40 @@ public function getGroupMembersAttributes(array $attributes, array $default_valu
376392 $ default_values ,
377393 );
378394 }
395+
396+ public function getIsDisabled (): bool
397+ {
398+ $ value = $ this ->entry ->getAttribute ("isDisabled " );
399+ switch (count ($ value )) {
400+ case 0 :
401+ return false ;
402+ case 1 :
403+ switch ($ value [0 ]) {
404+ case "TRUE " :
405+ return true ;
406+ case "FALSE " :
407+ return false ;
408+ default :
409+ throw new \RuntimeException (
410+ sprintf (
411+ "unexpected value for isDisabled: '%s'. expected 'TRUE' or 'FALSE' " ,
412+ $ value [0 ],
413+ ),
414+ );
415+ }
416+ default :
417+ throw new \RuntimeException (
418+ sprintf (
419+ "expected value of length 0 or 1, found value %s of length %s " ,
420+ _json_encode ($ value ),
421+ count ($ value ),
422+ ),
423+ );
424+ }
425+ }
426+
427+ public function setIsDisabled (bool $ new_value ): void
428+ {
429+ $ this ->entry ->setAttribute ("isDisabled " , $ new_value ? "TRUE " : "FALSE " );
430+ }
379431}
0 commit comments