Elgg  Version 3.0
PasswordService.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Elgg;
4 
12 final class PasswordService {
13 
17  public function __construct() {
18  if (!function_exists('password_hash')) {
19  throw new \RuntimeException("password_hash and associated functions are required.");
20  }
21  }
22 
32  public function needsRehash($hash) {
33  return password_needs_rehash($hash, PASSWORD_DEFAULT);
34  }
35 
44  public function verify($password, $hash) {
45  return password_verify($password, $hash);
46  }
47 
55  public function generateHash($password) {
56  return password_hash($password, PASSWORD_DEFAULT);
57  }
58 
68  $user_guid = (int) $user_guid;
69 
70  $user = _elgg_services()->entityTable->get($user_guid);
71  if (!$user instanceof \ElggUser) {
72  return false;
73  }
74 
75  // generate code
77  $user->setPrivateSetting('passwd_conf_code', $code);
78  $user->setPrivateSetting('passwd_conf_time', time());
79 
80  // generate link
81  $link = elgg_generate_url('account:password:change', [
82  'u' => $user_guid,
83  'c' => $code,
84  ]);
85  $link = _elgg_services()->urlSigner->sign($link, '+1 day');
86 
87  // generate email
88  $ip_address = _elgg_services()->request->getClientIp();
89  $message = _elgg_services()->translator->translate('email:changereq:body', [
90  $user->name,
91  $ip_address,
92  $link,
93  ], $user->language);
94  $subject = _elgg_services()->translator->translate('email:changereq:subject', [], $user->language);
95 
96  $params = [
97  'action' => 'requestnewpassword',
98  'object' => $user,
99  'ip_address' => $ip_address,
100  'link' => $link,
101  ];
102 
103  return notify_user($user->guid, elgg_get_site_entity()->guid, $subject, $message, $params, 'email');
104  }
105 
116  public function forcePasswordReset($user, $password) {
117  if (!$user instanceof \ElggUser) {
118  $user = _elgg_services()->entityTable->get($user, 'user');
119  if (!$user instanceof \ElggUser) {
120  return false;
121  }
122  }
123 
124  $user->setPassword($password);
125 
126  $ia = _elgg_services()->session->setIgnoreAccess(true);
127  $result = (bool) $user->save();
128  _elgg_services()->session->setIgnoreAccess($ia);
129 
130  return $result;
131  }
132 
142  public function executeNewPasswordReset($user_guid, $conf_code, $password = null) {
143  $user_guid = (int) $user_guid;
145 
146  if ($password === null) {
148  $reset = true;
149  } else {
150  $reset = false;
151  }
152 
153  if (!$user instanceof \ElggUser) {
154  return false;
155  }
156 
157  $saved_code = $user->getPrivateSetting('passwd_conf_code');
158  $code_time = (int) $user->getPrivateSetting('passwd_conf_time');
159  $codes_match = _elgg_services()->crypto->areEqual($saved_code, $conf_code);
160 
161  if (!$saved_code || !$codes_match) {
162  return false;
163  }
164 
165  // Discard for security if it is 24h old
166  if (!$code_time || $code_time < time() - 24 * 60 * 60) {
167  return false;
168  }
169 
170  if (!$this->forcePasswordReset($user, $password)) {
171  return false;
172  }
173 
174  $user->removePrivateSetting('passwd_conf_code');
175  $user->removePrivateSetting('passwd_conf_time');
176 
177  // clean the logins failures
179 
180  $ns = $reset ? 'resetpassword' : 'changepassword';
181 
182  $message = _elgg_services()->translator->translate(
183  "email:$ns:body", [$user->username, $password], $user->language);
184  $subject = _elgg_services()->translator->translate("email:$ns:subject", [], $user->language);
185 
186  $params = [
187  'action' => $ns,
188  'object' => $user,
189  'password' => $password,
190  ];
191 
192  notify_user($user->guid, elgg_get_site_entity()->guid, $subject, $message, $params, 'email');
193 
194  return true;
195  }
196 }
verify($password, $hash)
Verify a password against a hash using a timing attack resistant approach.
$params
Saves global plugin settings.
Definition: save.php:13
__construct()
Constructor.
reset_login_failure_count($user_guid)
Resets the fail login count for $user_guid.
Definition: sessions.php:184
executeNewPasswordReset($user_guid, $conf_code, $password=null)
Validate and change password for a user.
notify_user($to, $from=0, $subject= '', $message= '', array $params=[], $methods_override=null)
Notify a user via their preferences.
if(!$item instanceof ElggEntity) $link
Definition: container.php:16
$code
$user_guid
Validate a user.
Definition: validate.php:6
Configuration exception.
if(!$user||!$user->canEdit()) $password
elgg_generate_url($name, array $parameters=[])
Generate a URL for named route.
Definition: pagehandler.php:58
$user
Definition: ban.php:7
needsRehash($hash)
Determine if the password hash needs to be rehashed.
elgg_get_site_entity()
Get the current site entity.
Definition: entities.php:130
generate_random_cleartext_password()
Generate a random 12 character clear text password.
Definition: users.php:146
_elgg_services()
Get the global service provider.
Definition: elgglib.php:1292
$subject
Definition: useradd.php:59
generateHash($password)
Hash a password for storage using password_hash()
forcePasswordReset($user, $password)
Set a user&#39;s new password and save the entity.
sendNewPasswordRequest($user_guid)
Generate and send a password request email to a given user&#39;s registered email address.
get_entity($guid)
Loads and returns an entity object from a guid.
Definition: entities.php:87