Пример #1
0
 /**
  * @param string|MWRestrictions $value The value the field was submitted with
  * @param array $alldata The data collected from the form
  *
  * @return bool|string True on success, or String error to display, or
  *   false to fail validation without displaying an error.
  */
 public function validate($value, $alldata)
 {
     if ($this->isHidden($alldata)) {
         return true;
     }
     if (isset($this->mParams['required']) && $this->mParams['required'] !== false && $value instanceof MWRestrictions && !$value->toArray()['IPAddresses']) {
         return $this->msg('htmlform-required')->parse();
     }
     if (is_string($value)) {
         // MWRestrictions::newFromArray failed; one of the IP ranges must be invalid
         $status = Status::newGood();
         foreach (explode(PHP_EOL, $value) as $range) {
             if (!\IP::isIPAddress($range)) {
                 $status->fatal('restrictionsfield-badip', $range);
             }
         }
         if ($status->isOK()) {
             $status->fatal('unknown-error');
         }
         return $status->getMessage()->parse();
     }
     if (isset($this->mValidationCallback)) {
         return call_user_func($this->mValidationCallback, $value, $alldata, $this->mParent);
     }
     return true;
 }
Пример #2
0
 /**
  * Save the BotPassword to the database
  * @param string $operation 'update' or 'insert'
  * @param Password|null $password Password to set.
  * @return bool Success
  */
 public function save($operation, Password $password = null)
 {
     $conds = array('bp_user' => $this->centralId, 'bp_app_id' => $this->appId);
     $fields = array('bp_token' => MWCryptRand::generateHex(User::TOKEN_LENGTH), 'bp_restrictions' => $this->restrictions->toJson(), 'bp_grants' => FormatJson::encode($this->grants));
     if ($password !== null) {
         $fields['bp_password'] = $password->toString();
     } elseif ($operation === 'insert') {
         $fields['bp_password'] = PasswordFactory::newInvalidPassword()->toString();
     }
     $dbw = self::getDB(DB_MASTER);
     switch ($operation) {
         case 'insert':
             $dbw->insert('bot_passwords', $fields + $conds, __METHOD__, array('IGNORE'));
             break;
         case 'update':
             $dbw->update('bot_passwords', $fields, $conds, __METHOD__);
             break;
         default:
             return false;
     }
     $ok = (bool) $dbw->affectedRows();
     if ($ok) {
         $this->token = $dbw->selectField('bot_passwords', 'bp_token', $conds, __METHOD__);
         $this->isSaved = true;
     }
     return $ok;
 }
 public function testConstruct()
 {
     $field = new HTMLRestrictionsField(['fieldname' => 'restrictions']);
     $this->assertNotEmpty($field->getLabel(), 'has a default label');
     $this->assertNotEmpty($field->getHelpText(), 'has a default help text');
     $this->assertEquals(MWRestrictions::newDefault(), $field->getDefault(), 'defaults to the default MWRestrictions object');
     $field = new HTMLRestrictionsField(['fieldname' => 'restrictions', 'label' => 'foo', 'help' => 'bar', 'default' => 'baz']);
     $this->assertEquals('foo', $field->getLabel(), 'label can be customized');
     $this->assertEquals('bar', $field->getHelpText(), 'help text can be customized');
     $this->assertEquals('baz', $field->getDefault(), 'default can be customized');
 }
Пример #4
0
 /**
  * @covers MWRestrictions::newFromJson
  * @covers MWRestrictions::__construct
  * @covers MWRestrictions::loadFromArray
  * @covers MWRestrictions::toJson
  * @covers MWRestrictions::__toString
  * @dataProvider provideJson
  * @param string $json
  * @param array|InvalidArgumentException $expect
  */
 public function testJson($json, $expect)
 {
     if (is_array($expect)) {
         $ret = MWRestrictions::newFromJson($json);
         $this->assertInstanceOf('MWRestrictions', $ret);
         $this->assertSame($expect, $ret->toArray());
         $this->assertSame($json, $ret->toJson(false));
         $this->assertSame($json, (string) $ret);
         $this->assertSame(FormatJson::encode($expect, true, FormatJson::ALL_OK), $ret->toJson(true));
     } else {
         try {
             MWRestrictions::newFromJson($json);
             $this->fail('Expected exception not thrown');
         } catch (InvalidArgumentException $ex) {
             $this->assertTrue(true);
         }
     }
 }
Пример #5
0
 /**
  * @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'));
 }
Пример #6
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);
 }
Пример #7
0
 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);
     }
 }