diff --git a/application/controllers/admin/checkintegrity.php b/application/controllers/admin/checkintegrity.php index 023091ac8a9..2e54558f72b 100644 --- a/application/controllers/admin/checkintegrity.php +++ b/application/controllers/admin/checkintegrity.php @@ -248,26 +248,30 @@ private function _deleteQuotaMembers(array $aData) return $aData; } + /** + * This function Deletes quota language settings without related main entries + * + */ private function _deleteQuotaLanguageSettings() { - $quotas = Quota::model()->findAll(); - foreach ($quotas as $quota) $quota_ids[] = $quota['id']; - $criteria = new CDbCriteria; - $criteria->addNotInCondition('quotals_quota_id', $quota_ids); - - QuotaLanguageSetting::model()->deleteAll($criteria); + $oCriteria = new CDbCriteria; + $oCriteria->join = 'LEFT JOIN {{quota}} q ON t.quotals_quota_id=q.id'; + $oCriteria->condition = '(q.id IS NULL)'; + QuotaLanguageSetting::model()->deleteAll($oCriteria); if (QuotaLanguageSetting::model()->hasErrors()) throw new \CHttpException(500, QuotaLanguageSetting::model()->getError()); } + /** + * This function deletes quota entries which not having a related survey entry + * + * @param mixed $aData + */ private function _deleteQuotas(array $aData) { - $sids = array(); - $surveys = Survey::model()->findAll(); - foreach ($surveys as $survey) $sids[] = $survey['sid']; - $criteria = new CDbCriteria; - $criteria->addNotInCondition('sid', $sids); - - Quota::model()->deleteAll($criteria); + $oCriteria = new CDbCriteria; + $oCriteria->join = 'LEFT JOIN {{surveys}} q ON t.sid=q.sid'; + $oCriteria->condition = '(q.sid IS NULL)'; + Quota::model()->deleteAll($oCriteria); if (Quota::model()->hasErrors()) throw new \CHttpException(500, Quota::model()->getError()); $aData['messages'][] = gT('Deleting orphaned quotas.'); return $aData; @@ -320,25 +324,21 @@ private function _deleteConditions(array $conditions, array $aData) */ protected function _checkintegrity() { - - - /*** Plainly delete survey permissions if the survey or user does not exist ***/ - $users = User::model()->findAll(); - $uids = array(); - foreach ($users as $user) $uids[] = $user['uid']; + // Delete survey permissions if the user does not exist $oCriteria = new CDbCriteria; - $oCriteria->addNotInCondition('uid', $uids, 'OR'); - - $surveys = Survey::model()->findAll(); - $sids = array(); - foreach ($surveys as $survey) $sids[] = $survey['sid']; - $oCriteria->addNotInCondition('entity_id', $sids, 'OR'); - $oCriteria->addCondition("entity='survey'"); + $oCriteria->join = 'LEFT JOIN {{users}} u ON {{permissions}}.uid=u.uid'; + $oCriteria->condition = '(u.uid IS NULL)'; + Permission::model()->deleteAll($oCriteria); + // Delete survey permissions if the survey does not exist + $oCriteria = new CDbCriteria; + $oCriteria->join = 'LEFT JOIN {{surveys}} s ON {{permissions}}.entity_id=s.sid'; + $oCriteria->condition = "(s.sid IS NULL AND entity='survey')"; Permission::model()->deleteAll($oCriteria); // Deactivate surveys that have a missing response table + $surveys = Survey::model()->findAll(); foreach ($surveys as $survey) { if ($survey['active']=='Y' && !tableExists("{{survey_{$survey['sid']}}}")) @@ -454,26 +454,19 @@ protected function _checkintegrity() /**********************************************************************/ /* Check quotas */ /**********************************************************************/ - $surveys = Survey::model()->findAll(); - if (Survey::model()->hasErrors()) throw new \CHttpException(500, Survey::model()->getError()); - $sids = array(); - foreach ($surveys as $survey) $sids[] = $survey['sid']; - $oCriteria = new CDbCriteria; - $oCriteria->addNotInCondition('sid', $sids); + $oCriteria = new CDbCriteria; + $oCriteria->join = 'LEFT JOIN {{surveys}} s ON t.sid=s.sid'; + $oCriteria->condition = '(s.sid IS NULL)'; $aDelete['quotas'] = count(Quota::model()->findAll($oCriteria)); if (Quota::model()->hasErrors()) throw new \CHttpException(500, Quota::model()->getError()); /**********************************************************************/ /* Check quota languagesettings */ /**********************************************************************/ - $quotas = Quota::model()->findAll(); - if (Quota::model()->hasErrors()) throw new \CHttpException(500, Quota::model()->getError()); - $ids = array(); - foreach ($quotas as $quota) $ids[] = $quota['id']; $oCriteria = new CDbCriteria; - $oCriteria->addNotInCondition('quotals_quota_id', $ids); - + $oCriteria->join = 'LEFT JOIN {{quota}} s ON t.quotals_quota_id=s.id'; + $oCriteria->condition = '(s.id IS NULL)'; $aDelete['quotals'] = count(QuotaLanguageSetting::model()->findAll($oCriteria)); if (QuotaLanguageSetting::model()->hasErrors()) throw new \CHttpException(500, QuotaLanguageSetting::model()->getError()); @@ -560,19 +553,14 @@ protected function _checkintegrity() } } - /**********************************************************************/ /* Check survey language settings */ /**********************************************************************/ - $surveys = Survey::model()->findAll(); - if (Survey::model()->hasErrors()) throw new \CHttpException(500, Survey::model()->getError()); - $sids = array(); - foreach ($surveys as $survey) $sids[] = $survey['sid']; $oCriteria = new CDbCriteria; - $oCriteria->addNotInCondition('surveyls_survey_id', $sids); + $oCriteria->join = 'LEFT JOIN {{surveys}} s ON t.surveyls_survey_id=s.sid'; + $oCriteria->condition = '(s.sid IS NULL)'; $surveys_languagesettings = SurveyLanguageSetting::model()->findAll($oCriteria); if (SurveyLanguageSetting::model()->hasErrors()) throw new \CHttpException(500, SurveyLanguageSetting::model()->getError()); - foreach ($surveys_languagesettings as $surveys_languagesetting) { $aDelete['surveylanguagesettings'][] = array('slid' => $surveys_languagesetting['surveyls_survey_id'], 'reason' => gT('The related survey is missing.')); @@ -595,9 +583,8 @@ protected function _checkintegrity() /* Check groups */ /**********************************************************************/ $oCriteria = new CDbCriteria; - $oCriteria->addNotInCondition('sid', array_map(function(Survey $survey) { - return $survey->primaryKey; - }, Survey::model()->findAll())); + $oCriteria->join = 'LEFT JOIN {{surveys}} s ON t.sid=s.sid'; + $oCriteria->condition = '(s.sid IS NULL)'; $groups = QuestionGroup::model()->findAll($oCriteria); /** @var QuestionGroup $group */ foreach ($groups as $group) diff --git a/application/core/LSYii_Validators.php b/application/core/LSYii_Validators.php index 76bb188a76f..437ee119bbe 100644 --- a/application/core/LSYii_Validators.php +++ b/application/core/LSYii_Validators.php @@ -46,10 +46,11 @@ protected function validateAttribute($object,$attribute) $object->$attribute=str_replace('javascript:','',html_entity_decode($object->$attribute, ENT_QUOTES, "UTF-8")); } } + // Note that URL checking only checks basic URL properties. As a URL can contain EM expression there needs to be a lot of freedom. if($this->isUrl) { if ($object->$attribute== 'http://' || $object->$attribute=='https://') {$object->$attribute="";} - $object->$attribute=str_replace(array('"',"'",' ','<','>'),'',html_entity_decode($object->$attribute, ENT_QUOTES, "UTF-8")); // 140219 : Why not urlencode ? + $object->$attribute=html_entity_decode($object->$attribute, ENT_QUOTES, "UTF-8"); } if($this->isLanguage) { diff --git a/application/core/plugins/AuthLDAP/AuthLDAP.php b/application/core/plugins/AuthLDAP/AuthLDAP.php index c426b4bf54b..06c80cdac02 100644 --- a/application/core/plugins/AuthLDAP/AuthLDAP.php +++ b/application/core/plugins/AuthLDAP/AuthLDAP.php @@ -6,14 +6,6 @@ class AuthLDAP extends ls\pluginmanager\AuthPluginBase static protected $description = 'Core: LDAP authentication'; static protected $name = 'LDAP'; - /** - * Can we autocreate users? For the moment this is disabled, will be moved - * to a setting when we have more robust user creation system. - * - * @var boolean - */ - protected $autoCreate = false; - protected $settings = array( 'server' => array( 'type' => 'string', @@ -91,6 +83,10 @@ class AuthLDAP extends ls\pluginmanager\AuthPluginBase 'is_default' => array( 'type' => 'checkbox', 'label' => 'Check to make default authentication method' + ), + 'autocreate' => array( + 'type' => 'checkbox', + 'label' => 'Automatically create user if it exists in LDAP server' ) ); @@ -119,8 +115,17 @@ public function createNewUser() return; } + $this->_createNewUser(flattenText(Yii::app()->request->getPost('new_user'), false, true)); + } + + /** + * Create a LDAP user + * + * @return unknown_type + */ + private function _createNewUser($new_user) + { $oEvent = $this->getEvent(); - $new_user = flattenText(Yii::app()->request->getPost('new_user'), false, true); // Get configuration settings: $ldapserver = $this->get('server'); @@ -206,7 +211,16 @@ public function createNewUser() return; } $new_pass = createPassword(); - $iNewUID = User::model()->insertUser($new_user, $new_pass, $new_full_name, Yii::app()->session['loginID'], $new_email); + // If user is being auto created we set parent ID to 1 (admin user) + if (isset(Yii::app()->session['loginID'])) + { + $parentID = Yii::app()->session['loginID']; + } + else + { + $parentID = 1; + } + $iNewUID = User::model()->insertUser($new_user, $new_pass, $new_full_name, $parentID, $new_email); if (!$iNewUID) { $oEvent->set('errorCode',self::ERROR_ALREADY_EXISTING_USER); @@ -224,7 +238,6 @@ public function createNewUser() $oEvent->set('errorCode',self::ERROR_NONE); } - /** * Create LDAP connection * @@ -348,15 +361,22 @@ public function newUserSession() $username = $this->getUsername(); $password = $this->getPassword(); + $autoCreateFlag = false; $user = $this->api->getUserByName($username); - if ($user === null) { - // If the user doesnt exist in the LS database, he can not login - $this->setAuthFailure(self::ERROR_USERNAME_INVALID); - return; + if ($this->get('autocreate', null, null, false) == true) + { + $autoCreateFlag = true; + } + else + { + // If the user doesnt exist in the LS database, he can not login + $this->setAuthFailure(self::ERROR_USERNAME_INVALID); + return; + } } - if ($user->uid == 1 || !Permission::model()->hasGlobalPermission('auth_ldap','read',$user->uid)) + if ($user !== null && ($user->uid == 1 || !Permission::model()->hasGlobalPermission('auth_ldap','read',$user->uid))) { $this->setAuthFailure(self::ERROR_AUTH_METHOD_INVALID, gT('LDAP authentication method is not allowed for this user')); return; @@ -452,28 +472,19 @@ public function newUserSession() return; } - // Authentication was successful, now see if we have a user or that we should create one - if (is_null($user)) { - if ($this->autoCreate === true) { - /* - * Dispatch the newUserLogin event, and hope that after this we can find the user - * this allows users to create their own plugin for handling the user creation - * we will need more methods to pass username, rdn and ldap connection. - */ - $this->pluginManager->dispatchEvent(new PluginEvent('newUserLogin', $this)); - - // Check ourselves, we do not want fake responses from a plugin - $user = $this->api->getUserByName($username); - } + ldap_close($ldapconn); // all done? close connection - if (is_null($user)) { - $this->setAuthFailure(self::ERROR_USERNAME_INVALID); - ldap_close($ldapconn); // all done? close connection - return; - } + // Finally, if user didn't exist and auto creation is enabled, we create it + if ($autoCreateFlag) + { + $this->_createNewUser($username); + } + $user = $this->api->getUserByName($username); + if ($user === null) + { + $this->setAuthFailure(self::ERROR_USERNAME_INVALID, gT('Credentials are valid but we failed to create user')); + return; } - - ldap_close($ldapconn); // all done? close connection // If we made it here, authentication was a success and we do have a valid user $this->setAuthSuccess($user); diff --git a/application/helpers/update/updatedb_helper.php b/application/helpers/update/updatedb_helper.php index d38139925b2..a82620a2fd2 100644 --- a/application/helpers/update/updatedb_helper.php +++ b/application/helpers/update/updatedb_helper.php @@ -1304,10 +1304,15 @@ function db_upgrade_all($iOldDBVersion) { upgradeSurveyTables181(); $oDB->createCommand()->update('{{settings_global}}',array('stg_value'=>181),"stg_name='DBVersion'"); } - if ($iOldDBVersion < 182) + if ($iOldDBVersion < 183) { - fixKCFinder182(); - $oDB->createCommand()->update('{{settings_global}}',array('stg_value'=>182),"stg_name='DBVersion'"); + upgradeSurveyTables183(); + $oDB->createCommand()->update('{{settings_global}}',array('stg_value'=>183),"stg_name='DBVersion'"); + } + if ($iOldDBVersion < 184) + { + fixKCFinder184(); + $oDB->createCommand()->update('{{settings_global}}',array('stg_value'=>184),"stg_name='DBVersion'"); } $oTransaction->commit(); // Activate schema caching @@ -1353,15 +1358,15 @@ function upgradeSurveyTables183() } -function fixKCFinder182() +function fixKCFinder184() { - $sThirdPartyDir=Yii::app()->getConfig('standardtemplaterootdir').DIRECTORY_SEPARATOR.'third_party'.DIRECTORY_SEPARATOR; + $sThirdPartyDir=Yii::app()->getConfig('homedir').DIRECTORY_SEPARATOR.'third_party'.DIRECTORY_SEPARATOR; rmdirr($sThirdPartyDir.'ckeditor/plugins/toolbar'); rmdirr($sThirdPartyDir.'ckeditor/plugins/toolbar/ls-office2003'); array_map('unlink', glob($sThirdPartyDir.'kcfinder/cache/*.js')); array_map('unlink', glob($sThirdPartyDir.'kcfinder/cache/*.css')); rmdirr($sThirdPartyDir.'kcfinder/upload/files'); - rmdirr($sThirdPartyDir.'kcfinder/upload/.htumbs'); + rmdirr($sThirdPartyDir.'kcfinder/upload/.thumbs'); } @@ -1430,8 +1435,15 @@ function upgradeTokenTables179() { $oDB = Yii::app()->db; $oSchema = Yii::app()->db->schema; - if(Yii::app()->db->driverName=='mssql' || Yii::app()->db->driverName=='mysql') $sSubstringCommand='substring'; else $sSubstringCommand='substr'; - + switch (Yii::app()->db->driverName){ + case 'sqlsrv': + case 'dblib': + case 'mssql': + $sSubstringCommand='substring'; + break; + default: + $sSubstringCommand='substr'; + } $surveyidresult = dbGetTablesLike("tokens%"); if ($surveyidresult) { @@ -2194,6 +2206,9 @@ function alterLanguageCode($sOldLanguageCode,$sNewLanguageCode) } } +/** + * @param string $sTablename + */ function addPrimaryKey($sTablename, $aColumns) { return Yii::app()->db->createCommand()->addPrimaryKey('PRIMARY', '{{'.$sTablename.'}}', $aColumns); @@ -2218,6 +2233,7 @@ function dropPrimaryKey($sTablename) Yii::app()->db->createCommand($sQuery)->execute(); break; case 'pgsql': + case 'sqlsrv': case 'mssql': $pkquery = "SELECT CONSTRAINT_NAME " ."FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS " @@ -2290,6 +2306,10 @@ function alterColumn($sTable, $sColumn, $sFieldType, $bAllowNull=true, $sDefault } +/** + * @param string $sTableName + * @param string $sColumnName + */ function dropColumn($sTableName, $sColumnName) { if (Yii::app()->db->getDriverName()=='mssql' || Yii::app()->db->getDriverName()=='sqlsrv' || Yii::app()->db->getDriverName()=='dblib') @@ -2303,6 +2323,9 @@ function dropColumn($sTableName, $sColumnName) +/** + * @param string $sType + */ function addColumn($sTableName, $sColumn, $sType) { Yii::app()->db->createCommand()->addColumn($sTableName,$sColumn,$sType); diff --git a/installer/sql/create-mssql.sql b/installer/sql/create-mssql.sql index 5c1fa5bc2b4..79687f21824 100644 --- a/installer/sql/create-mssql.sql +++ b/installer/sql/create-mssql.sql @@ -566,4 +566,4 @@ create index [parent_qid_idx] on [prefix_questions] ([parent_qid]); -- -- Version Info -- -INSERT INTO [prefix_settings_global] VALUES ('DBVersion', '182'); +INSERT INTO [prefix_settings_global] VALUES ('DBVersion', '184'); diff --git a/installer/sql/create-mysql.sql b/installer/sql/create-mysql.sql index 9e058fbf5e2..c0657f750fe 100644 --- a/installer/sql/create-mysql.sql +++ b/installer/sql/create-mysql.sql @@ -575,4 +575,4 @@ CREATE INDEX `parent_qid_idx` ON `prefix_questions` (`parent_qid`); -- -- Version Info -- -INSERT INTO `prefix_settings_global` VALUES ('DBVersion', '182'); +INSERT INTO `prefix_settings_global` VALUES ('DBVersion', '184'); diff --git a/installer/sql/create-pgsql.sql b/installer/sql/create-pgsql.sql index be60c2ddad3..596413f0863 100644 --- a/installer/sql/create-pgsql.sql +++ b/installer/sql/create-pgsql.sql @@ -576,4 +576,4 @@ create unique index permissions_idx2 ON prefix_permissions (entity_id, entity, u -- -- Version Info -- -INSERT INTO prefix_settings_global VALUES ('DBVersion', '182'); +INSERT INTO prefix_settings_global VALUES ('DBVersion', '184'); diff --git a/plugins/AuditLog/AuditLog.php b/plugins/AuditLog/AuditLog.php index cbda0e01a0f..fe00a3a15c8 100644 --- a/plugins/AuditLog/AuditLog.php +++ b/plugins/AuditLog/AuditLog.php @@ -190,7 +190,12 @@ public function beforeUserSave() if (count(array_diff_assoc($aNewValues,$aOldValues))) { $oAutoLog = $this->api->newModel($this, 'log'); - $oAutoLog->uid=$oCurrentUser->uid; + if ($oCurrentUser) { + $oAutoLog->uid=$oCurrentUser->uid; + } + else { + $oAutoLog->uid='Automatic creation'; + } $oAutoLog->entity='user'; if ($sAction=='update') $oAutoLog->entityid=$oOldUser['uid']; $oAutoLog->action=$sAction;