From 69c66adb93546fad567bfdec9e835f272ea1fef2 Mon Sep 17 00:00:00 2001 From: Ioannis Igoumenos Date: Thu, 15 Feb 2024 15:11:34 +0000 Subject: [PATCH 1/7] Refactoring backend.Naming conventions.CAKEPHPism and COmanage conform to conventions. --- Config/Schema/empty | 0 Config/Schema/schema.xml | 5 +- ...php => CoGrouperLiteWidgetsController.php} | 33 +- Controller/GrouperGroupsController.php | 624 +++++++----------- Controller/GrouperLiteAppController.php | 7 - Controller/GrouperLiteWidgetAppController.php | 7 + Lib/GrouperApiAccess.php | 432 ++++++------ Lib/GrouperHTTPWrapper.php | 6 +- ...ion.php => GrouperLiteWidgetException.php} | 4 +- Lib/empty | 0 Lib/enum.php | 9 + Lib/lang.php | 8 +- Model/CoGrouperLite.php | 98 --- Model/CoGrouperLiteWidget.php | 152 +++++ Model/CoManagePerson.php | 2 +- Model/GrouperAttribute.php | 12 +- Model/GrouperGroup.php | 154 ++--- ...{GrouperLite.php => GrouperLiteWidget.php} | 25 +- ...odel.php => GrouperLiteWidgetAppModel.php} | 2 +- .../display.ctp | 25 +- .../edit.ctp | 0 .../fields.inc | 87 ++- View/Elements/Components/vue-table.ctp | 84 +-- View/GrouperGroups/base.ctp | 11 +- View/GrouperGroups/groupmember.ctp | 2 +- View/GrouperGroups/groupoptin.ctp | 6 +- View/GrouperGroups/groupowner.ctp | 6 +- View/GrouperGroups/index.ctp | 82 +-- View/Layouts/error.ctp | 6 +- 29 files changed, 906 insertions(+), 983 deletions(-) delete mode 100644 Config/Schema/empty rename Controller/{CoGrouperLitesController.php => CoGrouperLiteWidgetsController.php} (70%) delete mode 100644 Controller/GrouperLiteAppController.php create mode 100644 Controller/GrouperLiteWidgetAppController.php rename Lib/{GrouperLiteException.php => GrouperLiteWidgetException.php} (94%) delete mode 100644 Lib/empty create mode 100644 Lib/enum.php delete mode 100644 Model/CoGrouperLite.php create mode 100644 Model/CoGrouperLiteWidget.php rename Model/{GrouperLite.php => GrouperLiteWidget.php} (79%) rename Model/{GrouperLiteAppModel.php => GrouperLiteWidgetAppModel.php} (95%) rename View/{CoGrouperLites => CoGrouperLiteWidgets}/display.ctp (87%) rename View/{CoGrouperLites => CoGrouperLiteWidgets}/edit.ctp (100%) rename View/{CoGrouperLites => CoGrouperLiteWidgets}/fields.inc (72%) diff --git a/Config/Schema/empty b/Config/Schema/empty deleted file mode 100644 index e69de29..0000000 diff --git a/Config/Schema/schema.xml b/Config/Schema/schema.xml index 1e39027..f2bfb51 100644 --- a/Config/Schema/schema.xml +++ b/Config/Schema/schema.xml @@ -25,7 +25,7 @@ must be specified in raw SQL, which needs the prefixed table name. --> - +
@@ -34,6 +34,7 @@ REFERENCES cm_co_dashboard_widgets(id) + @@ -44,7 +45,7 @@ - + co_dashboard_widget_id diff --git a/Controller/CoGrouperLitesController.php b/Controller/CoGrouperLiteWidgetsController.php similarity index 70% rename from Controller/CoGrouperLitesController.php rename to Controller/CoGrouperLiteWidgetsController.php index ccbaa42..1ea93f0 100644 --- a/Controller/CoGrouperLitesController.php +++ b/Controller/CoGrouperLiteWidgetsController.php @@ -2,16 +2,18 @@ App::uses("SDWController", "Controller"); -class CoGrouperLitesController extends SDWController { +class CoGrouperLiteWidgetsController extends SDWController { public $helpers = array('Html', 'Form', 'Flash'); public $components = array('Flash'); // Class name, used by Cake - public $name = "CoGrouperLites"; + public $name = "CoGrouperLiteWidgets"; public $uses = array( - "GrouperLite.CoGrouperLite" + 'GrouperLiteWidget.CoGrouperLiteWidget', + 'Identifier', + 'Co', ); /** @@ -21,13 +23,26 @@ class CoGrouperLitesController extends SDWController { */ function beforeRender() { + parent::beforeRender(); + $this->set('title_for_layout', _txt('pl.grouperlite.config.edit.title')); - parent::beforeRender(); + // Gather the available identifier address types for the config form + $this->set('vv_available_types', $this->Identifier->types($this->cur_co['Co']['id'], 'type')); + // Pass the config + $cfg = $this->CoGrouperLiteWidget->getConfig(); + $this->set('vv_config', $cfg); } + + /** + * Render the widget according to the requested user and current configuration. + * + * @since COmanage Registry v4.4.0 + * @param Integer $id CO Grouper Lite Widget ID + */ public function display($id) { - $cfg = $this->CoGrouperLite->getConfig(); + $cfg = $this->CoGrouperLiteWidget->getConfig(); $this->set('pl_grouperlite_index_url', Router::url([ 'plugin' => "grouper_lite", @@ -43,6 +58,14 @@ public function display($id) { // Pass the config so we know which div to overwrite $this->set('vv_config', $cfg); + + // Pass the Dashboard Widget configuration + $args = array(); + $args['conditions']['CoGrouperLiteWidget.id'] = $id; + $args['contain']['CoDashboardWidget'][] = 'CoDashboard'; + + $codw = $this->CoGrouperLiteWidget->find('first', $args); + $this->set('vv_codw', $codw); } diff --git a/Controller/GrouperGroupsController.php b/Controller/GrouperGroupsController.php index 03f0146..d0379bd 100644 --- a/Controller/GrouperGroupsController.php +++ b/Controller/GrouperGroupsController.php @@ -26,8 +26,8 @@ */ App::uses('Validator', 'Vendor/cakephp/Validation'); -App::uses('CoGrouperLite', 'GrouperLite.Model/'); -App::uses('GrouperGroup', 'GrouperLite.Model/'); +App::uses('CoGrouperLite', 'GrouperLiteWidget.Model/'); +App::uses('GrouperGroup', 'GrouperLiteWidget.Model/'); App::uses('Identifier', 'Model'); /** @@ -35,10 +35,19 @@ * Main Class for Grouper Lite functionality * */ -class GrouperGroupsController extends GrouperLiteAppController +class GrouperGroupsController extends GrouperLiteWidgetAppController { public $helpers = array('Html', 'Form', 'Flash'); - public $uses = array('GrouperLite.GrouperGroup', 'CoPerson'); + + // Dynamic properties are deprecated so we will define the property here + protected $userId = null; + + public $uses = array( + 'GrouperLiteWidget.GrouperGroup', + 'GrouperLiteWidget.CoGrouperLiteWidget', + 'Identifier', + 'CoPerson'); + public $components = array('Flash', 'Paginator', 'RequestHandler', 'Security' => array( 'validatePost' => false, 'csrfUseOnce' => false @@ -56,6 +65,11 @@ public function beforeFilter() { parent::beforeFilter(); + if(empty($this->request->params['named']['glid'])) { + throw new InvalidArgumentException(_txt('er.grouperlite.glid'), + HttpStatusCodesEnum::HTTP_BAD_REQUEST); + } + $this->Security->unlockedActions = array( 'removeSubscriber', 'addSubscriber', @@ -66,70 +80,37 @@ public function beforeFilter() 'groupOwner' ); - //Need to find which plugin instance choosing, if more than one from cm_co_grouper_lites - // table being used in COmanage. - $grouperConnData = $this->Session->read('Plugin.Grouper.Api'); - if ($this->Session->check('Plugin.Grouper.Api.id') && count($grouperConnData) == 10) { - if (isset($this->passedArgs['glid'])) { - if ($this->Session->read('Plugin.Grouper.Api.id') !== $this->passedArgs['glid']) { - $this->setConnection(); - } - } - } else { - if (!isset($this->passedArgs['glid'])) { - //If user links directly to GrouperLite url, will be redirected to main index to choose an - //appropriate Dashboard Widget. - return $this->redirect('/'); - } - $this->setConnection(); + if ($this->request->is('ajax')) { + $this->response->disableCache(); + $this->RequestHandler->addInputType('json', array('json_decode', true)); } - //Also check for CO of Organization - if (!$this->Session->check('Plugin.Grouper.Api.co')) { - $this->Session->write('Plugin.Grouper.Api.co', $this->passedArgs['co']); - } + // Get the config + $args = array(); + $args['conditions']['CoGrouperLiteWidget.id'] = $this->request->params["named"]["glid"]; + $args['contain'] = false; + $cfg = $this->CoGrouperLiteWidget->find('first', $args); + // Set the config so that everybody can access it + $this->CoGrouperLiteWidget->setConfig($cfg); } /** - * Adding Grouper Conn info to SESSION for use in Lib/GrouperApiAccess.php + * Callback after controller methods are invoked but before views are rendered. + * - precondition: Request Handler component has set $this->request + * + * @since COmanage Registry v4.4.0 */ - private function setConnection() - { - $this->Session->write('Plugin.Grouper.Api.id', $this->passedArgs['glid']); - $this->Session->write('Plugin.Grouper.Api.co', $this->passedArgs['co']); - - //Now get the setup Dasboard instance from db for connection info. - $getConnInfo = new CoGrouperLite(); - $connectionInfo = $getConnInfo->findById($this->passedArgs['glid']); - $this->Session->write('Plugin.Grouper.Api.url', $connectionInfo['CoGrouperLite']['conn_url']); - $this->Session->write('Plugin.Grouper.Api.version', $connectionInfo['CoGrouperLite']['conn_ver']); - $this->Session->write('Plugin.Grouper.Api.user', $connectionInfo['CoGrouperLite']['conn_user']); - $this->Session->write('Plugin.Grouper.Api.pass', $connectionInfo['CoGrouperLite']['conn_pass']); - $this->Session->write('Plugin.Grouper.Api.grouperUrl', $connectionInfo['CoGrouperLite']['grouper_url']); - - $this->Session->write('Plugin.Grouper.Api.adHocHeading', $connectionInfo['CoGrouperLite']['adhoc_heading']); - $this->Session->write('Plugin.Grouper.Api.wgHeading', $connectionInfo['CoGrouperLite']['wg_heading']); - $this->Session->write('Plugin.Grouper.Api.defaultCollapse', $connectionInfo['CoGrouperLite']['default_collapse']); - } - private function getConfig($page = 'groupmember') - { - $this->set('title', _txt('pl.grouperlite.title.groupmember')); + public function beforeRender() { + parent::beforeRender(); + $cfg = $this->CoGrouperLiteWidget->getConfig(); + $this->set('vv_config', $cfg); - $config = [ - "grouperbaseurl" => $this->Session->read('Plugin.Grouper.Api.grouperUrl'), - "isuserowner" => $this->GrouperGroup->isUserOwner($this->userId), - "isTemplateUser" => $this->GrouperGroup->isTemplateUser($this->userId), - "isGrouperVisible" => $this->GrouperGroup->isGrouperVisible($this->userId), - "defaultCollapse" => CakeSession::read('Plugin.Grouper.Api.defaultCollapse'), - "adHocHeading" => CakeSession::read('Plugin.Grouper.Api.adHocHeading'), - "wgHeading" => CakeSession::read('Plugin.Grouper.Api.wgHeading'), - 'co' => CakeSession::read('Plugin.Grouper.Api.co'), - 'glid' => $this->Session->read('Plugin.Grouper.Api.id'), - 'view' => $page - ]; - - return $config; + $this->set('title', _txt('pl.grouperlite.title.groupmember')); + $this->set('vv_is_user_owner', $this->GrouperGroup->isUserOwner($this->userId ?? '', $cfg) ); + $this->set('vv_is_template_user', $this->GrouperGroup->isTemplateUser($this->userId ?? '', $cfg) ); + $this->set('vv_is_grouper_visible', $this->GrouperGroup->isGrouperVisible($this->userId ?? '', $cfg)); + $this->set('vv_coid', $this->cur_co['Co']['id']); } /** @@ -137,26 +118,29 @@ private function getConfig($page = 'groupmember') * * @return CakeResponse Redirect to MyMembership page */ - public function index() - { - $this->set('config', $this->getConfig('groupmember')); - } + public function index() {} + /** + * @return void + */ public function groupMember() { - $this->set('config', $this->getConfig('groupmember')); $this->render('index'); } + /** + * @return void + */ public function groupOptin() { - $this->set('config', $this->getConfig('groupoptin')); $this->render('index'); } + /** + * @return void + */ public function groupOwner() { - $this->set('config', $this->getConfig('groupowner')); $this->render('index'); } @@ -168,25 +152,19 @@ public function groupOwner() public function groupSubscribers() { $groupName = urldecode($this->request->query['groupname']); - - if ($this->request->is('ajax')) { - $this->response->disableCache(); - } + $subscribers = 0; //Need to see if coming from AdHoc or from a WG (Working Group) - if (strpos($groupName, ':') === false) { - $groupNameFormatted = 'ref:incommon-collab:' . $groupName . ':users'; - } else { - $groupNameFormatted = $groupName; - } - + $groupNameFormatted = strpos($groupName, ':') === false ? 'ref:incommon-collab:' . $groupName . ':users' + : $groupName; //Set initial $scope = [ 'groupName' => $groupNameFormatted ]; try { - $subscribers = $this->GrouperGroup->membersInGroup($scope, $this->userId); + $subscribers = $this->GrouperGroup->membersInGroup($scope, $this->userId, $this->CoGrouperLiteWidget->getConfig()); + CakeLog::write('debug', __METHOD__ . '::response: ' . var_export($subscribers, true)); } catch (Exception $e) { CakeLog::write('error', __METHOD__ . ': ' . var_export($e->getMessage(), true)); @@ -195,21 +173,14 @@ public function groupSubscribers() } if(count($subscribers) < 1){ - $this->response->type('json'); - $this->response->statusCode(404); - //$this->response->body(json_encode(array('status' => 'ERROR', 'message' => 'NO ACCESS'))); - $this->response->send(); - $subscribers = ''; - } elseif (count($subscribers) == 1 && $subscribers[0]['sourceId'] == "NoAccess") { - $this->response->type('json'); - $this->response->statusCode(403); - //$this->response->body(json_encode(array('status' => 'ERROR', 'message' => 'NO ACCESS'))); - $this->response->send(); - $subscribers = ''; + $this->restResponse(HttpStatusCodesEnum::HTTP_NOT_FOUND, ErrorsEnum::Error); + } elseif (count($subscribers) == 1 + && $subscribers[0]['sourceId'] === 'NoAccess') { + $this->restResponse(HttpStatusCodesEnum::HTTP_FORBIDDEN, ErrorsEnum::NoAccess); } - $this->set(compact('subscribers')); - $this->set('_serialize', 'subscribers'); + $this->set(compact('subscribers')); + $this->set('_serialize', 'subscribers'); } /** @@ -217,22 +188,14 @@ public function groupSubscribers() * Called from all pages via AJAX call * */ - public function addSubscriber() - { + public function addSubscriber() { $groupName = urldecode($this->request->query['group']); $addUserId = urldecode($this->request->query['userId']); - - if ($this->request->is('ajax')) { - $this->response->disableCache(); - } + $resultAdd = ''; //Need to see if coming from AdHoc or from a WG (Working Group) - if (strpos($groupName, ':') === false) { - $groupNameFormatted = 'ref:incommon-collab:' . $groupName . ':users'; - } else { - $groupNameFormatted = $groupName; - } - + $groupNameFormatted = strpos($groupName, ':') === false ? 'ref:incommon-collab:' . $groupName . ':users' + : $groupName; //Set initial $scope = [ 'groupName' => $groupNameFormatted, @@ -240,30 +203,18 @@ public function addSubscriber() ]; try { - $resultAdd = $this->GrouperGroup->addMemberToGroup($scope, $this->userId); - + $resultAdd = $this->GrouperGroup->addMemberToGroup($scope, + $this->userId, $this->CoGrouperLiteWidget->getConfig()); + CakeLog::write('debug', __METHOD__ . '::response: ' . var_export($resultAdd, true)); } catch (Exception $e) { CakeLog::write('error', __METHOD__ . ': ' . var_export($e->getMessage(), true)); - $subscribers = 'ERROR'; - - // $this->Flash->set(_txt('pl.grouperlite.message.flash.group-detail-members-failed'), array('key' => 'error')); } - if ($resultAdd == 'SUCCESS') { - // Do nothing - } elseif ($resultAdd == 'EXCEPTION') { - $this->response->type('json'); - $this->response->statusCode(404); - $this->response->body(json_encode(array('status' => 'ERROR', 'message' => 'EXCEPTION'))); - $this->response->send(); - $resultAdd = ''; - } else { - $this->response->type('json'); - $this->response->statusCode(401); - $this->response->body(json_encode(array('status' => 'ERROR', 'message' => 'ERROR'))); - $this->response->send(); + if ($resultAdd !== 'SUCCESS') { + $this->restResponse(HttpStatusCodesEnum::HTTP_UNAUTHORIZED, ErrorsEnum::Error); $resultAdd = ''; } + $this->set(compact('resultAdd')); $this->set('_serialize', 'resultAdd'); @@ -275,14 +226,7 @@ public function addSubscriber() * to work. * */ - public function findSubscriber() - { - - if ($this->request->is('ajax')) { - $this->response->disableCache(); - } - - // $groupName = urldecode($this->request->query['group']); + public function findSubscriber() { $findUserId = urldecode($this->request->query['term']); $co = urldecode($this->request->query['co']); @@ -390,22 +334,14 @@ public function findSubscriber() * Called from all pages via AJAX call * */ - public function removeSubscriber() - { + public function removeSubscriber() { $groupName = urldecode($this->request->query['group']); $remUserId = urldecode($this->request->query['userId']); - - if ($this->request->is('ajax')) { - $this->response->disableCache(); - } + $resultRemove = ''; //Need to see if coming from AdHoc or from a WG (Working Group) - if (strpos($groupName, ':') === false) { - $groupNameFormatted = 'ref:incommon-collab:' . $groupName . ':users'; - } else { - $groupNameFormatted = $groupName; - } - + $groupNameFormatted = (strpos($groupName, ':') === false) ? 'ref:incommon-collab:' . $groupName . ':users' + : $groupName; //Set initial $scope = [ 'groupName' => $groupNameFormatted, @@ -413,23 +349,20 @@ public function removeSubscriber() ]; try { - $resultRemove = $this->GrouperGroup->removeMemberToGroup($scope, $this->userId); + $resultRemove = $this->GrouperGroup->removeMemberToGroup($scope, + $this->userId, + $this->CoGrouperLiteWidget->getConfig()); + CakeLog::write('debug', __METHOD__ . '::response: ' . var_export($resultRemove, true)); } 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')); } - if ($resultRemove == 'SUCCESS') { - // Do nothing - } else { - $this->response->type('json'); - $this->response->statusCode(404); - $this->response->body(json_encode(array('status' => 'ERROR', 'message' => 'ERROR'))); - $this->response->send(); + if ($resultRemove != 'SUCCESS') { + $this->restResponse(HttpStatusCodesEnum::HTTP_NOT_FOUND, ErrorsEnum::Error); $resultRemove = ''; } + $this->set(compact('resultRemove')); $this->set('_serialize', 'resultRemove'); } @@ -437,12 +370,7 @@ public function removeSubscriber() /** * Listing of all Grouper Groups owned/admin by User Or search those Grouper Groups */ - public function groupOwnerApi() - { - if ($this->request->is('ajax')) { - $this->response->disableCache(); - } - + public function groupOwnerApi() { //Set initial setting $scope = [ 'userId' => $this->userId @@ -450,44 +378,29 @@ public function groupOwnerApi() if (isset($this->request->query['search'])) { $searchCriteria = urldecode($this->request->query['search']); - $this->set('searchcriteria', $searchCriteria); - - try { - //Add settings for search Owned Groups - $scope['method'] = 'getSearchedGroups'; - $scope['searchcriteria'] = $searchCriteria; - $scope['searchpage'] = 'ownerGroups'; - - $groupowners = $this->GrouperGroup->getSearchedGroups($scope); - - } catch (Exception $e) { - CakeLog::write('error', __METHOD__ . ' Search: ' . var_export($e->getMessage(), true)); - $this->response->type('json'); - $this->response->statusCode(500); - $this->response->send(); - $this->set('groupsowners', array()); - - $this->Flash->set(_txt('pl.grouperlite.message.flash.owner-group-failed'), array('key' => 'error')); - return; - } + //Add settings for search Owned Groups + $scope['method'] = 'getSearchedGroups'; + $scope['searchcriteria'] = $searchCriteria; + $scope['searchpage'] = 'ownerGroups'; + $errorHint = 'Search'; } else { - try { - $scope['method'] = 'ownerGroups'; - - $groupowners = $this->GrouperGroup->ownerGroups($scope); - - } catch (Exception $e) { - CakeLog::write('error', __METHOD__ . ': ' . var_export($e->getMessage(), true)); - $this->response->type('json'); - $this->response->statusCode(500); - $this->response->send(); - $this->set('groupsowners', array()); + $scope['method'] = 'ownerGroups'; + $errorHint = ''; + } + try { + $func = $scope['method']; + $groupowners = $this->GrouperGroup->$func($scope, $this->CoGrouperLiteWidget->getConfig()); + CakeLog::write('debug', __METHOD__ . "::response: " . var_export($groupowners, true)); + } catch (Exception $e) { + CakeLog::write('error', __METHOD__ . "::{$errorHint}: " . var_export($e->getMessage(), true)); + $this->restResponse(HttpStatusCodesEnum::HTTP_INTERNAL_SERVER_ERROR, ErrorsEnum::Exception); - $this->Flash->set(_txt('pl.grouperlite.message.flash.owner-group-failed'), array('key' => 'error')); - return; - } + $this->set('groupsowners', array()); + $this->Flash->set(_txt('pl.grouperlite.message.flash.owner-group-failed'), array('key' => 'error')); + return; } + $this->set(compact('groupowners')); $this->set('_serialize', 'groupowners'); } @@ -497,12 +410,7 @@ public function groupOwnerApi() * This includes self-joined Optin Groups, as well as required Groups User cannot leave * */ - public function groupMemberApi() - { - if ($this->request->is('ajax')) { - $this->response->disableCache(); - } - + public function groupMemberApi() { //Set initial setting $scope = [ 'userId' => $this->userId @@ -510,66 +418,44 @@ public function groupMemberApi() if (isset($this->request->query['search'])) { $searchCriteria = urldecode($this->request->query['search']); - $this->set('searchcriteria', $searchCriteria); - try { - //Add settings for search Member Groups - $scope['method'] = 'getSearchedGroups'; - $scope['searchcriteria'] = $searchCriteria; - $scope['searchpage'] = 'filteredMemberOfGroups'; - $scope['ContainsWG'] = true; - - $data = $this->GrouperGroup->getSearchedGroups($scope); - - $finalData = $this->breakoutGroups($data); - - } catch (Exception $e) { - CakeLog::write('error', __METHOD__ . ' Search: ' . var_export($e->getMessage(), true)); - $this->response->type('json'); - $this->response->statusCode(500); - $this->response->send(); - $this->set('groupmemberships', array()); - $this->set('wgmemberships', array()); - - $this->Flash->set("Your Search Group cannot be found, please try again later.", array('key' => 'error')); - return; - } + //Add settings for search Member Groups + $scope['method'] = 'getSearchedGroups'; + $scope['searchcriteria'] = $searchCriteria; + $scope['searchpage'] = 'filteredMemberOfGroups'; + $scope['ContainsWG'] = true; + $errorHint = 'Search'; } else { - try { - //Add setting for Group Membership - $scope['method'] = 'filteredMemberOfGroups'; + //Add setting for Group Membership + $scope['method'] = 'filteredMemberOfGroups'; + $errorHint = ''; + } - $data = $this->GrouperGroup->filteredMemberOfGroups($scope); + try { + $func = $scope['method']; + $data = $this->GrouperGroup->$func($scope, + $this->CoGrouperLiteWidget->getConfig()); + $finalData = $this->breakoutGroups($data); + } catch (Exception $e) { + CakeLog::write('error', __METHOD__ . "::{$errorHint}: " . var_export($e->getMessage(), true)); - $finalData = $this->breakoutGroups($data); + $this->restResponse(HttpStatusCodesEnum::HTTP_INTERNAL_SERVER_ERROR, ErrorsEnum::Exception); + $this->set('groupmemberships', []); + $this->set('wgmemberships', []); - } catch (Exception $e) { - CakeLog::write('error', __METHOD__ . ': ' . var_export($e->getMessage(), true)); - $this->response->type('json'); - $this->response->statusCode(500); - $this->response->send(); - $this->set('groupmemberships', array()); - $this->set('wgmemberships', array()); - - $this->Flash->set("Your Member Group cannot be found, please try again later.", array('key' => 'error')); - return; - } + $this->Flash->set('Your Member Group cannot be found, please try again later.', array('key' => 'error')); + return; } - $this->set(compact('finalData')); - $this->set('_serialize', 'finalData'); + $this->set(compact('finalData')); + $this->set('_serialize', 'finalData'); } /** * Display all Groups a User can Join */ - public function groupOptinApi() - { - if ($this->request->is('ajax')) { - $this->response->disableCache(); - } - + public function groupOptinApi() { //Set initial setting $scope = [ 'userId' => $this->userId @@ -577,45 +463,30 @@ public function groupOptinApi() if (isset($this->request->query['search'])) { $searchCriteria = urldecode($this->request->query['search']); - $this->set('searchcriteria', $searchCriteria); + //Add settings for search Optin's + $scope['method'] = 'getSearchedGroups'; + $scope['searchcriteria'] = $searchCriteria; + $scope['searchpage'] = 'optinGroups'; + $errorHint = 'Search'; - try { - //Add settings for search Optin's - $scope['method'] = 'getSearchedGroups'; - $scope['searchcriteria'] = $searchCriteria; - $scope['searchpage'] = 'optinGroups'; - - $groupoptins = $this->GrouperGroup->getSearchedGroups($scope); - - } catch (Exception $e) { - CakeLog::write('error', __METHOD__ . 'Search: ' . var_export($e->getMessage(), true)); - $this->response->type('json'); - $this->response->statusCode(500); - $this->response->send(); - $this->set('groupoptins', array()); - - $this->Flash->set("Your Optin Group Search cannot be found, please try again later.", array('key' => 'error')); - return; - } } else { - try { - //Add settings for optinGroups - $scope['method'] = 'optinGroups'; - - $groupoptins = $this->GrouperGroup->optinGroups($scope); - - } catch (Exception $e) { - CakeLog::write('error', __METHOD__ . ': ' . var_export($e->getMessage(), true)); - $this->response->type('json'); - $this->response->statusCode(500); - $this->response->send(); - $this->set('groupoptins', array()); + $scope['method'] = 'optinGroups'; + $errorHint = ''; + } + try { + $func = $scope['method']; + $groupoptins = $this->GrouperGroup->$func($scope, + $this->CoGrouperLiteWidget->getConfig()); + } catch (Exception $e) { + CakeLog::write('error', __METHOD__ . "::{$errorHint}: " . var_export($e->getMessage(), true)); + $this->restResponse(HttpStatusCodesEnum::HTTP_INTERNAL_SERVER_ERROR, ErrorsEnum::Exception); + $this->set('groupoptins', array()); - $this->Flash->set("An error occurred with the Optin Groups, please try again later.", array('key' => 'error')); - return; - } + $this->Flash->set('An error occurred with the Optin Groups, please try again later.', array('key' => 'error')); + return; } + $this->set(compact('groupoptins')); $this->set('_serialize', 'groupoptins'); } @@ -626,14 +497,14 @@ public function groupOptinApi() * Note: This is tightly coupled code to requirements, so view is hardcoded to reflect current reqs. Will need * to update when reqs change or are updated!!! * - * Editing via a template will not be supported in this version of the plugin - Bill Kaufman - * */ public function groupCreateTemplate() { if ($this->request->is('post')) { try { - $status = $this->GrouperGroup->createGroupWithTemplate($this->userId, $this->request->data); + $status = $this->GrouperGroup->createGroupWithTemplate($this->userId, + $this->request->data, + $this->CoGrouperLiteWidget->getConfig()); if ($status['status'] !== true) { $this->Flash->set($status['message'], array('key' => 'error')); @@ -658,33 +529,18 @@ public function groupCreateTemplate() */ public function joinGroup() { + $resultAdd = 'Success'; $name = urldecode($this->request->query['GroupName']); $display = urldecode($this->request->query['GroupDisplayName']); - if ($this->request->is('ajax')) { - $this->response->disableCache(); - } - try { - if ($this->GrouperGroup->joinGroup($this->userId, $name)) { - /*$this->Flash->set( - _txt('pl.grouperlite.message.flash.join-group-success', array(filter_var($display, FILTER_SANITIZE_SPECIAL_CHARS))), - array('key' => 'success') - );*/ - $resultAdd = "Success"; - } else { - $this->response->type('json'); - $this->response->statusCode(401); - $this->response->body(json_encode(array('status' => 'ERROR', 'message' => 'NOT ADDED'))); - $this->response->send(); + if (!$this->GrouperGroup->joinGroup($this->userId, $name)) { + $this->restResponse(HttpStatusCodesEnum::HTTP_UNAUTHORIZED, ErrorsEnum::NotAdded); $resultAdd = ''; } } catch (Exception $e) { CakeLog::write('error', __METHOD__ . ': ' . var_export($e->getMessage(), true)); - $this->response->type('json'); - $this->response->statusCode(404); - $this->response->body(json_encode(array('status' => 'ERROR', 'message' => 'EXCEPTION'))); - $this->response->send(); + $this->restResponse(HttpStatusCodesEnum::HTTP_NOT_FOUND, ErrorsEnum::Exception); $resultAdd = ''; } @@ -701,27 +557,18 @@ public function leaveGroup() { $name = urldecode($this->request->query['GroupName']); $display = urldecode($this->request->query['GroupDisplayName']); - - if ($this->request->is('ajax')) { - $this->response->disableCache(); - } + $resultRemove = 'Success'; try { - if ($this->GrouperGroup->leaveGroup($this->userId, $name)) { - $resultRemove = "Success"; - } else { - $this->response->type('json'); - $this->response->statusCode(401); - $this->response->body(json_encode(array('status' => 'ERROR', 'message' => 'NOT DELETED'))); - $this->response->send(); + if (!$this->GrouperGroup->leaveGroup($this->userId, + $name, + $this->CoGrouperLiteWidget->getConfig())) { + $this->restResponse(HttpStatusCodesEnum::HTTP_UNAUTHORIZED, ErrorsEnum::NotDeleted); $resultRemove = ''; } } catch (Exception $e) { CakeLog::write('error', __METHOD__ . ': ' . var_export($e->getMessage(), true)); - $this->response->type('json'); - $this->response->statusCode(404); - $this->response->body(json_encode(array('status' => 'ERROR', 'message' => 'EXCEPTION'))); - $this->response->send(); + $this->restResponse(HttpStatusCodesEnum::HTTP_NOT_FOUND, ErrorsEnum::Exception); $resultRemove = ''; } @@ -744,44 +591,22 @@ function isAuthorized() { $roles = $this->Role->calculateCMRoles(); - /** - * The following code displays a few custom implementations of the - * login process used to crosswalk a user for Grouper authentication. - * - * You may need to further customize this section to meet your organization - * crosswalk needs. - */ - - /** - * Default when login-id is the same as grouper id - */ - // Default Begin =============================================== - - /* - if ($this->Session->check('Auth.User.username')) { - $this->userId = $this->Session->read('Auth.User.username'); - } - */ - // Default End =============================================== - - /** - * Customized Crosswalk from login-id to Grouper Username - */ - // Custom Begin =============================================== - - $username = $this->Session->read('Auth.User.username'); + // Find the identifier + $args = array(); + // XXX This should become configuration + $args['conditions']['Identifier.type'] = 'I2CollabPN'; + $args['conditions']['Identifier.status'] = SuspendableStatusEnum::Active; + $args['conditions']['Identifier.co_person_id'] = $roles["copersonid"]; + $args['contain'] = false; - if ($this->Session->check('Plugin.Grouper.UserId')) { - $this->userId = $this->Session->read('Plugin.Grouper.UserId'); - } else { - $uid = $this->getPersonIdFromUsername($username); - $this->userId = $this->getUserId($uid); - $this->Session->write('Plugin.Grouper.UserId', $this->userId); + $identifiers = $this->Identifier->find('first', $args); + if(!empty($identifiers) + && is_array($identifiers) + && isset($identifiers["Identifier"]["identifier"]) + ) { + $this->userId = $identifiers["Identifier"]["identifier"]; } - // Custom End =============================================== - - // Determine what operations this user can perform // Construct the permission set for this user, which will also be passed to the view. //Note: Leaving in current format, in case need to restrict certain pages, can just remove true and add params. @@ -810,48 +635,15 @@ function isAuthorized() return ($p[$this->action]); } - private function getPersonIdFromUsername($username) - { - $args = array(); - $args['conditions']['Identifier.identifier'] = $username; - $args['conditions']['Identifier.status'] = SuspendableStatusEnum::Active; - $args['conditions']['Identifier.deleted'] = false; - $args['conditions']['Identifier.identifier_id'] = null; - $args['conditions']['NOT']['Identifier.co_person_id'] = null; - $args['conditions']['Identifier.type'] = 'eppn'; - $args['contain'] = false; - - $Identifier = new Identifier(); - $co_person_id = $Identifier->find('first', $args); - - return $co_person_id['Identifier']['co_person_id']; - } - - private function getUserId($id) - { - $args = array(); - $args['conditions']['Identifier.co_person_id'] = $id; - $args['conditions']['Identifier.type'] = 'I2CollabPN'; - $args['conditions']['Identifier.status'] = SuspendableStatusEnum::Active; - $args['contain'] = false; - - $Identifier = new Identifier(); - $grouper_identifier = $Identifier->find('first', $args); - - return $grouper_identifier['Identifier']['identifier']; - } - /** * Breakout Working Groups from AdHoc Groups for display purposes in UI. * * @param array $recordSet - * @param string $type 'basic' = view in Member page, 'admin' = view in Admin page, 'optin' = View in Optin page * @return array[] * */ - private function breakoutGroups(array $recordSet, $type = 'basic') + private function breakoutGroups(array $recordSet) { - //TODO - May move this logic down into the GrouperGroup model file, once all is agreed upon. $wgData = array(); $notWGData = array(); //Parse out the Working Groups from the Ad-hoc groups @@ -869,5 +661,69 @@ private function breakoutGroups(array $recordSet, $type = 'basic') ); } + /** + * Override the default sanity check performed in AppController + * + * @since COmanage Registry v4.3.0 + * @return Boolean True if sanity check is successful + */ + public function verifyRequestedId() { + return true; + } + + + /** + * For Models that accept a CO ID, find the provided CO ID. + * - precondition: A coid must be provided in $this->request (params or data) + * + * @since COmanage Registry v4.3.0 + * @return Integer The CO ID if found, or -1 if not + */ + + public function parseCOID($data = null) { + if(!empty($this->request->params["named"]["co"])) { + return $this->request->params["named"]["co"]; + } + if(!empty($this->request->params["named"]["glid"])) { + $connectionInfo = $this->CoGrouperLiteWidget->findById($this->passedArgs['glid']); + $this->CoGrouperLiteWidget->CoDashboardWidget->CoDashboard->id = $connectionInfo["CoDashboardWidget"]["co_dashboard_id"]; + $co_id = $this->CoGrouperLiteWidget->CoDashboardWidget->CoDashboard->field('co_id'); + + if(!empty($co_id)) { + return $co_id; + } + } + + return -1; + } + + /** + * Prepare a REST result HTTP header. + * - precondition: HTTP headers must not yet have been sent + * - postcondition: CakeResponse configured with header + * + * @param integer $status HTTP result code + * @param array $body HTTP result comment + * @param string $contentType HTTP Response content Type + * @param $statusTxt $contentType Status text + * + * @throws JsonException + * @since COmanage Registry v4.4.4 + */ + + public function restResponse(int $status, + array $body=[], + string $contentType = 'json', + ?string $statusTxt = null) { + if(isset($statusTxt)) { + // We need to update the text associated with $status + $this->response->httpCodes(array($status => $statusTxt)); + } + + $this->response->type($contentType); + $this->response->statusCode($status); + $this->response->body(json_encode($body, JSON_THROW_ON_ERROR)); + $this->response->send(); + } } \ No newline at end of file diff --git a/Controller/GrouperLiteAppController.php b/Controller/GrouperLiteAppController.php deleted file mode 100644 index 15ac4ac..0000000 --- a/Controller/GrouperLiteAppController.php +++ /dev/null @@ -1,7 +0,0 @@ -http = new GrouperHTTPWrapper(); - if (!CakeSession::check('Plugin.Grouper.Api.id')) { - CakeLog::write('error', __METHOD__ . ': No Widget record in Session'); - throw new GrouperLiteException("No GrouperLite instance captured"); + if (empty($cfg['CoGrouperLiteWidget']['id'])) { + throw new GrouperLiteWidgetException('No GrouperLite instance captured'); } - $connUrl = CakeSession::read('Plugin.Grouper.Api.url'); - $connVer = CakeSession::read('Plugin.Grouper.Api.version'); + $connUrl = $cfg['CoGrouperLiteWidget']['conn_url']; + $connVer = $cfg['CoGrouperLiteWidget']['conn_ver']; $this->config['fullUrl'] = $connUrl . $this->_urlServlet . $connVer; - $this->http->setUser(CakeSession::read('Plugin.Grouper.Api.user')); - $this->http->setPassword(CakeSession::read('Plugin.Grouper.Api.pass')); + $this->http->setUser($cfg['CoGrouperLiteWidget']['conn_user']); + $this->http->setPassword($cfg['CoGrouperLiteWidget']['conn_pass']); } /** @@ -79,7 +78,7 @@ public function __construct() * * @param array $queryData Array of conditions for querying * @return array Membership records that User is a member of in Grouper - * @throws GrouperLiteException + * @throws GrouperLiteWidgetException */ public function getGrouperMemberOfGroups(array $queryData) { @@ -91,6 +90,7 @@ public function getGrouperMemberOfGroups(array $queryData) try { $results = $this->http->sendRequest('GET', $connectionUrl); + CakeLog::write('debug', __METHOD__ . '::response: ' . var_export($results, true)); // Parse out relevant records to send front end if (isset($results['WsGetGroupsLiteResult']['wsGroups']) && $results['WsGetGroupsLiteResult']['wsGroups'] != NULL) { @@ -108,12 +108,12 @@ public function getGrouperMemberOfGroups(array $queryData) * For Optin groups, calls Grouper WS to join or leave a group * * @param array $queryData Array of conditions for querying + * * @return bool True if join or leave successful, False if not - * @throws GrouperLiteException + * @throws GrouperLiteWidgetException|JsonException */ public function grouperGroupLeaveOrJoin(array $queryData) { - $groupName = $queryData['groupName']; $userId = $queryData['userId']; $groupLeaveOrJoin = $queryData['LeaveJoin']; @@ -129,7 +129,7 @@ public function grouperGroupLeaveOrJoin(array $queryData) $resultGroup = 'wsGroupAssigned'; } else { CakeLog::write('error', __METHOD__ . ": Option of $groupLeaveOrJoin is not supported"); - throw new GrouperLiteException("Received option of $groupLeaveOrJoin which is not supported"); + throw new GrouperLiteWidgetException("Received option of $groupLeaveOrJoin which is not supported"); } //Build request logic @@ -149,9 +149,10 @@ public function grouperGroupLeaveOrJoin(array $queryData) $connectionUrl = "{$this->config['fullUrl']}/groups/$groupName/members"; try { - $results = $this->http->sendRequest('PUT', $connectionUrl, json_encode($groupCommand)); + $results = $this->http->sendRequest('PUT', $connectionUrl, json_encode($groupCommand, JSON_THROW_ON_ERROR)); + CakeLog::write('debug', __METHOD__ . '::response: ' . var_export($results, true)); - if (isset($results[$resultResponse][$resultGroup]) && $results[$resultResponse][$resultGroup] != NULL) { + if (isset($results[$resultResponse][$resultGroup])) { $groupAssigned = $results[$resultResponse][$resultGroup]['name']; if ($groupAssigned == urldecode($groupName)) { return true; @@ -172,7 +173,7 @@ public function grouperGroupLeaveOrJoin(array $queryData) * * @param array $queryData Array of conditions for querying * @return array Optin groups from Grouper - * @throws GrouperLiteException + * @throws GrouperLiteWidgetException * */ public function getOptionalGroups(array $queryData) @@ -180,8 +181,9 @@ public function getOptionalGroups(array $queryData) try { $results = $this->useMembershipUrl($queryData); + CakeLog::write('debug', __METHOD__ . '::response: ' . var_export($results, true)); - if (isset($results['WsGetMembershipsResults']['wsGroups']) && $results['WsGetMembershipsResults']['wsGroups'] != NULL) { + if (isset($results['WsGetMembershipsResults']['wsGroups'])) { return $results['WsGetMembershipsResults']['wsGroups']; } } catch (Exception $e) { @@ -196,29 +198,28 @@ public function getOptionalGroups(array $queryData) * * @param array $queryData Array of conditions for querying * @return array Array of groups from Grouper - * @throws GrouperLiteException + * @throws GrouperLiteWidgetException * */ public function getOwnedGroups(array $queryData) { + $admins = array(); + $updaters = array(); try { $queryData['groupType'] = 'admin'; $resultsAdmin = $this->useMembershipUrl($queryData); + CakeLog::write('debug', __METHOD__ . '::response admins: ' . var_export($resultsAdmin, true)); $queryData['groupType'] = 'update'; $resultsUpdate = $this->useMembershipUrl($queryData); + CakeLog::write('debug', __METHOD__ . '::response updates: ' . var_export($resultsUpdate, true)); - if (isset($resultsAdmin['WsGetMembershipsResults']['wsGroups']) && $resultsAdmin['WsGetMembershipsResults']['wsGroups'] != NULL) { + if (isset($resultsAdmin['WsGetMembershipsResults']['wsGroups'])) { $admins = $resultsAdmin['WsGetMembershipsResults']['wsGroups']; - } else { - $admins = array(); } - - if (isset($resultsUpdate['WsGetMembershipsResults']['wsGroups']) && $resultsUpdate['WsGetMembershipsResults']['wsGroups'] != NULL) { + if (isset($resultsUpdate['WsGetMembershipsResults']['wsGroups'])) { $updaters = $resultsUpdate['WsGetMembershipsResults']['wsGroups']; - } else { - $updaters = array(); } return $this->removeDuplicates($admins, $updaters); @@ -264,40 +265,43 @@ public function removeDuplicates(array $arrOne, array $arrTwo) * Get members associated to a specific Grouper Group * * @param array $queryData Array of conditions for querying + * * @return array Listing of Members belonging to Grouper Group - * @throws GrouperLiteException + * @throws GrouperLiteWidgetException|JsonException */ - public function getMembersInGroup(array $queryData) - { + public function getMembersInGroup(array $queryData) { + //Build request logic + $usersToShow = array( + 'WsRestGetMembersRequest' => array( + 'actAsSubjectLookup' => array( + 'subjectId' => $queryData['userId'] + ), + 'wsGroupLookups' => array( + array('groupName' => $queryData['groupName']) + ), + 'subjectAttributeNames' => array('name') + ) + ); + $connectionUrl = "{$this->config['fullUrl']}/groups"; - try { - //Build request logic - $usersToShow = array( - "WsRestGetMembersRequest" => array( - "actAsSubjectLookup" => array( - "subjectId" => $queryData['userId'] - ), - "wsGroupLookups" => array( - array("groupName" => $queryData['groupName']) - ), - "subjectAttributeNames" => array( - "name" - ) - ) - ); + try { $this->http->setHeader(array('Content-Type' => 'application/json', 'Accept' => 'application/json')); - $connectionUrl = "{$this->config['fullUrl']}/groups"; - $results = $this->http->sendRequest('POST', $connectionUrl, json_encode($usersToShow)); + $results = $this->http->sendRequest('POST', $connectionUrl, json_encode($usersToShow, JSON_THROW_ON_ERROR)); + + CakeLog::write('debug', __METHOD__ . '::response: ' . var_export($results, true)); // Parse out relevant records to send front end - if(isset($results['WsGetMembersResults']['results'][0]['resultMetadata']['resultCode']) && $results['WsGetMembersResults']['results'][0]['resultMetadata']['resultCode'] != NULL){ - if ($results['WsGetMembersResults']['results'][0]['resultMetadata']['resultCode'] == 'GROUP_NOT_FOUND'){ - return array(array("sourceId" => "NoAccess", "name" => "", "id" => "")); - } + if(isset($results['WsGetMembersResults']['results'][0]['resultMetadata']['resultCode']) + && $results['WsGetMembersResults']['results'][0]['resultMetadata']['resultCode'] == 'GROUP_NOT_FOUND') { + return array(array( + 'sourceId' => 'NoAccess', + 'name' => '', + 'id' => '' + )); } - if (isset($results['WsGetMembersResults']['results'][0]['wsSubjects']) && $results['WsGetMembersResults']['results'][0]['wsSubjects'] != NULL) { + if (isset($results['WsGetMembersResults']['results'][0]['wsSubjects'])) { return $results['WsGetMembersResults']['results'][0]['wsSubjects']; } } catch (Exception $e) { @@ -312,35 +316,37 @@ public function getMembersInGroup(array $queryData) * Add a member to a specific Grouper Group * * @param array $queryData Array of conditions for querying + * * @return string Requests success or not - * @throws GrouperLiteException + * @throws GrouperLiteWidgetException|JsonException */ public function addMemberToGroup(array $queryData) { + $groupName = $queryData['groupName']; + $connectionUrl = "{$this->config['fullUrl']}/groups/$groupName/members"; - try { - $groupName = $queryData['groupName']; - - //Build request logic - $usersToAdd = array( - "WsRestAddMemberRequest" => array( - "subjectLookups" => array( - array("subjectId" => $queryData['addUserId']), - ), - "replaceAllExisting" => "F", - "actAsSubjectLookup" => array( - "subjectId" => $queryData['userId'] - ) + //Build request logic + $usersToAdd = array( + 'WsRestAddMemberRequest' => array( + 'subjectLookups' => array( + array('subjectId' => $queryData['addUserId']), + ), + 'replaceAllExisting' => 'F', + 'actAsSubjectLookup' => array( + 'subjectId' => $queryData['userId'] ) - ); + ) + ); - $this->http->setHeader(array('Content-Type' => 'application/json', 'Accept' => 'application/json')); - $connectionUrl = "{$this->config['fullUrl']}/groups/$groupName/members"; + $this->http->setHeader(array('Content-Type' => 'application/json', 'Accept' => 'application/json')); + + try { + $results = $this->http->sendRequest('PUT', $connectionUrl, json_encode($usersToAdd, JSON_THROW_ON_ERROR)); - $results = $this->http->sendRequest('PUT', $connectionUrl, json_encode($usersToAdd)); + CakeLog::write('debug', __METHOD__ . '::response: ' . var_export($results, true)); // Parse out relevant records to send front end - if (isset($results['WsAddMemberResults']['results'][0]['resultMetadata']) && $results['WsAddMemberResults']['results'][0]['resultMetadata'] != NULL) { + if (isset($results['WsAddMemberResults']['results'][0]['resultMetadata'])) { return $results['WsAddMemberResults']['results'][0]['resultMetadata']['resultCode']; } } catch (Exception $e) { @@ -348,40 +354,45 @@ public function addMemberToGroup(array $queryData) throw $e; } - return ""; + return ''; } /** * Remove a member from a specific Grouper Group * - * @param array $queryData Array of conditions for querying + * @param array $queryData Array of conditions for querying + * * @return string Requests success or not - * @throws GrouperLiteException + * + * @throws GrouperLiteWidgetException + * @throws JsonException */ public function removeMemberToGroup(array $queryData) { + $groupName = $queryData['groupName']; + $connectionUrl = "{$this->config['fullUrl']}/groups/$groupName/members"; - try { - $groupName = $queryData['groupName']; - - //Build request logic - $userToDelete = array( - "WsRestDeleteMemberRequest" => array( - "subjectLookups" => array( - array("subjectId" => $queryData['remUserId']), - ), - "actAsSubjectLookup" => array( - "subjectId" => $queryData['userId'] - ) + //Build request logic + $userToDelete = array( + 'WsRestDeleteMemberRequest' => array( + 'subjectLookups' => array( + array('subjectId' => $queryData['remUserId']), + ), + 'actAsSubjectLookup' => array( + 'subjectId' => $queryData['userId'] ) - ); + ) + ); - $this->http->setHeader(array('Content-Type' => 'application/json', 'Accept' => 'application/json')); - $connectionUrl = "{$this->config['fullUrl']}/groups/$groupName/members"; - $results = $this->http->sendRequest('POST', $connectionUrl, json_encode($userToDelete)); + $this->http->setHeader(array('Content-Type' => 'application/json', 'Accept' => 'application/json')); + + try { + $results = $this->http->sendRequest('POST', $connectionUrl, json_encode($userToDelete, JSON_THROW_ON_ERROR)); + + CakeLog::write('debug', __METHOD__ . '::response: ' . var_export($results, true)); // Parse out relevant records to send front end - if (isset($results['WsDeleteMemberResults']['results'][0]['resultMetadata']) && $results['WsDeleteMemberResults']['results'][0]['resultMetadata'] != NULL) { + if (isset($results['WsDeleteMemberResults']['results'][0]['resultMetadata'])) { return $results['WsDeleteMemberResults']['results'][0]['resultMetadata']['resultCode']; } } catch (Exception $e) { @@ -389,7 +400,7 @@ public function removeMemberToGroup(array $queryData) throw $e; } - return ""; + return ''; } /** @@ -397,7 +408,7 @@ public function removeMemberToGroup(array $queryData) * * @param array $queryData Array of conditions for querying * @return array Group records associated to calling method - * @throws GrouperLiteException + * @throws GrouperLiteWidgetException * * @see getOwnedStems() * @see getOptinGroups() @@ -408,48 +419,39 @@ private function useMembershipUrl(array $queryData) { $groupType = $queryData['groupType']; $userId = $queryData['userId']; - + if ($groupType == 'optins' || $groupType == 'optouts') { - $subjectId = "GrouperAll"; + $subjectId = 'GrouperAll'; } elseif ($groupType == 'admin' || $groupType == 'update' || $groupType == 'stemAdmin') { $subjectId = $userId; } else { CakeLog::write('error', __METHOD__ . ": Option of $groupType is not supported"); - throw new GrouperLiteException("Option of $groupType is not supported"); + throw new GrouperLiteWidgetException("Option of $groupType is not supported"); } - if ($groupType == 'optins' || $groupType == 'optouts') { + //Build request logic + $groupsToShow = []; + $groupsToShow['WsRestGetMembershipsRequest']['fieldName'] = $groupType; + $groupsToShow['WsRestGetMembershipsRequest']['wsSubjectLookups'][0]['subjectId'] = $subjectId; + + 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" => $groupType, - "wsSubjectLookups" => array( - array("subjectId" => $subjectId), - array("subjectId" => $userId) - ) - ) - ); - } else { - //Build request logic - $groupsToShow = array( - "WsRestGetMembershipsRequest" => array( - "fieldName" => $groupType, - "wsSubjectLookups" => array( - array("subjectId" => $subjectId) - ) - ) - ); + $groupsToShow['WsRestGetMembershipsRequest']['wsSubjectLookups'][1]['subjectId'] = $userId; } $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)); + $results = $this->http->sendRequest('POST', $connectionUrl, json_encode($groupsToShow)); + CakeLog::write('debug', __METHOD__ . '::response: ' . var_export($results, true)); } catch (Exception $e) { CakeLog::write('error', __METHOD__ . ': An error occurred'); throw $e; } + + return $results; } /** @@ -457,7 +459,7 @@ private function useMembershipUrl(array $queryData) * * @param array $queryData Array of conditions and data adding new Grouper Group * @return array status and error message, if applicable - * @throws GrouperLiteException + * @throws GrouperLiteWidgetException * */ public function createGroupWithTemplate(array $queryData) @@ -469,8 +471,7 @@ public function createGroupWithTemplate(array $queryData) //need to take out SympaDomain if domain not being created. if ($data['gsh_input_isSympa'] == 'false') { - unset($data['gsh_input_sympaDomain']); - unset($data['gsh_input_isSympaModerated']); + unset($data['gsh_input_sympaDomain'], $data['gsh_input_isSympaModerated']); } //Build request logic @@ -480,17 +481,17 @@ public function createGroupWithTemplate(array $queryData) } $groupToSave = array( - "WsRestGshTemplateExecRequest" => array( - "gshTemplateActAsSubjectLookup" => array( - "subjectSourceId" => "ldap", - "subjectId" => $userId + 'WsRestGshTemplateExecRequest' => array( + 'gshTemplateActAsSubjectLookup' => array( + 'subjectSourceId' => 'ldap', + 'subjectId' => $userId ), - "ownerStemLookup" => array( - "stemName" => "ref:incommon-collab" + 'ownerStemLookup' => array( + 'stemName' => 'ref:incommon-collab' ), - "ownerType" => "stem", - "configId" => "createNewWorkingGroup", - "inputs" => $inputFields + 'ownerType' => 'stem', + 'configId' => 'createNewWorkingGroup', + 'inputs' => $inputFields ) ); @@ -501,47 +502,40 @@ public function createGroupWithTemplate(array $queryData) $message = ''; try { $results = $this->http->sendRequest('POST', $connectionUrl, json_encode($groupToSave)); - - if (isset($results['WsGshTemplateExecResult']['resultMetadata']['resultCode'])) { - 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'); throw $e; } - return array( - 'status' => $status, - 'message' => $message - ); + if (isset($results['WsGshTemplateExecResult']['resultMetadata']['resultCode'])) { + $status = false; + $message = 'An error occurred, please try again later.'; + + CakeLog::write('error', __METHOD__ . ': An error occurred in creating your Working Group!'); + + if (isset($results['WsGshTemplateExecResult']['gshValidationLines'][0]['validationText']) + && stripos( + $results['WsGshTemplateExecResult']['gshValidationLines'][0]['validationText'], + 'already exist', + 0 ) !== false) + { + $message = 'There already is a WG named: ' . $data['gsh_input_workingGroupExtension']; + } elseif (stripos($results['WsGshTemplateExecResult']['resultMetadata']['resultCode'], 'EXCEPTION', 0) !== false) { + throw new GrouperLiteWidgetException('An error occurred in creating your Working Group!'); + } + } + return compact('status', 'message'); } /** - * ======================== NOT BEING USED ======================== * * Method used to DELETE a Group in Grouper via the Template method. * * @param array $queryData Array of conditions and data adding new Grouper Group + * * @return bool True if deleted successfully - * @throws GrouperLiteException + * @throws GrouperLiteWidgetException|JsonException * */ public function deleteGroupWithTemplate(array $queryData) @@ -551,20 +545,20 @@ public function deleteGroupWithTemplate(array $queryData) $userId = $queryData['userId']; $groupToDelete = array( - "WsRestGshTemplateExecRequest" => array( - "gshTemplateActAsSubjectLookup" => array( - "subjectSourceId" => "ldap", - "subjectId" => $userId + 'WsRestGshTemplateExecRequest' => array( + 'gshTemplateActAsSubjectLookup' => array( + 'subjectSourceId' => 'ldap', + 'subjectId' => $userId ), - "ownerStemLookup" => array( - "stemName" => "ref:incommon-collab" + 'ownerStemLookup' => array( + 'stemName' => 'ref:incommon-collab' ), - "ownerType" => "stem", - "configId" => "createWorkingGroup", - "inputs" => array( + 'ownerType' => 'stem', + 'configId' => 'createWorkingGroup', + 'inputs' => array( array( - "name" => "gsh_input_workingGroupExtension", - "value" => $workingGroupExt + 'name' => 'gsh_input_workingGroupExtension', + 'value' => $workingGroupExt ) ) ) @@ -574,30 +568,34 @@ public function deleteGroupWithTemplate(array $queryData) $connectionUrl = "{$this->config['fullUrl']}/gshTemplateExec"; try { - $results = $this->http->sendRequest('POST', $connectionUrl, json_encode($groupToDelete)); - - if (isset($results['WsGshTemplateExecResult']['resultMetadata']['resultCode'])) { - if (stripos($results['WsGshTemplateExecResult']['resultMetadata']['resultCode'], "SUCCESS", 0) !== false) { - return true; - } - } + $results = $this->http->sendRequest('POST', $connectionUrl, json_encode($groupToDelete, JSON_THROW_ON_ERROR)); + CakeLog::write('debug', __METHOD__ . '::response: ' . var_export($results, true)); } catch (Exception $e) { CakeLog::write('error', __METHOD__ . ': An error occurred'); throw $e; } + + if (isset($results['WsGshTemplateExecResult']['resultMetadata']['resultCode']) && stripos( + $results['WsGshTemplateExecResult']['resultMetadata']['resultCode'], + 'SUCCESS', + 0 + ) !== false) { + return true; + } + return false; } /** - * ======================== NOT BEING USED ======================== * * For creating/updating Ad-Hoc groups not using the Grouper Template format * * Create or Update a Group where User is Admin/Owner * * @param array $queryData Array of conditions and data adding new Grouper Group + * * @return bool True if added or updated successful - * @throws GrouperLiteException + * @throws GrouperLiteWidgetException|JsonException */ public function createUpdateGroup(array $queryData) { @@ -606,7 +604,6 @@ public function createUpdateGroup(array $queryData) $stemName = htmlentities($queryData['stem']); $userId = $queryData['userId']; $groupDescription = htmlentities($queryData['description']); - $privileges = $queryData['privileges']; //Group name may be in "friendly" format, so need to do some small conversions before saving. $newGroupName = ucfirst(strtolower($groupName)); @@ -616,19 +613,19 @@ public function createUpdateGroup(array $queryData) //Build request logic $groupToSave = array( - "WsRestGroupSaveRequest" => array( - "actAsSubjectLookup" => array( - "subjectId" => $userId + 'WsRestGroupSaveRequest' => array( + 'actAsSubjectLookup' => array( + 'subjectId' => $userId ), - "wsGroupToSaves" => array( + 'wsGroupToSaves' => array( array( - "wsGroup" => array( - "description" => $groupDescription, - "name" => $newGroupToSave, - "displayExtension" => $groupName + 'wsGroup' => array( + 'description' => $groupDescription, + 'name' => $newGroupToSave, + 'displayExtension' => $groupName ), - "wsGroupLookup" => array( - "groupName" => $groupDescription + 'wsGroupLookup' => array( + 'groupName' => $groupDescription ) ) ) @@ -638,29 +635,34 @@ public function createUpdateGroup(array $queryData) $connectionUrl = "{$this->config['fullUrl']}/groups"; try { - $results = $this->http->sendRequest('POST', $connectionUrl, json_encode($groupToSave)); - - if (isset($results['WsGroupSaveResults']['results']['resultMetadata']['resultCode'])) { - if (stripos($results['WsGroupSaveResults']['results']['resultMetadata']['resultCode'], "Success", 0) !== false) { - return true; - } - } + $results = $this->http->sendRequest('POST', $connectionUrl, json_encode($groupToSave, JSON_THROW_ON_ERROR)); + CakeLog::write('debug', __METHOD__ . '::response: ' . var_export($results, true)); } catch (Exception $e) { CakeLog::write('error', __METHOD__ . ': An error occurred'); throw $e; } + + if (isset($results['WsGroupSaveResults']['results']['resultMetadata']['resultCode']) + && stripos( + $results['WsGroupSaveResults']['results']['resultMetadata']['resultCode'], + 'Success', + 0 + ) !== false) { + return true; + } + return false; } /** - * ======================== NOT BEING USED ======================== * Used to be used for Grouper group info page. * * Grouper Group information plus a listing of attributes in Grouper for that given Group * * @param array $queryData Array of conditions for querying + * * @return array Record of Grouper attributes for given GroupName - * @throws GrouperLiteException + * @throws GrouperLiteWidgetException|JsonException */ public function getGrouperGroupInfo(array $queryData) { @@ -669,12 +671,12 @@ public function getGrouperGroupInfo(array $queryData) //Build request logic $stemToFind = array( - "WsRestGetAttributeAssignmentsRequest" => array( - "attributeAssignType" => "group", - "includeAssignmentsOnAssignments" => "T", - "wsOwnerGroupLookups" => array( + 'WsRestGetAttributeAssignmentsRequest' => array( + 'attributeAssignType' => 'group', + 'includeAssignmentsOnAssignments' => 'T', + 'wsOwnerGroupLookups' => array( array( - "groupName" => $groupName, + 'groupName' => $groupName, ) ) ) @@ -683,25 +685,23 @@ public function getGrouperGroupInfo(array $queryData) $connectionUrl = "{$this->config['fullUrl']}/attributeAssignments"; try { - $results = $this->http->sendRequest('POST', $connectionUrl, json_encode($stemToFind)); + $results = $this->http->sendRequest('POST', $connectionUrl, json_encode($stemToFind, JSON_THROW_ON_ERROR)); + CakeLog::write('debug', __METHOD__ . '::response: ' . var_export($results, true)); - //Get the group information - if (isset($results['WsGetAttributeAssignmentsResults']['wsGroups']) && $results['WsGetAttributeAssignmentsResults']['wsGroups'] != NULL) { - $groupInfo = $results['WsGetAttributeAssignmentsResults']['wsGroups']; - } - - //Now get the Group Attributes and add them to group - if (isset($results['WsGetAttributeAssignmentsResults']['wsAttributeAssigns']) && $results['WsGetAttributeAssignmentsResults']['wsAttributeAssigns'] != NULL) { - $groupInfo[0]["attributes"] = $results['WsGetAttributeAssignmentsResults']['wsAttributeAssigns']; - } else { - $groupInfo[0]["attributes"] = array(); - } - - return $groupInfo; } catch (Exception $e) { CakeLog::write('error', __METHOD__ . ': An error occurred'); throw $e; } + + //Get the group information + if (isset($results['WsGetAttributeAssignmentsResults']['wsGroups'])) { + $groupInfo = $results['WsGetAttributeAssignmentsResults']['wsGroups']; + } + + //Now get the Group Attributes and add them to group + $groupInfo[0]['attributes'] = $results['WsGetAttributeAssignmentsResults']['wsAttributeAssigns'] ?? array(); + + return $groupInfo; } /** @@ -713,7 +713,7 @@ public function getGrouperGroupInfo(array $queryData) * * @param array $queryData Array of conditions for querying * @return array Array of Stems/Folders from Grouper - * @throws GrouperLiteException + * @throws GrouperLiteWidgetException */ public function getOwnedStems(array $queryData) { diff --git a/Lib/GrouperHTTPWrapper.php b/Lib/GrouperHTTPWrapper.php index dbcd822..9df9640 100644 --- a/Lib/GrouperHTTPWrapper.php +++ b/Lib/GrouperHTTPWrapper.php @@ -26,7 +26,7 @@ */ App::uses('HttpSocket', 'Network/Http'); -App::uses('GrouperLiteException', 'GrouperLite.Lib/'); +App::uses('GrouperLiteWidgetException', 'GrouperLiteWidget.Lib/'); /** * Class GrouperHTTPWrapper @@ -102,7 +102,7 @@ public function setHeader(array $headerSetting) { * @param string $uri Grouper RESTful endpoint with request string, if applicable * @param string $body JSON formatted request, if applicable * @return array array of records | array with error message - * @throws GrouperLiteException If issue with Grouper WS connection + * @throws GrouperLiteWidgetException If issue with Grouper WS connection */ public function sendRequest(string $method, string $uri, string $body = ''): array { @@ -116,7 +116,7 @@ public function sendRequest(string $method, string $uri, string $body = ''): arr $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'); + throw new GrouperLiteWidgetException('An error occurred talking to Grouper WS'); } // Call may return non-200, which may be okay depending on call diff --git a/Lib/GrouperLiteException.php b/Lib/GrouperLiteWidgetException.php similarity index 94% rename from Lib/GrouperLiteException.php rename to Lib/GrouperLiteWidgetException.php index 6e4621b..7ac0890 100644 --- a/Lib/GrouperLiteException.php +++ b/Lib/GrouperLiteWidgetException.php @@ -25,10 +25,10 @@ * @license Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) */ -class GrouperLiteException extends Exception +class GrouperLiteWidgetException extends Exception { /** - * GrouperLiteException constructor. + * GrouperLiteWidgetException constructor. * @param $message * @param int $code * @param Exception|null $previous diff --git a/Lib/empty b/Lib/empty deleted file mode 100644 index e69de29..0000000 diff --git a/Lib/enum.php b/Lib/enum.php new file mode 100644 index 0000000..dd4aaa0 --- /dev/null +++ b/Lib/enum.php @@ -0,0 +1,9 @@ + 'ERROR', 'message' => 'EXCEPTION'); + const NotDeleted = array('status' => 'ERROR', 'message' => 'NOT DELETED'); + const NotAdded = array('status' => 'ERROR', 'message' => 'NOT ADDED'); + const Error = array('status' => 'ERROR', 'message' => 'ERROR'); + const NoAccess = array('status' => 'ERROR', 'message' => 'NO ACCESS'); +} \ No newline at end of file diff --git a/Lib/lang.php b/Lib/lang.php index bcae1dd..8c26b24 100644 --- a/Lib/lang.php +++ b/Lib/lang.php @@ -1,6 +1,6 @@ 'Grouper Configuration Settings', 'pl.grouperlite.config.edit.title' => 'Edit Grouper Configuration Settings', 'pl.grouperlite.config.grouper-url' => 'Grouper Site URL', @@ -15,6 +15,8 @@ 'pl.grouperlite.config.wg-subscript' => '', 'pl.grouperlite.config.default-collapse' => 'Collapse groups by default?', 'pl.grouperlite.config.default-collapse-subscript' => '', + 'pl.grouperlite.config.identifier' => 'Identifier Type', + 'pl.grouperlite.config.identifier.desc' => 'Identifier eligible to make requests to Grouper', 'pl.grouperlite.crumb.root' => 'Grouper', 'pl.grouperlite.nav.groups-can-join' => 'Groups I can join', @@ -166,5 +168,7 @@ 'pl.grouperlite.working-groups.zero-state' => 'None.', 'pl.grouperlite.email-lists.zero-state' => 'No email lists found.', 'pl.grouperlite.members.noaccess' => 'You do not have access to view memberships.', - 'pl.grouperlite.members.empty' => 'This group has no member OR you are not authorized to see the members of this group.' + 'pl.grouperlite.members.empty' => 'This group has no member OR you are not authorized to see the members of this group.', + + 'er.grouperlite.glid' => 'Named parameter glid was not found', ); \ No newline at end of file diff --git a/Model/CoGrouperLite.php b/Model/CoGrouperLite.php deleted file mode 100644 index 1226065..0000000 --- a/Model/CoGrouperLite.php +++ /dev/null @@ -1,98 +0,0 @@ - array( - "parent" => "CoDashboardWidget", - "fk" => "co_dashboard_widget_id" - ) - );*/ - - // Validation rules for table elements - //Tried adding rule to each field to make alphaNumeric, but keeps throwing errors. will research. - public $validate = array( - 'co_dashboard_widget_id' => array( - 'rule' => 'alphaNumeric', - 'required' => true - ), - 'conn_url' => array( - 'rule' => array('custom', '/^https?:\/\/.*/'), - 'required' => true - ), - 'conn_ver' => array( - 'rule' => array('minLength', 4), - 'required' => true - ), - 'grouper_url' => array( - 'rule' => array('custom', '/^https?:\/\/.*/'), - 'required' => true - ), - 'conn_user' => array( - 'rule' => array('minLength', 1), - 'required' => true - ), - 'conn_pass' => array( - 'rule' => array('minLength', 1), - 'required' => true - ), - 'adhoc_heading' => array( - 'rule' => array('minLength', 1), - 'required' => false, - 'default' => 'Ad-hoc groups' - ), - 'wg_heading' => array( - 'rule' => array('minLength', 1), - 'required' => false, - 'default' => 'Working groups' - ), - 'default_collapse' => array( - 'rule' => array('minLength', 1), - 'required' => false, - 'default' => 'collapsed' - ), - ); - -} \ No newline at end of file diff --git a/Model/CoGrouperLiteWidget.php b/Model/CoGrouperLiteWidget.php new file mode 100644 index 0000000..2f57fd2 --- /dev/null +++ b/Model/CoGrouperLiteWidget.php @@ -0,0 +1,152 @@ + array( + 'rule' => 'numeric', + 'required' => true, + 'allowEmpty' => false + ), + 'conn_url' => array( + 'rule' => array('custom', '/^https?:\/\/.*/'), + 'required' => true, + 'allowEmpty' => false + ), + 'conn_ver' => array( + 'rule' => array('minLength', 4), + 'required' => true, + 'allowEmpty' => false + ), + 'grouper_url' => array( + 'rule' => array('custom', '/^https?:\/\/.*/'), + 'required' => true, + 'allowEmpty' => false + ), + 'conn_user' => array( + 'rule' => array('minLength', 1), + 'required' => true, + 'allowEmpty' => false + ), + 'conn_pass' => array( + 'rule' => array('minLength', 1), + 'required' => true, + 'allowEmpty' => false + ), + 'adhoc_heading' => array( + 'rule' => array('minLength', 1), + 'required' => false, + 'allowEmpty' => true, + 'default' => 'Ad-hoc groups' + ), + 'wg_heading' => array( + 'rule' => array('minLength', 1), + 'required' => false, + 'allowEmpty' => true, + 'default' => 'Working groups' + ), + 'default_collapse' => array( + 'rule' => array('minLength', 1), + 'required' => false, + 'default' => 'collapsed' + ), + 'identifier_type' => array( + 'content' => array( + 'rule' => array( + 'validateExtendedType', + array('attribute' => 'Identifier.type', + 'default' => array(IdentifierEnum::AffiliateSOR, + IdentifierEnum::Badge, + IdentifierEnum::Enterprise, + IdentifierEnum::ePPN, + IdentifierEnum::ePTID, + IdentifierEnum::ePUID, + IdentifierEnum::GuestSOR, + IdentifierEnum::HRSOR, + IdentifierEnum::Mail, + IdentifierEnum::National, + IdentifierEnum::Network, + IdentifierEnum::OIDCsub, + IdentifierEnum::OpenID, + IdentifierEnum::ORCID, + IdentifierEnum::ProvisioningTarget, + IdentifierEnum::Reference, + IdentifierEnum::SamlPairwise, + IdentifierEnum::SamlSubject, + IdentifierEnum::SORID, + IdentifierEnum::StudentSOR, + IdentifierEnum::UID))), + 'required' => true, + 'allowEmpty' => false + ) + ), + ); + + /** + * Actions to take before a validate operation is executed. + * + * @since COmanage Registry v4.4.0 + */ + + public function beforeValidate($options = array()) { + if(!empty($this->data[$this->alias]['co_dashboard_widget_id']) + && isset($this->id)) { + // Dashboard Widget Plugins will refer to Dashboard Widget, which in turn + // refers to a Dashboard + + $args = array(); + $args['conditions'][$this->alias.'.id'] = $this->id; + $args['contain']['CoDashboardWidget'][] = 'CoDashboard'; + + $codw = $this->find('first', $args); + + if(!empty($codw["CoDashboardWidget"]["CoDashboard"]["co_id"])) { + $contentRule = $this->validator()->getField('identifier_type')->getRule('content')->rule; + $contentRule[1]['coid'] = $codw["CoDashboardWidget"]["CoDashboard"]["co_id"]; + $this->validator()->getField('identifier_type')->getRule('content')->rule = $contentRule; + } + } + + return parent::beforeValidate($options); + } + +} \ No newline at end of file diff --git a/Model/CoManagePerson.php b/Model/CoManagePerson.php index 8d999c9..c8f1cc3 100644 --- a/Model/CoManagePerson.php +++ b/Model/CoManagePerson.php @@ -2,7 +2,7 @@ App::uses('CoPersonRole', 'Model/'); -class CoManagePerson extends GrouperLiteAppModel +class CoManagePerson extends GrouperLiteWidgetAppModel { public $name = "CoManagePerson"; diff --git a/Model/GrouperAttribute.php b/Model/GrouperAttribute.php index 7e00fe1..4df4c4d 100644 --- a/Model/GrouperAttribute.php +++ b/Model/GrouperAttribute.php @@ -25,14 +25,14 @@ * @license Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) */ -App::uses('GrouperApiAccess', 'GrouperLite.Lib/'); +App::uses('GrouperApiAccess', 'GrouperLiteWidget.Lib/'); /** * Class GrouperAttribute * * Model class to get attributes from Grouper */ -class GrouperAttribute extends GrouperLiteAppModel +class GrouperAttribute extends GrouperLiteWidgetAppModel { /** @var string $name used by CakePHP for locating model */ @@ -44,9 +44,9 @@ class GrouperAttribute extends GrouperLiteAppModel /** * Used to instantiate API class */ - private function initApi() { + private function initApi(array $cfg) { if ($this->grouperAPI == null) { - $this->grouperAPI = new GrouperApiAccess(); + $this->grouperAPI = new GrouperApiAccess($cfg); } } @@ -55,10 +55,10 @@ private function initApi() { * * @param string $groupName Name of Group * @return array Attributes in Grouper for this Group - * @throws GrouperLiteException + * @throws GrouperLiteWidgetException */ public function getGroupAttributes(string $groupName) { - $this->initApi(); + $this->initApi($cfg); try { $args = array(); diff --git a/Model/GrouperGroup.php b/Model/GrouperGroup.php index 9bff932..3baa9fd 100644 --- a/Model/GrouperGroup.php +++ b/Model/GrouperGroup.php @@ -25,24 +25,22 @@ * @license Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) */ -App::uses('GrouperApiAccess', 'GrouperLite.Lib/'); -App::uses('GrouperAttribute', 'GrouperLite.Model/'); +App::uses('GrouperApiAccess', 'GrouperLiteWidget.Lib/'); +App::uses('GrouperAttribute', 'GrouperLiteWidget.Model/'); /*** * Class GrouperGroup * * Model class that does most of the heavy lifting in Grouper Lite Widget */ -class GrouperGroup extends GrouperLiteAppModel +class GrouperGroup extends GrouperLiteWidgetAppModel { /** @var string $name used by CakePHP for locating model */ public $name = "GrouperGroup"; /** @var GrouperApiAccess $grouperAPI */ - public $grouperAPI = null; - - private $totalRecords = 0; + private $grouperAPI = null; /** @var string Group whose members can create Groups via Template process */ private $templateCreationGroup = 'ref:workinggroupadmins'; @@ -75,18 +73,14 @@ class GrouperGroup extends GrouperLiteAppModel * * @param string $userId Id of User * @return String T or F - * @throws GrouperLiteException + * @throws GrouperLiteWidgetException * * @see GrouperGroup::resetUserOwner() * */ - public function isUserOwner(string $userId) + public function isUserOwner(string $userId, array $cfg) { - if (CakeSession::check('Plugin.Grouper.isUserOwner')) { - return CakeSession::read('Plugin.Grouper.isUserOwner'); - } - - $this->initApi(); + $this->initApi($cfg); try { $args = array(); @@ -94,13 +88,7 @@ public function isUserOwner(string $userId) $ownGroups = $this->grouperAPI->getOwnedGroups($args); - if (count($ownGroups) > 0) { - CakeSession::write('Plugin.Grouper.isUserOwner', 'T'); - return 'T'; - } - CakeSession::write('Plugin.Grouper.isUserOwner', 'F'); - return 'F'; - + return count($ownGroups) > 0 ? 'T' : 'F'; } catch (Exception $e) { CakeLog::write('error', __METHOD__ . ': An error occurred'); throw $e; @@ -112,16 +100,12 @@ public function isUserOwner(string $userId) * * @param string $userId Id of User * @return String T or F - * @throws GrouperLiteException + * @throws GrouperLiteWidgetException * */ - public function isGrouperVisible(string $userId) + public function isGrouperVisible(string $userId, array $cfg) { - if (CakeSession::check('Plugin.Grouper.isGrouperVisible')) { - return CakeSession::read('Plugin.Grouper.isGrouperVisible'); - } - - $this->initApi(); + $this->initApi($cfg); try { $args = array(); @@ -129,8 +113,6 @@ public function isGrouperVisible(string $userId) $memberOfGroups = $this->grouperAPI->getGrouperMemberOfGroups($args); - $memberOfGroups = $this->grouperAPI->getGrouperMemberOfGroups($args); - //now cycle through and see if part of correct group to be able to use template $member = 'F'; foreach ($memberOfGroups as $memberOfGroup) { @@ -140,14 +122,7 @@ public function isGrouperVisible(string $userId) } } - if ($member == 'T') { - CakeSession::write('Plugin.Grouper.isGrouperVisible', 'T'); - return 'T'; - } else { - CakeSession::write('Plugin.Grouper.isGrouperVisible', 'F'); - return 'F'; - } - + return $member; } catch (Exception $e) { CakeLog::write('error', __METHOD__ . ': An error occurred'); throw $e; @@ -162,10 +137,10 @@ public function isGrouperVisible(string $userId) * so error was being thrown. * Now will call this before each function call to verify set. */ - private function initApi() + private function initApi(array $cfg) { if ($this->grouperAPI == null) { - $this->grouperAPI = new GrouperApiAccess(); + $this->grouperAPI = new GrouperApiAccess($cfg); } } @@ -175,12 +150,12 @@ private function initApi() * * @param array $conditions Listing of conditions for display of records, including UserId * @return array Records of Groups from Grouper that the User belongs to - * @throws GrouperLiteException + * @throws GrouperLiteWidgetException * */ - public function filteredMemberOfGroups(array $conditions) + public function filteredMemberOfGroups(array $conditions, array $cfg) { - $this->initApi(); + $this->initApi($cfg); try { @@ -217,7 +192,7 @@ public function filteredMemberOfGroups(array $conditions) * * @param array $conditions Listing of conditions for display of records, including UserId * @return array Records of Groups from Grouper that the User belongs to - * @throws GrouperLiteException + * @throws GrouperLiteWidgetException * */ private function memberOfGroups(array $conditions) @@ -238,13 +213,15 @@ private function memberOfGroups(array $conditions) * * @param string $userId Id of User * @param string $groupName Name of Group Leaving, do not confuse with DisplayName field! + * @param array $cfg the plugin configuration + * * @return bool True|False - * @throws GrouperLiteException + * @throws GrouperLiteWidgetException * */ - public function leaveGroup(string $userId, string $groupName) + public function leaveGroup(string $userId, string $groupName, array $cfg) { - $this->initApi(); + $this->initApi($cfg); try { $args = array(); @@ -266,12 +243,12 @@ public function leaveGroup(string $userId, string $groupName) * @param string $userId Id of User * @param string $groupName Name of Group Joining, do not confuse with DisplayName field! * @return bool True|False - * @throws GrouperLiteException + * @throws GrouperLiteWidgetException * */ - public function joinGroup(string $userId, string $groupName) + public function joinGroup(string $userId, string $groupName, array $cfg) { - $this->initApi(); + $this->initApi($cfg); try { $args = array(); @@ -292,12 +269,12 @@ public function joinGroup(string $userId, string $groupName) * * @param array $conditions Listing of conditions for display of records, including UserId * @return array - * @throws GrouperLiteException + * @throws GrouperLiteWidgetException * */ - public function ownerGroups(array $conditions) + public function ownerGroups(array $conditions, array $cfg) { - $this->initApi(); + $this->initApi($cfg); try { $resultSet = $this->grouperAPI->getOwnedGroups($conditions); @@ -317,12 +294,12 @@ public function ownerGroups(array $conditions) * @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 + * @throws GrouperLiteWidgetException Captured in Controller * */ - public function membersInGroup(array $conditions, string $userId) + public function membersInGroup(array $conditions, string $userId, array $cfg) { - $this->initApi(); + $this->initApi($cfg); $conditions['userId'] = $userId; @@ -354,12 +331,12 @@ public function membersInGroup(array $conditions, string $userId) * @param array $conditions Listing of conditions for display of records * @param string $userId Id of User * @return string success of Request - * @throws GrouperLiteException Captured in Controller + * @throws GrouperLiteWidgetException Captured in Controller * */ - public function addMemberToGroup(array $conditions, string $userId) + public function addMemberToGroup(array $conditions, string $userId, array $cfg) { - $this->initApi(); + $this->initApi($cfg); $conditions['userId'] = $userId; @@ -380,20 +357,17 @@ public function addMemberToGroup(array $conditions, string $userId) * @param array $conditions Listing of conditions for display of records * @param string $userId Id of User * @return string success of Request - * @throws GrouperLiteException Captured in Controller + * @throws GrouperLiteWidgetException Captured in Controller * */ - public function removeMemberToGroup(array $conditions, string $userId) + public function removeMemberToGroup(array $conditions, string $userId, array $cfg) { - $this->initApi(); + $this->initApi($cfg); $conditions['userId'] = $userId; try { - $resultRemove = $this->grouperAPI->removeMemberToGroup($conditions); - - return $resultRemove; - + return $this->grouperAPI->removeMemberToGroup($conditions); } catch (Exception $e) { CakeLog::write('error', __METHOD__ . ': An error occurred'); throw $e; @@ -408,11 +382,11 @@ public function removeMemberToGroup(array $conditions, string $userId) * * @param array $conditions Listing of conditions for display of records, including UserId * @return array Listing of Optin groups available in Grouper - * @throws GrouperLiteException Captured in Controller + * @throws GrouperLiteWidgetException Captured in Controller */ - public function optinGroups(array $conditions) + public function optinGroups(array $conditions, array $cfg) { - $this->initApi(); + $this->initApi($cfg); try { $conditions['groupType'] = 'optins'; @@ -445,15 +419,11 @@ public function optinGroups(array $conditions) * * @param string $userId Id of User * @return string T for True and F for False - * @throws GrouperLiteException + * @throws GrouperLiteWidgetException */ - public function isTemplateUser(string $userId) + public function isTemplateUser(string $userId, array $cfg) { - if (CakeSession::check('Plugin.Grouper.isTemplateUser')) { - return CakeSession::read('Plugin.Grouper.isTemplateUser'); - } - - $this->initApi(); + $this->initApi($cfg); try { $args = array(); @@ -470,13 +440,7 @@ public function isTemplateUser(string $userId) } } - if ($member == 'T') { - CakeSession::write('Plugin.Grouper.isTemplateUser', 'T'); - return 'T'; - } - CakeSession::write('Plugin.Grouper.isTemplateUser', 'F'); - return 'F'; - + return $member; } catch (Exception $e) { CakeLog::write('error', __METHOD__ . ': An error occurred'); throw $e; @@ -490,12 +454,12 @@ public function isTemplateUser(string $userId) * @param string $userId Id of User * @param array $groupData Data needed to create new Grouper Group via Template * @return array status and error message, if applicable - * @throws GrouperLiteException + * @throws GrouperLiteWidgetException * */ - public function createGroupWithTemplate(string $userId, array $groupData) + public function createGroupWithTemplate(string $userId, array $groupData, array $cfg) { - $this->initApi(); + $this->initApi($cfg); try { //Need to massage incoming data to meet Grouper Template requirements @@ -527,19 +491,6 @@ public function createGroupWithTemplate(string $userId, array $groupData) } - /** - * Private function used to reset the IsUserOwner Session variable, - * that maintains the status of a user being an owner/admin of a group - * - * @see GrouperGroup::isUserOwner() - */ - private function resetUserOwner() - { - if (CakeSession::check('Plugin.Grouper.isUserOwner')) { - CakeSession::delete('Plugin.Grouper.isUserOwner'); - } - } - /** * Search for Groups/Lists related to Search term. * @@ -551,9 +502,9 @@ private function resetUserOwner() * @return array Records that meet search criteria * @throws Exception Captured in Controller */ - public function getSearchedGroups(array $conditions) + public function getSearchedGroups(array $conditions, array $cfg) { - $this->initApi(); + $this->initApi($cfg); try { //Breakout page where search was called and forward to appropriate method for processing @@ -605,6 +556,9 @@ private function getFriendlyWorkingGroupName(array $groups, $method) $arrayIndex = 0; $workingGroups = array(); + + CakeLog::write('debug', __METHOD__ . '::raw groups: ', print_r($groups, true)); + //First need to loop through all groups and pull in all top levels $topLevelWG = array(); foreach ($groups as $group) { diff --git a/Model/GrouperLite.php b/Model/GrouperLiteWidget.php similarity index 79% rename from Model/GrouperLite.php rename to Model/GrouperLiteWidget.php index dec2df3..bfa3d4a 100644 --- a/Model/GrouperLite.php +++ b/Model/GrouperLiteWidget.php @@ -25,33 +25,26 @@ * @license Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) */ -class GrouperLite extends AppModel { +class GrouperLiteWidget extends AppModel { // Define class name for cake - public $name = "GrouperLite"; + public $name = "GrouperLiteWidget"; // Required by COmanage Plugins public $cmPluginType = "dashboardwidget"; + // Document foreign keys + public $cmPluginHasMany = array(); + // Association rules from this model to other models - public $belongsTo = array( - ); + public $belongsTo = array(); - public $hasMany = array( - ); + public $hasMany = array(); // Validation rules for table elements - public $validate = array( - ); + public $validate = array(); public function cmPluginMenus() { - return array( - /*"cogroups" => array( - 'Grouper groups' => array( - 'controller' => "groupergroups", - 'action' => "groupoptin" - ) - )*/ - ); + return array(); } diff --git a/Model/GrouperLiteAppModel.php b/Model/GrouperLiteWidgetAppModel.php similarity index 95% rename from Model/GrouperLiteAppModel.php rename to Model/GrouperLiteWidgetAppModel.php index 18cbb6d..be6cb29 100644 --- a/Model/GrouperLiteAppModel.php +++ b/Model/GrouperLiteWidgetAppModel.php @@ -27,6 +27,6 @@ App::uses('AppModel', 'Model'); -class GrouperLiteAppModel extends AppModel { +class GrouperLiteWidgetAppModel extends AppModel { } diff --git a/View/CoGrouperLites/display.ctp b/View/CoGrouperLiteWidgets/display.ctp similarity index 87% rename from View/CoGrouperLites/display.ctp rename to View/CoGrouperLiteWidgets/display.ctp index 480ee25..ccf0c76 100644 --- a/View/CoGrouperLites/display.ctp +++ b/View/CoGrouperLiteWidgets/display.ctp @@ -31,35 +31,36 @@ // Figure out the widget ID so we can overwrite the dashboard's widget div -$divid = $vv_config['CoGrouperLite']['co_dashboard_widget_id']; +$divid = $vv_config['CoGrouperLiteWidget']['co_dashboard_widget_id']; -// $coid = $config['co']; -// $glid = $config['glid']; +$plugin = filter_var($vv_codw["CoDashboardWidget"]["plugin"],FILTER_SANITIZE_SPECIAL_CHARS); +$pl = Inflector::underscore($plugin); +$plcmodel = Inflector::pluralize($pl); $this->extend('/GrouperGroups/base'); -echo $this->element('GrouperLite.base-styles'); +echo $this->element('GrouperLiteWidget.base-styles'); $idsuffix = rand(); ?>