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 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());
 }
Exemple #4
0
 /**
  * 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;
 }
Exemple #5
0
 /**
  * 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__);
 }
 /**
  * @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'));
 }
 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);
     }
 }
Exemple #9
0
 /**
  * Get the password
  * @return Password
  */
 protected function getPassword()
 {
     list($index, $options) = DBAccessObjectUtils::getDBOptions($this->flags);
     $db = self::getDB($index);
     $password = $db->selectField('bot_passwords', 'bp_password', array('bp_user' => $this->centralId, 'bp_app_id' => $this->appId), __METHOD__, $options);
     if ($password === false) {
         return PasswordFactory::newInvalidPassword();
     }
     $passwordFactory = new \PasswordFactory();
     $passwordFactory->init(\RequestContext::getMain()->getConfig());
     try {
         return $passwordFactory->newFromCiphertext($password);
     } catch (PasswordError $ex) {
         return PasswordFactory::newInvalidPassword();
     }
 }
Exemple #10
0
 /**
  * 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']);
 }