diff --git a/modules/api/controllers/components/ApiComponent.php b/modules/api/controllers/components/ApiComponent.php index 84cfa399b..70eda616f 100644 --- a/modules/api/controllers/components/ApiComponent.php +++ b/modules/api/controllers/components/ApiComponent.php @@ -2905,8 +2905,9 @@ function metadataQualifiersList($args) /** * helper function to validate args of methods for adding or removing * users from groups. - * @param type $args - * @return type + * @param group_id the group to add the user to + * @param user_id the user to add to the group + * @return an array of (groupModel, groupDao, groupUserDao) */ protected function _validateGroupUserChangeParams($args) { @@ -2948,6 +2949,7 @@ protected function _validateGroupUserChangeParams($args) * admin privileges on the community associated with the group. * @param group_id the group to add the user to * @param user_id the user to add to the group + * @return success = true on success. */ function groupAddUser($args) { @@ -2961,6 +2963,7 @@ function groupAddUser($args) * admin privileges on the community associated with the group. * @param group_id the group to remove the user from * @param user_id the user to remove from the group + * @return success = true on success. */ function groupRemoveUser($args) { @@ -2970,4 +2973,75 @@ function groupRemoveUser($args) } + + /** + * add a group associated with a community, requires admin privileges on the + * community. + * @param community_id the id of the community the group will associate with + * @param name the name of the new group + * @return group_id of the newly created group on success. + */ + function groupAdd($args) + { + $this->_validateParams($args, array('community_id', 'name')); + + $userDao = $this->_getUser($args); + if(!$userDao) + { + throw new Exception('You must be logged in to add group', MIDAS_INVALID_POLICY); + } + + $communityModel = MidasLoader::loadModel('Community'); + $communityId = $args['community_id']; + $community = $communityModel->load($communityId); + if($community == false) + { + throw new Exception('This community does not exist', MIDAS_INVALID_PARAMETER); + } + if(!$communityModel->policyCheck($community, $userDao, MIDAS_POLICY_ADMIN)) + { + throw new Zend_Exception("Community Admin permissions required.", MIDAS_INVALID_POLICY); + } + + $name = $args['name']; + $groupModel = MidasLoader::loadModel('Group'); + $group = $groupModel->createGroup($community, $name); + + return array('group_id' => $group->getGroupId()); + } + + /** + * remove a group associated with a community, requires admin privileges on the + * community. + * @param group_id the id of the group to be removed + * @return success = true on success. + */ + function groupRemove($args) + { + $this->_validateParams($args, array('group_id')); + + $userDao = $this->_getUser($args); + if(!$userDao) + { + throw new Exception('You must be logged in to remove a group', MIDAS_INVALID_POLICY); + } + + $groupId = $args['group_id']; + $groupModel = MidasLoader::loadModel('Group'); + $group = $groupModel->load($groupId); + if($group == false) + { + throw new Exception('This group does not exist', MIDAS_INVALID_PARAMETER); + } + + $communityModel = MidasLoader::loadModel('Community'); + if(!$communityModel->policyCheck($group->getCommunity(), $userDao, MIDAS_POLICY_ADMIN)) + { + throw new Zend_Exception("Community Admin permissions required.", MIDAS_INVALID_POLICY); + } + + $groupModel->delete($group); + return array('success' => 'true'); + } + } // end class diff --git a/modules/api/tests/controllers/ApiCallGroupMethodsTest.php b/modules/api/tests/controllers/ApiCallGroupMethodsTest.php index 3e8df0ff3..9aa2afe3c 100644 --- a/modules/api/tests/controllers/ApiCallGroupMethodsTest.php +++ b/modules/api/tests/controllers/ApiCallGroupMethodsTest.php @@ -27,6 +27,111 @@ public function setUp() parent::setUp(); } + /** + * helper function to test simple invalid cases: + * will test all invalid users sending in all required valid params + * will also test all combinations of invalid params with a valid user + * for each required param + * @param type $method + * @param type $validUser + * @param type $invalidUsers + * @param type $requiredParams + */ + protected function exerciseInvalidCases($method, $validUser, $invalidUsers, $requiredParams) + { + // test all invalid users with valid params + foreach($invalidUsers as $invalidUser) + { + $this->resetAll(); + if($invalidUser != null) + { + $this->params['token'] = $this->_loginAsUser($invalidUser); + } + $this->params['method'] = $method; + foreach($requiredParams as $requiredParam) + { + $this->params[$requiredParam['name']] = $requiredParam['valid']; + } + $resp = $this->_callJsonApi(); + $this->_assertStatusFail($resp, MIDAS_INVALID_POLICY); + } + + // test valid user with all combinations of missing/invalid/valid params + // will not test a case of valid user and all valid params + + $numParams = sizeof($requiredParams); + // create an int array that is initially all 0 + $requiredParamStates = array_fill(0, $numParams, 0); + $allTwosSum = 2 * $numParams; + + while(array_sum($requiredParamStates) < $allTwosSum) + { + $this->resetAll(); + $this->params['token'] = $this->_loginAsUser($validUser); + $this->params['method'] = $method; + $skipTestCase = false; + foreach($requiredParams as $ind => $requiredParam) + { + // find the state corresponding to this param + $state = $requiredParamStates[$ind]; + // 0s mean the param is missing (not sent) + if($state == 1) + { + // 1s mean an invalid form of the param is sent + if(!array_key_exists('invalid', $requiredParam)) + { + // some params may not have an invalid form + // skip this test case as it would repeat the case of the missing param + $skipTestCase = true; + break; + } + $this->params[$requiredParam['name']] = $requiredParam['invalid']; + } + elseif($state == 2) + { + // 2s mean a valid form of the param is sent + $this->params[$requiredParam['name']] = $requiredParam['valid']; + } + elseif($state < 0 || $state > 2) + { + throw new Exception("left most param state is invalid value: ".$state); + } + } + if(!$skipTestCase) + { + $resp = $this->_callJsonApi(); + $this->_assertStatusFail($resp, MIDAS_INVALID_PARAMETER); + } + + // now increment the parameter states + // add 1 to the right most value + $incrementIndex = $numParams - 1; + $rightMost = $requiredParamStates[$incrementIndex]; + $rightMost += 1; + $requiredParamStates[$incrementIndex] = $rightMost; + while($rightMost == 3) + { + // if the right most goes to 3, set it to 0 + // and repeat the process one index to the left, stop moving + // to the left when the last increment doesn't go to 3, + // i.e. there are no more carry bits + $rightMost = 0; + $requiredParamStates[$incrementIndex] = $rightMost; + if($incrementIndex > 0) + { + $incrementIndex -= 1; + $rightMost = $requiredParamStates[$incrementIndex]; + $rightMost += 1; + $requiredParamStates[$incrementIndex] = $rightMost; + } + else + { + throw new Exception("left most param state is 3"); + } + } + } + } + /** Test adding and removing a user from a group */ public function testGroupUserAddRemove() { @@ -40,71 +145,23 @@ public function testGroupUserAddRemove() $commMember = $userModel->load('4'); $commModerator = $userModel->load('5'); $commAdmin = $userModel->load('6'); - $nonModerators = array($commMember); - $nonAdmins = array($commMember, $commModerator); - $moderators = array($commModerator, $commAdmin); $validGroupId = '3004'; $invalidGroupId = '-10'; $validUserId = '2'; $invalidUserId = '-10'; - // test all the failure cases + // add in an anonymous user to non admins + $invalidUsers = array($commMember, $commModerator, false); + + // test all the invalid cases foreach($methods as $method) { - // Try anonymously first - $this->resetAll(); - $this->params['method'] = $method; - $this->params['group_id'] = $validGroupId; - $this->params['user_id'] = $validUserId; - $resp = $this->_callJsonApi(); - $this->_assertStatusFail($resp, MIDAS_INVALID_POLICY); + $requiredParams = array( + array('name' => 'group_id', 'valid' => $validGroupId, 'invalid' => $invalidGroupId), + array('name' => 'user_id', 'valid' => $validUserId, 'invalid' => $invalidUserId)); - // missing group_id - $this->resetAll(); - $this->params['token'] = $this->_loginAsUser($commAdmin); - $this->params['method'] = $method; - $this->params['user_id'] = $validUserId; - $resp = $this->_callJsonApi(); - $this->_assertStatusFail($resp, MIDAS_INVALID_PARAMETER); - - // missing user_id - $this->resetAll(); - $this->params['token'] = $this->_loginAsUser($commAdmin); - $this->params['method'] = $method; - $this->params['group_id'] = $validGroupId; - $resp = $this->_callJsonApi(); - $this->_assertStatusFail($resp, MIDAS_INVALID_PARAMETER); - - // an invalid group - $this->resetAll(); - $this->params['token'] = $this->_loginAsUser($commAdmin); - $this->params['method'] = $method; - $this->params['group_id'] = $invalidGroupId; - $this->params['user_id'] = $validUserId; - $resp = $this->_callJsonApi(); - $this->_assertStatusFail($resp, MIDAS_INVALID_PARAMETER); - - // an invalid user - $this->resetAll(); - $this->params['token'] = $this->_loginAsUser($commAdmin); - $this->params['method'] = $method; - $this->params['group_id'] = $validGroupId; - $this->params['user_id'] = $invalidUserId; - $resp = $this->_callJsonApi(); - $this->_assertStatusFail($resp, MIDAS_INVALID_PARAMETER); - - // as a non admin - foreach($nonAdmins as $nonAdmin) - { - $this->resetAll(); - $this->params['token'] = $this->_loginAsUser($nonAdmin); - $this->params['method'] = $method; - $this->params['group_id'] = $validGroupId; - $this->params['user_id'] = $validUserId; - $resp = $this->_callJsonApi(); - $this->_assertStatusFail($resp, MIDAS_INVALID_POLICY); - } + $this->exerciseInvalidCases($method, $commAdmin, $invalidUsers, $requiredParams); } // ensure the user isn't already in the group @@ -137,5 +194,79 @@ public function testGroupUserAddRemove() $this->assertFalse($groupModel->userInGroup($changedUser, $group), "This user is not expected to be in the group"); } + /** Test adding and removing a group */ + public function testGroupAddRemove() + { + $validCommunityId = 2001; + $invalidCommunityId = -10; + + $communityModel = MidasLoader::loadModel('Community'); + $comm2001 = $communityModel->load('2001'); + $userModel = MidasLoader::loadModel('User'); + $commMember = $userModel->load('4'); + $commModerator = $userModel->load('5'); + $commAdmin = $userModel->load('6'); + + // add in an anonymous user to non admins + $invalidUsers = array($commMember, $commModerator, false); + + // group add + + $addMethod = "midas.group.add"; + $newGroupName = 'new group'; + $addMethodRequiredParams = array( + array('name' => 'community_id', 'valid' => $validCommunityId, 'invalid' => $invalidCommunityId), + array('name' => 'name', 'valid' => $newGroupName)); // no invalid name + + $this->exerciseInvalidCases($addMethod, $commAdmin, $invalidUsers, $addMethodRequiredParams); + + $groupModel = MidasLoader::loadModel('Group'); + $existingGroups = $groupModel->findByCommunity($comm2001); + // add a group via the api call + + $addedGroupName = 'ApiCallGroupMethodsTest'; + $this->resetAll(); + $this->params['token'] = $this->_loginAsUser($commAdmin); + $this->params['method'] = $addMethod; + $this->params['community_id'] = $validCommunityId; + $this->params['name'] = $addedGroupName; + $resp = $this->_callJsonApi(); + $this->_assertStatusOk($resp); + + $addedGroupId = $resp->data->group_id; + // check that the group didn't already exist for the community + foreach($existingGroups as $existingGroup) + { + $this->assertNotEquals($addedGroupId, $existingGroup->getGroupId(), 'added group has the same id as an existing group'); + } + $addedGroup = $groupModel->load($addedGroupId); + // check that the added group has the correct values + $this->assertEquals($addedGroup->getCommunityId(), $validCommunityId, 'added group has incorrect community id'); + $this->assertEquals($addedGroup->getName(), $addedGroupName, 'added group has incorrect community id'); + + // group remove + + $invalidGroupId = -10; + $removeMethod = "midas.group.remove"; + $removeMethodRequiredParams = array( + array('name' => 'group_id', 'valid' => $addedGroupId, 'invalid' => $invalidGroupId)); + + $this->exerciseInvalidCases($removeMethod, $commAdmin, $invalidUsers, $removeMethodRequiredParams); + + // remove the group via the api call + + $this->resetAll(); + $this->params['token'] = $this->_loginAsUser($commAdmin); + $this->params['method'] = $removeMethod; + $this->params['group_id'] = $addedGroupId; + $resp = $this->_callJsonApi(); + $this->_assertStatusOk($resp); + $success = $resp->data->success; + $this->assertEquals($success, 'true', 'success value should have been true'); + + // ensure that the group doesn't exist + $addedGroup = $groupModel->load($addedGroupId); + $this->assertFalse($addedGroup, "group should have been removed but remains"); + } }