public function testTestUserCanAuthenticate()
 {
     $user = $this->getMutableTestUser()->getUser();
     $userName = $user->getName();
     $dbw = wfGetDB(DB_MASTER);
     $provider = $this->getProvider();
     $this->assertFalse($provider->testUserCanAuthenticate('<invalid>'));
     $this->assertFalse($provider->testUserCanAuthenticate('DoesNotExist'));
     $this->assertTrue($provider->testUserCanAuthenticate($userName));
     $lowerInitialUserName = mb_strtolower($userName[0]) . substr($userName, 1);
     $this->assertTrue($provider->testUserCanAuthenticate($lowerInitialUserName));
     $dbw->update('user', ['user_password' => \PasswordFactory::newInvalidPassword()->toString()], ['user_name' => $userName]);
     $this->assertFalse($provider->testUserCanAuthenticate($userName));
     // Really old format
     $dbw->update('user', ['user_password' => '0123456789abcdef0123456789abcdef'], ['user_name' => $userName]);
     $this->assertTrue($provider->testUserCanAuthenticate($userName));
 }
Exemple #2
0
 /**
  * Check if the given clear-text password matches the temporary password
  * sent by e-mail for password reset operations.
  *
  * @deprecated since 1.27. AuthManager is coming.
  * @param string $plaintext
  * @return bool True if matches, false otherwise
  */
 public function checkTemporaryPassword($plaintext)
 {
     global $wgNewPasswordExpiry;
     $this->load();
     $passwordFactory = new PasswordFactory();
     $passwordFactory->init(RequestContext::getMain()->getConfig());
     $db = $this->queryFlagsUsed & self::READ_LATEST ? wfGetDB(DB_MASTER) : wfGetDB(DB_SLAVE);
     $row = $db->selectRow('user', array('user_newpassword', 'user_newpass_time'), array('user_id' => $this->getId()), __METHOD__);
     try {
         $newPassword = $passwordFactory->newFromCiphertext($row->user_newpassword);
     } catch (PasswordError $e) {
         wfDebug('Invalid password hash found in database.');
         $newPassword = PasswordFactory::newInvalidPassword();
     }
     if ($newPassword->equals($plaintext)) {
         if (is_null($row->user_newpass_time)) {
             return true;
         }
         $expiry = wfTimestamp(TS_UNIX, $row->user_newpass_time) + $wgNewPasswordExpiry;
         return time() < $expiry;
     } else {
         return false;
     }
 }
Exemple #3
0
 /**
  * Invalidate all passwords for a user, by central ID
  * @param int $centralId
  * @return bool Whether any passwords were invalidated
  */
 public static function invalidateAllPasswordsForCentralId($centralId)
 {
     global $wgEnableBotPasswords;
     if (!$wgEnableBotPasswords) {
         return false;
     }
     $dbw = self::getDB(DB_MASTER);
     $dbw->update('bot_passwords', array('bp_password' => PasswordFactory::newInvalidPassword()->toString()), array('bp_user' => $centralId), __METHOD__);
     return (bool) $dbw->affectedRows();
 }
 public function testTestUserCanAuthenticate()
 {
     $dbw = wfGetDB(DB_MASTER);
     $passwordFactory = new \PasswordFactory();
     $passwordFactory->init(\RequestContext::getMain()->getConfig());
     // A is unsalted MD5 (thus fast) ... we don't care about security here, this is test only
     $passwordFactory->setDefaultType('A');
     $pwhash = $passwordFactory->newFromPlaintext('password')->toString();
     $provider = $this->getProvider();
     $providerPriv = \TestingAccessWrapper::newFromObject($provider);
     $this->assertFalse($provider->testUserCanAuthenticate('<invalid>'));
     $this->assertFalse($provider->testUserCanAuthenticate('DoesNotExist'));
     $dbw->update('user', ['user_newpassword' => \PasswordFactory::newInvalidPassword()->toString(), 'user_newpass_time' => null], ['user_name' => 'UTSysop']);
     $this->assertFalse($provider->testUserCanAuthenticate('UTSysop'));
     $dbw->update('user', ['user_newpassword' => $pwhash, 'user_newpass_time' => null], ['user_name' => 'UTSysop']);
     $this->assertTrue($provider->testUserCanAuthenticate('UTSysop'));
     $this->assertTrue($provider->testUserCanAuthenticate('uTSysop'));
     $dbw->update('user', ['user_newpassword' => $pwhash, 'user_newpass_time' => $dbw->timestamp(time() - 10)], ['user_name' => 'UTSysop']);
     $providerPriv->newPasswordExpiry = 100;
     $this->assertTrue($provider->testUserCanAuthenticate('UTSysop'));
     $providerPriv->newPasswordExpiry = 1;
     $this->assertFalse($provider->testUserCanAuthenticate('UTSysop'));
     $dbw->update('user', ['user_newpassword' => \PasswordFactory::newInvalidPassword()->toString(), 'user_newpass_time' => null], ['user_name' => 'UTSysop']);
 }
Exemple #5
0
 /**
  * Add this existing user object to the database. If the user already
  * exists, a fatal status object is returned, and the user object is
  * initialised with the data from the database.
  *
  * Previously, this function generated a DB error due to a key conflict
  * if the user already existed. Many extension callers use this function
  * in code along the lines of:
  *
  *   $user = User::newFromName( $name );
  *   if ( !$user->isLoggedIn() ) {
  *       $user->addToDatabase();
  *   }
  *   // do something with $user...
  *
  * However, this was vulnerable to a race condition (bug 16020). By
  * initialising the user object if the user exists, we aim to support this
  * calling sequence as far as possible.
  *
  * Note that if the user exists, this function will acquire a write lock,
  * so it is still advisable to make the call conditional on isLoggedIn(),
  * and to commit the transaction after calling.
  *
  * @throws MWException
  * @return Status
  */
 public function addToDatabase()
 {
     $this->load();
     if (!$this->mToken) {
         $this->setToken();
         // init token
     }
     $this->mTouched = $this->newTouchedTimestamp();
     $noPass = PasswordFactory::newInvalidPassword()->toString();
     $dbw = wfGetDB(DB_MASTER);
     $seqVal = $dbw->nextSequenceValue('user_user_id_seq');
     $dbw->insert('user', ['user_id' => $seqVal, 'user_name' => $this->mName, 'user_password' => $noPass, 'user_newpassword' => $noPass, 'user_email' => $this->mEmail, 'user_email_authenticated' => $dbw->timestampOrNull($this->mEmailAuthenticated), 'user_real_name' => $this->mRealName, 'user_token' => strval($this->mToken), 'user_registration' => $dbw->timestamp($this->mRegistration), 'user_editcount' => 0, 'user_touched' => $dbw->timestamp($this->mTouched)], __METHOD__, ['IGNORE']);
     if (!$dbw->affectedRows()) {
         // Use locking reads to bypass any REPEATABLE-READ snapshot.
         $this->mId = $dbw->selectField('user', 'user_id', ['user_name' => $this->mName], __METHOD__, ['LOCK IN SHARE MODE']);
         $loaded = false;
         if ($this->mId) {
             if ($this->loadFromDatabase(self::READ_LOCKING)) {
                 $loaded = true;
             }
         }
         if (!$loaded) {
             throw new MWException(__METHOD__ . ": hit a key conflict attempting " . "to insert user '{$this->mName}' row, but it was not present in select!");
         }
         return Status::newFatal('userexists');
     }
     $this->mId = $dbw->insertId();
     self::$idCacheByName[$this->mName] = $this->mId;
     // Clear instance cache other than user table data, which is already accurate
     $this->clearInstanceCache();
     $this->saveOptions();
     return Status::newGood();
 }