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));
 }