diff --git a/Controller/GrouperGroupsController.php b/Controller/GrouperGroupsController.php index 1a03e42..2d52501 100644 --- a/Controller/GrouperGroupsController.php +++ b/Controller/GrouperGroupsController.php @@ -97,81 +97,20 @@ private function setConnection() { } /** - * No true Index page, so sent to default page of Optin + * No true Index page, so sent to default page of My Membership * - * @return CakeResponse Redirect to Optin page + * @return CakeResponse Redirect to MyMembership page */ public function index() { return $this->redirect( - array('controller' => 'grouper_groups', 'action' => 'groupoptin') + array('controller' => 'grouper_groups', 'action' => 'groupmember') ); } - /** - * Display of Grouper Group Information, such as Group Properties, Members and Attributes - * - */ - public function groupInfo() { - $name = urldecode($this->request->query['groupname']); - - $this->set('isuserowner', $this->GrouperGroup->isUserOwner($this->userId)); - - $this->set('title', _txt('pl.grouperlite.title.groupinfo')); - - try { - $details = $this->GrouperGroup->groupDescriptions($name); - $this->set('groupergroupsdetail', $details[0]); - - } catch (Exception $e) { - CakeLog::write('error', __METHOD__ . ': ' . var_export($e->getMessage(), true)); - - $this->set('groupergroupsdetail', array()); - $this->Flash->set(_txt('pl.grouperlite.message.flash.info-group-failed'), array('key' => 'error')); - } - - try { - $groupMembers = $this->membersInGroup(); - $this->set('groupergroupssubscribers', $groupMembers); - } catch (Exception $e) { - CakeLog::write('error', __METHOD__ . ': ' . var_export($e->getMessage(), true)); - - $this->set('groupergroupssubscribers', array()); - $this->Flash->set(_txt('pl.grouperlite.message.flash.group-detail-members-failed'), array('key' => 'error')); - } - - $this->set('grouperbaseurl', $this->Session->read('Plugin.Grouper.Api.grouperUrl')); - } - - /** - * Show all members of group in Grouper Group detail page - * Called from method GroupInfo - * - */ - public function membersInGroup() { - $groupName = urldecode($this->request->query['groupname']); - - //Set initial - $scope = [ - 'groupName' => $groupName - ]; - - $details = []; - try { - $details = $this->GrouperGroup->membersInGroup($scope); - - } catch (Exception $e) { - CakeLog::write('error', __METHOD__ . ': ' . var_export($e->getMessage(), true)); - - $this->Flash->set(_txt('pl.grouperlite.message.flash.group-detail-members-failed'), array('key' => 'error')); - } - - return $details; - } - /** - * Show all members of group in Grouper Group detail page - * Called from method GroupInfo + * Show all members of a group + * Called from all pages via AJAX call * */ public function groupSubscribers() { @@ -194,7 +133,7 @@ public function groupSubscribers() { ]; try { - $subscribers = $this->GrouperGroup->membersInGroup($scope); + $subscribers = $this->GrouperGroup->membersInGroup($scope, $this->userId); } catch (Exception $e) { CakeLog::write('error', __METHOD__ . ': ' . var_export($e->getMessage(), true)); @@ -411,12 +350,19 @@ public function groupOptin() { */ public function groupCreateTemplate() { if ($this->request->is('post')) { - if (!$this->GrouperGroup->createGroupWithTemplate($this->userId, $this->request->data)) { - $this->Flash->set("Error in creating group!", array('key' => 'error')); - return $this->redirect(array('action' => 'groupoptin')); - } else { - $this->Flash->set("Success in creating group!", array('key' => 'success')); - return $this->redirect(array('action' => 'groupoptin')); + try { + $status = $this->GrouperGroup->createGroupWithTemplate($this->userId, $this->request->data); + + if ($status['status'] !== true) { + $this->Flash->set($status['message'], array('key' => 'error')); + } else { + $this->Flash->set("Success in creating group!", array('key' => 'success')); + return $this->redirect(array('action' => 'groupowner')); + } + + } catch (Exception $e) { + CakeLog::write('error', __METHOD__ . ': ' . var_export($e->getMessage(), true)); + $this->Flash->set(var_export($e->getMessage(), true), array('key' => 'error')); } } $this->set('title', _txt('pl.grouperlite.title.templatecreate')); @@ -424,7 +370,7 @@ public function groupCreateTemplate() { /** * Delete a Grouper Group via Grouper Template - * + * NOT USED IN CODE */ public function groupDeleteTemplate() { if (!$this->GrouperGroup->deleteGroupWithTemplate($this->userId, $this->request->data)) { @@ -435,33 +381,40 @@ public function groupDeleteTemplate() { $this->set('title', _txt('pl.grouperlite.title.templatecreate')); } - + /** + * @deprecated + * NOT USED IN CODE + * + * @return CakeResponse|void|null + */ public function groupCreate() { if ($this->request->is('post')) { if (!$this->GrouperGroup->createUpdateGroup($this->userId, $this->request->data)) { $this->Flash->set("Error in creating group!", array('key' => 'error')); - return $this->redirect(array('action' => 'groupOwner')); } else { $this->Flash->set("Your Group has been created!", array('key' => 'success')); - return $this->redirect(array('action' => 'groupOwner')); } + return $this->redirect(array('action' => 'groupOwner')); } $this->set('title', _txt('pl.grouperlite.title.groupcreate')); $this->set('grouperstems', $this->GrouperGroup->getOwnedStems($this->userId)); } - //TODO - Finish this call + + /** + * This method is currently not used. + * @return CakeResponse|null + */ public function groupDelete() { if (!$this->GrouperGroup->deleteGroup($this->userId, $this->request->data)) { $this->Flash->set("Error in deleting group!", array('key' => 'error')); - return $this->redirect(array('action' => 'groupOwner')); } else { $this->Flash->set("Your Group has been deleted!", array('key' => 'success')); - return $this->redirect(array('action' => 'groupOwner')); } $this->set('grouperstems', $this->GrouperGroup->getOwnedStems($this->userId)); + return $this->redirect(array('action' => 'groupOwner')); } @@ -484,7 +437,6 @@ public function joinGroup() { CakeLog::write('error', __METHOD__ . ': ' . var_export($e->getMessage(), true)); $this->Flash->set(_txt('pl.grouperlite.message.flash.join-group-error'), array('key' => 'error')); } - } else { $this->Flash->set(_txt('pl.grouperlite.message.flash.join-group-error')); } @@ -752,11 +704,10 @@ private function breakoutGroups(array $recordSet, $type = 'basic') { $wgRec['workingDesc'] = $this->hackDescription($rec['description']); //Capturing record for incommon-collab since deleting a few lines below. if ($rec['WGApp'] == 'incommon-collab') { - $recToDelete = $subCount; if ($type == 'basic') { //Removing record with stem of 'incommon-collab' since displaying on groups Member page, // will show on Admin page - unset($wgRec['Groups'][$recToDelete]); + unset($wgRec['Groups'][$subCount]); } } $subCount += 1; @@ -787,7 +738,6 @@ private function breakoutGroups(array $recordSet, $type = 'basic') { * */ private function hackDescription($description) { - //Verify description has period in it. if (strpos($description, ".") === false) { return $description; @@ -795,6 +745,5 @@ private function hackDescription($description) { $newString = substr($description, strpos($description, ".") + 1); return trim($newString); - } } diff --git a/Lib/GrouperApiAccess.php b/Lib/GrouperApiAccess.php index 091e994..518ddd7 100644 --- a/Lib/GrouperApiAccess.php +++ b/Lib/GrouperApiAccess.php @@ -73,6 +73,9 @@ public function __construct() { /** * Get Groups that User is a member of from Grouper. * + * Note: Params added at end make sure that the groups returned can only be viewed by the member logged into + * Grouper Lite + * * @param array $queryData Array of conditions for querying * @return array Membership records that User is a member of in Grouper * @throws GrouperLiteException @@ -81,7 +84,8 @@ public function getGrouperMemberOfGroups(array $queryData) { //Build request logic $userId = $queryData['userId']; - $connectionUrl = "{$this->config['fullUrl']}/subjects/{$userId}/groups"; + $connectionUrl = "{$this->config['fullUrl']}/subjects/$userId/groups?"; + $connectionUrl .= "wsLiteObjectType=WsRestGetGroupsLiteRequest&actAsSubjectSourceId=ldap&actAsSubjectId=$userId"; try { $results = $this->http->sendRequest('GET', $connectionUrl); @@ -91,7 +95,7 @@ public function getGrouperMemberOfGroups(array $queryData) { return $results['WsGetGroupsLiteResult']['wsGroups']; } } catch (Exception $e) { - CakeLog::write('error', __METHOD__ . ': An error occurred'); + CakeLog::write('error', __METHOD__ . ': An error occurred'); throw $e; } @@ -121,8 +125,8 @@ public function grouperGroupLeaveOrJoin(array $queryData) { $resultResponse = 'WsAddMemberResults'; $resultGroup = 'wsGroupAssigned'; } else { - CakeLog::write('error',__METHOD__ . ": Option of $groupLeaveOrJoin is not supported"); - throw new GrouperLiteException("Receved option of $groupLeaveOrJoin which is not supported"); + CakeLog::write('error', __METHOD__ . ": Option of $groupLeaveOrJoin is not supported"); + throw new GrouperLiteException("Received option of $groupLeaveOrJoin which is not supported"); } //Build request logic @@ -139,7 +143,7 @@ public function grouperGroupLeaveOrJoin(array $queryData) { ); $this->http->setHeader(array('Content-Type' => 'application/json', 'Accept' => 'application/json')); - $connectionUrl = "{$this->config['fullUrl']}/groups/{$groupName}/members"; + $connectionUrl = "{$this->config['fullUrl']}/groups/$groupName/members"; try { $results = $this->http->sendRequest('PUT', $connectionUrl, json_encode($groupCommand)); @@ -151,7 +155,7 @@ public function grouperGroupLeaveOrJoin(array $queryData) { } } } catch (Exception $e) { - CakeLog::write('error', __METHOD__ . ': An error occurred'); + CakeLog::write('error', __METHOD__ . ': An error occurred'); throw $e; } @@ -192,21 +196,63 @@ public function getOptionalGroups(array $queryData) { * */ public function getOwnedGroups(array $queryData) { - $queryData['groupType'] = 'Owner'; try { - $results = $this->useMembershipUrl($queryData); + $queryData['groupType'] = 'admin'; + $resultsAdmin = $this->useMembershipUrl($queryData); - if (isset($results['WsGetMembershipsResults']['wsGroups']) && $results['WsGetMembershipsResults']['wsGroups'] != NULL) { - return $results['WsGetMembershipsResults']['wsGroups']; + $queryData['groupType'] = 'update'; + $resultsUpdate = $this->useMembershipUrl($queryData); + + if (isset($resultsAdmin['WsGetMembershipsResults']['wsGroups']) && $resultsAdmin['WsGetMembershipsResults']['wsGroups'] != NULL) { + $admins = $resultsAdmin['WsGetMembershipsResults']['wsGroups']; + } else { + $admins = array(); + } + + if (isset($resultsUpdate['WsGetMembershipsResults']['wsGroups']) && $resultsUpdate['WsGetMembershipsResults']['wsGroups'] != NULL) { + $updaters = $resultsUpdate['WsGetMembershipsResults']['wsGroups']; + } else { + $updaters = array(); } + + return $this->removeDuplicates($admins, $updaters); } catch (Exception $e) { - CakeLog::write('error', __METHOD__ . ': An error occurred'); + CakeLog::write('error', __METHOD__ . ': An error occurred'); throw $e; } - return array(); } + /** + * Removes duplicates where the user is the owner and the updater of the group. Just one line instead of two. + * + * @param array $arrOne + * @param array $arrTwo + * @return array + */ + public function removeDuplicates(array $arrOne, array $arrTwo) { + + //Determine which array is bigger and use as base + $countOne = count($arrOne); + $countTwo = count($arrTwo); + if ($countOne >= $countTwo) { + $arrL = $arrOne; + $arrS = $arrTwo; + } else { + $arrL = $arrTwo; + $arrS = $arrOne; + } + + foreach ($arrL as $large) { + foreach ($arrS as $key => $val) { + if ($large['uuid'] == $val['uuid']) { + unset($arrS[$key]); + } + } + } + + return array_merge_recursive($arrL, $arrS); + } /** * Get members associated to a specific Grouper Group @@ -217,22 +263,32 @@ public function getOwnedGroups(array $queryData) { */ public function getMembersInGroup(array $queryData) { - //Build request logic - $usersToShow = array( - "WsRestGetMembersRequest" => array( - "wsGroupLookups" => array( - array("groupName" => $queryData['groupName']) - ), - "subjectAttributeNames" => array( - "name" + try { + // First verify that user has read access to group + if ($this->verifyPrivileges($queryData, 'read') === false) { + return array( + array( + "sourceId" => "ldap", + "name" => "You do not have access to memberships" + ) + ); + } + + //Build request logic + $usersToShow = array( + "WsRestGetMembersRequest" => array( + "wsGroupLookups" => array( + array("groupName" => $queryData['groupName']) + ), + "subjectAttributeNames" => array( + "name" + ) ) - ) - ); + ); - $this->http->setHeader(array('Content-Type' => 'application/json', 'Accept' => 'application/json')); - $connectionUrl = "{$this->config['fullUrl']}/groups"; + $this->http->setHeader(array('Content-Type' => 'application/json', 'Accept' => 'application/json')); + $connectionUrl = "{$this->config['fullUrl']}/groups"; - try { $results = $this->http->sendRequest('POST', $connectionUrl, json_encode($usersToShow)); // Parse out relevant records to send front end @@ -240,13 +296,51 @@ public function getMembersInGroup(array $queryData) { return $results['WsGetMembersResults']['results'][0]['wsSubjects']; } } catch (Exception $e) { - CakeLog::write('error', __METHOD__ . ': An error occurred'); + CakeLog::write('error', __METHOD__ . ': An error occurred'); throw $e; } return array(); } + /** + * @param array $queryData Array of conditions for querying + * @param string $privilege attribute verifying user has set + * @return bool If user has said attribute correctly set + * @throws GrouperLiteException + */ + public function verifyPrivileges(array $queryData, string $privilege) { + //Build request logic + $verifyPrivs = array( + "WsRestGetGrouperPrivilegesLiteRequest" => array( + "privilegeName" => $privilege, + "groupName" => $queryData['groupName'], + "subjectId" => $queryData['userId'] + ) + ); + + $this->http->setHeader(array('Content-Type' => 'application/json', 'Accept' => 'application/json')); + $connectionUrl = "{$this->config['fullUrl']}/grouperPrivileges"; + + try { + $results = $this->http->sendRequest('POST', $connectionUrl, json_encode($verifyPrivs)); + + // Parse out relevant records to send front end + if (isset($results['WsGetGrouperPrivilegesLiteResult']['resultMetadata']['resultCode']) && $results['WsGetGrouperPrivilegesLiteResult']['resultMetadata']['resultCode'] != NULL) { + if ($results['WsGetGrouperPrivilegesLiteResult']['resultMetadata']['resultCode'] == 'SUCCESS_ALLOWED') { + return true; + } else { + return false; + } + } + } catch (Exception $e) { + CakeLog::write('error', __METHOD__ . ': An error occurred'); + throw $e; + } + + return false; + } + /** * Gets all Stems/Folders where User is admin/owner * @@ -255,7 +349,7 @@ public function getMembersInGroup(array $queryData) { * @throws GrouperLiteException */ public function getOwnedStems(array $queryData) { - $queryData['groupType'] = 'StemOwner'; + $queryData['groupType'] = 'stemAdmin'; try { $results = $this->useMembershipUrl($queryData); @@ -264,7 +358,7 @@ public function getOwnedStems(array $queryData) { return $results['WsGetMembershipsResults']['wsStems']; } } catch (Exception $e) { - CakeLog::write('error', __METHOD__ . ': An error occurred'); + CakeLog::write('error', __METHOD__ . ': An error occurred'); throw $e; } return array(); @@ -273,41 +367,33 @@ public function getOwnedStems(array $queryData) { /** * Used for requests made to Membership endpoint in Grouper WS * - * @see getOptinGroups() - * @see getOptOutGroups() - * @see getOwnedGroups() - * @see getOwnedStems() - * * @param array $queryData Array of conditions for querying * @return array Group records associated to calling method * @throws GrouperLiteException + * + * @see getOwnedStems() + * @see getOptinGroups() + * @see getOptOutGroups() + * @see getOwnedGroups() */ private function useMembershipUrl(array $queryData) { $groupType = $queryData['groupType']; $userId = $queryData['userId']; - if ($groupType == 'Optins') { - $fieldName = "optins"; - $subjectId = "GrouperAll"; - } elseif ($groupType == 'Optouts') { - $fieldName = "optouts"; + if ($groupType == 'optins' || $groupType == 'optouts') { $subjectId = "GrouperAll"; - } elseif ($groupType == 'Owner') { - $fieldName = "admin"; - $subjectId = $userId; - } elseif ($groupType == 'StemOwner') { - $fieldName = "stemAdmin"; + } elseif ($groupType == 'admin' || $groupType == 'update' || $groupType == 'stemAdmin') { $subjectId = $userId; } else { - CakeLog::write('error', __METHOD__ . ": Option of $groupType is not supported"); + CakeLog::write('error', __METHOD__ . ": Option of $groupType is not supported"); throw new GrouperLiteException("Option of $groupType is not supported"); } - if ($groupType == 'Optins' || $groupType == 'Optouts') { + if ($groupType == 'optins' || $groupType == 'optouts') { //Build request logic, 2 subjectId's, second is for when user in "Secret" Optin/Optout Group $groupsToShow = array( "WsRestGetMembershipsRequest" => array( - "fieldName" => $fieldName, + "fieldName" => $groupType, "wsSubjectLookups" => array( array("subjectId" => $subjectId), array("subjectId" => $userId) @@ -318,7 +404,7 @@ private function useMembershipUrl(array $queryData) { //Build request logic $groupsToShow = array( "WsRestGetMembershipsRequest" => array( - "fieldName" => $fieldName, + "fieldName" => $groupType, "wsSubjectLookups" => array( array("subjectId" => $subjectId) ) @@ -326,29 +412,27 @@ private function useMembershipUrl(array $queryData) { ); } - $this->http->setHeader(array('Content-Type' => 'application/json', 'Accept' => 'application/json')); $connectionUrl = "{$this->config['fullUrl']}/memberships"; try { return $this->http->sendRequest('POST', $connectionUrl, json_encode($groupsToShow)); } catch (Exception $e) { - CakeLog::write('error', __METHOD__ . ': An error occurred'); + CakeLog::write('error', __METHOD__ . ': An error occurred'); throw $e; } } - /** - * Method used to CREATE a new Group in Grouper via the Template method. + * Method used to CREATE a new Group in Grouper via the Working Group Template method. * * @param array $queryData Array of conditions and data adding new Grouper Group - * @return bool True if added successfully + * @return array status and error message, if applicable * @throws GrouperLiteException * */ public function createGroupWithTemplate(array $queryData) { - //Currently only supporting create group, need to test if update a group will work! + //Currently, only supporting create group, need to test if update a group will work! $data = $queryData['data']; $userId = $queryData['userId']; @@ -361,7 +445,7 @@ public function createGroupWithTemplate(array $queryData) { //Build request logic $inputFields = array(); - foreach($data as $key => $value) { + foreach ($data as $key => $value) { $inputFields[] = array('name' => $key, 'value' => $value); } @@ -383,19 +467,41 @@ public function createGroupWithTemplate(array $queryData) { $this->http->setHeader(array('Content-Type' => 'application/json', 'Accept' => 'application/json')); $connectionUrl = "{$this->config['fullUrl']}/gshTemplateExec"; + $status = true; + $message = ''; try { $results = $this->http->sendRequest('POST', $connectionUrl, json_encode($groupToSave)); if (isset($results['WsGshTemplateExecResult']['resultMetadata']['resultCode'])) { - if (stripos($results['WsGshTemplateExecResult']['resultMetadata']['resultCode'], "SUCCESS", 0) !== false) { - return true; + if (stripos($results['WsGshTemplateExecResult']['resultMetadata']['resultCode'], "INVALID", 0) !== false) { + // Need to see what error message is + if (isset($results['WsGshTemplateExecResult']['gshValidationLines'])) { + //Just grab first one, since do not want to overload the user with errors, plus they won't understand message + $errorMessage = $results['WsGshTemplateExecResult']['gshValidationLines'][0]['validationText']; + $status = false; + if (stripos($errorMessage, 'already exist', 0) !== false) { + $message = 'There already is a WG named: ' . $data['gsh_input_workingGroupExtension']; + } else { + $message = 'An error occurred, please try again later.'; + } + } else { + $status = false; + $message = 'An error occurred, please try again later.'; + } + } elseif (stripos($results['WsGshTemplateExecResult']['resultMetadata']['resultCode'], "EXCEPTION", 0) !== false) { + throw new GrouperLiteException("An error occurred in creating your Working Group!"); } } } catch (Exception $e) { - CakeLog::write('error', __METHOD__ . ': An error occurred'); + CakeLog::write('error', __METHOD__ . ': An error occurred'); throw $e; } - return false; + + return array( + 'status' => $status, + 'message' => $message + ); + } /** @@ -443,7 +549,7 @@ public function deleteGroupWithTemplate(array $queryData) { } } } catch (Exception $e) { - CakeLog::write('error', __METHOD__ . ': An error occurred'); + CakeLog::write('error', __METHOD__ . ': An error occurred'); throw $e; } return false; @@ -505,7 +611,7 @@ public function createUpdateGroup(array $queryData) { } } } catch (Exception $e) { - CakeLog::write('error', __METHOD__ . ': An error occurred'); + CakeLog::write('error', __METHOD__ . ': An error occurred'); throw $e; } return false; @@ -554,7 +660,7 @@ public function getGrouperGroupInfo(array $queryData) { return $groupInfo; } catch (Exception $e) { - CakeLog::write('error', __METHOD__ . ': An error occurred'); + CakeLog::write('error', __METHOD__ . ': An error occurred'); throw $e; } } diff --git a/Lib/GrouperHTTPWrapper.php b/Lib/GrouperHTTPWrapper.php index 625d96c..dbcd822 100644 --- a/Lib/GrouperHTTPWrapper.php +++ b/Lib/GrouperHTTPWrapper.php @@ -113,39 +113,17 @@ public function sendRequest(string $method, string $uri, string $body = ''): arr $this->_request['body'] = $body; try { - $results = $this->request($this->_request); + $apiResults = $this->request($this->_request); } catch (Exception $e) { CakeLog::write('error', __METHOD__ . ': An error occurred: ' . var_export($e->getMessage(), true)); throw new GrouperLiteException('An error occurred talking to Grouper WS'); } - return $this->_verifyResults($results); - } - /** - * Verify data from Grouper Web Service came back successfully, if not log error and send to front end. - * - * @param HttpSocketResponse $apiResults Results from Grouper WS - * @return array array of records | array with error message - * @throws GrouperLiteException If issue with Grouper WS data returned - */ - private function _verifyResults(HttpSocketResponse $apiResults): array { - - $resBody = array(); - if ($apiResults->isOk()) { - $resBody = json_decode($apiResults->body(), true); - - $mainKey = key($resBody); - $apiSuccess = $resBody[$mainKey]['resultMetadata']['resultCode']; - - if ($apiSuccess != 'SUCCESS') { - CakeLog::write('error', __METHOD__ . ': Result Code was ' . var_export($apiSuccess, true)); - CakeLog::write('error', __METHOD__ . ': Error of ' . var_export($apiResults->body(), true)); - throw new GrouperLiteException('Result from Grouper WS was' . var_export($apiSuccess, true)); - } - } else { - CakeLog::write('error', __METHOD__ . ': Verify error of ' . var_export($apiResults->body(), true)); - throw new GrouperLiteException('An error occurred while talking to Grouper WS'); + // Call may return non-200, which may be okay depending on call + if (!$apiResults->isOk()) { + CakeLog::write('error', __METHOD__ . ': Grouper WS returned non-200 of ' . var_export($apiResults->body(), true)); } - return $resBody; + + return json_decode($apiResults->body(), true); } } diff --git a/Model/GrouperGroup.php b/Model/GrouperGroup.php index dd22c00..d5ebae4 100644 --- a/Model/GrouperGroup.php +++ b/Model/GrouperGroup.php @@ -47,7 +47,6 @@ class GrouperGroup extends GrouperLiteAppModel /** @var string Group whose members can create Groups via Template process */ private $templateCreationGroup = 'ref:workinggroupadmins'; - private $wgStemsTopLevel = array( 'ref:incommon-collab' ); @@ -61,17 +60,10 @@ class GrouperGroup extends GrouperLiteAppModel 'ref:incommon-collab' ); - private $emailStem ='app:sympa'; - + //Stem for email groups, only email groups using this stem are viewable + private $emailStem = 'app:sympa'; - // Current listing of stems that are allowed to be viewed in Comanage as AdHoc groups - private $stemsAdHocAllowed = array( - 'app', - 'org', - 'ref' - ); - /** * Verifies if user is an owner/admin of a group and then stores results in Session. * Session variable is reset on Group Creation and Group Deletion @@ -109,7 +101,6 @@ public function isUserOwner(string $userId) { } } - /** * Used to instantiate API class * @@ -124,18 +115,33 @@ private function initApi() { } } + /** + * Listing of members in an email group + * + * @param array $conditions Listing of conditions for display of records, including UserId + * @return array List of members that belong to email group + * @throws GrouperLiteException + * + */ public function filteredMemberOfEmails(array $conditions) { + $this->initApi(); - $memberOfEmails = $this->filteredMemberOfGroups($conditions); + try { + $memberOfEmails = $this->filteredMemberOfGroups($conditions); - // Strip out all Groups that are not in app:sympa Stem/Directory - foreach ($memberOfEmails as $key => $value) { - if (strpos(strtolower($value['name']), $this->emailStem) === false) { - unset($memberOfEmails[$key]); + // Strip out all Groups that are not in app:sympa Stem/Directory + foreach ($memberOfEmails as $key => $value) { + if (strpos(strtolower($value['name']), $this->emailStem) === false) { + unset($memberOfEmails[$key]); + } } + return array_values($memberOfEmails); + + } catch (Exception $e) { + CakeLog::write('error', __METHOD__ . ': An error occurred'); + throw $e; } - return array_values($memberOfEmails); } /** @@ -151,7 +157,7 @@ public function filteredMemberOfGroups(array $conditions) { $this->initApi(); try { - $conditions['groupType'] = 'Optouts'; + $conditions['groupType'] = 'optouts'; $memberOfGroups = $this->memberOfGroups($conditions); // Determine which groups can be left by user, if want. @@ -201,7 +207,7 @@ private function memberOfGroups(array $conditions) { * Gets the Grouper Groups params and values as well as its associated attributes. * * @param string $groupName Name of Group, do not confuse with DisplayName field! - * @return array An set of attributes associated to a specific Grouper Group + * @return array A set of attributes associated to a specific Grouper Group * @throws GrouperLiteException */ public function groupDescriptions(string $groupName) { @@ -287,9 +293,7 @@ public function ownerGroups(array $conditions) { $this->initApi(); try { - $ownGroups = $this->grouperAPI->getOwnedGroups($conditions); - - return $ownGroups; + return $this->grouperAPI->getOwnedGroups($conditions); } catch (Exception $e) { CakeLog::write('error', __METHOD__ . ': An error occurred'); @@ -303,16 +307,23 @@ public function ownerGroups(array $conditions) { * members * * @param array $conditions Listing of conditions for display of records + * @param string $userId Id of User * @return array Listing of members in requested Grouper Group * @throws GrouperLiteException Captured in Controller * */ - public function membersInGroup(array $conditions) { + public function membersInGroup(array $conditions, string $userId) { $this->initApi(); + $conditions['userId'] = $userId; + try { $groupMembers = $this->grouperAPI->getMembersInGroup($conditions); + if (count($groupMembers) < 1){ + return $groupMembers; + } + $finalMembers = array(); foreach ($groupMembers as $member) { if ($member['sourceId'] !== 'g:gsa') { @@ -328,17 +339,34 @@ public function membersInGroup(array $conditions) { } } + /** + * List of Email Groups a user can opt into. + * + * @param array $conditions Listing of conditions for display of records, including UserId + * @return array Listing of Optin email groups available in Groupe + * @throws GrouperLiteException Captured in Controller + * + */ public function optinEmailGroups(array $conditions) { - $allGroups = $this->optinGroups($conditions); + $this->initApi(); + + try { + $allGroups = $this->optinGroups($conditions); - // Strip out all Groups that are not in Sympa Stem/Directory - foreach ($allGroups as $key => $value) { - if (strpos($value['name'], $this->emailStem) === false) { - unset($allGroups[$key]); + // Strip out all Groups that are not in Sympa Stem/Directory + foreach ($allGroups as $key => $value) { + if (strpos($value['name'], $this->emailStem) === false) { + unset($allGroups[$key]); + } } + + return array_values($allGroups); + + } catch (Exception $e) { + CakeLog::write('error', __METHOD__ . ': An error occurred'); + throw $e; } - return array_values($allGroups); } /** @@ -354,7 +382,7 @@ public function optinGroups(array $conditions) { $this->initApi(); try { - $conditions['groupType'] = 'Optins'; + $conditions['groupType'] = 'optins'; $joinOrLeave = $this->grouperAPI->getOptionalGroups($conditions); $userGroups = $this->memberOfGroups($conditions); @@ -428,7 +456,7 @@ public function isTemplateUser(string $userId) { * * @param string $userId Id of User * @param array $groupData Data needed to create new Grouper Group via Template - * @return bool True if successfully created record + * @return array status and error message, if applicable * @throws GrouperLiteException * */ @@ -598,23 +626,71 @@ public function getSearchedGroups(array $conditions) { * * @param array $conditions Listing of conditions for display of records with pagination * @return array Records requested by user with pagination support + * @throws Exception Captured in Controller * */ public function paginate($conditions) { + try { + //Pull out the method that should be run. + $method = $conditions['method']; + + $resultSet = $this->$method($conditions); - //Pull out the method that should be run. - $method = $conditions['method']; + if (isset($conditions['emailonly']) && $conditions['emailonly']) { + if ($method == 'getSearchedGroups' || $method == 'filteredMemberOfEmails') { + $friendlyResults = $this->getFriendlyEmailName($resultSet, 'member'); + } else { + $friendlyResults = $this->getFriendlyEmailName($resultSet, ''); + } - $resultSet = $this->$method($conditions); + } else { + if ($method == 'getSearchedGroups' || $method == 'filteredMemberOfGroups') { + $friendlyResults = $this->getFriendlyWorkingGroupName($resultSet, 'member'); + } else { + $friendlyResults = $this->getFriendlyWorkingGroupName($resultSet, ''); + } + } - if (isset($conditions['emailonly']) && $conditions['emailonly']) { - $friendlyResults = $this->getFriendlyEmailName($resultSet); - } else { - $friendlyResults = $this->getFriendlyWorkingGroupName($resultSet); + return $this->paginateRecords($friendlyResults, $conditions); + } catch (Exception $e) { + CakeLog::write('error', __METHOD__ . ': An error occurred'); + throw $e; } + } + + /** + * Process that parses the email list and makes it more user friendly + * @lists. + * + * @param array $groups - Array of email lists + * @param $method - User who is accessing, if plain member remove admin and owner email lists. + * @return array - Array of friendly email lists + */ + private function getFriendlyEmailName(array $groups, $method) { - return $this->paginateRecords($friendlyResults, $conditions); + $arrayIndex = 0; + foreach ($groups as &$group) { + if ($method == 'member') { + if ($group['extension'] == 'admins' || $group['extension'] == 'owners') { + unset($groups[$arrayIndex]); + } + } + $stems = explode(':', $group['name']); + $sectionCount = count($stems) - 2; + $groupName = $stems[$sectionCount]; + $domain = $stems[2]; + if (strtolower($domain) == 'incommon') { + $address = $groupName . '@lists.incommon.org'; + } elseif (strtolower($domain) == 'internet2') { + $address = $groupName . '@lists.internet2.edu'; + } else { + $address = $groupName . '@lists.' . strtolower($domain) . '.org'; + } + $group['friendlyEmail'] = $address; + $arrayIndex += 1; + } + return $groups; } /** @@ -629,9 +705,10 @@ public function paginate($conditions) { * @return array Listing of Groups in WG format for display * */ - private function getFriendlyWorkingGroupName(array $groups) { + private function getFriendlyWorkingGroupName(array $groups, $method) { $arrayIndex = 0; + $workingGroups = array(); //First need to loop through all groups and pull in all top levels $topLevelWG = array(); @@ -642,8 +719,8 @@ private function getFriendlyWorkingGroupName(array $groups) { $stemSections = explode(':', $group['name']); //Get second to last stem section $sectionCount = count($stemSections) - 2; - if (in_array($stemSections[$sectionCount], $topLevelWG) === false){ - $topLevelWG[] = $stemSections[$sectionCount]; + if (in_array($stemSections[$sectionCount], $topLevelWG) === false) { + $topLevelWG[] = $stemSections[$sectionCount]; } } } @@ -659,7 +736,7 @@ private function getFriendlyWorkingGroupName(array $groups) { //Get second to last stem section $sectionCount = count($stemSections) - 2; //If group not part of a top level WG, then do not show! - if (in_array($stemSections[$sectionCount], $topLevelWG) === false){ + if (in_array($stemSections[$sectionCount], $topLevelWG) === false) { break; } $group['WGName'] = $stemSections[$sectionCount]; @@ -694,17 +771,18 @@ private function getFriendlyWorkingGroupName(array $groups) { } $group['WGApp'] = $appName; - //TODO - FOR DEMO PURPOSE THAT LEAVES OUT ADMIN GROUPS TO SHOW WHAT AVERAGE USER SEES -// if ($group['WGRole'] !== 'admins' && $group['WGRole'] !== 'owners') { -// $workingGroups[] = $group; -// } - $workingGroups[] = $group; + if ($method == 'member') { + if ($group['WGRole'] !== 'admins' && $group['WGRole'] !== 'owners') { + $workingGroups[] = $group; + } + } else { + $workingGroups[] = $group; + } unset($groups[$arrayIndex]); } } $arrayIndex += 1; } - $finalWorkingGroups = array(); foreach ($workingGroups as $workingGroup) { @@ -725,8 +803,7 @@ private function getFriendlyWorkingGroupName(array $groups) { } } - $filteredGroups = $this->verifyAdHocStem(array_values($groups)); - $friendlyGroups = $this->getFriendlyName($filteredGroups); + $friendlyGroups = $this->getFriendlyName(array_values($groups)); //Now need to add the groups back together for one set foreach ($friendlyGroups as $friendlyGroup) { @@ -736,55 +813,6 @@ private function getFriendlyWorkingGroupName(array $groups) { return $finalWorkingGroups; } - private function getFriendlyEmailName(array $groups) { - - foreach($groups as &$group) { - $appCount = 0; - $appName = ''; - $stems = explode(':', $group['name']); - $sectionCount = count($stems) - 2; - $groupName = $stems[$sectionCount]; - $domain = $stems[2]; - if (strtolower($domain) == 'incommon') { - $address = $groupName . '@lists.incommon.org'; - } elseif (strtolower($domain) == 'internet2') { - $address = $groupName . '@lists.internet2.edu'; - } else { - $address = $groupName . '@lists.' . strtolower($domain) . '.org'; - } - $group['friendlyEmail'] = $address; - } - return $groups; - } - - /** - * Verify that the AdHoc groups are only coming from stems listed in $stemsAdHocAllowed - * - * @param array $groups Array of Ad Hoc groups - * @return array Ad Hoc groups that are coming from approved stems - * - */ - private function verifyAdHocStem(array $groups) { - - foreach ($groups as $key => $value) { - $legit = true; - foreach ($this->stemsAdHocAllowed as $legitStem) { - $len = strlen($legitStem); - if (substr(strtolower($value['name']), 0, $len) === $legitStem) { - $legit = true; - break; - } else { - $legit = false; - } - } - if (!$legit) { - unset($groups[$key]); - } - - } - - return $groups; - } /** * Determine if result set contains friendly name, if so add as a new attribute in result set diff --git a/View/CoGrouperLites/display.ctp b/View/CoGrouperLites/display.ctp index c79eb73..f112905 100644 --- a/View/CoGrouperLites/display.ctp +++ b/View/CoGrouperLites/display.ctp @@ -94,7 +94,7 @@ echo $this->element('GrouperLite.base-styles'); array( 'plugin' => "grouper_lite", 'controller' => 'grouper_groups', - 'action' => 'emaillistsMember', + 'action' => 'emaillistsmember', 'co' => $coid, 'glid' => $glid ) @@ -117,7 +117,7 @@ echo $this->element('GrouperLite.base-styles'); array( 'plugin' => "grouper_lite", 'controller' => 'grouper_groups', - 'action' => 'emaillistsManage', + 'action' => 'emaillistsmanage', 'co' => $coid, 'glid' => $glid ) diff --git a/View/GrouperGroups/emaillistsmanage.ctp b/View/GrouperGroups/emaillistsmanage.ctp index 09793f6..7657544 100644 --- a/View/GrouperGroups/emaillistsmanage.ctp +++ b/View/GrouperGroups/emaillistsmanage.ctp @@ -17,14 +17,9 @@ - Html->link( - isset($group['name']) ? $group['domain'] . ':' . $group['name'] : "--", - array( - 'controller' => 'grouper_groups', - 'action' => 'emaillistinfo', - '?' => array('groupname' => urlencode($group['name'])) - ) - ) ?> + + + (10) | diff --git a/View/GrouperGroups/emaillistsmember.ctp b/View/GrouperGroups/emaillistsmember.ctp index d6952ec..c26d517 100644 --- a/View/GrouperGroups/emaillistsmember.ctp +++ b/View/GrouperGroups/emaillistsmember.ctp @@ -16,15 +16,9 @@ $group) : ?> - Html->link( - - $group['friendlyEmail'] ?? "No Name", - array( - 'controller' => 'grouper_groups', - 'action' => 'emaillistinfo', - '?' => array('groupname' => urlencode($group['name'])) - ) - ) ?> + + + element('GrouperLite.Components/optAction', array( diff --git a/View/GrouperGroups/emaillistsoptin.ctp b/View/GrouperGroups/emaillistsoptin.ctp index bfb2399..391109c 100644 --- a/View/GrouperGroups/emaillistsoptin.ctp +++ b/View/GrouperGroups/emaillistsoptin.ctp @@ -15,14 +15,9 @@ - Html->link( - $group['friendlyEmail'] ?? "No Name", - array( - 'controller' => 'grouper_groups', - 'action' => 'emaillistinfo', - '?' => array('groupname' => urlencode($group['name'])) - ) - ) ?> + + +