From 8cfd068024443570a0f324e4271637537cff2d88 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Roland=20H=C3=A4der?= Date: Thu, 19 Jun 2008 13:49:05 +0000 Subject: [PATCH] Update of last activitity and action in user added, refresh of auth cookies added --- .gitattributes | 4 + .../result/class_ResultUpdateException.php | 45 +++++ .../interfaces/auth/class_Authorizeable.php | 7 + .../extended/class_LocalUpdateCriteria.php | 28 ++++ .../class_DatabaseFrontendInterface.php | 9 + .../response/class_Responseable.php | 8 + .../result/class_UpdateableResult.php | 45 +++++ inc/classes/main/auth/class_CookieAuth.php | 11 ++ .../main/class_BaseFrameworkSystem.php | 25 +++ .../main/criteria/class_SearchCriteria.php | 32 +++- .../main/criteria/class_UpdateCriteria.php | 110 ++++++++++++ .../main/crypto/class_CryptoHelper.php | 4 +- .../databases/class_LocalFileDatabase.php | 156 +++++++++++++++--- .../wrapper/class_UserDatabaseWrapper.php | 24 +++ .../filter/update/class_UserUpdateFilter.php | 5 +- .../main/response/class_HttpResponse.php | 14 ++ .../main/result/class_DatabaseResult.php | 137 ++++++++++++++- .../main/rng/class_RandomNumberGenerator.php | 25 ++- inc/classes/main/user/class_User.php | 55 ++++++ .../database/class_DatabaseConnection.php | 14 ++ inc/config.php | 3 + 21 files changed, 727 insertions(+), 34 deletions(-) create mode 100644 inc/classes/exceptions/result/class_ResultUpdateException.php create mode 100644 inc/classes/interfaces/criteria/extended/class_LocalUpdateCriteria.php create mode 100644 inc/classes/interfaces/result/class_UpdateableResult.php create mode 100644 inc/classes/main/criteria/class_UpdateCriteria.php diff --git a/.gitattributes b/.gitattributes index 0ff33d2..3fe37b7 100644 --- a/.gitattributes +++ b/.gitattributes @@ -230,6 +230,7 @@ inc/classes/exceptions/main/class_ResponseHeadersAlreadySentException.php -text inc/classes/exceptions/main/class_VariableIsNotSetException.php -text inc/classes/exceptions/result/.htaccess -text inc/classes/exceptions/result/class_InvalidDatabaseResultException.php -text +inc/classes/exceptions/result/class_ResultUpdateException.php -text inc/classes/exceptions/template/.htaccess -text inc/classes/exceptions/template/class_BasePathIsEmptyException.php -text inc/classes/exceptions/template/class_BasePathIsNoDirectoryException.php -text @@ -262,6 +263,7 @@ inc/classes/interfaces/criteria/.htaccess -text inc/classes/interfaces/criteria/class_Criteria.php -text inc/classes/interfaces/criteria/extended/.htaccess -text inc/classes/interfaces/criteria/extended/class_LocalSearchCriteria.php -text +inc/classes/interfaces/criteria/extended/class_LocalUpdateCriteria.php -text inc/classes/interfaces/criteria/extended/class_StoreableCriteria.php -text inc/classes/interfaces/database/.htaccess -text inc/classes/interfaces/database/class_FrameworkDatabaseInterface.php -text @@ -304,6 +306,7 @@ inc/classes/interfaces/response/.htaccess -text inc/classes/interfaces/response/class_Responseable.php -text inc/classes/interfaces/result/.htaccess -text inc/classes/interfaces/result/class_SearchableResult.php -text +inc/classes/interfaces/result/class_UpdateableResult.php -text inc/classes/interfaces/template/.htaccess -text inc/classes/interfaces/template/class_CompileableTemplate.php -text inc/classes/interfaces/template/view/class_ViewHelper.php -text @@ -353,6 +356,7 @@ inc/classes/main/controller/login/class_WebLoginAreaController.php -text inc/classes/main/criteria/.htaccess -text inc/classes/main/criteria/class_DataSetCriteria.php -text inc/classes/main/criteria/class_SearchCriteria.php -text +inc/classes/main/criteria/class_UpdateCriteria.php -text inc/classes/main/crypto/.htaccess -text inc/classes/main/crypto/class_CryptoHelper.php -text inc/classes/main/database/.htaccess -text diff --git a/inc/classes/exceptions/result/class_ResultUpdateException.php b/inc/classes/exceptions/result/class_ResultUpdateException.php new file mode 100644 index 0000000..bbebeb5 --- /dev/null +++ b/inc/classes/exceptions/result/class_ResultUpdateException.php @@ -0,0 +1,45 @@ + + * @version 0.0.0 + * @copyright Copyright(c) 2007, 2008 Roland Haeder, this is free software + * @license GNU GPL 3.0 or any newer version + * @link http://www.ship-simu.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +class ResultUpdateException extends FrameworkException { + /** + * The super constructor for all exceptions + * + * @param $resultInstance Instance of the failed result update + * @param $code Error code + * @return void + */ + public function __construct(UpdateableResult $resultInstance, $code) { + // Construct the message + $message = sprintf("[%s:%d] Update of result instance has nothing changed.", + $resultInstance->__toString(), + $this->getLine() + ); + + // Call parent exception constructor + parent::__construct($message, $code); + } +} + +// [EOF] +?> diff --git a/inc/classes/interfaces/auth/class_Authorizeable.php b/inc/classes/interfaces/auth/class_Authorizeable.php index 88e383f..0ca700b 100644 --- a/inc/classes/interfaces/auth/class_Authorizeable.php +++ b/inc/classes/interfaces/auth/class_Authorizeable.php @@ -28,6 +28,13 @@ interface Authorizeable extends FrameworkInterface { * @return void */ function destroyAuthData(); + + /** + * Updates the authorization data and/or sets additional tracking data + * + * @return void + */ + function updateAuthData (); } // diff --git a/inc/classes/interfaces/criteria/extended/class_LocalUpdateCriteria.php b/inc/classes/interfaces/criteria/extended/class_LocalUpdateCriteria.php new file mode 100644 index 0000000..17956a8 --- /dev/null +++ b/inc/classes/interfaces/criteria/extended/class_LocalUpdateCriteria.php @@ -0,0 +1,28 @@ + + * @version 0.0.0 + * @copyright Copyright(c) 2007, 2008 Roland Haeder, this is free software + * @license GNU GPL 3.0 or any newer version + * @link http://www.ship-simu.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +interface LocalUpdateCriteria extends Criteria { +} + +// +?> diff --git a/inc/classes/interfaces/database/frontend/class_DatabaseFrontendInterface.php b/inc/classes/interfaces/database/frontend/class_DatabaseFrontendInterface.php index 7621713..81ca81d 100644 --- a/inc/classes/interfaces/database/frontend/class_DatabaseFrontendInterface.php +++ b/inc/classes/interfaces/database/frontend/class_DatabaseFrontendInterface.php @@ -66,6 +66,15 @@ interface DatabaseFrontendInterface extends FrameworkDatabaseInterface { * @throws SqlException If an SQL error occurs */ function queryInsertDataSet (StoreableCriteria $dataSetInstance); + + /** + * "Updates" a data set instance with a database layer + * + * @param $dataSetInstance A storeable data set + * @return void + * @throws SqlException If an SQL error occurs + */ + function queryUpdateDataSet (StoreableCriteria $dataSetInstance); } // [EOF] diff --git a/inc/classes/interfaces/response/class_Responseable.php b/inc/classes/interfaces/response/class_Responseable.php index 1904b14..6186d71 100644 --- a/inc/classes/interfaces/response/class_Responseable.php +++ b/inc/classes/interfaces/response/class_Responseable.php @@ -95,6 +95,14 @@ interface Responseable extends FrameworkInterface { * @return void */ function expireCookie ($cookieName); + + /** + * Refreshs a given cookie. This will make the cookie live longer + * + * @param $cookieName Cookie to refresh + * @return void + */ + function refreshCookie ($cookieName); } // diff --git a/inc/classes/interfaces/result/class_UpdateableResult.php b/inc/classes/interfaces/result/class_UpdateableResult.php new file mode 100644 index 0000000..05a3968 --- /dev/null +++ b/inc/classes/interfaces/result/class_UpdateableResult.php @@ -0,0 +1,45 @@ + + * @version 0.0.0 + * @copyright Copyright(c) 2007, 2008 Roland Haeder, this is free software + * @license GNU GPL 3.0 or any newer version + * @link http://www.ship-simu.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +interface UpdateableResult extends FrameworkInterface { + /** + * Adds an update request to the database result for writing it to the + * database layer + * + * @param $criteriaInstance An instance of a updateable criteria + * @return void + * @throws ResultUpdateException If no result was updated + */ + function add2UpdateQueue (LocalUpdateCriteria $criteriaInstance); + + /** + * Adds registration elements to a given dataset instance + * + * @param $criteriaInstance An instance of a storeable criteria + * @return void + */ + function addElementsToDataSet (StoreableCriteria $criteriaInstance); +} + +// [EOF] +?> diff --git a/inc/classes/main/auth/class_CookieAuth.php b/inc/classes/main/auth/class_CookieAuth.php index 6b1bf3f..881d0d1 100644 --- a/inc/classes/main/auth/class_CookieAuth.php +++ b/inc/classes/main/auth/class_CookieAuth.php @@ -115,6 +115,17 @@ class CookieAuth extends BaseFrameworkSystem implements Authorizeable, Registera $this->getResponseInstance()->expireCookie('username'); $this->getResponseInstance()->expireCookie('u_hash'); } + + /** + * Updates the authorization data and/or sets additional tracking data + * + * @param $requestInstance An instance of a Requestable class + * @return void + */ + public function updateAuthData () { + $this->getResponseInstance()->refreshCookie('username'); + $this->getResponseInstance()->refreshCookie('u_hash'); + } } // [EOF] diff --git a/inc/classes/main/class_BaseFrameworkSystem.php b/inc/classes/main/class_BaseFrameworkSystem.php index 3484a4e..ade2a9c 100644 --- a/inc/classes/main/class_BaseFrameworkSystem.php +++ b/inc/classes/main/class_BaseFrameworkSystem.php @@ -32,6 +32,7 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface { * The language instance for the template loader */ private static $langInstance = null; + /** * Instance of a request class */ @@ -42,6 +43,11 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface { */ private $responseInstance = null; + /** + * Search criteria instance + */ + private $searchInstance = null; + /** * The real class name */ @@ -961,6 +967,25 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface { print ""; exit; } + + /** + * Setter for search instance + * + * @param $searchInstance Searchable criteria instance + * @return void + */ + public final function setSearchInstance (LocalSearchCriteria $searchInstance) { + $this->searchInstance = $searchInstance; + } + + /** + * Getter for search instance + * + * @return $searchInstance Searchable criteria instance + */ + public final function getSearchInstance () { + return $this->searchInstance; + } } // [EOF] diff --git a/inc/classes/main/criteria/class_SearchCriteria.php b/inc/classes/main/criteria/class_SearchCriteria.php index fc5b1ad..f6d7378 100644 --- a/inc/classes/main/criteria/class_SearchCriteria.php +++ b/inc/classes/main/criteria/class_SearchCriteria.php @@ -109,7 +109,6 @@ class SearchCriteria extends BaseFrameworkSystem implements LocalSearchCriteria /** * Getter for limit * - * @param * @return $limit Search limit */ public final function getLimit () { @@ -129,7 +128,6 @@ class SearchCriteria extends BaseFrameworkSystem implements LocalSearchCriteria /** * Getter for skip * - * @param * @return $skip Search skip */ public final function getSkip () { @@ -183,6 +181,36 @@ class SearchCriteria extends BaseFrameworkSystem implements LocalSearchCriteria // Return the value return $value; } + + /** + * Checks wether given array entry matches + * + * @param $entryArray Array with the entries to find + * @return $matches Wether the entry matches or not + */ + public function ifEntryMatches (array $entryArray) { + // First nothing matches and nothing is counted + $matches = false; + $counted = 0; + + // Walk through all entries + foreach ($entryArray as $key=>$entry) { + // Then walk through all search criteria + foreach ($this->searchCriteria as $criteriaKey=>$criteriaValue) { + // Is the element found and does it match? + if (($key == $criteriaKey) && ($criteriaValue == $entry)) { + // Then count this one up + $counted++; + } // END - if + } // END - foreach + } // END - foreach + + // Now check if the criteria matches + $matches = ($counted == count($this->searchCriteria)); + + // Return the result + return $matches; + } } // [EOF] diff --git a/inc/classes/main/criteria/class_UpdateCriteria.php b/inc/classes/main/criteria/class_UpdateCriteria.php new file mode 100644 index 0000000..c53f687 --- /dev/null +++ b/inc/classes/main/criteria/class_UpdateCriteria.php @@ -0,0 +1,110 @@ + + * @version 0.0.0 + * @copyright Copyright(c) 2007, 2008 Roland Haeder, this is free software + * @license GNU GPL 3.0 or any newer version + * @link http://www.ship-simu.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +class UpdateCriteria extends BaseFrameworkSystem implements LocalUpdateCriteria { + /** + * Criteria to handle + */ + private $updateCriteria = array(); + + /** + * Limitation for the update + */ + private $limit = 0; + + /** + * Skip these entries before using them + */ + private $skip = 0; + + /** + * Protected constructor + * + * @return void + */ + protected function __construct () { + // Call parent constructor + parent::__construct(__CLASS__); + + // Set part description + $this->setObjectDescription("Update criteria class"); + + // Create unique ID number + $this->generateUniqueId(); + + // Clean up a little + $this->removeNumberFormaters(); + $this->removeSystemArray(); + } + + /** + * Create an instance of this class + * + * @return $criteriaInstance An instance of this criteria + */ + public final static function createUpdateCriteria () { + // Get a new instance + $criteriaInstance = new UpdateCriteria(); + + // Return this instance + return $criteriaInstance; + } + + /** + * Add criteria + * + * @param $criteriaKey Criteria key + * @param $criteriaValue Criteria value + * @return void + */ + public function addCriteria ($criteriaKey, $criteriaValue) { + $this->updateCriteria[$criteriaKey] = $criteriaValue; + } + + /** + * Add configured criteria + * + * @param $criteriaKey Criteria key + * @param $configEntry Configuration entry + * @return void + */ + public function addConfiguredCriteria ($criteriaKey, $configEntry) { + // Add the configuration entry as a criteria + $value = $this->getConfigInstance()->readConfig($configEntry); + $this->addCriteria($criteriaKey, $value); + } + + /** + * Getter for update criteria array + * + * @return $updateCriteria Array holding the update criteria + */ + public final function getUpdateCriteria () { + return $this->updateCriteria; + } +} + +// [EOF] +?> diff --git a/inc/classes/main/crypto/class_CryptoHelper.php b/inc/classes/main/crypto/class_CryptoHelper.php index 93502cb..182d870 100644 --- a/inc/classes/main/crypto/class_CryptoHelper.php +++ b/inc/classes/main/crypto/class_CryptoHelper.php @@ -142,10 +142,10 @@ class CryptoHelper extends BaseFrameworkSystem { } // Hash the password with salt - //* DEBUG: */ echo $salt."/".$plainPassword."/".$this->rngInstance->getExtraSalt()."
\n"; + //* DEBUG: */ echo "salt=".$salt."/plain=".$plainPassword."
\n"; $hashed = $salt . md5(sprintf($this->getConfigInstance()->readConfig('hash_mask'), $salt, - $this->rngInstance->getExtraSalt(), + $this->rngInstance->getFixedSalt(), $plainPassword )); diff --git a/inc/classes/main/database/databases/class_LocalFileDatabase.php b/inc/classes/main/database/databases/class_LocalFileDatabase.php index 610843a..27ba98e 100644 --- a/inc/classes/main/database/databases/class_LocalFileDatabase.php +++ b/inc/classes/main/database/databases/class_LocalFileDatabase.php @@ -28,6 +28,7 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend // Constants for MySQL backward-compatiblity (PLEASE FIX THEM!) const DB_CODE_TABLE_MISSING = 0x010; const DB_CODE_TABLE_UNWRITEABLE = 0x011; + const DB_CODE_DATA_FILE_CORRUPT = 0x012; /** * Save path for "file database" @@ -155,6 +156,7 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend * * @param $object The object we shall save to the local file system * @return void + * @deprecated */ public final function saveObject (FrameworkInterface $object) { // Get a string containing the serialized object. We cannot exchange @@ -179,6 +181,7 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend * @see ObjectLimits An object holding limition information * @see SerializationContainer A special container class for e.g. * attributes from limited objects + * @deprecated */ private function serializeObject (FrameworkInterface $object) { // If there is no limiter instance we serialize the whole object @@ -473,6 +476,54 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend return $contents; } + /** + * Reads a local data file and returns it's contents in an array + * + * @param $fqfn The FQFN for the requested file + * @return $dataArray + */ + private function getDataArrayFromFile ($fqfn) { + // Get a file pointer + $fileInstance = FrameworkFileInputPointer::createFrameworkFileInputPointer($fqfn); + + // Get the raw data and BASE64-decode it + $compressedData = base64_decode($fileInstance->readLinesFromFile()); + + // Close the file and throw the instance away + $fileInstance->closeFile(); + unset($fileInstance); + + // Decompress it + $serializedData = $this->getCompressorChannel()->getCompressor()->decompressStream($compressedData); + + // Unserialize it + $dataArray = unserialize($serializedData); + + // Finally return it + return $dataArray; + } + + /** + * Writes data array to local file + * + * @param $fqfn The FQFN of the local file + * @param $dataArray An array with all the data we shall write + * @return void + */ + private function writeDataArrayToFqfn ($fqfn, array $dataArray) { + // Get a file pointer instance + $fileInstance = FrameworkFileOutputPointer::createFrameworkFileOutputPointer($fqfn, 'w'); + + // Serialize and compress it + $compressedData = $this->getCompressorChannel()->getCompressor()->compressStream(serialize($dataArray)); + + // Write this data BASE64 encoded to the file + $fileInstance->writeToFile(base64_encode($compressedData)); + + // Close the file pointer + $fileInstance->closeFile(); + } + /** * Makes sure that the database connection is alive * @@ -559,21 +610,8 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend // Read the directory with some exceptions while (($dataFile = $directoryInstance->readDirectoryExcept(array(".", "..", ".htaccess", ".svn"))) && ($limitFound < $criteriaInstance->getLimit())) { - // Open this file for reading - $filePointer = FrameworkFileInputPointer::createFrameworkFileInputPointer($pathName . $dataFile); - - // Get the raw data and BASE64-decode it - $compressedData = base64_decode($filePointer->readLinesFromFile()); - - // Close the file and throw the instance away - $filePointer->closeFile(); - unset($filePointer); - - // Decompress it - $serializedData = $this->getCompressorChannel()->getCompressor()->decompressStream($compressedData); - - // Unserialize it - $dataArray = unserialize($serializedData); + // Read the file + $dataArray = $this->getDataArrayFromFile($pathName . $dataFile); // Is this an array? if (is_array($dataArray)) { @@ -596,12 +634,15 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend } // END - if // Entry found! - $resultData['rows'][] = $dataArray; + $resultData['rows'][] = $dataArray; $limitFound++; break; } // END - if } // END - foreach - } // END - if + } else { + // Throw an exception here + throw new SqlException(sprintf("File '%s' contains invalid data.", $dataFile), self::DB_CODE_DATA_FILE_CORRUPT); + } } // END - while // Close directory and throw the instance away @@ -644,21 +685,90 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend ); // Try to save the request away + try { + // Write the data away + $this->writeDataArrayToFqfn($fqfn, $dataSetInstance->getCriteriaArray()); + + // Reset last error message and exception + $this->resetLastError(); + } catch (FrameworkException $e) { + // Catch all exceptions and store them in last error + $this->lastException = $e; + $this->lastError = $e->getMessage(); + + // Throw an SQL exception + throw new SqlException (array($this, sprintf("Cannot write data to table '%s'", $tableName), self::DB_CODE_TABLE_UNWRITEABLE), self::EXCEPTION_SQL_QUERY); + } + } + + /** + * "Updates" a data set instance with a database layer + * + * @param $dataSetInstance A storeable data set + * @return void + * @throws SqlException If an SQL error occurs + */ + public function queryUpdateDataSet (StoreableCriteria $dataSetInstance) { + // Create full path name + $pathName = $this->getSavePath() . $dataSetInstance->getTableName() . '/'; + + // Try all the requests try { // Get a file pointer instance - $filePointer = FrameworkFileOutputPointer::createFrameworkFileOutputPointer($fqfn, 'w'); + $directoryInstance = FrameworkDirectoryPointer::createFrameworkDirectoryPointer($pathName); + + // Initialize limit/skip + $limitFound = 0; $skipFound = 0; // Get the criteria array from the dataset $criteriaArray = $dataSetInstance->getCriteriaArray(); - // Serialize and compress it - $compressedData = $this->getCompressorChannel()->getCompressor()->compressStream(serialize($criteriaArray)); + // Get search criteria + $searchInstance = $dataSetInstance->getSearchInstance(); + + // Read the directory with some exceptions + while (($dataFile = $directoryInstance->readDirectoryExcept(array(".", "..", ".htaccess", ".svn"))) && ($limitFound < $searchInstance->getLimit())) { + // Open this file for reading + $dataArray = $this->getDataArrayFromFile($pathName . $dataFile); + + // Is this an array? + if (is_array($dataArray)) { + // Search in the criteria with FMFW (First Matches, First Wins) + foreach ($dataArray as $key=>$value) { + // Get criteria element + $criteria = $searchInstance->getCriteriaElemnent($key); + + // Is the criteria met? + if ((!is_null($criteria)) && ($criteria == $value)) { + + // Shall we skip this entry? + if ($searchInstance->getSkip() > 0) { + // We shall skip some entries + if ($skipFound < $searchInstance->getSkip()) { + // Skip this entry + $skipFound++; + break; + } // END - if + } // END - if + + // Entry found, so update it + foreach ($criteriaArray as $criteriaKey=>$criteriaValue) { + $dataArray[$criteriaKey] = $criteriaValue; + } // END - foreach + + // Write the data to a local file + $this->writeDataArrayToFqfn($pathName . $dataFile, $dataArray); - // Write this data BASE64 encoded to the file - $filePointer->writeToFile(base64_encode($compressedData)); + // Count it + $limitFound++; + break; + } // END - if + } // END - foreach + } // END - if + } // END - while // Close the file pointer - $filePointer->closeFile(); + $directoryInstance->closeDirectory(); // Reset last error message and exception $this->resetLastError(); diff --git a/inc/classes/main/database/wrapper/class_UserDatabaseWrapper.php b/inc/classes/main/database/wrapper/class_UserDatabaseWrapper.php index 5fc62e2..e2ff935 100644 --- a/inc/classes/main/database/wrapper/class_UserDatabaseWrapper.php +++ b/inc/classes/main/database/wrapper/class_UserDatabaseWrapper.php @@ -141,6 +141,30 @@ class UserDatabaseWrapper extends BaseDatabaseWrapper { // "Insert" this request instance completely into the database $this->getDatabaseInstance()->queryInsertDataSet($dataSetInstance); } + + /** + * Updates an user database entry with given result + * + * @param $resultInstance An instance of a Updateable database result + * @return void + */ + public function doUpdateByResult (UpdateableResult $resultInstance) { + // Generate a data set object + $dataSetInstance = ObjectFactory::createObjectByConfiguredName('dataset_criteria_class'); + $dataSetInstance->setTableName(self::DB_TABLE_USER); + + // Add all update criteria to the database set + $resultInstance->addElementsToDataSet($dataSetInstance); + + // Add seach criteria + $dataSetInstance->setSearchInstance($resultInstance->getSearchInstance()); + + // Add the primary key + $dataSetInstance->setUniqueKey('username'); + + // "Update" this request with the database + $this->getDatabaseInstance()->queryUpdateDataSet($dataSetInstance); + } } // [EOF] diff --git a/inc/classes/main/filter/update/class_UserUpdateFilter.php b/inc/classes/main/filter/update/class_UserUpdateFilter.php index b8f598f..0da323c 100644 --- a/inc/classes/main/filter/update/class_UserUpdateFilter.php +++ b/inc/classes/main/filter/update/class_UserUpdateFilter.php @@ -68,9 +68,12 @@ class UserUpdateFilter extends BaseFrameworkSystem implements Filterable { $userInstance = Registry::getRegistry()->getInstance('user'); // Now update last activity - $userInstance->updateLastActivity(); + $userInstance->updateLastActivity($requestInstance); // Update auth data as well + $authInstance = Registry::getRegistry()->getInstance('auth'); + $authInstance->updateAuthData(); + /* @TODO Add more user updates here */ // Write all updates to the database diff --git a/inc/classes/main/response/class_HttpResponse.php b/inc/classes/main/response/class_HttpResponse.php index 57e4eb7..7e78b43 100644 --- a/inc/classes/main/response/class_HttpResponse.php +++ b/inc/classes/main/response/class_HttpResponse.php @@ -345,6 +345,20 @@ class HttpResponse extends BaseFrameworkSystem implements Responseable { unset($_COOKIE[$cookieName]); } // END - if } + + /** + * Refreshs a given cookie. This will make the cookie live longer + * + * @param $cookieName Cookie to refresh + * @return void + */ + public function refreshCookie ($cookieName) { + // Only update existing cookies + if (isset($_COOKIE[$cookieName])) { + // Update the cookie + $this->addCookie($cookieName, $_COOKIE[$cookieName], false); + } // END - if + } } // [EOF] diff --git a/inc/classes/main/result/class_DatabaseResult.php b/inc/classes/main/result/class_DatabaseResult.php index fb02af3..75948a6 100644 --- a/inc/classes/main/result/class_DatabaseResult.php +++ b/inc/classes/main/result/class_DatabaseResult.php @@ -21,9 +21,10 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -class DatabaseResult extends BaseFrameworkSystem implements SearchableResult, SeekableIterator { +class DatabaseResult extends BaseFrameworkSystem implements SearchableResult, UpdateableResult, SeekableIterator { // Exception constants const EXCEPTION_INVALID_DATABASE_RESULT = 0x0b0; + const EXCEPTION_RESULT_UPDATE_FAILED = 0x0b1; /** * Current position in array @@ -40,6 +41,16 @@ class DatabaseResult extends BaseFrameworkSystem implements SearchableResult, Se */ private $resultArray = array(); + /** + * Array of out-dated entries + */ + private $outDated = array(); + + /** + * Affected rows + */ + private $affectedRows = 0; + /** * Protected constructor * @@ -87,6 +98,26 @@ class DatabaseResult extends BaseFrameworkSystem implements SearchableResult, Se $this->resultArray = $resultArray; } + /** + * Updates the current entry by given update criteria + * + * @param $updateInstance An instance of an Updateable criteria + * @return void + */ + private function updateCurrentEntryByCriteria (LocalUpdateCriteria $updateInstance) { + // Get the current entry key + $entryKey = $this->key(); + + // Now get the update criteria array and update all entries + foreach ($updateInstance->getUpdateCriteria() as $criteriaKey=>$criteriaValue) { + // Update data + $this->resultArray['rows'][$entryKey][$criteriaKey] = $criteriaValue; + + // Mark it as out-dated + $this->outDated[$criteriaKey] = 1; + } // END - foreach + } + /** * "Iterator" method next() to advance to the next valid entry. This method * does also check if the result is invalid @@ -192,7 +223,109 @@ class DatabaseResult extends BaseFrameworkSystem implements SearchableResult, Se * @return $result Found result entry */ public function searchEntry (LocalSearchCriteria $criteriaInstance) { - die(__METHOD__.": OK"); + die(__METHOD__.": Unfinished!"); + } + + /** + * Adds an update request to the database result for writing it to the + * database layer + * + * @param $criteriaInstance An instance of a updateable criteria + * @return void + * @throws ResultUpdateException If no result was updated + */ + public function add2UpdateQueue (LocalUpdateCriteria $criteriaInstance) { + // Rewind the pointer + $this->rewind(); + + // Get search criteria + $searchInstance = $criteriaInstance->getSearchInstance(); + + // And start looking for the result + $foundEntries = 0; + while (($this->valid()) && ($foundEntries < $searchInstance->getLimit())) { + // Get next entry + $this->next(); + $currentEntry = $this->current(); + + // Is this entry found? + if ($searchInstance->ifEntryMatches($currentEntry)) { + // Update this entry + $this->updateCurrentEntryByCriteria($criteriaInstance); + + // Count one up + $foundEntries++; + } // END - if + } // END - while + + // Set affected rows + $this->setAffectedRows($foundEntries); + + // If no entry is found/updated throw an exception + if ($foundEntries == 0) { + // Throw an exception here + throw new ResultUpdateException($this, self::EXCEPTION_RESULT_UPDATE_FAILED); + } // END - if + + // Set search instance + $this->setSearchInstance($searchInstance); + } + + /** + * Setter for affected rows + * + * @param $rows Number of affected rows + * @return void + */ + public final function setAffectedRows ($rows) { + $this->affectedRows = $rows; + } + + /** + * Getter for affected rows + * + * @return $rows Number of affected rows + */ + public final function getAffectedRows () { + return $this->affectedRows; + } + + /** + * Checks wether we have out-dated entries or not + * + * @return $needsUpdate Wether we have out-dated entries + */ + public function ifDataNeedsFlush () { + $needsUpdate = (count($this->outDated) > 0); + return $needsUpdate; + } + + /** + * Adds registration elements to a given dataset instance + * + * @param $criteriaInstance An instance of a storeable criteria + * @return void + */ + public function addElementsToDataSet (StoreableCriteria $criteriaInstance) { + // Rewind the pointer + $this->rewind(); + + // Walk through all entries + while ($this->valid()) { + // Get next entry + $this->next(); + $currentEntry = $this->current(); + + // Walk only through out-dated columns + foreach ($this->outDated as $key=>$dummy) { + // Does this key exist? + //* DEBUG: */ echo "outDated: {$key}
\n"; + if (isset($currentEntry[$key])) { + // Then update it + $criteriaInstance->addCriteria($key, $currentEntry[$key]); + } // END - foreach + } // END - foreach + } // END - while } } diff --git a/inc/classes/main/rng/class_RandomNumberGenerator.php b/inc/classes/main/rng/class_RandomNumberGenerator.php index 12e1c01..2439ffb 100644 --- a/inc/classes/main/rng/class_RandomNumberGenerator.php +++ b/inc/classes/main/rng/class_RandomNumberGenerator.php @@ -37,6 +37,11 @@ class RandomNumberGenerator extends BaseFrameworkSystem { */ private $extraSalt = ""; + /** + * Fixed salt for secured hashing + */ + private $fixedSalt = ""; + /** * Maximum length for random string */ @@ -102,11 +107,14 @@ class RandomNumberGenerator extends BaseFrameworkSystem { if ($this->getConfigInstance()->readConfig('is_single_server') == "Y") { // Then use that IP for extra security $serverIp = getenv('SERVER_ADDR'); - } + } // END - if + + // Yet-another fixed salt. This is not dependend on server software or date + $this->fixedSalt = sha1($serverIp . ":" . serialize($this->getDatabaseInstance()->getConnectionData())); // One-way data we need for "extra-salting" the random number /* @TODO Add site key for stronger salt! */ - $this->extraSalt = sha1($serverIp . ":" . getenv('SERVER_SOFTWARE') . ":" . $this->getConfigInstance()->readConfig('date_key') . ":" . serialize($this->getDatabaseInstance()->getConnectionData())); + $this->extraSalt = sha1($this->fixedSalt . ":" . getenv('SERVER_SOFTWARE') . ":" . $this->getConfigInstance()->readConfig('date_key')); // Get config entry for max salt length $this->rndStrLen = $this->getConfigInstance()->readConfig('rnd_str_length'); @@ -131,7 +139,7 @@ class RandomNumberGenerator extends BaseFrameworkSystem { $randomString .= chr($this->randomNumnber(0, 255)); } - // Return the random string mixed up + // Return the random string a little mixed up return str_shuffle($randomString); } @@ -143,7 +151,7 @@ class RandomNumberGenerator extends BaseFrameworkSystem { * @return $num Pseudo-random number */ public function randomNumnber ($min, $max) { - /* @TODO I had a better random number generator here */ + /* @TODO I had a better random number generator here but now it is somewhere lost :( */ return mt_rand($min, $max); } @@ -155,6 +163,15 @@ class RandomNumberGenerator extends BaseFrameworkSystem { public final function getExtraSalt () { return $this->extraSalt; } + + /** + * Getter for fixed salt + * + * @return $fixedSalt + */ + public final function getFixedSalt () { + return $this->fixedSalt; + } } // [EOF] diff --git a/inc/classes/main/user/class_User.php b/inc/classes/main/user/class_User.php index 2221111..49b285f 100644 --- a/inc/classes/main/user/class_User.php +++ b/inc/classes/main/user/class_User.php @@ -285,6 +285,7 @@ class User extends BaseFrameworkSystem implements ManageableUser, Registerable { $entry = $this->resultInstance->current(); // So does the hashes match? + //* DEBUG: */ echo $requestInstance->getRequestElement('pass_hash')."/".$entry['pass_hash']; $matches = ($requestInstance->getRequestElement('pass_hash') === $entry['pass_hash']); } // END - if @@ -324,6 +325,60 @@ class User extends BaseFrameworkSystem implements ManageableUser, Registerable { // And return the hash return $passHash; } + + /** + * Updates the last activity timestamp and last performed action in the + * database result. You should call flushUpdates() to flush these updates + * to the database layer. + * + * @param $requestInstance A requestable class instance + * @return void + */ + public function updateLastActivity (Requestable $requestInstance) { + // Set last action + $lastAction = $requestInstance->getRequestElement('action'); + + // If there is no action use the default on + if (is_null($lastAction)) { + $lastAction = $this->getConfigInstance()->readConfig('login_default_action'); + } // END - if + + // Get a critieria instance + $searchInstance = ObjectFactory::createObjectByConfiguredName('search_criteria_class'); + + // Add search criteria + $searchInstance->addCriteria(UserDatabaseWrapper::DB_COLUMN_USERNAME, $this->getUserName()); + $searchInstance->setLimit(1); + + // Now get another criteria + $updateInstance = ObjectFactory::createObjectByConfiguredName('update_criteria_class'); + + // And add our both entries + $updateInstance->addCriteria('last_activity', date("Y-m-d H:i:s", time())); + $updateInstance->addCriteria('last_action', $lastAction); + + // Add the search criteria for searching for the right entry + $updateInstance->setSearchInstance($searchInstance); + + // Remember the update in database result + $this->resultInstance->add2UpdateQueue($updateInstance); + } + + /** + * Flushs all updated entries to the database layer + * + * @return void + */ + public function flushUpdates () { + // Get a database wrapper + $wrapperInstance = ObjectFactory::createObjectByConfiguredName('user_db_wrapper_class'); + + // Do we have data to update? + if ($this->resultInstance->ifDataNeedsFlush()) { + // Yes, then send the whole result to the database layer + $wrapperInstance->doUpdateByResult($this->resultInstance); + } // END - if + } } // [EOF] diff --git a/inc/classes/middleware/database/class_DatabaseConnection.php b/inc/classes/middleware/database/class_DatabaseConnection.php index fc8ea91..7a9300f 100644 --- a/inc/classes/middleware/database/class_DatabaseConnection.php +++ b/inc/classes/middleware/database/class_DatabaseConnection.php @@ -165,6 +165,20 @@ class DatabaseConnection extends BaseMiddleware implements DatabaseConnector, Re // Ask the database layer $this->dbLayer->queryInsertDataSet($dataSetInstance); } + + /** + * "Updates" a data set instance with a database layer + * + * @param $dataSetInstance A storeable data set + * @return void + */ + public function queryUpdateDataSet (StoreableCriteria $dataSetInstance) { + // Connect to the database + $this->dbLayer->connectToDatabase(); + + // Ask the database layer + $this->dbLayer->queryUpdateDataSet($dataSetInstance); + } } // [EOF] diff --git a/inc/config.php b/inc/config.php index 0c75800..08052ad 100644 --- a/inc/config.php +++ b/inc/config.php @@ -158,6 +158,9 @@ $cfg->setConfigEntry('search_criteria_class', "SearchCriteria"); // CFG: DATASET-CRITERIA $cfg->setConfigEntry('dataset_criteria_class', "DataSetCriteria"); +// CFG: UPDATE-CRITERIA +$cfg->setConfigEntry('update_criteria_class', "UpdateCriteria"); + // CFG: FILE-IO-HANDLER $cfg->setConfigEntry('file_io_class', "FileIoHandler"); -- 2.39.5