/** * Limits amount of records in the table. This does not run often. * Records are removed in the uid order (oldest first). This is not a true * clean up, which would be based on the last access timestamp but good * enough to maintain performance. * * @param string $tableName * @return bool */ protected function limitTableRecords($tableName) { $cleanedUp = false; if (mt_rand(0, mt_getrandmax()) % 5 == 0) { $this->databaseConnection->sql_query('DELETE FROM ' . $tableName . ' WHERE uid <= (SELECT t2.uid FROM (SELECT uid FROM ' . $tableName . ' ORDER BY uid DESC LIMIT ' . self::$maximumNumberOfRecords . ',1) t2)'); $cleanedUp = $this->databaseConnection->sql_affected_rows() > 0; } return $cleanedUp; }
/** * Checks if this nonce was already used * * @param string $serverUrl Server URL * @param int $timestamp Time stamp * @param string $salt Nonce value * @return bool TRUE if nonce was not used before anc can be used now */ public function useNonce($serverUrl, $timestamp, $salt) { $result = false; if (abs($timestamp - time()) < $GLOBALS['Auth_OpenID_SKEW']) { $values = array('crdate' => time(), 'salt' => $salt, 'server_url' => $serverUrl, 'tstamp' => $timestamp); $this->databaseConnection->exec_INSERTquery(self::NONCE_TABLE_NAME, $values); $affectedRows = $this->databaseConnection->sql_affected_rows(); $result = $affectedRows > 0; } return $result; }
/** * Create new category MM records * * @param array $oldNewCategoryUidMapping */ protected function migrateCategoryMmRecords(array $oldNewCategoryUidMapping) { $newMmCount = 0; $oldMmRecords = $this->databaseConnection->exec_SELECTgetRows('uid_local, uid_foreign, tablenames, sorting', 'tx_news_domain_model_news_category_mm', ''); foreach ($oldMmRecords as $oldMmRecord) { $oldCategoryUid = $oldMmRecord['uid_foreign']; if (!empty($oldNewCategoryUidMapping[$oldCategoryUid])) { $newMmRecord = array('uid_local' => $oldNewCategoryUidMapping[$oldCategoryUid], 'uid_foreign' => $oldMmRecord['uid_local'], 'tablenames' => $oldMmRecord['tablenames'] ?: 'tx_news_domain_model_news', 'sorting_foreign' => $oldMmRecord['sorting'], 'fieldname' => 'categories'); // check if relation already exists $foundRelations = $this->databaseConnection->exec_SELECTcountRows('uid_local', 'sys_category_record_mm', 'uid_local=' . $newMmRecord['uid_local'] . ' AND uid_foreign=' . $newMmRecord['uid_foreign'] . ' AND tablenames="' . $newMmRecord['tablenames'] . '"' . ' AND fieldname="' . $newMmRecord['fieldname'] . '"'); if ($foundRelations === 0) { $this->databaseConnection->exec_INSERTquery('sys_category_record_mm', $newMmRecord); if ($this->databaseConnection->sql_affected_rows()) { $newMmCount++; } } } } $message = 'Created ' . $newMmCount . ' new MM relations'; $status = FlashMessage::INFO; $title = ''; $this->messageArray[] = array($status, $title, $message); }
/** * Running the functionality of the CLI (crawling URLs from queue) * * @param int $countInARun * @param int $sleepTime * @param int $sleepAfterFinish * @return string Status message */ public function CLI_run($countInARun, $sleepTime, $sleepAfterFinish) { $result = 0; $counter = 0; // First, run hooks: $this->CLI_runHooks(); // Clean up the queue if (intval($this->extensionSettings['purgeQueueDays']) > 0) { $purgeDate = $this->getCurrentTime() - 24 * 60 * 60 * intval($this->extensionSettings['purgeQueueDays']); $del = $this->db->exec_DELETEquery('tx_crawler_queue', 'exec_time!=0 AND exec_time<' . $purgeDate); } // Select entries: //TODO Shouldn't this reside within the transaction? $rows = $this->db->exec_SELECTgetRows('qid,scheduled', 'tx_crawler_queue', 'exec_time=0 AND process_scheduled= 0 AND scheduled<=' . $this->getCurrentTime(), '', 'scheduled, qid', intval($countInARun)); if (count($rows) > 0) { $quidList = array(); foreach ($rows as $r) { $quidList[] = $r['qid']; } $processId = $this->CLI_buildProcessId(); //reserve queue entrys for process $this->db->sql_query('BEGIN'); //TODO make sure we're not taking assigned queue-entires $this->db->exec_UPDATEquery('tx_crawler_queue', 'qid IN (' . implode(',', $quidList) . ')', array('process_scheduled' => intval($this->getCurrentTime()), 'process_id' => $processId)); //save the number of assigned queue entrys to determine who many have been processed later $numberOfAffectedRows = $this->db->sql_affected_rows(); $this->db->exec_UPDATEquery('tx_crawler_process', "process_id = '" . $processId . "'", array('assigned_items_count' => intval($numberOfAffectedRows))); if ($numberOfAffectedRows == count($quidList)) { $this->db->sql_query('COMMIT'); } else { $this->db->sql_query('ROLLBACK'); $this->CLI_debug("Nothing processed due to multi-process collision (" . $this->CLI_buildProcessId() . ")"); return $result | self::CLI_STATUS_ABORTED; } foreach ($rows as $r) { $result |= $this->readUrl($r['qid']); $counter++; usleep(intval($sleepTime)); // Just to relax the system // if during the start and the current read url the cli has been disable we need to return from the function // mark the process NOT as ended. if ($this->getDisabled()) { return $result | self::CLI_STATUS_ABORTED; } if (!$this->CLI_checkIfProcessIsActive($this->CLI_buildProcessId())) { $this->CLI_debug("conflict / timeout (" . $this->CLI_buildProcessId() . ")"); //TODO might need an additional returncode $result |= self::CLI_STATUS_ABORTED; break; //possible timeout } } sleep(intval($sleepAfterFinish)); $msg = 'Rows: ' . $counter; $this->CLI_debug($msg . " (" . $this->CLI_buildProcessId() . ")"); } else { $this->CLI_debug("Nothing within queue which needs to be processed (" . $this->CLI_buildProcessId() . ")"); } if ($counter > 0) { $result |= self::CLI_STATUS_PROCESSED; } return $result; }
/** * Migrates eu_ldap configuration records. * * @param array &$out * @return void */ protected function migrateEuLdapConfiguration(array &$out) { $euLdapConfigurationRecords = $this->databaseConnection->exec_SELECTgetRows('*', 'tx_euldap_server', 'tx_igldapssoauth_migrated=0'); foreach ($euLdapConfigurationRecords as $legacy) { $hasBackendAuthentication = $legacy['authenticate_be'] == 1 || $legacy['authenticate_be'] == 2; $hasFrontendAuthentication = $legacy['authenticate_be'] == 0 || $legacy['authenticate_be'] == 2; $data = array('pid' => 0, 'tstamp' => $GLOBALS['EXEC_TIME'], 'crdate' => $GLOBALS['EXEC_TIME'], 'cruser_id' => $GLOBALS['BE_USER']->user['uid'], 'name' => '[eu_ldap] ' . $legacy['server'], 'ldap_server' => $legacy['servertype'] == 3 ? 0 : 1, 'ldap_charset' => $legacy['characterset'], 'ldap_protocol' => $legacy['version'], 'ldap_host' => $legacy['server'], 'ldap_port' => $legacy['port'], 'ldap_tls' => 0, 'ldap_binddn' => $legacy['servertype'] == 2 || $legacy['servertype'] == 3 ? $legacy['user'] : ($legacy['servertype'] == 0 ? $legacy['domain'] . '\\' . $legacy['user'] : $legacy['user'] . '@' . $legacy['domain']), 'ldap_password' => $legacy['password'], 'be_users_basedn' => $hasBackendAuthentication ? $legacy['base_dn'] : '', 'be_users_filter' => $hasBackendAuthentication ? str_replace('<search>', '{USERNAME}', $legacy['filter']) : '', 'be_users_mapping' => '', 'be_groups_basedn' => $hasBackendAuthentication ? $legacy['base_dn'] : '', 'be_groups_filter' => '', 'be_groups_mapping' => $hasBackendAuthentication ? implode(LF, array('title = <cn>', 'tstamp = {DATE}')) : '', 'fe_users_basedn' => $hasFrontendAuthentication ? $legacy['base_dn'] : '', 'fe_users_filter' => $hasFrontendAuthentication ? str_replace('<search>', '{USERNAME}', $legacy['filter']) : '', 'fe_users_mapping' => '', 'fe_groups_basedn' => $hasFrontendAuthentication ? $legacy['base_dn'] : '', 'fe_groups_filter' => '', 'fe_groups_mapping' => $hasFrontendAuthentication ? implode(LF, array('pid = ' . (int) $legacy['feuser_pid'], 'title = <cn>', 'tstamp = {DATE}')) : '', 'be_groups_required' => $hasBackendAuthentication ? $legacy['matchgrps'] : '', 'be_groups_assigned' => $legacy['be_group'], 'fe_groups_required' => $hasFrontendAuthentication ? $legacy['matchgrps'] : '', 'fe_groups_assigned' => $legacy['fe_group'], 'group_membership' => $legacy['memberof'] == 1 ? $legacy['servertype'] == 3 ? \Causal\IgLdapSsoAuth\Library\Configuration::GROUP_MEMBERSHIP_FROM_GROUP : \Causal\IgLdapSsoAuth\Library\Configuration::GROUP_MEMBERSHIP_FROM_MEMBER : 0, 'sorting' => $legacy['sorting']); if ($hasBackendAuthentication) { $mapping = array(); $mapping[] = 'tstamp = ' . (!empty($legacy['timestamp']) ? '<' . $legacy['timestamp'] . '>' : '{DATE}'); switch ($legacy['servertype']) { case 0: case 1: $mapping[] = 'usergroup = <memberof>'; $data['be_groups_filter'] = '(objectClass=posixGroup)'; break; case 2: $mapping[] = 'usergroup = <groupmembership>'; $data['be_groups_filter'] = '(objectClass=posixGroup)'; break; case 3: $data['be_groups_filter'] = '(&(memberUid={USERUID})(objectClass=posixGroup))'; break; } $mapping[] = 'realName = <' . $legacy['name'] . '>'; if (!empty($legacy['mail'])) { $mapping[] = 'email = <' . $legacy['mail'] . '>'; } $data['be_users_mapping'] = implode(LF, $mapping); } if ($hasFrontendAuthentication) { $mapping = array(); $mapping[] = 'pid = ' . (int) $legacy['feuser_pid']; $mapping[] = 'tstamp = ' . (!empty($legacy['timestamp']) ? '<' . $legacy['timestamp'] . '>' : '{DATE}'); switch ($legacy['servertype']) { case 0: case 1: $mapping[] = 'usergroup = <memberof>'; $data['fe_groups_filter'] = '(objectClass=posixGroup)'; break; case 2: $mapping[] = 'usergroup = <groupmembership>'; $data['fe_groups_filter'] = '(objectClass=posixGroup)'; break; case 3: $data['fe_groups_filter'] = '(&(memberUid={USERUID})(objectClass=posixGroup))'; break; } if (!empty($legacy['mail'])) { $mapping[] = 'email = <' . $legacy['mail'] . '>'; } $mapping[] = 'name = <' . $legacy['name'] . '>'; if (!empty($legacy['address'])) { $mapping[] = 'address = <' . $legacy['address'] . '>'; } if (!empty($legacy['zip'])) { $mapping[] = 'zip = <' . $legacy['zip'] . '>'; } if (!empty($legacy['city'])) { $mapping[] = 'city = <' . $legacy['city'] . '>'; } if (!empty($legacy['country'])) { $mapping[] = 'country = <' . $legacy['country'] . '>'; } if (!empty($legacy['phone'])) { $mapping[] = 'telephone = <' . $legacy['phone'] . '>'; } if (!empty($legacy['fax'])) { $mapping[] = 'fax = <' . $legacy['fax'] . '>'; } if (!empty($legacy['www'])) { $mapping[] = 'www = <' . $legacy['www'] . '>'; } $additionalInstructions = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $legacy['map_additional_fields'], TRUE); foreach ($additionalInstructions as $additionalInstruction) { list($dbField, $ldapField) = explode('=', $additionalInstruction, 2); $mapping[] = $dbField . ' = <' . $ldapField . '>'; } $data['fe_users_mapping'] = implode(LF, $mapping); } if ($data['be_groups_required'] === '*') { // Replace '*' by every local BE group $groups = $this->databaseConnection->exec_SELECTgetRows('uid', 'be_groups', 'hidden=0 AND deleted=0 AND tx_igldapssoauth_dn=\'\' AND eu_ldap=0', '', '', '', 'uid'); $data['be_groups_required'] = implode(',', array_keys($groups)); } if ($data['fe_groups_required'] === '*') { // Replace '*' by every local FE group $groups = $this->databaseConnection->exec_SELECTgetRows('uid', 'fe_groups', 'hidden=0 AND deleted=0 AND tx_igldapssoauth_dn=\'\' AND eu_ldap=0', '', '', '', 'uid'); $data['fe_groups_required'] = implode(',', array_keys($groups)); } if ($legacy['only_emailusers'] == 1) { $emailAttribute = !empty($legacy['mail']) ? $legacy['mail'] : 'mail'; if ($hasBackendAuthentication) { $data['be_users_filter'] = sprintf('(&%s(%s=*))', $data['be_users_filter'], $emailAttribute); } if ($hasFrontendAuthentication) { $data['fe_users_filter'] = sprintf('(&%s(%s=*))', $data['fe_users_filter'], $emailAttribute); } } // Insert the migrated record to ig_ldap_sso_auth $this->databaseConnection->exec_INSERTquery($this->table, $data); if ($this->databaseConnection->sql_affected_rows() == 1) { $this->databaseConnection->exec_UPDATEquery('tx_euldap_server', 'uid=' . $legacy['uid'], array('tx_igldapssoauth_migrated' => 1)); } } $out[] = $this->formatOk('Successfully migrated eu_ldap configuration records.'); }
/** * @test * * @return void */ public function sqlAffectedRowsReturnsCorrectAmountOfRows() { $this->subject->exec_INSERTquery($this->testTable, [$this->testField => 'test']); $this->assertEquals(1, $this->subject->sql_affected_rows()); }