/** * @dataProvider providePasswordTests * @covers InvalidPassword::equals * @covers InvalidPassword::toString */ public function testInvalidUnequalNormal($shouldMatch, $hash, $password) { $invalid = $this->passwordFactory->newFromCiphertext(null); $normal = $this->passwordFactory->newFromCiphertext($hash); $this->assertFalse($invalid->equals($normal)); $this->assertFalse($normal->equals($invalid)); }
public function addDBDataOnce() { $passwordFactory = new \PasswordFactory(); $passwordFactory->init(\RequestContext::getMain()->getConfig()); $passwordHash = $passwordFactory->newFromPlaintext('foobaz'); $sysop = static::getTestSysop()->getUser(); $userId = \CentralIdLookup::factory('local')->centralIdFromName($sysop->getName()); $dbw = wfGetDB(DB_MASTER); $dbw->delete('bot_passwords', ['bp_user' => $userId, 'bp_app_id' => 'BotPasswordSessionProvider'], __METHOD__); $dbw->insert('bot_passwords', ['bp_user' => $userId, 'bp_app_id' => 'BotPasswordSessionProvider', 'bp_password' => $passwordHash->toString(), 'bp_token' => 'token!', 'bp_restrictions' => '{"IPAddresses":["127.0.0.0/8"]}', 'bp_grants' => '["test"]'], __METHOD__); }
public function addDBData() { $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('foobaz'); $userId = \CentralIdLookup::factory('local')->centralIdFromName('UTSysop'); $dbw = wfGetDB(DB_MASTER); $dbw->delete('bot_passwords', array('bp_user' => $userId, 'bp_app_id' => 'BotPasswordSessionProvider'), __METHOD__); $dbw->insert('bot_passwords', array('bp_user' => $userId, 'bp_app_id' => 'BotPasswordSessionProvider', 'bp_password' => $pwhash->toString(), 'bp_token' => 'token!', 'bp_restrictions' => '{"IPAddresses":["127.0.0.0/8"]}', 'bp_grants' => '["test"]'), __METHOD__); }
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)); }
/** * Return an instance with a new, random password * @return TemporaryPasswordAuthenticationRequest */ public static function newRandom() { $config = \ConfigFactory::getDefaultInstance()->makeConfig('main'); // get the min password length $minLength = $config->get('MinimalPasswordLength'); $policy = $config->get('PasswordPolicy'); foreach ($policy['policies'] as $p) { if (isset($p['MinimalPasswordLength'])) { $minLength = max($minLength, $p['MinimalPasswordLength']); } if (isset($p['MinimalPasswordLengthToLogin'])) { $minLength = max($minLength, $p['MinimalPasswordLengthToLogin']); } } $password = \PasswordFactory::generateRandomPasswordString($minLength); return new self($password); }
public function execute() { global $wgAuth; if (!$wgAuth->allowSetLocalPassword()) { $this->error('$wgAuth does not allow local passwords. Aborting.', true); } $passwordFactory = new PasswordFactory(); $passwordFactory->init(RequestContext::getMain()->getConfig()); $typeInfo = $passwordFactory->getTypes(); $layeredType = $this->getOption('type'); // Check that type exists and is a layered type if (!isset($typeInfo[$layeredType])) { $this->error('Undefined password type', true); } $passObj = $passwordFactory->newFromType($layeredType); if (!$passObj instanceof LayeredParameterizedPassword) { $this->error('Layered parameterized password type must be used.', true); } // Extract the first layer type $typeConfig = $typeInfo[$layeredType]; $firstType = $typeConfig['types'][0]; // Get a list of password types that are applicable $dbw = $this->getDB(DB_MASTER); $typeCond = 'user_password' . $dbw->buildLike(":{$firstType}:", $dbw->anyString()); $minUserId = 0; do { $dbw->begin(); $res = $dbw->select('user', array('user_id', 'user_name', 'user_password'), array('user_id > ' . $dbw->addQuotes($minUserId), $typeCond), __METHOD__, array('ORDER BY' => 'user_id', 'LIMIT' => $this->mBatchSize, 'LOCK IN SHARE MODE')); /** @var User[] $updateUsers */ $updateUsers = array(); foreach ($res as $row) { if ($this->hasOption('verbose')) { $this->output("Updating password for user {$row->user_name} ({$row->user_id}).\n"); } $user = User::newFromId($row->user_id); /** @var ParameterizedPassword $password */ $password = $passwordFactory->newFromCiphertext($row->user_password); /** @var LayeredParameterizedPassword $layeredPassword */ $layeredPassword = $passwordFactory->newFromType($layeredType); $layeredPassword->partialCrypt($password); $updateUsers[] = $user; $dbw->update('user', array('user_password' => $layeredPassword->toString()), array('user_id' => $row->user_id), __METHOD__); $minUserId = $row->user_id; } $dbw->commit(); // Clear memcached so old passwords are wiped out foreach ($updateUsers as $user) { $user->clearSharedCache(); } } while ($res->numRows()); }
public function execute() { $userName = $this->getArg(0); if (preg_match('/^#\\d+$/', $userName)) { $user = User::newFromId(substr($userName, 1)); } else { $user = User::newFromName($userName); } if (!$user || !$user->getId() || !$user->loadFromId()) { $this->error("Error: user '{$userName}' does not exist\n", 1); } $email = $this->getArg(1); if (!Sanitizer::validateEmail($email)) { $this->error("Error: email '{$email}' is not valid\n", 1); } // Code from https://wikitech.wikimedia.org/wiki/Password_reset $user->setEmail($email); $user->setEmailAuthenticationTimestamp(wfTimestampNow()); $user->saveSettings(); // Kick whomever is currently controlling the account off $user->setPassword(PasswordFactory::generateRandomPasswordString(128)); }
/** * Test the account creation API with a valid request. Also * make sure the new account can log in and is valid. * * This test does multiple API requests so it might end up being * a bit slow. Raise the default timeout. * @group medium */ public function testValid() { global $wgServer; if (!isset($wgServer)) { $this->markTestIncomplete('This test needs $wgServer to be set in LocalSettings.php'); } $password = PasswordFactory::generateRandomPasswordString(); $ret = $this->doApiRequest(array('action' => 'createaccount', 'name' => 'Apitestnew', 'password' => $password, 'email' => '*****@*****.**', 'realname' => 'Test Name')); $result = $ret[0]; $this->assertNotInternalType('bool', $result); $this->assertNotInternalType('null', $result['createaccount']); // Should first ask for token. $a = $result['createaccount']; $this->assertEquals('NeedToken', $a['result']); $token = $a['token']; // Finally create the account $ret = $this->doApiRequest(array('action' => 'createaccount', 'name' => 'Apitestnew', 'password' => $password, 'token' => $token, 'email' => '*****@*****.**', 'realname' => 'Test Name'), $ret[2]); $result = $ret[0]; $this->assertNotInternalType('bool', $result); $this->assertEquals('Success', $result['createaccount']['result']); // Try logging in with the new user. $ret = $this->doApiRequest(array('action' => 'login', 'lgname' => 'Apitestnew', 'lgpassword' => $password)); $result = $ret[0]; $this->assertNotInternalType('bool', $result); $this->assertNotInternalType('null', $result['login']); $a = $result['login']['result']; $this->assertEquals('NeedToken', $a); $token = $result['login']['token']; $ret = $this->doApiRequest(array('action' => 'login', 'lgtoken' => $token, 'lgname' => 'Apitestnew', 'lgpassword' => $password), $ret[2]); $result = $ret[0]; $this->assertNotInternalType('bool', $result); $a = $result['login']['result']; $this->assertEquals('Success', $a); // log out to destroy the session $ret = $this->doApiRequest(array('action' => 'logout'), $ret[2]); $this->assertEquals(array(), $ret[0]); }
public function testBotPassword() { global $wgServer, $wgSessionProviders; if (!isset($wgServer)) { $this->markTestIncomplete('This test needs $wgServer to be set in LocalSettings.php'); } $this->setMwGlobals(array('wgSessionProviders' => array_merge($wgSessionProviders, array(array('class' => 'MediaWiki\\Session\\BotPasswordSessionProvider', 'args' => array(array('priority' => 40))))), 'wgEnableBotPasswords' => true, 'wgBotPasswordsDatabase' => false, 'wgCentralIdLookupProvider' => 'local', 'wgGrantPermissions' => array('test' => array('read' => true)))); // Make sure our session provider is present $manager = TestingAccessWrapper::newFromObject(MediaWiki\Session\SessionManager::singleton()); if (!isset($manager->sessionProviders['MediaWiki\\Session\\BotPasswordSessionProvider'])) { $tmp = $manager->sessionProviders; $manager->sessionProviders = null; $manager->sessionProviders = $tmp + $manager->getProviders(); } $this->assertNotNull(MediaWiki\Session\SessionManager::singleton()->getProvider('MediaWiki\\Session\\BotPasswordSessionProvider'), 'sanity check'); $user = self::$users['sysop']; $centralId = CentralIdLookup::factory()->centralIdFromLocalUser($user->getUser()); $this->assertNotEquals(0, $centralId, 'sanity check'); $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('foobaz'); $dbw = wfGetDB(DB_MASTER); $dbw->insert('bot_passwords', array('bp_user' => $centralId, 'bp_app_id' => 'foo', 'bp_password' => $pwhash->toString(), 'bp_token' => '', 'bp_restrictions' => MWRestrictions::newDefault()->toJson(), 'bp_grants' => '["test"]'), __METHOD__); $lgName = $user->username . BotPassword::getSeparator() . 'foo'; $ret = $this->doApiRequest(array('action' => 'login', 'lgname' => $lgName, 'lgpassword' => 'foobaz')); $result = $ret[0]; $this->assertNotInternalType('bool', $result); $this->assertNotInternalType('null', $result['login']); $a = $result['login']['result']; $this->assertEquals('NeedToken', $a); $token = $result['login']['token']; $ret = $this->doApiRequest(array('action' => 'login', 'lgtoken' => $token, 'lgname' => $lgName, 'lgpassword' => 'foobaz'), $ret[2]); $result = $ret[0]; $this->assertNotInternalType('bool', $result); $a = $result['login']['result']; $this->assertEquals('Success', $a); }
private function save(array $data) { $bp = BotPassword::newUnsaved(['centralId' => $this->userId, 'appId' => $this->par, 'restrictions' => MWRestrictions::newFromJson($data['restrictions']), 'grants' => array_merge(MWGrants::getHiddenGrants(), preg_replace('/^grant-/', '', $data['grants']))]); if ($this->operation === 'insert' || !empty($data['resetPassword'])) { $this->password = PasswordFactory::generateRandomPasswordString(max(32, $this->getConfig()->get('MinimalPasswordLength'))); $passwordFactory = new PasswordFactory(); $passwordFactory->init(RequestContext::getMain()->getConfig()); $password = $passwordFactory->newFromPlaintext($this->password); } else { $password = null; } if ($bp->save($this->operation, $password)) { return Status::newGood(); } else { // Messages: botpasswords-insert-failed, botpasswords-update-failed return Status::newFatal("botpasswords-{$this->operation}-failed", $this->par); } }
/** * 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(); }
/** * Set the password on a testing user * * This assumes we're still using the generic AuthManager config from * PHPUnitMaintClass::finalSetup(), and just sets the password in the * database directly. * @param User $user * @param string $password */ public static function setPasswordForUser(User $user, $password) { if (!$user->getId()) { throw new MWException("Passed User has not been added to the database yet!"); } $dbw = wfGetDB(DB_MASTER); $row = $dbw->selectRow('user', ['user_password'], ['user_id' => $user->getId()], __METHOD__); if (!$row) { throw new MWException("Passed User has an ID but is not in the database?"); } $passwordFactory = new PasswordFactory(); $passwordFactory->init(RequestContext::getMain()->getConfig()); if (!$passwordFactory->newFromCiphertext($row->user_password)->equals($password)) { $passwordHash = $passwordFactory->newFromPlaintext($password); $dbw->update('user', ['user_password' => $passwordHash->toString()], ['user_id' => $user->getId()], __METHOD__); } }
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']); }
/** * Returns a (raw, unhashed) random password string. * @param Config $config * @return string */ public static function generatePassword($config) { return PasswordFactory::generateRandomPasswordString(max(32, $config->get('MinimalPasswordLength'))); }
/** * @dataProvider provideSave * @param string|null $password */ public function testSave($password) { $passwordFactory = new \PasswordFactory(); $passwordFactory->init(\RequestContext::getMain()->getConfig()); $bp = BotPassword::newUnsaved(['centralId' => 42, 'appId' => 'TestSave', 'restrictions' => MWRestrictions::newFromJson('{"IPAddresses":["127.0.0.0/8"]}'), 'grants' => ['test']]); $this->assertFalse($bp->isSaved(), 'sanity check'); $this->assertNull(BotPassword::newFromCentralId(42, 'TestSave', BotPassword::READ_LATEST), 'sanity check'); $passwordHash = $password ? $passwordFactory->newFromPlaintext($password) : null; $this->assertFalse($bp->save('update', $passwordHash)); $this->assertTrue($bp->save('insert', $passwordHash)); $bp2 = BotPassword::newFromCentralId(42, 'TestSave', BotPassword::READ_LATEST); $this->assertInstanceOf('BotPassword', $bp2); $this->assertEquals($bp->getUserCentralId(), $bp2->getUserCentralId()); $this->assertEquals($bp->getAppId(), $bp2->getAppId()); $this->assertEquals($bp->getToken(), $bp2->getToken()); $this->assertEquals($bp->getRestrictions(), $bp2->getRestrictions()); $this->assertEquals($bp->getGrants(), $bp2->getGrants()); $pw = TestingAccessWrapper::newFromObject($bp)->getPassword(); if ($password === null) { $this->assertInstanceOf('InvalidPassword', $pw); } else { $this->assertTrue($pw->equals($password)); } $token = $bp->getToken(); $this->assertFalse($bp->save('insert')); $this->assertTrue($bp->save('update')); $this->assertNotEquals($token, $bp->getToken()); $bp2 = BotPassword::newFromCentralId(42, 'TestSave', BotPassword::READ_LATEST); $this->assertInstanceOf('BotPassword', $bp2); $this->assertEquals($bp->getToken(), $bp2->getToken()); $pw = TestingAccessWrapper::newFromObject($bp)->getPassword(); if ($password === null) { $this->assertInstanceOf('InvalidPassword', $pw); } else { $this->assertTrue($pw->equals($password)); } $passwordHash = $passwordFactory->newFromPlaintext('XXX'); $token = $bp->getToken(); $this->assertTrue($bp->save('update', $passwordHash)); $this->assertNotEquals($token, $bp->getToken()); $pw = TestingAccessWrapper::newFromObject($bp)->getPassword(); $this->assertTrue($pw->equals('XXX')); $this->assertTrue($bp->delete()); $this->assertFalse($bp->isSaved()); $this->assertNull(BotPassword::newFromCentralId(42, 'TestSave', BotPassword::READ_LATEST)); $this->assertFalse($bp->save('foobar')); }
/** * @param User $u * @param bool $throttle * @param string $emailTitle Message name of email title * @param string $emailText Message name of email text * @return Status */ function mailPasswordInternal($u, $throttle = true, $emailTitle = 'passwordremindertitle', $emailText = 'passwordremindertext') { global $wgNewPasswordExpiry, $wgMinimalPasswordLength; if ($u->getEmail() == '') { return Status::newFatal('noemail', $u->getName()); } $ip = $this->getRequest()->getIP(); if (!$ip) { return Status::newFatal('badipaddress'); } $currentUser = $this->getUser(); Hooks::run('User::mailPasswordInternal', [&$currentUser, &$ip, &$u]); $np = PasswordFactory::generateRandomPasswordString($wgMinimalPasswordLength); $u->setNewpassword($np, $throttle); $u->saveSettings(); $userLanguage = $u->getOption('language'); $mainPage = Title::newMainPage(); $mainPageUrl = $mainPage->getCanonicalURL(); $m = $this->msg($emailText, $ip, $u->getName(), $np, '<' . $mainPageUrl . '>', round($wgNewPasswordExpiry / 86400))->inLanguage($userLanguage)->text(); $result = $u->sendMail($this->msg($emailTitle)->inLanguage($userLanguage)->text(), $m); return $result; }
/** * Set the password on a testing user * * This assumes we're still using the generic AuthManager config from * PHPUnitMaintClass::finalSetup(), and just sets the password in the * database directly. * @param User $user * @param string $password */ public static function setPasswordForUser(User $user, $password) { if (!$user->getId()) { throw new MWException("Passed User has not been added to the database yet!"); } $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); wfGetDB(DB_MASTER)->update('user', array('user_password' => $pwhash->toString()), array('user_id' => $user->getId()), __METHOD__); }
/** * Process the form. At this point we know that the user passes all the criteria in * userCanExecute(), and if the data array contains 'Username', etc, then Username * resets are allowed. * @param array $data * @throws MWException * @throws ThrottledError|PermissionsError * @return bool|array */ public function onSubmit(array $data) { global $wgAuth, $wgMinimalPasswordLength; if (isset($data['Domain'])) { if ($wgAuth->validDomain($data['Domain'])) { $wgAuth->setDomain($data['Domain']); } else { $wgAuth->setDomain('invaliddomain'); } } if (isset($data['Capture']) && !$this->getUser()->isAllowed('passwordreset')) { // The user knows they don't have the passwordreset permission, // but they tried to spoof the form. That's naughty throw new PermissionsError('passwordreset'); } /** * @var $firstUser User * @var $users User[] */ if (isset($data['Username']) && $data['Username'] !== '') { $method = 'username'; $users = [User::newFromName($data['Username'])]; } elseif (isset($data['Email']) && $data['Email'] !== '' && Sanitizer::validateEmail($data['Email'])) { $method = 'email'; $res = wfGetDB(DB_SLAVE)->select('user', User::selectFields(), ['user_email' => $data['Email']], __METHOD__); if ($res) { $users = []; foreach ($res as $row) { $users[] = User::newFromRow($row); } } else { // Some sort of database error, probably unreachable throw new MWException('Unknown database error in ' . __METHOD__); } } else { // The user didn't supply any data return false; } // Check for hooks (captcha etc), and allow them to modify the users list $error = []; if (!Hooks::run('SpecialPasswordResetOnSubmit', [&$users, $data, &$error])) { return [$error]; } $this->method = $method; if (count($users) == 0) { if ($method == 'email') { // Don't reveal whether or not an email address is in use return true; } else { return ['noname']; } } $firstUser = $users[0]; if (!$firstUser instanceof User || !$firstUser->getId()) { // Don't parse username as wikitext (bug 65501) return [['nosuchuser', wfEscapeWikiText($data['Username'])]]; } // Check against the rate limiter if ($this->getUser()->pingLimiter('mailpassword')) { throw new ThrottledError(); } // Check against password throttle foreach ($users as $user) { if ($user->isPasswordReminderThrottled()) { # Round the time in hours to 3 d.p., in case someone is specifying # minutes or seconds. return [['throttled-mailpassword', round($this->getConfig()->get('PasswordReminderResendTime'), 3)]]; } } // All the users will have the same email address if ($firstUser->getEmail() == '') { // This won't be reachable from the email route, so safe to expose the username return [['noemail', wfEscapeWikiText($firstUser->getName())]]; } // We need to have a valid IP address for the hook, but per bug 18347, we should // send the user's name if they're logged in. $ip = $this->getRequest()->getIP(); if (!$ip) { return ['badipaddress']; } $caller = $this->getUser(); Hooks::run('User::mailPasswordInternal', [&$caller, &$ip, &$firstUser]); $username = $caller->getName(); $msg = IP::isValid($username) ? 'passwordreset-emailtext-ip' : 'passwordreset-emailtext-user'; // Send in the user's language; which should hopefully be the same $userLanguage = $firstUser->getOption('language'); $passwords = []; foreach ($users as $user) { $password = PasswordFactory::generateRandomPasswordString($wgMinimalPasswordLength); $user->setNewpassword($password); $user->saveSettings(); $passwords[] = $this->msg('passwordreset-emailelement', $user->getName(), $password)->inLanguage($userLanguage)->text(); // We'll escape the whole thing later } $passwordBlock = implode("\n\n", $passwords); $this->email = $this->msg($msg)->inLanguage($userLanguage); $this->email->params($username, $passwordBlock, count($passwords), '<' . Title::newMainPage()->getCanonicalURL() . '>', round($this->getConfig()->get('NewPasswordExpiry') / 86400)); $title = $this->msg('passwordreset-emailtitle')->inLanguage($userLanguage); $this->result = $firstUser->sendMail($title->text(), $this->email->text()); if (isset($data['Capture']) && $data['Capture']) { // Save the user, will be used if an error occurs when sending the email $this->firstUser = $firstUser; } else { // Blank the email if the user is not supposed to see it $this->email = null; } if ($this->result->isGood()) { return true; } elseif (isset($data['Capture']) && $data['Capture']) { // The email didn't send, but maybe they knew that and that's why they captured it return true; } else { // @todo FIXME: The email wasn't sent, but we have already set // the password throttle timestamp, so they won't be able to try // again until it expires... :( return [['mailerror', $this->result->getMessage()]]; } }
/** * Lazily instantiate and return a factory object for making passwords * * @deprecated since 1.27, create a PasswordFactory directly instead * @return PasswordFactory */ public static function getPasswordFactory() { wfDeprecated(__METHOD__, '1.27'); $ret = new PasswordFactory(); $ret->init(RequestContext::getMain()->getConfig()); return $ret; }
public function testInvalidPlaintext() { $passwordFactory = new PasswordFactory(); $invalid = $passwordFactory->newFromPlaintext(null); $this->assertInstanceOf('InvalidPassword', $invalid); }