public function testRebuildDatabaseWithNonSuperAdminUser() { $steven = UserTestHelper::createBasicUser('Steven'); Yii::app()->user->userModel = $steven; $item = NamedSecurableItem::getByName('AccountsModule'); $this->assertEquals(Permission::NONE, $item->getEffectivePermissions($steven)); $accounts = Account::getAll(); $users = User::getAll(); $this->assertEquals(0, count($accounts)); $this->assertEquals(2, count($users)); $adapter = new ModelAttributesAdapter(new Account()); $adapter->resolveDatabaseSchemaForModel('Account'); //Confirm the counts of data are still correct $accounts = Account::getAll(); $users = User::getAll(); $this->assertEquals(0, count($accounts)); $this->assertEquals(2, count($users)); //Explicitly deny read, write, and deny Yii::app()->user->userModel = User::getByUsername('super'); $item->addPermissions($steven, Permission::READ_WRITE_DELETE, Permission::DENY); $this->assertTrue($item->save()); //Make sure steven has explicit deny $item = NamedSecurableItem::getByName('AccountsModule'); $this->assertEquals(Permission::NONE, $item->getEffectivePermissions($steven)); Yii::app()->user->userModel = $steven; $adapter = new ModelAttributesAdapter(new Account()); $adapter->resolveDatabaseSchemaForModel('Account'); //Confirm the counts of data are still correct $accounts = Account::getAll(); $users = User::getAll(); $this->assertEquals(0, count($accounts)); $this->assertEquals(2, count($users)); }
/** * Test when a normal user who can only view records he owns, tries to import records assigned to another user. */ public function testImportSwitchingOwnerButShouldStillCreate() { $super = User::getByUsername('super'); $jim = User::getByUsername('jim'); Yii::app()->user->userModel = $jim; //Confirm Jim can can only view ImportModelTestItems he owns. $item = NamedSecurableItem::getByName('ContactsModule'); $this->assertEquals(Permission::NONE, $item->getEffectivePermissions($jim)); $testModels = Contact::getAll(); $this->assertEquals(0, count($testModels)); $import = new Import(); $serializedData['importRulesType'] = 'Contacts'; $serializedData['firstRowIsHeaderRow'] = true; $import->serializedData = serialize($serializedData); $this->assertTrue($import->save()); ImportTestHelper::createTempTableByFileNameAndTableName('importTest.csv', $import->getTempTableName(), true, Yii::getPathOfAlias('application.modules.contacts.tests.unit.files')); $this->assertEquals(4, ImportDatabaseUtil::getCount($import->getTempTableName())); // includes header rows. $ownerColumnMappingData = array('attributeIndexOrDerivedType' => 'owner', 'type' => 'extraColumn', 'mappingRulesData' => array('DefaultModelNameIdMappingRuleForm' => array('defaultModelId' => $super->id), 'UserValueTypeModelAttributeMappingRuleForm' => array('type' => UserValueTypeModelAttributeMappingRuleForm::ZURMO_USER_ID))); $startingStateId = ContactsUtil::getStartingState()->id; $mappingData = array('column_0' => ImportMappingUtil::makeStringColumnMappingData('firstName'), 'column_1' => ImportMappingUtil::makeStringColumnMappingData('lastName'), 'column_2' => $ownerColumnMappingData, 'column_3' => ContactImportTestHelper::makeStateColumnMappingData($startingStateId, 'extraColumn')); $importRules = ImportRulesUtil::makeImportRulesByType('Contacts'); $page = 0; $config = array('pagination' => array('pageSize' => 50)); //This way all rows are processed. $dataProvider = new ImportDataProvider($import->getTempTableName(), true, $config); $dataProvider->getPagination()->setCurrentPage($page); $importResultsUtil = new ImportResultsUtil($import); $messageLogger = new ImportMessageLogger(); ImportUtil::importByDataProvider($dataProvider, $importRules, $mappingData, $importResultsUtil, new ExplicitReadWriteModelPermissions(), $messageLogger); $importResultsUtil->processStatusAndMessagesForEachRow(); //3 models are created, but Jim can't see them since they are assigned to someone else. $testModels = Contact::getAll(); $this->assertEquals(0, count($testModels)); //Using super, should see all 3 models created. Yii::app()->user->userModel = $super; $testModels = Contact::getAll(); $this->assertEquals(3, count($testModels)); foreach ($testModels as $model) { $this->assertEquals(array(Permission::NONE, Permission::NONE), $model->getExplicitActualPermissions($jim)); } //Confirm 4 rows were processed as 'created'. $this->assertEquals(3, ImportDatabaseUtil::getCount($import->getTempTableName(), "status = " . ImportRowDataResultsUtil::CREATED)); //Confirm that 0 rows were processed as 'updated'. $this->assertEquals(0, ImportDatabaseUtil::getCount($import->getTempTableName(), "status = " . ImportRowDataResultsUtil::UPDATED)); //Confirm 0 rows were processed as 'errors'. $this->assertEquals(0, ImportDatabaseUtil::getCount($import->getTempTableName(), "status = " . ImportRowDataResultsUtil::ERROR)); $beansWithErrors = ImportDatabaseUtil::getSubset($import->getTempTableName(), "status = " . ImportRowDataResultsUtil::ERROR); $this->assertEquals(0, count($beansWithErrors)); //Clear out data in table Contact::deleteAll(); }
public function testCachingNamedSecurableItemActualPermissions() { if (MEMCACHE_ON && Yii::app()->cache !== null) { Yii::app()->user->userModel = User::getByUsername('super'); $super = User::getByUsername('super'); $namedSecurableItem = 'AccountsModule'; $item = NamedSecurableItem::getByName('AccountsModule'); $actualPermissions = $item->getActualPermissions(); PermissionsCache::cacheNamedSecurableItemActualPermissions($namedSecurableItem, $super, $actualPermissions); $actualPermissionsFromCache = PermissionsCache::getNamedSecurableItemActualPermissions($namedSecurableItem, $super); $this->assertEquals($actualPermissions, $actualPermissionsFromCache); } }
public function testCachingNamedSecurableItemActualPermissions() { if (PermissionsCache::supportsAndAllowsMemcache() || PermissionsCache::supportsAndAllowsDatabaseCaching()) { Yii::app()->user->userModel = User::getByUsername('super'); $super = User::getByUsername('super'); $namedSecurableItem = 'AccountsModule'; $item = NamedSecurableItem::getByName('AccountsModule'); $actualPermissions = $item->getActualPermissions(); PermissionsCache::cacheNamedSecurableItemActualPermissions($namedSecurableItem, $super, $actualPermissions); $actualPermissionsFromCache = PermissionsCache::getNamedSecurableItemActualPermissions($namedSecurableItem, $super); $this->assertEquals($actualPermissions, $actualPermissionsFromCache); } }
protected function setSomePermissions() { if (!SECURITY_OPTIMIZED) { return; } $accounts = Account::getAll(); $account = $accounts[0]; $user = User::getByUsername('bobby'); $this->assertNotEquals($account->owner->id, $user->id); $everyone = Group::getByName('Everyone'); $account->addPermissions($user, Permission::READ); $account->addPermissions($user, Permission::WRITE, Permission::DENY); $account->addPermissions($everyone, Permission::CHANGE_OWNER); $this->assertTrue($account->save()); try { $securableItem1 = NamedSecurableItem::getByName('Account'); } catch (NotFoundException $e) { $securableItem1 = new NamedSecurableItem(); $securableItem->name = 'Account'; } $securableItem1->addPermissions($everyone, Permission::DELETE); $this->assertTrue($securableItem1->save()); try { $securableItem2 = NamedSecurableItem::getByName('Account'); } catch (NotFoundException $e) { $securableItem2 = new NamedSecurableItem(); $securableItem->name = 'AccountsModule'; } $securableItem2->addPermissions($everyone, Permission::CHANGE_PERMISSIONS); $this->assertTrue($securableItem2->save()); }
public function getInheritedActualPermissions($permitable = null) { assert('$permitable === null || $permitable instanceof Permitable'); if ($permitable === null) { $permitable = Yii::app()->user->userModel; if (!$permitable instanceof User) { throw new NoCurrentUserSecurityException(); } } $allowPermissions = Permission::NONE; $denyPermissions = Permission::NONE; foreach ($this->unrestrictedGet('permissions') as $permission) { $inheritedPermissions = $permission->getInheritedPermissions($permitable); if ($permission->type == Permission::ALLOW) { $allowPermissions |= $inheritedPermissions; } else { $denyPermissions |= $inheritedPermissions; } } if (!$this instanceof NamedSecurableItem) { foreach (array(get_class($this), static::getModuleClassName()) as $securableItemName) { try { $securableType = NamedSecurableItem::getByName($securableItemName); $typeAllowPermissions = Permission::NONE; $typeDenyPermissions = Permission::NONE; foreach ($securableType->permissions as $permission) { $inheritedPermissions = $permission->getInheritedPermissions($permitable); if ($permission->type == Permission::ALLOW) { $typeAllowPermissions |= $inheritedPermissions; } else { $typeDenyPermissions |= $inheritedPermissions; } } $allowPermissions |= $typeAllowPermissions; $denyPermissions |= $typeDenyPermissions; } catch (NotFoundException $e) { } } } assert("({$allowPermissions} & ~Permission::ALL) == 0"); assert("({$denyPermissions} & ~Permission::ALL) == 0"); return array($allowPermissions, $denyPermissions); }
/** * If a current user cannot write the module, then render a AccessFailurePageView * and end the application. * @param $model - RedBeanModel * @return null; */ public static function resolveAccessCanCurrentUserWriteModule($moduleClassName, $fromAjax = false) { assert('is_string($moduleClassName)'); $item = NamedSecurableItem::getByName($moduleClassName); if (ControllerSecurityUtil::doesCurrentUserHavePermissionOnSecurableItem($item, Permission::WRITE)) { return; } static::processAccessFailure($fromAjax); Yii::app()->end(0, false); }
protected static function AddorRemoveSpecificPermission($moduleClassName, $permitable, $permission, $value) { assert('is_string($moduleClassName)'); assert('$permitable instanceof Permitable'); assert('$permitable->id > 0'); assert('is_int($permission)'); assert('is_int($value) || $value == null'); $item = NamedSecurableItem::getByName($moduleClassName); $item->allowChangePermissionsRegardlessOfUser = true; if (!empty($value) && $value == Permission::ALLOW) { //Before adding explicit allow permission, remove any existing deny permission $item->removePermissions($permitable, $permission, Permission::DENY); $item->addPermissions($permitable, $permission, Permission::ALLOW); } elseif (!empty($value) && $value == Permission::DENY) { $item->addPermissions($permitable, $permission, Permission::DENY); } else { $item->removePermissions($permitable, $permission); } $saved = $item->save(); $item->forget(); return $saved; }
/** * Should not throw an exception AccessDeniedSecurityException */ public function testARegularUserWhoCanAccessGroupsCanProperlyModifyModulePermission() { $nobody = UserTestHelper::createBasicUser('nobody'); $nobody->setRight('GroupsModule', GroupsModule::RIGHT_ACCESS_GROUPS); $nobody->setRight('GroupsModule', GroupsModule::RIGHT_CREATE_GROUPS); $nobody->setRight('GroupsModule', GroupsModule::RIGHT_DELETE_GROUPS); $this->assertTrue($nobody->save()); Yii::app()->user->userModel = $nobody; $group = new Group(); $group->name = 'newGroup2'; $saved = $group->save(); $this->assertTrue($saved); $group->forget(); $newItem = NamedSecurableItem::getByName('SomeModule'); $this->assertEquals(array(Permission::NONE, Permission::NONE), $newItem->getExplicitActualPermissions($group)); $newItem->forget(); $fakePost = array('SomeModule__' . Permission::CHANGE_PERMISSIONS => strval(Permission::ALLOW), 'SomeModule__' . Permission::CHANGE_OWNER => strval(Permission::ALLOW)); $validatedPost = ModulePermissionsFormUtil::typeCastPostData($fakePost); $saved = ModulePermissionsFormUtil::setPermissionsFromCastedPost($validatedPost, $group); $this->assertTrue($saved); //Success, an exception was not thrown. AccessDeniedSecurityException }
/** * Given a moduleClassName, what is the actual read permission? * Permission::DENY, Permission::ALLOW, or Permission::NONE? */ public static function getActualPermissionDataForReadByModuleNameForUser($moduleClassName, User $user = null) { assert('is_string($moduleClassName)'); if ($user == null) { $user = Yii::app()->user->userModel; } $item = NamedSecurableItem::getByName($moduleClassName); return PermissionsUtil::resolveActualPermission($item->getActualPermissions($user), Permission::READ); }
public function testUserWithNotReadPermissionForEmailTemplatesModuleStillCanSeePredefinedTemplates() { $this->logoutCurrentUserLoginNewUserAndGetByUsername('super'); $everyone = Group::getByName(Group::EVERYONE_GROUP_NAME); $item = NamedSecurableItem::getByName('EmailTemplatesModule'); $item->addPermissions($everyone, Permission::READ, Permission::DENY); $this->assertTrue($item->save()); ReadPermissionsOptimizationUtil::rebuild(); $this->logoutCurrentUserLoginNewUserAndGetByUsername('nobody'); $emailTemplate2 = EmailTemplateTestHelper::create('Test Name Regular 02', 'Test Subject Regular 02', 'Contact', 'Test HtmlContent Regular 01', 'Test TextContent Regular 01', EmailTemplate::TYPE_CONTACT, 0, EmailTemplate::BUILT_TYPE_BUILDER_TEMPLATE); $this->setGetArray(array('id' => $emailTemplate2->id, 'filterBy' => SelectBaseTemplateElement::FILTER_BY_PREDEFINED_TEMPLATES, 'ajax' => 'BuilderEmailTemplateWizardForm_baseTemplateId_list_view')); $content = @$this->runControllerWithNoExceptionsAndGetContent('emailTemplates/default/edit'); $this->assertContains('<div class="summary">Displaying 1-6 of 6 results.</div><ul class="template-list clearfix">', $content); $emailTemplate2->delete(); }
public function actionRebuildSecurityCache($User_page = 1, $continue = false) { if (!Group::isUserASuperAdministrator(Yii::app()->user->userModel)) { $failureMessageContent = Zurmo::t('Core', 'You must be a super administrator to rebuild the security cache.'); $messageView = new AccessFailureView($failureMessageContent); $view = new AccessFailurePageView($messageView); echo $view->render(); Yii::app()->end(0, false); } if ($User_page == 1) { //to more quickly show the view to the user. To give a better indication of what is happening. $pageSize = 1; } else { $pageSize = 25; } $namedSecurableItems = array(); $modules = Module::getModuleObjects(); foreach ($modules as $module) { if ($module instanceof SecurableModule) { $namedSecurableItems[] = NamedSecurableItem::getByName(get_class($module)); } } if ($continue) { $page = static::getMassActionProgressStartFromGet('User_page', $pageSize); } else { $page = 1; } $title = Zurmo::t('ZurmoModule', 'Rebuilding Cache'); $searchAttributeData['clauses'] = array(1 => array('attributeName' => 'isSystemUser', 'operatorType' => 'equals', 'value' => 0), 2 => array('attributeName' => 'isSystemUser', 'operatorType' => 'isNull', 'value' => null)); $searchAttributeData['structure'] = '1 or 2'; $dataProvider = RedBeanModelDataProviderUtil::makeDataProvider($searchAttributeData, 'User', 'RedBeanModelDataProvider', null, false, $pageSize); $selectedRecordCount = $dataProvider->getTotalItemCount(); $users = $dataProvider->getData(); foreach ($users as $user) { if (!$user->isSuperAdministrator()) { foreach ($namedSecurableItems as $namedSecurableItem) { $namedSecurableItem->getActualPermissions($user); } } RightsUtil::cacheAllRightsByPermitable($user); } $rebuildView = new RebuildSecurityCacheProgressView($this->getId(), $this->getModule()->getId(), new User(), $selectedRecordCount, $page, $pageSize, $User_page, 'rebuildSecurityCache', $title); if (!$continue) { $view = new ZurmoPageView(ZurmoDefaultAdminViewUtil::makeStandardViewForCurrentUser($this, $rebuildView)); echo $view->render(); Yii::app()->end(0, false); } else { echo $rebuildView->renderRefreshJSONScript(); } }
public function testChangingPermissionsOnEmptyModelsWhenNamedSecuredItemPermissionsChange() { $super = User::getByUsername('super'); $user = new User(); $user->username = '******'; $user->firstName = 'KAAA'; $user->lastName = 'XXA'; $saved = $user->save(); $this->assertTrue($saved); $this->assertTrue($user->id > 0); $item = NamedSecurableItem::getByName('AccountsModule'); $this->assertEquals(Permission::NONE, $item->getEffectivePermissions($user)); $account = new Account(); //loading defaults means the owner will be super. If you do not load defaults //then the users will have Permission::ALL because its id < 0. //@see OwnedSecurableItem::getEffectivePermissions $this->assertEquals(null, $account->name); $this->assertEquals(Permission::ALL, $account->getEffectivePermissions($user)); //switch current user to make sure, still the same. Yii::app()->user->userModel = $user; $this->assertEquals(Permission::ALL, $account->getEffectivePermissions($user)); Yii::app()->user->userModel = $super; $item->addPermissions($user, Permission::READ); $this->assertTrue($item->save()); //now check that new user has permission to read on accounts in general. $permission = $account->getEffectivePermissions($user); $this->assertEquals(Permission::ALL, $permission); Yii::app()->user->userModel = User::getByUsername('ktest'); $permission = $account->getEffectivePermissions($user); $this->assertEquals(Permission::ALL, $permission); Yii::app()->user->userModel = $super; $item->delete(); }
public function testMungeForRegularUserMakeSubsetOrCountSqlQuery() { $quote = DatabaseCompatibilityUtil::getQuote(); //regular user no elevation $benny = User::getByUsername('benny'); Yii::app()->user->userModel = $benny; $joinTablesAdapter = new RedBeanModelJoinTablesQueryAdapter('OwnedSecurableTestItem'); $mungeIds = AllPermissionsOptimizationUtil::getMungeIdsByUser($benny); $subsetSql = OwnedSecurableTestItem::makeSubsetOrCountSqlQuery('ownedsecurabletestitem', $joinTablesAdapter, 1, 5, null, null); $compareSubsetSql = "select distinct {$quote}ownedsecurabletestitem{$quote}.{$quote}id{$quote} id "; $compareSubsetSql .= "from ({$quote}ownedsecurabletestitem{$quote}, {$quote}ownedsecurableitem{$quote}) "; $compareSubsetSql .= "left join {$quote}ownedsecurabletestitem_read{$quote} on "; $compareSubsetSql .= "{$quote}ownedsecurabletestitem_read{$quote}.{$quote}securableitem_id{$quote} = "; $compareSubsetSql .= "{$quote}ownedsecurableitem{$quote}.{$quote}securableitem_id{$quote} "; $compareSubsetSql .= "and {$quote}munge_id{$quote} in ('" . join("', '", $mungeIds) . "') "; $compareSubsetSql .= "where ({$quote}ownedsecurableitem{$quote}.{$quote}owner__user_id{$quote} = {$benny->id} "; $compareSubsetSql .= "OR {$quote}ownedsecurabletestitem_read{$quote}.{$quote}munge_id{$quote} IS NOT NULL) "; // Not Coding Standard $compareSubsetSql .= "and {$quote}ownedsecurableitem{$quote}.{$quote}id{$quote} = "; $compareSubsetSql .= "{$quote}ownedsecurabletestitem{$quote}.{$quote}ownedsecurableitem_id{$quote}"; $compareSubsetSql .= ' limit 5 offset 1'; $this->assertEquals($compareSubsetSql, $subsetSql); //Make sure the sql runs properly. $joinTablesAdapter = new RedBeanModelJoinTablesQueryAdapter('OwnedSecurableTestItem'); $data = OwnedSecurableTestItem::getSubset($joinTablesAdapter, 0, 5, null, null); $this->assertEquals(1, count($data)); $this->assertTrue($data[0]->owner->isSame($benny)); //Check using the getCount method produces the same results. $joinTablesAdapter = new RedBeanModelJoinTablesQueryAdapter('OwnedSecurableTestItem'); $this->assertEquals(1, OwnedSecurableTestItem::getCount($joinTablesAdapter)); //Add in a where clause and make sure the query still works. $metadataAdapter = new SearchDataProviderMetadataAdapter(new OwnedSecurableTestItem(), $benny->id, array('member' => 'test')); $searchAttributeData = $metadataAdapter->getAdaptedMetadata(); $joinTablesAdapter = new RedBeanModelJoinTablesQueryAdapter('OwnedSecurableTestItem'); $where = RedBeanModelDataProvider::makeWhere('OwnedSecurableTestItem', $searchAttributeData, $joinTablesAdapter); $compareWhere = "({$quote}ownedsecurabletestitem{$quote}.{$quote}member{$quote} like 'test%')"; $this->assertEquals($compareWhere, $where); $subsetSql = OwnedSecurableTestItem::makeSubsetOrCountSqlQuery('ownedsecurabletestitem', $joinTablesAdapter, 1, 5, $where, null); $compareSubsetSql = "select distinct {$quote}ownedsecurabletestitem{$quote}.{$quote}id{$quote} id "; $compareSubsetSql .= "from ({$quote}ownedsecurabletestitem{$quote}, {$quote}ownedsecurableitem{$quote}) "; $compareSubsetSql .= "left join {$quote}ownedsecurabletestitem_read{$quote} on "; $compareSubsetSql .= "{$quote}ownedsecurabletestitem_read{$quote}.{$quote}securableitem_id{$quote} = "; $compareSubsetSql .= "{$quote}ownedsecurableitem{$quote}.{$quote}securableitem_id{$quote} "; $compareSubsetSql .= "and {$quote}munge_id{$quote} in ('" . join("', '", $mungeIds) . "') "; $compareSubsetSql .= "where ({$compareWhere}) and ({$quote}ownedsecurableitem{$quote}.{$quote}owner__user_id{$quote} = {$benny->id} "; $compareSubsetSql .= "OR {$quote}ownedsecurabletestitem_read{$quote}.{$quote}munge_id{$quote} IS NOT NULL) "; // Not Coding Standard $compareSubsetSql .= "and {$quote}ownedsecurableitem{$quote}.{$quote}id{$quote} = "; $compareSubsetSql .= "{$quote}ownedsecurabletestitem{$quote}.{$quote}ownedsecurableitem_id{$quote}"; $compareSubsetSql .= ' limit 5 offset 1'; $this->assertEquals($compareSubsetSql, $subsetSql); //now run query to make sure it actually works. $joinTablesAdapter = new RedBeanModelJoinTablesQueryAdapter('OwnedSecurableTestItem'); $where = RedBeanModelDataProvider::makeWhere('OwnedSecurableTestItem', $searchAttributeData, $joinTablesAdapter); $data = OwnedSecurableTestItem::getSubset($joinTablesAdapter, 0, 5, null, null); $this->assertEquals(1, count($data)); $this->assertTrue($data[0]->owner->isSame($benny)); //Check using the getCount method produces the same results. $joinTablesAdapter = new RedBeanModelJoinTablesQueryAdapter('OwnedSecurableTestItem'); RedBeanModelDataProvider::makeWhere('OwnedSecurableTestItem', $searchAttributeData, $joinTablesAdapter); $this->assertEquals(1, OwnedSecurableTestItem::getCount($joinTablesAdapter)); //Now give Benny READ on the module. After that he should not need the munge query. Yii::app()->user->userModel = User::getByUsername('super'); $item = NamedSecurableItem::getByName('ZurmoModule'); $item->addPermissions($benny, Permission::READ); $this->assertTrue($item->save()); Yii::app()->user->userModel = User::getByUsername('benny'); //There should not be a 'distinct' in the query or the munge part. $joinTablesAdapter = new RedBeanModelJoinTablesQueryAdapter('OwnedSecurableTestItem'); $subsetSql = OwnedSecurableTestItem::makeSubsetOrCountSqlQuery('ownedsecurabletestitem', $joinTablesAdapter, 1, 5, null, null); $compareSubsetSql = "select {$quote}ownedsecurabletestitem{$quote}.{$quote}id{$quote} id "; $compareSubsetSql .= "from {$quote}ownedsecurabletestitem{$quote} "; $compareSubsetSql .= ' limit 5 offset 1'; $this->assertEquals($compareSubsetSql, $subsetSql); //Make sure the sql runs properly. $data = OwnedSecurableTestItem::getSubset($joinTablesAdapter, 0, 5, null, null); $this->assertEquals(3, count($data)); //Check using the getCount method produces the same results. $joinTablesAdapter = new RedBeanModelJoinTablesQueryAdapter('OwnedSecurableTestItem'); $this->assertEquals(3, OwnedSecurableTestItem::getCount($joinTablesAdapter)); //make sure adding a where query is ok without any munge query parts $metadataAdapter = new SearchDataProviderMetadataAdapter(new OwnedSecurableTestItem(), $benny->id, array('member' => 'test')); $searchAttributeData = $metadataAdapter->getAdaptedMetadata(); $joinTablesAdapter = new RedBeanModelJoinTablesQueryAdapter('OwnedSecurableTestItem'); $where = RedBeanModelDataProvider::makeWhere('OwnedSecurableTestItem', $searchAttributeData, $joinTablesAdapter); $compareWhere = "({$quote}ownedsecurabletestitem{$quote}.{$quote}member{$quote} like 'test%')"; $this->assertEquals($compareWhere, $where); $subsetSql = OwnedSecurableTestItem::makeSubsetOrCountSqlQuery('ownedsecurabletestitem', $joinTablesAdapter, 1, 5, $where, null); $compareSubsetSql = "select {$quote}ownedsecurabletestitem{$quote}.{$quote}id{$quote} id "; $compareSubsetSql .= "from {$quote}ownedsecurabletestitem{$quote} "; $compareSubsetSql .= "where {$compareWhere}"; $compareSubsetSql .= ' limit 5 offset 1'; $this->assertEquals($compareSubsetSql, $subsetSql); //now run query to make sure it actually works. $joinTablesAdapter = new RedBeanModelJoinTablesQueryAdapter('OwnedSecurableTestItem'); RedBeanModelDataProvider::makeWhere('OwnedSecurableTestItem', $searchAttributeData, $joinTablesAdapter); $data = OwnedSecurableTestItem::getSubset($joinTablesAdapter, 0, 5, null, null); $this->assertEquals(3, count($data)); //Check using the getCount method produces the same results. $joinTablesAdapter = new RedBeanModelJoinTablesQueryAdapter('OwnedSecurableTestItem'); $where = RedBeanModelDataProvider::makeWhere('OwnedSecurableTestItem', $searchAttributeData, $joinTablesAdapter); $this->assertEquals(3, OwnedSecurableTestItem::getCount($joinTablesAdapter)); //Now remove READ ALLOW for BENNY, and Add READ DENY Yii::app()->user->userModel = User::getByUsername('super'); $item = NamedSecurableItem::getByName('ZurmoModule'); $item->removePermissions($benny, Permission::READ); $this->assertTrue($item->save()); $item->addPermissions($benny, Permission::READ, Permission::DENY); $this->assertTrue($item->save()); Yii::app()->user->userModel = User::getByUsername('benny'); //Now confirm that the query is just on the owner only, no munge. $joinTablesAdapter = new RedBeanModelJoinTablesQueryAdapter('OwnedSecurableTestItem'); $subsetSql = OwnedSecurableTestItem::makeSubsetOrCountSqlQuery('ownedsecurabletestitem', $joinTablesAdapter, 1, 5, null, null); $compareSubsetSql = "select {$quote}ownedsecurabletestitem{$quote}.{$quote}id{$quote} id "; $compareSubsetSql .= "from ({$quote}ownedsecurabletestitem{$quote}, {$quote}ownedsecurableitem{$quote}) "; $compareSubsetSql .= "where {$quote}ownedsecurableitem{$quote}.{$quote}owner__user_id{$quote} = {$benny->id} "; $compareSubsetSql .= "and {$quote}ownedsecurableitem{$quote}.{$quote}id{$quote} = "; $compareSubsetSql .= "{$quote}ownedsecurabletestitem{$quote}.{$quote}ownedsecurableitem_id{$quote}"; $compareSubsetSql .= ' limit 5 offset 1'; $this->assertEquals($compareSubsetSql, $subsetSql); //Make sure the sql runs properly. $joinTablesAdapter = new RedBeanModelJoinTablesQueryAdapter('OwnedSecurableTestItem'); $data = OwnedSecurableTestItem::getSubset($joinTablesAdapter, 0, 5, null, null); $this->assertEquals(1, count($data)); $this->assertTrue($data[0]->owner->isSame($benny)); //Check using the getCount method produces the same results. $joinTablesAdapter = new RedBeanModelJoinTablesQueryAdapter('OwnedSecurableTestItem'); $this->assertEquals(1, OwnedSecurableTestItem::getCount($joinTablesAdapter)); }
/** * @depends testUserCanReadEmptyModelWithoutPermissionAndNoDefaultsSetOnModelButCantSaveItUntilTheySetAnOwner */ public function testUserWhoCreatesModelAndGivesItAwayLosesAccessAndCantGetItBack() { $user = User::getByUsername('atester'); $user2 = UserTestHelper::createBasicUser('atester2'); $item = NamedSecurableItem::getByName('AccountsModule'); $this->assertEquals(Permission::NONE, $item->getEffectivePermissions($user)); Yii::app()->user->userModel = $user; $account = new Account(false); // When an account has no owner (meaning the unsaved user // automatically) associated with it can be manipulated // but whoever created. $this->assertEquals('', $account->name); // If it is given away... $account->owner = $user2; $account->save(); try { // They lose access to it. $name = $account->name; //They should still have access to it. This is a change made in 2.0.13 to properly support cloning. } catch (AccessDeniedSecurityException $e) { $this->fail(); } try { // AS of 2.0.13 they should be able to get it back. $account->owner = new User(); } catch (AccessDeniedSecurityException $e) { $this->fail(); } }
/** * @depends testNewlyImportedDataForUpdateEmailDedupe */ public function testImportedDataForNameUpdateDedupe() { $jim = User::getByUsername('jim'); Yii::app()->user->userModel = $jim; //Confirm Jim can can only view ImportModelTestItems he owns. $item = NamedSecurableItem::getByName('ImportModule'); $this->assertEquals(Permission::NONE, $item->getEffectivePermissions($jim)); $testModels = Account::getByName('hello'); $this->assertEquals(1, count($testModels)); $import = new Import(); $serializedData['importRulesType'] = 'Accounts'; $serializedData['firstRowIsHeaderRow'] = true; $import->serializedData = serialize($serializedData); $this->assertTrue($import->save()); ImportTestHelper::createTempTableByFileNameAndTableName('importDedupeNameTest.csv', $import->getTempTableName(), true); $this->assertEquals(2, ImportDatabaseUtil::getCount($import->getTempTableName())); // includes header rows. $emailMappingData = ImportMappingUtil::makeEmailColumnMappingData('primaryEmail__emailAddress'); $emailMappingData['mappingRulesData']['EmailModelAttributeDedupeMappingRuleForm'] = array('dedupeRule' => ImportDedupeRulesRadioDropDownElement::DO_NOT_DEDUPE); $nameMappingData = ImportMappingUtil::makeEmailColumnMappingData('name'); $nameMappingData['mappingRulesData']['NameModelAttributeDedupeMappingRuleForm'] = array('dedupeRule' => ImportDedupeRulesRadioDropDownElement::UPDATE_ROW_ON_MATCH_FOUND); $mappingData = array('column_0' => $nameMappingData, 'column_1' => $emailMappingData); $importRules = ImportRulesUtil::makeImportRulesByType('Accounts'); $page = 0; $config = array('pagination' => array('pageSize' => 50)); //This way all rows are processed. $dataProvider = new ImportDataProvider($import->getTempTableName(), true, $config); $dataProvider->getPagination()->setCurrentPage($page); $importResultsUtil = new ImportResultsUtil($import); $messageLogger = new ImportMessageLogger(); ImportUtil::importByDataProvider($dataProvider, $importRules, $mappingData, $importResultsUtil, new ExplicitReadWriteModelPermissions(), $messageLogger); $importResultsUtil->processStatusAndMessagesForEachRow(); $testModels = Account::getByName('hello'); $this->assertEquals(1, count($testModels)); $this->assertEquals('*****@*****.**', $testModels[0]->primaryEmail->emailAddress); }
/** * Test when a normal user who can only view records he owns, tries to import records assigned to another user. * @depends testSetDataAnalyzerMultiSelectAndTagCloudImport */ public function testImportSwitchingOwnerButShouldStillCreate() { $super = User::getByUsername('super'); $jim = User::getByUsername('jim'); Yii::app()->user->userModel = $jim; //Confirm Jim can can only view ImportModelTestItems he owns. $item = NamedSecurableItem::getByName('ImportModule'); $this->assertEquals(Permission::NONE, $item->getEffectivePermissions($jim)); //Unfreeze since the test model is not part of the standard schema. $freezeWhenComplete = false; if (RedBeanDatabase::isFrozen()) { RedBeanDatabase::unfreeze(); $freezeWhenComplete = true; } $testModels = ImportModelTestItem::getAll(); $this->assertEquals(0, count($testModels)); $import = new Import(); $serializedData['importRulesType'] = 'ImportModelTestItem'; $serializedData['firstRowIsHeaderRow'] = true; $import->serializedData = serialize($serializedData); $this->assertTrue($import->save()); ImportTestHelper::createTempTableByFileNameAndTableName('importEmptyCurrencyTest.csv', $import->getTempTableName()); $this->assertEquals(3, ImportDatabaseUtil::getCount($import->getTempTableName())); // includes header rows. $columnMappingData = array('attributeIndexOrDerivedType' => 'owner', 'type' => 'extraColumn', 'mappingRulesData' => array('DefaultModelNameIdMappingRuleForm' => array('defaultModelId' => $super->id), 'UserValueTypeModelAttributeMappingRuleForm' => array('type' => UserValueTypeModelAttributeMappingRuleForm::ZURMO_USER_ID))); $mappingData = array('column_0' => ImportMappingUtil::makeStringColumnMappingData('lastName'), 'column_1' => ImportMappingUtil::makeStringColumnMappingData('string'), 'column_2' => $columnMappingData); $importRules = ImportRulesUtil::makeImportRulesByType('ImportModelTestItem'); $page = 0; $config = array('pagination' => array('pageSize' => 50)); //This way all rows are processed. $dataProvider = new ImportDataProvider($import->getTempTableName(), true, $config); $dataProvider->getPagination()->setCurrentPage($page); $importResultsUtil = new ImportResultsUtil($import); $messageLogger = new ImportMessageLogger(); ImportUtil::importByDataProvider($dataProvider, $importRules, $mappingData, $importResultsUtil, new ExplicitReadWriteModelPermissions(), $messageLogger); $importResultsUtil->processStatusAndMessagesForEachRow(); //Confirm that 2 models where created. $testModels = ImportModelTestItem::getAll(); $this->assertEquals(2, count($testModels)); foreach ($testModels as $model) { $this->assertEquals(array(Permission::NONE, Permission::NONE), $model->getExplicitActualPermissions($jim)); } //Confirm 10 rows were processed as 'created'. $this->assertEquals(2, ImportDatabaseUtil::getCount($import->getTempTableName(), "status = " . ImportRowDataResultsUtil::CREATED)); //Confirm that 0 rows were processed as 'updated'. $this->assertEquals(0, ImportDatabaseUtil::getCount($import->getTempTableName(), "status = " . ImportRowDataResultsUtil::UPDATED)); //Confirm 2 rows were processed as 'errors'. $this->assertEquals(0, ImportDatabaseUtil::getCount($import->getTempTableName(), "status = " . ImportRowDataResultsUtil::ERROR)); $beansWithErrors = ImportDatabaseUtil::getSubset($import->getTempTableName(), "status = " . ImportRowDataResultsUtil::ERROR); $this->assertEquals(0, count($beansWithErrors)); //Clear out data in table R::exec("delete from " . ImportModelTestItem::getTableName('ImportModelTestItem')); //Re-freeze if needed. if ($freezeWhenComplete) { RedBeanDatabase::freeze(); } }