PageRenderTime 61ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/ojs/ojs-2.2/classes/security/Validation.inc.php

https://github.com/mcrider/pkpUpgradeTestSuite
PHP | 401 lines | 201 code | 57 blank | 143 comment | 40 complexity | 56c60919f78e2035c6bdae73b9b2a8b8 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. <?php
  2. /**
  3. * @file Validation.inc.php
  4. *
  5. * Copyright (c) 2003-2007 John Willinsky
  6. * Distributed under the GNU GPL v2. For full terms see the file docs/COPYING.
  7. *
  8. * @package security
  9. * @class Validation
  10. *
  11. * Class providing user validation/authentication operations.
  12. *
  13. * $Id: Validation.inc.php,v 1.31 2007/09/19 00:04:34 asmecher Exp $
  14. */
  15. import('security.Role');
  16. class Validation {
  17. /**
  18. * Authenticate user credentials and mark the user as logged in in the current session.
  19. * @param $username string
  20. * @param $password string unencrypted password
  21. * @param $reason string reference to string to receive the reason an account was disabled; null otherwise
  22. * @param $remember boolean remember a user's session past the current browser session
  23. * @return User the User associated with the login credentials, or false if the credentials are invalid
  24. */
  25. function &login($username, $password, &$reason, $remember = false) {
  26. $reason = null;
  27. $valid = false;
  28. $userDao = &DAORegistry::getDAO('UserDAO');
  29. $user = &$userDao->getUserByUsername($username, true);
  30. if (!isset($user)) {
  31. // User does not exist
  32. return $valid;
  33. }
  34. if ($user->getAuthId()) {
  35. $authDao = &DAORegistry::getDAO('AuthSourceDAO');
  36. $auth = &$authDao->getPlugin($user->getAuthId());
  37. }
  38. if (isset($auth)) {
  39. // Validate against remote authentication source
  40. $valid = $auth->authenticate($username, $password);
  41. if ($valid) {
  42. $oldEmail = $user->getEmail();
  43. $auth->doGetUserInfo($user);
  44. if ($user->getEmail() != $oldEmail) {
  45. // FIXME OJS requires email addresses to be unique; if changed email already exists, ignore
  46. if ($userDao->userExistsByEmail($user->getEmail())) {
  47. $user->setEmail($oldEmail);
  48. }
  49. }
  50. }
  51. } else {
  52. // Validate against OJS user database
  53. $valid = ($user->getPassword() === Validation::encryptCredentials($username, $password));
  54. }
  55. if (!$valid) {
  56. // Login credentials are invalid
  57. return $valid;
  58. } else {
  59. if ($user->getDisabled()) {
  60. // The user has been disabled.
  61. $reason = $user->getDisabledReason();
  62. if ($reason === null) $reason = '';
  63. $valid = false;
  64. return $valid;
  65. }
  66. // The user is valid, mark user as logged in in current session
  67. $sessionManager = &SessionManager::getManager();
  68. // Regenerate session ID first
  69. $sessionManager->regenerateSessionId();
  70. $session = &$sessionManager->getUserSession();
  71. $session->setSessionVar('userId', $user->getUserId());
  72. $session->setUserId($user->getUserId());
  73. $session->setSessionVar('username', $user->getUsername());
  74. $session->setRemember($remember);
  75. if ($remember && Config::getVar('general', 'session_lifetime') > 0) {
  76. // Update session expiration time
  77. $sessionManager->updateSessionLifetime(time() + Config::getVar('general', 'session_lifetime') * 86400);
  78. }
  79. $user->setDateLastLogin(Core::getCurrentDate());
  80. $userDao->updateUser($user);
  81. return $user;
  82. }
  83. }
  84. /**
  85. * Mark the user as logged out in the current session.
  86. * @return boolean
  87. */
  88. function logout() {
  89. $sessionManager = &SessionManager::getManager();
  90. $session = &$sessionManager->getUserSession();
  91. $session->unsetSessionVar('userId');
  92. $session->unsetSessionVar('signedInAs');
  93. $session->setUserId(null);
  94. if ($session->getRemember()) {
  95. $session->setRemember(0);
  96. $sessionManager->updateSessionLifetime(0);
  97. }
  98. $sessionDao = &DAORegistry::getDAO('SessionDAO');
  99. $sessionDao->updateSession($session);
  100. return true;
  101. }
  102. /**
  103. * Redirect to the login page, appending the current URL as the source.
  104. * @param $message string Optional name of locale key to add to login page
  105. */
  106. function redirectLogin($message = null) {
  107. $args = array();
  108. if (isset($_SERVER['REQUEST_URI'])) {
  109. $args['source'] = $_SERVER['REQUEST_URI'];
  110. }
  111. if ($message !== null) {
  112. $args['loginMessage'] = $message;
  113. }
  114. Request::redirect(null, 'login', null, null, $args);
  115. }
  116. /**
  117. * Check if a user's credentials are valid.
  118. * @param $username string username
  119. * @param $password string unencrypted password
  120. * @return boolean
  121. */
  122. function checkCredentials($username, $password) {
  123. $userDao = &DAORegistry::getDAO('UserDAO');
  124. $user = &$userDao->getUserByUsername($username, false);
  125. $valid = false;
  126. if (isset($user)) {
  127. if ($user->getAuthId()) {
  128. $authDao = &DAORegistry::getDAO('AuthSourceDAO');
  129. $auth = &$authDao->getPlugin($user->getAuthId());
  130. }
  131. if (isset($auth)) {
  132. $valid = $auth->authenticate($username, $password);
  133. } else {
  134. $valid = ($user->getPassword() === Validation::encryptCredentials($username, $password));
  135. }
  136. }
  137. return $valid;
  138. }
  139. /**
  140. * Check if a user is authorized to access the specified role in the specified journal.
  141. * @param $roleId int
  142. * @param $journalId optional (e.g., for global site admin role), the ID of the journal
  143. * @return boolean
  144. */
  145. function isAuthorized($roleId, $journalId = 0) {
  146. if (!Validation::isLoggedIn()) {
  147. return false;
  148. }
  149. if ($journalId === -1) {
  150. // Get journal ID from request
  151. $journal = &Request::getJournal();
  152. $journalId = $journal == null ? 0 : $journal->getJournalId();
  153. }
  154. $sessionManager = &SessionManager::getManager();
  155. $session = &$sessionManager->getUserSession();
  156. $user = &$session->getUser();
  157. $roleDao = &DAORegistry::getDAO('RoleDAO');
  158. return $roleDao->roleExists($journalId, $user->getUserId(), $roleId);
  159. }
  160. /**
  161. * Encrypt user passwords for database storage.
  162. * The username is used as a unique salt to make dictionary
  163. * attacks against a compromised database more difficult.
  164. * @param $username string username
  165. * @param $password string unencrypted password
  166. * @param $encryption string optional encryption algorithm to use, defaulting to the value from the site configuration
  167. * @return string encrypted password
  168. */
  169. function encryptCredentials($username, $password, $encryption = false) {
  170. $valueToEncrypt = $username . $password;
  171. if ($encryption == false) {
  172. $encryption = Config::getVar('security', 'encryption');
  173. }
  174. switch ($encryption) {
  175. case 'sha1':
  176. if (function_exists('sha1')) {
  177. return sha1($valueToEncrypt);
  178. }
  179. case 'md5':
  180. default:
  181. return md5($valueToEncrypt);
  182. }
  183. }
  184. /**
  185. * Generate a random password.
  186. * Assumes the random number generator has already been seeded.
  187. * @param $length int the length of the password to generate (default 8)
  188. * @return string
  189. */
  190. function generatePassword($length = 8) {
  191. $letters = 'abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ';
  192. $numbers = '23456789';
  193. $password = "";
  194. for ($i=0; $i<$length; $i++) {
  195. $password .= mt_rand(1, 4) == 4 ? $numbers[mt_rand(0,strlen($numbers)-1)] : $letters[mt_rand(0, strlen($letters)-1)];
  196. }
  197. return $password;
  198. }
  199. /**
  200. * Generate a hash value to use for confirmation to reset a password.
  201. * @param $userId int
  202. * @return string (boolean false if user is invalid)
  203. */
  204. function generatePasswordResetHash($userId) {
  205. $userDao = &DAORegistry::getDAO('UserDAO');
  206. if (($user = $userDao->getUser($userId)) == null) {
  207. // No such user
  208. return false;
  209. }
  210. return substr(md5($user->getUserId() . $user->getUsername() . $user->getPassword()), 0, 6);
  211. }
  212. /**
  213. * Suggest a username given the first and last names.
  214. * @return string
  215. */
  216. function suggestUsername($firstName, $lastName) {
  217. $initial = String::substr($firstName, 0, 1);
  218. $suggestion = String::regexp_replace('/[^a-zA-Z0-9_-]/', '', String::strtolower($initial . $lastName));
  219. $userDao =& DAORegistry::getDAO('UserDAO');
  220. for ($i = ''; $userDao->userExistsByUsername($suggestion . $i); $i++);
  221. return $suggestion . $i;
  222. }
  223. /**
  224. * Check if the user must change their password in order to log in.
  225. * @return boolean
  226. */
  227. function isLoggedIn() {
  228. $sessionManager = &SessionManager::getManager();
  229. $session = &$sessionManager->getUserSession();
  230. $userId = $session->getUserId();
  231. return isset($userId) && !empty($userId);
  232. }
  233. /**
  234. * Shortcut for checking authorization as site admin.
  235. * @return boolean
  236. */
  237. function isSiteAdmin() {
  238. return Validation::isAuthorized(ROLE_ID_SITE_ADMIN);
  239. }
  240. /**
  241. * Shortcut for checking authorization as journal manager.
  242. * @param $journalId int
  243. * @return boolean
  244. */
  245. function isJournalManager($journalId = -1) {
  246. return Validation::isAuthorized(ROLE_ID_JOURNAL_MANAGER, $journalId);
  247. }
  248. /**
  249. * Shortcut for checking authorization as editor.
  250. * @param $journalId int
  251. * @return boolean
  252. */
  253. function isEditor($journalId = -1) {
  254. return Validation::isAuthorized(ROLE_ID_EDITOR, $journalId);
  255. }
  256. /**
  257. * Shortcut for checking authorization as section editor.
  258. * @param $journalId int
  259. * @return boolean
  260. */
  261. function isSectionEditor($journalId = -1) {
  262. return Validation::isAuthorized(ROLE_ID_SECTION_EDITOR, $journalId);
  263. }
  264. /**
  265. * Shortcut for checking authorization as layout editor.
  266. * @param $journalId int
  267. * @return boolean
  268. */
  269. function isLayoutEditor($journalId = -1) {
  270. return Validation::isAuthorized(ROLE_ID_LAYOUT_EDITOR, $journalId);
  271. }
  272. /**
  273. * Shortcut for checking authorization as reviewer.
  274. * @param $journalId int
  275. * @return boolean
  276. */
  277. function isReviewer($journalId = -1) {
  278. return Validation::isAuthorized(ROLE_ID_REVIEWER, $journalId);
  279. }
  280. /**
  281. * Shortcut for checking authorization as copyeditor.
  282. * @param $journalId int
  283. * @return boolean
  284. */
  285. function isCopyeditor($journalId = -1) {
  286. return Validation::isAuthorized(ROLE_ID_COPYEDITOR, $journalId);
  287. }
  288. /**
  289. * Shortcut for checking authorization as proofreader.
  290. * @param $journalId int
  291. * @return boolean
  292. */
  293. function isProofreader($journalId = -1) {
  294. return Validation::isAuthorized(ROLE_ID_PROOFREADER, $journalId);
  295. }
  296. /**
  297. * Shortcut for checking authorization as author.
  298. * @param $journalId int
  299. * @return boolean
  300. */
  301. function isAuthor($journalId = -1) {
  302. return Validation::isAuthorized(ROLE_ID_AUTHOR, $journalId);
  303. }
  304. /**
  305. * Shortcut for checking authorization as reader.
  306. * @param $journalId int
  307. * @return boolean
  308. */
  309. function isReader($journalId = -1) {
  310. return Validation::isAuthorized(ROLE_ID_READER, $journalId);
  311. }
  312. /**
  313. * Shortcut for checking authorization as subscription manager.
  314. * @param $journalId int
  315. * @return boolean
  316. */
  317. function isSubscriptionManager($journalId = -1) {
  318. return Validation::isAuthorized(ROLE_ID_SUBSCRIPTION_MANAGER, $journalId);
  319. }
  320. /**
  321. * Check whether a user is allowed to administer another user.
  322. * @param $journalId int
  323. * @param $userId int
  324. * @return boolean
  325. */
  326. function canAdminister($journalId, $userId) {
  327. if (Validation::isSiteAdmin()) return true;
  328. if (!Validation::isJournalManager($journalId)) return false;
  329. // Check for roles in other journals that this user
  330. // doesn't have administrative rights over.
  331. $roleDao = &DAORegistry::getDAO('RoleDAO');
  332. $roles = &$roleDao->getRolesByUserId($userId);
  333. foreach ($roles as $role) {
  334. if ($role->getRoleId() == ROLE_ID_SITE_ADMIN) return false;
  335. if (
  336. $role->getJournalId() != $journalId &&
  337. !Validation::isJournalManager($role->getJournalId())
  338. ) return false;
  339. }
  340. // There were no conflicting roles.
  341. return true;
  342. }
  343. }
  344. ?>