| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 | 
							- <?php
 
- namespace Elgg;
 
- /**
 
-  * PRIVATE CLASS. API IN FLUX. DO NOT USE DIRECTLY.
 
-  * 
 
-  * @package Elgg.Core
 
-  * @access  private
 
-  * @since   1.10.0
 
-  */
 
- final class PasswordService {
 
- 	/**
 
- 	 * Constructor
 
- 	 */
 
- 	public function __construct() {
 
- 		if (!function_exists('password_hash')) {
 
- 			throw new \RuntimeException("password_hash and associated functions are required.");
 
- 		}
 
- 	}
 
- 	/**
 
- 	 * Determine if the password hash needs to be rehashed
 
- 	 *
 
- 	 * If the answer is true, after validating the password using password_verify, rehash it.
 
- 	 *
 
- 	 * @param string $hash The hash to test
 
- 	 *
 
- 	 * @return boolean True if the password needs to be rehashed.
 
- 	 */
 
- 	function needsRehash($hash) {
 
- 		return password_needs_rehash($hash, PASSWORD_DEFAULT);
 
- 	}
 
- 	/**
 
- 	 * Verify a password against a hash using a timing attack resistant approach
 
- 	 *
 
- 	 * @param string $password The password to verify
 
- 	 * @param string $hash     The hash to verify against
 
- 	 *
 
- 	 * @return boolean If the password matches the hash
 
- 	 */
 
- 	function verify($password, $hash) {
 
- 		return password_verify($password, $hash);
 
- 	}
 
- 	/**
 
- 	 * Hash a password for storage using password_hash()
 
- 	 *
 
- 	 * @param string $password Password in clear text
 
- 	 *
 
- 	 * @return string
 
- 	 */
 
- 	function generateHash($password) {
 
- 		return password_hash($password, PASSWORD_DEFAULT);
 
- 	}
 
- 	/**
 
- 	 * Hash a password for storage. Currently salted MD5.
 
- 	 *
 
- 	 * @param \ElggUser $user     The user this is being generated for.
 
- 	 * @param string    $password Password in clear text
 
- 	 *
 
- 	 * @return string
 
- 	 */
 
- 	function generateLegacyHash(\ElggUser $user, $password) {
 
- 		return md5($password . $user->salt);
 
- 	}
 
- 	/**
 
- 	 * Generate and send a password request email to a given user's registered email address.
 
- 	 *
 
- 	 * @param int $user_guid User GUID
 
- 	 *
 
- 	 * @return bool
 
- 	 */
 
- 	function sendNewPasswordRequest($user_guid) {
 
- 		$user_guid = (int)$user_guid;
 
- 		$user = _elgg_services()->entityTable->get($user_guid);
 
- 		if (!$user instanceof \ElggUser) {
 
- 			return false;
 
- 		}
 
- 		// generate code
 
- 		$code = generate_random_cleartext_password();
 
- 		$user->setPrivateSetting('passwd_conf_code', $code);
 
- 		$user->setPrivateSetting('passwd_conf_time', time());
 
- 		// generate link
 
- 		$link = _elgg_services()->config->getSiteUrl() . "changepassword?u=$user_guid&c=$code";
 
- 		// generate email
 
- 		$ip_address = _elgg_services()->request->getClientIp();
 
- 		$message = _elgg_services()->translator->translate(
 
- 			'email:changereq:body', array($user->name, $ip_address, $link), $user->language);
 
- 		$subject = _elgg_services()->translator->translate(
 
- 			'email:changereq:subject', array(), $user->language);
 
- 		return notify_user($user->guid, elgg_get_site_entity()->guid, $subject, $message, array(), 'email');
 
- 	}
 
- 	/**
 
- 	 * Set a user's new password and save the entity.
 
- 	 *
 
- 	 * This can only be called from execute_new_password_request().
 
- 	 *
 
- 	 * @param \ElggUser|int $user     The user GUID or entity
 
- 	 * @param string        $password Text (which will then be converted into a hash and stored)
 
- 	 *
 
- 	 * @return bool
 
- 	 */
 
- 	function forcePasswordReset($user, $password) {
 
- 		if (!$user instanceof \ElggUser) {
 
- 			$user = _elgg_services()->entityTable->get($user, 'user');
 
- 			if (!$user) {
 
- 				return false;
 
- 			}
 
- 		}
 
- 		$user->setPassword($password);
 
- 		$ia = elgg_set_ignore_access(true);
 
- 		$result = (bool)$user->save();
 
- 		elgg_set_ignore_access($ia);
 
- 		return $result;
 
- 	}
 
- 	/**
 
- 	 * Validate and change password for a user.
 
- 	 *
 
- 	 * @param int    $user_guid The user id
 
- 	 * @param string $conf_code Confirmation code as sent in the request email.
 
- 	 * @param string $password  Optional new password, if not randomly generated.
 
- 	 *
 
- 	 * @return bool True on success
 
- 	 */
 
- 	function executeNewPasswordReset($user_guid, $conf_code, $password = null) {
 
- 		$user_guid = (int)$user_guid;
 
- 		$user = get_entity($user_guid);
 
- 		if ($password === null) {
 
- 			$password = generate_random_cleartext_password();
 
- 			$reset = true;
 
- 		} else {
 
- 			$reset = false;
 
- 		}
 
- 		if (!$user instanceof \ElggUser) {
 
- 			return false;
 
- 		}
 
- 		$saved_code = $user->getPrivateSetting('passwd_conf_code');
 
- 		$code_time = (int) $user->getPrivateSetting('passwd_conf_time');
 
- 		$codes_match = _elgg_services()->crypto->areEqual($saved_code, $conf_code);
 
- 		if (!$saved_code || !$codes_match) {
 
- 			return false;
 
- 		}
 
- 		// Discard for security if it is 24h old
 
- 		if (!$code_time || $code_time < time() - 24 * 60 * 60) {
 
- 			return false;
 
- 		}
 
- 		if (!$this->forcePasswordReset($user, $password)) {
 
- 			return false;
 
- 		}
 
- 		remove_private_setting($user_guid, 'passwd_conf_code');
 
- 		remove_private_setting($user_guid, 'passwd_conf_time');
 
- 		// clean the logins failures
 
- 		reset_login_failure_count($user_guid);
 
- 		$ns = $reset ? 'resetpassword' : 'changepassword';
 
- 		$message = _elgg_services()->translator->translate(
 
- 			"email:$ns:body", array($user->username, $password), $user->language);
 
- 		$subject = _elgg_services()->translator->translate("email:$ns:subject", array(), $user->language);
 
- 		notify_user($user->guid, elgg_get_site_entity()->guid, $subject, $message, array(), 'email');
 
- 		return true;
 
- 	}
 
- }
 
 
  |