The stored password can be plain, a md5 hash or a phpass hash.
If the password wasn't a phppass hash, the Weak property is set to **true**.
public checkPassword ( string $Password, string $StoredHash, boolean | string $Method = false ) : boolean | ||
$Password | string | The plaintext password to check. |
$StoredHash | string | The password hash stored in the database. |
$Method | boolean | string | The password hashing method. |
return | boolean | Returns **true** if the password matches the hash or **false** if it doesn't. |
/** * Signin process that multiple authentication methods. * * @access public * @since 2.0.0 * @author Tim Gunter * * @param string $Method * @param array $Arg1 * @return string Rendered XHTML template. */ public function signIn($Method = false, $Arg1 = false) { if (!$this->Request->isPostBack()) { $this->checkOverride('SignIn', $this->target()); } Gdn::session()->ensureTransientKey(); $this->addJsFile('entry.js'); $this->setData('Title', t('Sign In')); $this->Form->addHidden('Target', $this->target()); $this->Form->addHidden('ClientHour', date('Y-m-d H:00')); // Use the server's current hour as a default. // Additional signin methods are set up with plugins. $Methods = array(); $this->setData('Methods', $Methods); $this->setData('FormUrl', url('entry/signin')); $this->fireEvent('SignIn'); if ($this->Form->isPostBack()) { $this->Form->validateRule('Email', 'ValidateRequired', sprintf(t('%s is required.'), t(UserModel::signinLabelCode()))); $this->Form->validateRule('Password', 'ValidateRequired'); if (!$this->Request->isAuthenticatedPostBack() && !c('Garden.Embed.Allow')) { $this->Form->addError('Please try again.'); } // Check the user. if ($this->Form->errorCount() == 0) { $Email = $this->Form->getFormValue('Email'); $User = Gdn::userModel()->GetByEmail($Email); if (!$User) { $User = Gdn::userModel()->GetByUsername($Email); } if (!$User) { $this->Form->addError('@' . sprintf(t('User not found.'), strtolower(t(UserModel::SigninLabelCode())))); Logger::event('signin_failure', Logger::INFO, '{signin} failed to sign in. User not found.', array('signin' => $Email)); } else { // Check the password. $PasswordHash = new Gdn_PasswordHash(); $Password = $this->Form->getFormValue('Password'); try { $PasswordChecked = $PasswordHash->checkPassword($Password, val('Password', $User), val('HashMethod', $User)); // Rate limiting Gdn::userModel()->rateLimit($User, $PasswordChecked); if ($PasswordChecked) { // Update weak passwords $HashMethod = val('HashMethod', $User); if ($PasswordHash->Weak || $HashMethod && strcasecmp($HashMethod, 'Vanilla') != 0) { $Pw = $PasswordHash->hashPassword($Password); Gdn::userModel()->setField(val('UserID', $User), array('Password' => $Pw, 'HashMethod' => 'Vanilla')); } Gdn::session()->start(val('UserID', $User), true, (bool) $this->Form->getFormValue('RememberMe')); if (!Gdn::session()->checkPermission('Garden.SignIn.Allow')) { $this->Form->addError('ErrorPermission'); Gdn::session()->end(); } else { $ClientHour = $this->Form->getFormValue('ClientHour'); $HourOffset = Gdn::session()->User->HourOffset; if (is_numeric($ClientHour) && $ClientHour >= 0 && $ClientHour < 24) { $HourOffset = $ClientHour - date('G', time()); } if ($HourOffset != Gdn::session()->User->HourOffset) { Gdn::userModel()->setProperty(Gdn::session()->UserID, 'HourOffset', $HourOffset); } Gdn::userModel()->fireEvent('AfterSignIn'); $this->_setRedirect(); } } else { $this->Form->addError('Invalid password.'); Logger::event('signin_failure', Logger::WARNING, '{username} failed to sign in. Invalid password.', array('InsertName' => $User->Name)); } } catch (Gdn_UserException $Ex) { $this->Form->addError($Ex); } } } } else { if ($Target = $this->Request->get('Target')) { $this->Form->addHidden('Target', $Target); } $this->Form->setValue('RememberMe', true); } return $this->render(); }
/** * Validate User Credential. * * Fetches a user row by email (or name) and compare the password. * If the password was not stored as a blowfish hash, the password will be saved again. * Return the user's id, admin status and attributes. * * @param string $Email * @param string $Password * @return object|false Returns the user matching the credentials or **false** if the user doesn't validate. */ public function validateCredentials($Email = '', $ID = 0, $Password) { $this->EventArguments['Credentials'] = ['Email' => $Email, 'ID' => $ID, 'Password' => $Password]; $this->fireEvent('BeforeValidateCredentials'); if (!$Email && !$ID) { throw new Exception('The email or id is required'); } try { $this->SQL->select('UserID, Name, Attributes, Admin, Password, HashMethod, Deleted, Banned')->from('User'); if ($ID) { $this->SQL->where('UserID', $ID); } else { if (strpos($Email, '@') > 0) { $this->SQL->where('Email', $Email); } else { $this->SQL->where('Name', $Email); } } $DataSet = $this->SQL->get(); } catch (Exception $Ex) { $this->SQL->reset(); // Try getting the user information without the new fields. $this->SQL->select('UserID, Name, Attributes, Admin, Password')->from('User'); if ($ID) { $this->SQL->where('UserID', $ID); } else { if (strpos($Email, '@') > 0) { $this->SQL->where('Email', $Email); } else { $this->SQL->where('Name', $Email); } } $DataSet = $this->SQL->get(); } if ($DataSet->numRows() < 1) { return false; } $UserData = $DataSet->firstRow(); // Check for a deleted user. if (val('Deleted', $UserData)) { return false; } $PasswordHash = new Gdn_PasswordHash(); $HashMethod = val('HashMethod', $UserData); if (!$PasswordHash->checkPassword($Password, $UserData->Password, $HashMethod, $UserData->Name)) { return false; } if ($PasswordHash->Weak || $HashMethod && strcasecmp($HashMethod, 'Vanilla') != 0) { $Pw = $PasswordHash->hashPassword($Password); $this->SQL->update('User')->set('Password', $Pw)->set('HashMethod', 'Vanilla')->where('UserID', $UserData->UserID)->put(); } $UserData->Attributes = dbdecode($UserData->Attributes); return $UserData; }
/** * * * @throws Exception * @throws Gdn_UserException */ public function authenticate() { if (!$this->Request->isPostBack()) { throw forbiddenException($this->Request->requestMethod()); } $Args = array_change_key_case($this->Form->formValues()); $UserModel = new UserModel(); // Look up the user. $User = null; if ($Email = val('email', $Args)) { $User = $UserModel->getByEmail($Email); } elseif ($Name = val('name', $Args)) { $User = $UserModel->getByUsername($Name); } else { throw new Gdn_UserException("One of the following parameters required: Email, Name.", 400); } if (!$User) { throw notFoundException('User'); } // Check the password. $PasswordHash = new Gdn_PasswordHash(); $Password = val('password', $Args); try { $PasswordChecked = $PasswordHash->checkPassword($Password, val('Password', $User), val('HashMethod', $User)); // Rate limiting Gdn::userModel()->rateLimit($User, $PasswordChecked); if ($PasswordChecked) { $this->setData('User', arrayTranslate((array) $User, array('UserID', 'Name', 'Email', 'PhotoUrl'))); if (val('session', $Args)) { Gdn::session()->start($this->data('User.UserID')); $this->setData('Cookie', array(c('Garden.Cookie.Name') => $_COOKIE[c('Garden.Cookie.Name')])); } } else { throw new Exception(t('Invalid password.'), 401); // Can't be a user exception. } } catch (Gdn_UserException $Ex) { $this->Form->addError($Ex); } $this->render(); }