3v4l.org

run code in 300+ PHP versions simultaneously
<?php /** * @file classes/security/Validation.inc.php * * Copyright (c) 2013-2015 Simon Fraser University Library * Copyright (c) 2003-2015 John Willinsky * Distributed under the GNU GPL v2. For full terms see the file docs/COPYING. * * @class Validation * @ingroup security * * @brief Class providing user validation/authentication operations. */ import('classes.security.Role'); import('classes.security.password'); class Validation { /** * Authenticate user credentials and mark the user as logged in in the current session. * @param $username string * @param $password string unencrypted password * @param $reason string reference to string to receive the reason an account was disabled; null otherwise * @param $remember boolean remember a user's session past the current browser session * @return User the User associated with the login credentials, or false if the credentials are invalid */ function &login($username, $password, &$reason, $remember = false) { $implicitAuth = Config::getVar('security', 'implicit_auth'); $reason = null; $valid = false; $userDao =& DAORegistry::getDAO('UserDAO'); if ($implicitAuth) { // Implicit auth if (!Validation::isLoggedIn()) { PluginRegistry::loadCategory('implicitAuth'); // Call the implicitAuth hook. It will set user. HookRegistry::call('ImplicitAuthPlugin::implicitAuth', array(&$user)); $valid=true; } } else { // Regular Auth $user =& $userDao->getByUsername($username, true); if (!isset($user)) { // User does not exist return $valid; } if ($user->getAuthId()) { $authDao =& DAORegistry::getDAO('AuthSourceDAO'); $auth =& $authDao->getPlugin($user->getAuthId()); } if (isset($auth)) { // Validate against remote authentication source $valid = $auth->authenticate($username, $password); if ($valid) { $oldEmail = $user->getEmail(); $auth->doGetUserInfo($user); if ($user->getEmail() != $oldEmail) { // FIXME OJS requires email addresses to be unique; if changed email already exists, ignore if ($userDao->userExistsByEmail($user->getEmail())) { $user->setEmail($oldEmail); } } } } else { // Validate against OJS user database $valid = Validation::verifyPassword($username, $password, $user->getPassword(), $rehash); if ($valid && !empty($rehash)) { // update to new hashing algorithm $user->setPassword($rehash); } } } if (!$valid) { // Login credentials are invalid return $valid; } else { if ($user->getDisabled()) { // The user has been disabled. $reason = $user->getDisabledReason(); if ($reason === null) $reason = ''; $valid = false; return $valid; } // The user is valid, mark user as logged in in current session $sessionManager =& SessionManager::getManager(); // Regenerate session ID first $sessionManager->regenerateSessionId(); $session =& $sessionManager->getUserSession(); $session->setSessionVar('userId', $user->getId()); $session->setUserId($user->getId()); $session->setSessionVar('username', $user->getUsername()); $session->setRemember($remember); if ($remember && Config::getVar('general', 'session_lifetime') > 0) { // Update session expiration time $sessionManager->updateSessionLifetime(time() + Config::getVar('general', 'session_lifetime') * 86400); } $user->setDateLastLogin(Core::getCurrentDate()); $userDao->updateObject($user); return $user; } } /** * verify if the input password is correct * * @param string $username the string username * @param string $password the plaintext password * @param string $hash the password hash from the database * @param string &$rehash if password needs rehash, this variable is used * @return boolean */ function verifyPassword($username, $password, $hash, &$rehash) { if (LEGACY_ENCRYPTION) { // BCRYPT not supported return $hash === Validation::encryptCredentials($username, $password, false, true); } else if (password_needs_rehash($hash, PASSWORD_BCRYPT)) { // update to new hashing algorithm $oldHash = Validation::encryptCredentials($username, $password, false, true); if ($oldHash === $hash) { // update hash $rehash = Validation::encryptCredentials($username, $password); return true; } } else if (password_verify($password, $hash)) { return true; } return false; } /** * Mark the user as logged out in the current session. * @return boolean */ function logout() { $sessionManager =& SessionManager::getManager(); $session =& $sessionManager->getUserSession(); $session->unsetSessionVar('userId'); $session->unsetSessionVar('signedInAs'); $session->setUserId(null); if ($session->getRemember()) { $session->setRemember(0); $sessionManager->updateSessionLifetime(0); } $sessionDao =& DAORegistry::getDAO('SessionDAO'); $sessionDao->updateObject($session); return true; } /** * Redirect to the login page, appending the current URL as the source. * @param $message string Optional name of locale key to add to login page */ function redirectLogin($message = null) { $args = array(); if (isset($_SERVER['REQUEST_URI'])) { $args['source'] = $_SERVER['REQUEST_URI']; } if ($message !== null) { $args['loginMessage'] = $message; } Request::redirect(null, 'login', null, null, $args); } /** * Check if a user's credentials are valid. * @param $username string username * @param $password string unencrypted password * @return boolean */ function checkCredentials($username, $password) { $userDao =& DAORegistry::getDAO('UserDAO'); $user =& $userDao->getByUsername($username, false); $valid = false; if (isset($user)) { if ($user->getAuthId()) { $authDao =& DAORegistry::getDAO('AuthSourceDAO'); $auth =& $authDao->getPlugin($user->getAuthId()); } if (isset($auth)) { $valid = $auth->authenticate($username, $password); } else { // Validate against OJS user database $valid = Validation::verifyPassword($username, $password, $user->getPassword(), $rehash); if ($valid && !empty($rehash)) { // update to new hashing algorithm $user->setPassword($rehash); // save new password hash to database $userDao->updateObject($user); } } } return $valid; } /** * Check if a user is authorized to access the specified role in the specified journal. * @param $roleId int * @param $journalId optional (e.g., for global site admin role), the ID of the journal * @return boolean */ function isAuthorized($roleId, $journalId = 0) { if (!Validation::isLoggedIn()) { return false; } if ($journalId === -1) { // Get journal ID from request $journal =& Request::getJournal(); $journalId = $journal == null ? 0 : $journal->getId(); } $sessionManager =& SessionManager::getManager(); $session =& $sessionManager->getUserSession(); $user =& $session->getUser(); $roleDao =& DAORegistry::getDAO('RoleDAO'); return $roleDao->userHasRole($journalId, $user->getId(), $roleId); } /** * Encrypt user passwords for database storage. * The username is used as a unique salt to make dictionary * attacks against a compromised database more difficult. * @param $username string username (kept for backwards compatibility) * @param $password string unencrypted password * @param $encryption string optional encryption algorithm to use, defaulting to the value from the site configuration * @param $legacy boolean if true, use legacy hashing technique for backwards compatibility * @return string encrypted password */ function encryptCredentials($username, $password, $encryption = false, $legacy = LEGACY_ENCRYPTION) { if ($legacy || LEGACY_ENCRYPTION) { $valueToEncrypt = $username . $password; if ($encryption == false) { $encryption = Config::getVar('security', 'encryption'); } switch ($encryption) { case 'sha1': if (function_exists('sha1')) { return sha1($valueToEncrypt); } case 'md5': default: return md5($valueToEncrypt); } } else { return password_hash($password, PASSWORD_BCRYPT); } } /** * Generate a random password. * Assumes the random number generator has already been seeded. * @param $length int the length of the password to generate (default 8) * @return string */ function generatePassword($length = 8) { $letters = 'abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'; $numbers = '23456789'; $password = ""; for ($i=0; $i<$length; $i++) { $password .= mt_rand(1, 4) == 4 ? $numbers[mt_rand(0,strlen($numbers)-1)] : $letters[mt_rand(0, strlen($letters)-1)]; } return $password; } /** * Generate a hash value to use for confirmation to reset a password. * @param $userId int * @return string (boolean false if user is invalid) */ function generatePasswordResetHash($userId) { $userDao =& DAORegistry::getDAO('UserDAO'); if (($user = $userDao->getUser($userId)) == null) { // No such user return false; } // create hash payload $salt = Config::getVar('security', 'salt'); // use last login time to create a basic expiry coeffecient $lastLogin = strtotime($user->getDateLastLogin()); $time = time(); $normalised = ($time - ($time % 3600)) + 7200; $diff = floor(($normalised - $lastLogin) / 3600); $data = $user->getUsername() . $user->getPassword() . $lastLogin . $diff; switch (true) { case function_exists('hash_hmac'): // always use HMAC SHA256 if available return hash_hmac('sha256', $data, $salt); case function_exists('sha1'); // use SHA1 is HMAC not available return sha1($data . $salt); default: // fallback to MD5 return md5($data . $salt); } } /** * Suggest a username given the first and last names. * @return string */ function suggestUsername($firstName, $lastName) { $initial = String::substr($firstName, 0, 1); $suggestion = String::regexp_replace('/[^a-zA-Z0-9_-]/', '', String::strtolower($initial . $lastName)); $userDao =& DAORegistry::getDAO('UserDAO'); for ($i = ''; $userDao->userExistsByUsername($suggestion . $i); $i++); return $suggestion . $i; } /** * Check if the user must change their password in order to log in. * @return boolean */ function isLoggedIn() { $sessionManager =& SessionManager::getManager(); $session =& $sessionManager->getUserSession(); $userId = $session->getUserId(); return isset($userId) && !empty($userId); } /** * Shortcut for checking authorization as site admin. * @return boolean */ function isSiteAdmin() { return Validation::isAuthorized(ROLE_ID_SITE_ADMIN); } /** * Shortcut for checking authorization as journal manager. * @param $journalId int * @return boolean */ function isJournalManager($journalId = -1) { return Validation::isAuthorized(ROLE_ID_JOURNAL_MANAGER, $journalId); } /** * Shortcut for checking authorization as editor. * @param $journalId int * @return boolean */ function isEditor($journalId = -1) { return Validation::isAuthorized(ROLE_ID_EDITOR, $journalId); } /** * Shortcut for checking authorization as section editor. * @param $journalId int * @return boolean */ function isSectionEditor($journalId = -1) { return Validation::isAuthorized(ROLE_ID_SECTION_EDITOR, $journalId); } /** * Shortcut for checking authorization as layout editor. * @param $journalId int * @return boolean */ function isLayoutEditor($journalId = -1) { return Validation::isAuthorized(ROLE_ID_LAYOUT_EDITOR, $journalId); } /** * Shortcut for checking authorization as reviewer. * @param $journalId int * @return boolean */ function isReviewer($journalId = -1) { return Validation::isAuthorized(ROLE_ID_REVIEWER, $journalId); } /** * Shortcut for checking authorization as copyeditor. * @param $journalId int * @return boolean */ function isCopyeditor($journalId = -1) { return Validation::isAuthorized(ROLE_ID_COPYEDITOR, $journalId); } /** * Shortcut for checking authorization as proofreader. * @param $journalId int * @return boolean */ function isProofreader($journalId = -1) { return Validation::isAuthorized(ROLE_ID_PROOFREADER, $journalId); } /** * Shortcut for checking authorization as author. * @param $journalId int * @return boolean */ function isAuthor($journalId = -1) { return Validation::isAuthorized(ROLE_ID_AUTHOR, $journalId); } /** * Shortcut for checking authorization as reader. * @param $journalId int * @return boolean */ function isReader($journalId = -1) { return Validation::isAuthorized(ROLE_ID_READER, $journalId); } /** * Shortcut for checking authorization as subscription manager. * @param $journalId int * @return boolean */ function isSubscriptionManager($journalId = -1) { return Validation::isAuthorized(ROLE_ID_SUBSCRIPTION_MANAGER, $journalId); } /** * Check whether a user is allowed to administer another user. * @param $journalId int * @param $userId int * @return boolean */ function canAdminister($journalId, $userId) { if (Validation::isSiteAdmin()) return true; if (!Validation::isJournalManager($journalId)) return false; // Check for roles in other journals that this user // doesn't have administrative rights over. $roleDao =& DAORegistry::getDAO('RoleDAO'); $roles =& $roleDao->getRolesByUserId($userId); foreach ($roles as $role) { if ($role->getRoleId() == ROLE_ID_SITE_ADMIN) return false; if ( $role->getJournalId() != $journalId && !Validation::isJournalManager($role->getJournalId()) ) return false; } // There were no conflicting roles. return true; } } ?>

preferences:
36.03 ms | 402 KiB | 5 Q