public function testGetMungeIdsByUserIncludesEveryoneGroup() { Yii::app()->user->userModel = User::getByUsername('super'); $mungeIds = AllPermissionsOptimizationUtil::getMungeIdsByUser(Yii::app()->user->userModel); $this->assertEquals(2, count($mungeIds)); $group = Group::getByName(Group::EVERYONE_GROUP_NAME); $group->save(); AllPermissionsOptimizationCache::forgetAll(); $mungeIds = AllPermissionsOptimizationUtil::getMungeIdsByUser(Yii::app()->user->userModel); $this->assertEquals(3, count($mungeIds)); }
protected function addReadOptimizationWhereClause(&$where, $whereKey, $tableAliasName) { assert('is_array($where)'); assert('is_int($whereKey)'); assert('is_string($tableAliasName)'); $q = DatabaseCompatibilityUtil::getQuote(); $columnWithTableAlias = self::makeColumnNameWithTableAlias($tableAliasName, $this->modelAttributeToDataProviderAdapter->getColumnName()); $mungeTableName = ReadPermissionsOptimizationUtil::getMungeTableName($this->modelAttributeToDataProviderAdapter->getModelClassName()); $mungeIds = AllPermissionsOptimizationUtil::getMungeIdsByUser(Yii::app()->user->userModel); $whereContent = $columnWithTableAlias . " " . SQLOperatorUtil::getOperatorByType('equals') . " "; $whereContent .= "(select securableitem_id from {$q}{$mungeTableName}{$q} " . "where {$q}securableitem_id{$q} = {$columnWithTableAlias} and {$q}munge_id{$q}" . " in ('" . join("', '", $mungeIds) . "') limit 1)"; $where[$whereKey] = $whereContent; }
/** * @param string $modelClassName * @param null | string $attributeIndexes * @param null | string $attributeIndexPrefix */ public static function resolveAttributeIndexes($modelClassName, &$attributeIndexes, $attributeIndexPrefix = null) { assert('is_string($modelClassName)'); assert('is_string($attributeIndexPrefix) || $attributeIndexPrefix == null'); $moduleClassName = $modelClassName::getModuleClassName(); if (is_subclass_of($modelClassName, 'SecurableItem') && $modelClassName::hasReadPermissionsOptimization() && $moduleClassName != null && is_subclass_of($moduleClassName, 'SecurableModule')) { $permission = PermissionsUtil::getActualPermissionDataForReadByModuleNameForUser($moduleClassName); if ($permission == Permission::NONE || $permission == Permission::DENY) { $indexes = array(); $indexes[] = 'owner__User'; $mungeIds = AllPermissionsOptimizationUtil::getMungeIdsByUser(Yii::app()->user->userModel); if (count($mungeIds) > 0 && $permission == Permission::NONE) { $indexes[] = 'ReadOptimization'; } $attributeIndexes[$attributeIndexPrefix] = $indexes; } } }
/** * @param User $user * @param RedBeanModelJoinTablesQueryAdapter $joinTablesAdapter * @param $where * @param $selectDistinct * @throws NotSupportedException */ public static function resolveReadPermissionsOptimizationToSqlQuery(User $user, RedBeanModelJoinTablesQueryAdapter $joinTablesAdapter, &$where, &$selectDistinct) { assert('$where == null || is_string($where)'); assert('is_bool($selectDistinct)'); $modelClassName = get_called_class(); $moduleClassName = $modelClassName::getModuleClassName(); //Currently only adds munge if the module is securable and this model supports it. if (static::hasReadPermissionsOptimization() && $moduleClassName != null && is_subclass_of($moduleClassName, 'SecurableModule')) { $permission = PermissionsUtil::getActualPermissionDataForReadByModuleNameForUser($moduleClassName); if (($permission == Permission::NONE || $permission == Permission::DENY) && !static::bypassReadPermissionsOptimizationToSqlQueryBasedOnWhere($where)) { $quote = DatabaseCompatibilityUtil::getQuote(); $modelAttributeToDataProviderAdapter = new OwnedSecurableItemIdToDataProviderAdapter($modelClassName, null); $builder = new ModelJoinBuilder($modelAttributeToDataProviderAdapter, $joinTablesAdapter); $ownedTableAliasName = $builder->resolveJoins(); $ownerColumnName = static::getForeignKeyName('OwnedSecurableItem', 'owner'); $mungeIds = AllPermissionsOptimizationUtil::getMungeIdsByUser($user); if ($where != null) { $where = '(' . $where . ') and '; } if (count($mungeIds) > 0 && $permission == Permission::NONE) { $extraOnQueryPart = " and {$quote}munge_id{$quote} in ('" . join("', '", $mungeIds) . "')"; $mungeTableName = ReadPermissionsOptimizationUtil::getMungeTableName($modelClassName); $mungeTableAliasName = $joinTablesAdapter->addLeftTableAndGetAliasName($mungeTableName, 'securableitem_id', $ownedTableAliasName, 'securableitem_id', $extraOnQueryPart); $where .= "({$quote}{$ownedTableAliasName}{$quote}.{$quote}{$ownerColumnName}{$quote} = {$user->id} OR "; // Not Coding Standard $where .= "{$quote}{$mungeTableName}{$quote}.{$quote}munge_id{$quote} IS NOT NULL)"; // Not Coding Standard $selectDistinct = true; //must use distinct since adding munge table query. } elseif ($permission == Permission::DENY) { $where .= "{$quote}{$ownedTableAliasName}{$quote}.{$quote}{$ownerColumnName}{$quote} = {$user->id}"; // Not Coding Standard } else { throw new NotSupportedException(); } } } }
public function testUnionQuery() { //regular user no elevation $user = new User(); $user->username = '******'; $user->firstName = 'aaa'; $user->lastName = 'aaa'; $saved = $user->save(); $this->assertTrue($saved); $aUser = User::getByUsername('aaa'); Yii::app()->user->userModel = $aUser; $mungeIds = AllPermissionsOptimizationUtil::getMungeIdsByUser($aUser); $model = new OwnedSecurableTestItem(); $model->member = 'test4'; $model->owner = $aUser; $this->assertTrue($model->save()); Yii::app()->user->userModel = User::getByUsername('super'); $this->assertEquals(4, OwnedSecurableTestItem::getCount()); $model = new OwnedSecurableTestItem2(); $model->member = 'test4'; $model->owner = $aUser; $this->assertTrue($model->save()); $this->assertEquals(2, OwnedSecurableTestItem2::getCount()); Yii::app()->user->userModel = User::getByUsername('aaa'); $quote = DatabaseCompatibilityUtil::getQuote(); //Test search attribute data across multiple models. $aFakePost = array('member' => 'test4'); $aMetadataAdapter = new SearchDataProviderMetadataAdapter(new OwnedSecurableTestItem(false), $aUser->id, $aFakePost); $bFakePost = array('member' => 'test4'); $bMetadataAdapter = new SearchDataProviderMetadataAdapter(new OwnedSecurableTestItem2(false), $aUser->id, $bFakePost); $modelClassNamesAndSearchAttributeData = array(array('OwnedSecurableTestItem' => $aMetadataAdapter->getAdaptedMetadata()), array('OwnedSecurableTestItem2' => $bMetadataAdapter->getAdaptedMetadata())); $unionSql = RedBeanModelsDataProvider::makeUnionSql($modelClassNamesAndSearchAttributeData, null, false, 2, 7); $compareWhere = "({$quote}ownedsecurabletestitem{$quote}.{$quote}member{$quote} like 'test4%')"; $compareWhere2 = "({$quote}ownedsecurabletestitem2{$quote}.{$quote}member{$quote} like 'test4%')"; $compareSubsetSql = "("; $compareSubsetSql .= "select distinct {$quote}ownedsecurabletestitem{$quote}.{$quote}id{$quote} id"; $compareSubsetSql .= ", 'OwnedSecurableTestItem' modelClassName "; $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} = {$aUser->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 .= ") "; $compareSubsetSql .= "UNION ("; $compareSubsetSql .= "select distinct {$quote}ownedsecurabletestitem2{$quote}.{$quote}id{$quote} id"; $compareSubsetSql .= ", 'OwnedSecurableTestItem2' modelClassName "; $compareSubsetSql .= "from ({$quote}ownedsecurabletestitem2{$quote}, {$quote}ownedsecurableitem{$quote}) "; $compareSubsetSql .= "left join {$quote}ownedsecurabletestitem2_read{$quote} on "; $compareSubsetSql .= "{$quote}ownedsecurabletestitem2_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 ({$compareWhere2}) and ({$quote}ownedsecurableitem{$quote}.{$quote}owner__user_id{$quote} = {$aUser->id} "; $compareSubsetSql .= "OR {$quote}ownedsecurabletestitem2_read{$quote}.{$quote}munge_id{$quote} IS NOT NULL) "; // Not Coding Standard $compareSubsetSql .= "and {$quote}ownedsecurableitem{$quote}.{$quote}id{$quote} = "; $compareSubsetSql .= "{$quote}ownedsecurabletestitem2{$quote}.{$quote}ownedsecurableitem_id{$quote}"; $compareSubsetSql .= ") "; $compareSubsetSql .= 'limit 7 offset 2'; $this->assertEquals($compareSubsetSql, $unionSql); //Make sure the sql runs properly. $dataProvider = new RedBeanModelsDataProvider('anId', null, false, $modelClassNamesAndSearchAttributeData); $data = $dataProvider->getData(); //Test results are correct $this->assertEquals(2, count($data)); $this->assertEquals('OwnedSecurableTestItem', get_class($data[0])); $this->assertEquals('OwnedSecurableTestItem2', get_class($data[1])); //Make sure union count query produces the same count. $this->assertEquals(2, $dataProvider->calculateTotalItemCount()); }
public function testResolveSearchAttributesDataByRelatedItemIdWithRegularUser() { //TODO: @sergio: Fix where and sql asserts Yii::app()->user->userModel = User::getByUsername('benny'); $mungeIds = AllPermissionsOptimizationUtil::getMungeIdsByUser(Yii::app()->user->userModel); $quote = DatabaseCompatibilityUtil::getQuote(); $rules = new EmailMessageMashableActivityRules(); $searchAttributeData = $rules->resolveSearchAttributesDataByRelatedItemId(5); $joinTablesAdapter = new RedBeanModelJoinTablesQueryAdapter('EmailMessage'); $where = RedBeanModelDataProvider::makeWhere('EmailMessage', $searchAttributeData, $joinTablesAdapter); $compareWhere = "(({$quote}emailmessagesender{$quote}.{$quote}personoraccount_item_id{$quote} = 5) or (1 = "; $compareWhere .= "(select 1 from {$quote}emailmessagerecipient{$quote} emailmessagerecipient where "; $compareWhere .= "{$quote}emailmessagerecipient{$quote}.{$quote}emailmessage_id` = {$quote}emailmessage"; $compareWhere .= "{$quote}.id and {$quote}emailmessagerecipient{$quote}.{$quote}personoraccount_item_id` = 5 limit 1)))"; //$this->assertEquals($compareWhere, $where); $sql = EmailMessage::makeSubsetOrCountSqlQuery('emailmessage', $joinTablesAdapter, 1, 5, $where, null); $compareSubsetSql = "select distinct {$quote}emailmessage{$quote}.{$quote}id{$quote} id "; $compareSubsetSql .= "from ({$quote}emailmessage{$quote}, {$quote}ownedsecurableitem{$quote}) "; $compareSubsetSql .= "left join {$quote}emailmessagesender{$quote} on "; $compareSubsetSql .= "{$quote}emailmessagesender{$quote}.{$quote}id{$quote} = {$quote}emailmessage{$quote}."; $compareSubsetSql .= "{$quote}sender_emailmessagesender_id{$quote} "; $compareSubsetSql .= "left join {$quote}emailmessage_read{$quote} on "; $compareSubsetSql .= "{$quote}emailmessage_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 . ') '; $compareSubsetSql .= "and ({$quote}ownedsecurableitem{$quote}.{$quote}owner__user_id{$quote} = " . Yii::app()->user->userModel->id . " "; // Not Coding Standard $compareSubsetSql .= "OR {$quote}emailmessage_read{$quote}.{$quote}munge_id{$quote} IS NOT NULL) "; // Not Coding Standard $compareSubsetSql .= "and {$quote}ownedsecurableitem{$quote}.{$quote}id{$quote} = "; $compareSubsetSql .= "{$quote}emailmessage{$quote}.{$quote}ownedsecurableitem_id{$quote} "; $compareSubsetSql .= 'limit 5 offset 1'; //$this->assertEquals($compareSubsetSql, $sql); //Make sure the sql runs properly. $data = EmailMessage::getSubset($joinTablesAdapter, 0, 5, $where, null); $this->assertEquals(0, count($data)); }