@@ -210,4 +213,5 @@ $suffix = Configure::read('debug') > 0 ? '?time=' . time() : '';
diff --git a/Controller/GrouperGroupsController.php b/Controller/GrouperGroupsController.php index a9790da..edf0bcf 100644 --- a/Controller/GrouperGroupsController.php +++ b/Controller/GrouperGroupsController.php @@ -111,7 +111,7 @@ public function beforeFilter() HttpStatusCodesEnum::HTTP_BAD_REQUEST); } $this->response->disableCache(); - $this->RequestHandler->addInputType('json', array('json_decode', true)); + $this->RequestHandler->addInputType('json', ['json_decode', true]); $this->Security->unlockedActions = [ 'removeSubscriber', @@ -125,7 +125,7 @@ public function beforeFilter() // Get the config $args = array(); - $args['conditions']['CoGrouperLiteWidget.id'] = $this->request->params["named"]["glid"]; + $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 @@ -436,6 +436,14 @@ public function isAuthorized(): array|bool $this->setUserId($identifiers['Identifier']['identifier']); } + // Find if the user belongs to Group + $eligibleGroup = $cfg['CoGrouperLiteWidget']['act_as_grp_name']; + $isActAsEligibilityGroupmember = false; + + if(!empty($eligibleGroup)) { + $isActAsEligibilityGroupmember = $this->GrouperGroup->isGroupMember($this->getUserId(), $eligibleGroup, $cfg); + } + // Determine what operations this user can perform // Construct the permission set for this user, which will also be passed to the view. $p = []; @@ -459,6 +467,7 @@ public function isAuthorized(): array|bool $p['joinGroup'] = ($roles['cmadmin'] || $roles['coadmin'] || $roles['comember']); $p['leaveGroup'] = ($roles['cmadmin'] || $roles['coadmin'] || $roles['comember']); $p['groupcreatetemplate'] = ($roles['cmadmin'] || $roles['coadmin'] || $roles['comember']); + $p['actAsAction'] = $isActAsEligibilityGroupmember; $this->set('permissions', $p); diff --git a/Controller/GrouperLiteActAsPeopleController.php b/Controller/GrouperLiteActAsPeopleController.php new file mode 100644 index 0000000..d69da89 --- /dev/null +++ b/Controller/GrouperLiteActAsPeopleController.php @@ -0,0 +1,135 @@ + [ + 'validatePost' => false, + 'csrfUseOnce' => false + ] + ]; + + + public $name = 'GrouperLiteActAsPeople'; + + /** + * Overrides parent beforeFilter to verify that Session contains the correct API settings. + * + * @return void + */ + public function beforeFilter() + { + parent::beforeFilter(); + + if(empty($this->request->params['named']['glid'])) { + throw new InvalidArgumentException(_txt('er.grouperlite.glid'), + HttpStatusCodesEnum::HTTP_BAD_REQUEST); + } + $this->response->disableCache(); + $this->RequestHandler->addInputType('json', ['json_decode', true]); + + $this->Security->unlockedActions = [ + 'add', + 'edit', + 'delete' + ]; + + // 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); + } + + /** + * NOTE: All permissions will be done on the Grouper side. All Authenticated users will be able to + * use this plugin for self-admin of groups. + * + * Authorization for this Controller, called by Auth component + * - precondition: Session.Auth holds data used for authz decisions + * - postcondition: $permissions set with calculated permissions + * + * @return array|bool Permissions + * @since COmanage Registry v4.4.0 + */ + public function isAuthorized(): array|bool + { + $roles = $this->Role->calculateCMRoles(); + $cfg = $this->CoGrouperLiteWidget->getConfig(); + // Find the identifier + $args = array(); + $args['conditions']['Identifier.type'] = $cfg['CoGrouperLiteWidget']['identifier_type']; + $args['conditions']['Identifier.status'] = SuspendableStatusEnum::Active; + $args['conditions']['Identifier.co_person_id'] = $roles['copersonid']; + $args['contain'] = false; + + $identifiers = $this->Identifier->find('first', $args); + if(!empty($identifiers) + && is_array($identifiers) + && isset($identifiers['Identifier']['identifier']) + ) { + $this->setUserId($identifiers['Identifier']['identifier']); + } + + // Find if the user belongs to Group + $eligibleGroup = $cfg['CoGrouperLiteWidget']['act_as_grp_name']; + $isActAsEligibilityGroupmember = false; + + if(!empty($eligibleGroup)) { + $isActAsEligibilityGroupmember = $this->GrouperGroup->isGroupMember($this->getUserId(), $eligibleGroup, $cfg); + } + + // Determine what operations this user can perform + // Construct the permission set for this user, which will also be passed to the view. + $p = []; + + $p['add'] = $isActAsEligibilityGroupmember; + $p['delete'] = $isActAsEligibilityGroupmember; + $p['edit'] = $isActAsEligibilityGroupmember; + $p['update'] = $isActAsEligibilityGroupmember; + + $this->set('permissions', $p); + + return ($p[$this->action]); + } + + /** + * @return null + */ + public function getUserId() + { + return $this->userId; + } + + + /** + * @param null $userId + */ + private function setUserId($userId): void + { + $this->userId = $userId; + } +} \ No newline at end of file diff --git a/Model/GrouperGroup.php b/Model/GrouperGroup.php index 1468b07..6f14364 100644 --- a/Model/GrouperGroup.php +++ b/Model/GrouperGroup.php @@ -528,6 +528,31 @@ public function optinGroups(string $userId, array $cfg): array ); } + /** + * Determine if a User can use the Grouper Template to create a Working Group. + * + * @param string $userId User ID + * @param string $groupName Group Name + * @param array $cfg + * + * @return bool T for True and F for False + * @throws GrouperLiteWidgetException + * @since COmanage Registry v4.4.0 + */ + public function isGroupMember(string $userId, string $groupName, array $cfg): bool + { + $this->initApi($cfg); + + try { + $isMember = $this->grouperAPI->isMemberOfGroup($groupName, $userId); + } catch (Exception $e) { + CakeLog::write('error', __METHOD__ . ': An error occurred'); + throw $e; + } + + return (bool)$isMember; + } + /** * Determine if User can use the Grouper Template to create a Working Group. * diff --git a/Model/GrouperLiteActAsPerson.php b/Model/GrouperLiteActAsPerson.php index 7d2eb9c..4f833e4 100644 --- a/Model/GrouperLiteActAsPerson.php +++ b/Model/GrouperLiteActAsPerson.php @@ -29,6 +29,21 @@ class GrouperLiteActAsPerson extends AppModel { public $name = 'GrouperLiteActAsPerson'; + public $cmPluginHasMany = [ + "CoGrouperLiteWidget" => ["GrouperLiteActAsPerson"], + 'CoPerson' => [ + 'GrouperLiteActAsPerson' => [ + 'className' => 'GrouperLiteActAsPerson', + 'foreignKey' => 'actor_co_person_id' + ] + ], + 'CoPerson' => [ + 'GrouperLiteActAsPerson' => [ + 'className' => 'GrouperLiteActAsPerson', + 'foreignKey' => 'act_as_co_person_id' + ] + ] + ]; // Association rules from this model to other models public $belongsTo = [ @@ -40,7 +55,8 @@ class GrouperLiteActAsPerson extends AppModel 'ActorCoPerson' => [ 'className' => 'CoPerson', 'foreignKey' => 'actor_co_person_id' - ] + ], + 'CoGrouperLiteWidget' ]; // Validation rules for table elements diff --git a/View/GrouperGroups/index.ctp b/View/GrouperGroups/index.ctp index bc80b10..bf00aba 100644 --- a/View/GrouperGroups/index.ctp +++ b/View/GrouperGroups/index.ctp @@ -124,6 +124,7 @@ $suffix = Configure::read('debug') > 0 ? '?time=' . time() : ''; JSON_THROW_ON_ERROR) ?>, }, api: { + permissions: = json_encode($permissions, JSON_THROW_ON_ERROR) ?>, co: = $vv_coid ?>, glid: = $vv_config['CoGrouperLiteWidget']['id'] ?>, mode: "= PeoplePickerModeEnum::All ?>", @@ -151,10 +152,12 @@ $suffix = Configure::read('debug') > 0 ? '?time=' . time() : ''; -