* The wfUseMW function, soft-deprecated in 1.26, is now hard deprecated.
* All MagicWord static methods are now deprecated. Use the MagicWordFactory
methods instead.
+* PasswordFactory::init is deprecated. To get a password factory with the
+ standard configuration, use MediaWikiServices::getPasswordFactory.
=== Other changes in 1.32 ===
* (T198811) The following tables have had their UNIQUE indexes turned into
use ObjectCache;
use Parser;
use ParserCache;
+use PasswordFactory;
use ProxyLookup;
use SearchEngine;
use SearchEngineConfig;
return $this->getService( 'ContentLanguage' );
}
+ /**
+ * @since 1.32
+ * @return PasswordFactory
+ */
+ public function getPasswordFactory() {
+ return $this->getService( 'PasswordFactory' );
+ }
+
///////////////////////////////////////////////////////////////////////////
// NOTE: When adding a service getter here, don't forget to add a test
// case for it in MediaWikiServicesTest::provideGetters() and in
return Language::factory( $services->getMainConfig()->get( 'LanguageCode' ) );
},
+ 'PasswordFactory' => function ( MediaWikiServices $services ) {
+ $config = $services->getMainConfig();
+ return new PasswordFactory(
+ $config->get( 'PasswordConfig' ),
+ $config->get( 'PasswordDefault' )
+ );
+ },
+
///////////////////////////////////////////////////////////////////////////
// NOTE: When adding a service here, don't forget to add a getter function
// in the MediaWikiServices class. The convenience getter should just call
*/
protected function getPasswordFactory() {
if ( $this->passwordFactory === null ) {
- $this->passwordFactory = new PasswordFactory();
- $this->passwordFactory->init( $this->config );
+ $this->passwordFactory = new PasswordFactory(
+ $this->config->get( 'PasswordConfig' ),
+ $this->config->get( 'PasswordDefault' )
+ );
}
return $this->passwordFactory;
}
/**
* Mapping of password types to classes
+ *
* @var array
* @see PasswordFactory::register
* @see Setup.php
'' => [ 'type' => '', 'class' => InvalidPassword::class ],
];
+ /**
+ * Construct a new password factory.
+ * Most of the time you'll want to use MediaWikiServices::getPasswordFactory instead.
+ * @param array $config Mapping of password type => config
+ * @param string $default Default password type
+ * @see PasswordFactory::register
+ * @see PasswordFactory::setDefaultType
+ */
+ public function __construct( array $config = [], $default = '' ) {
+ foreach ( $config as $type => $options ) {
+ $this->register( $type, $options );
+ }
+
+ if ( $default !== '' ) {
+ $this->setDefaultType( $default );
+ }
+ }
+
/**
* Register a new type of password hash
*
- * @param string $type Unique type name for the hash
- * @param array $config Array of configuration options
+ * @param string $type Unique type name for the hash. Will be prefixed to the password hashes
+ * to identify what hashing method was used.
+ * @param array $config Array of configuration options. 'class' is required (the Password
+ * subclass name), everything else is passed to the constructor of that class.
*/
public function register( $type, array $config ) {
$config['type'] = $type;
/**
* Set the default password type
*
- * @throws InvalidArgumentException If the type is not registered
+ * This type will be used for creating new passwords when the type is not specified.
+ * Passwords of a different type will be considered outdated and in need of update.
+ *
* @param string $type Password hash type
+ * @throws InvalidArgumentException If the type is not registered
*/
public function setDefaultType( $type ) {
if ( !isset( $this->types[$type] ) ) {
}
/**
+ * @deprecated since 1.32 Initialize settings using the constructor
+ *
* Initialize the internal static variables using the global variables
*
* @param Config $config Configuration object to load data from
*/
use MediaWiki\Logger\LoggerFactory;
+use MediaWiki\MediaWikiServices;
/**
* Let users manage bot passwords
} else {
$linkRenderer = $this->getLinkRenderer();
- $passwordFactory = new PasswordFactory();
- $passwordFactory->init( $this->getConfig() );
+ $passwordFactory = MediaWikiServices::getInstance()->getPasswordFactory();
$dbr = BotPassword::getDB( DB_REPLICA );
$res = $dbr->select(
if ( $this->operation === 'insert' || !empty( $data['resetPassword'] ) ) {
$this->password = BotPassword::generatePassword( $this->getConfig() );
- $passwordFactory = new PasswordFactory();
- $passwordFactory->init( RequestContext::getMain()->getConfig() );
+ $passwordFactory = MediaWikiServices::getInstance()->getPasswordFactory();
$password = $passwordFactory->newFromPlaintext( $this->password );
} else {
$password = null;
return PasswordFactory::newInvalidPassword();
}
- $passwordFactory = new \PasswordFactory();
- $passwordFactory->init( \RequestContext::getMain()->getConfig() );
+ $passwordFactory = MediaWikiServices::getInstance()->getPasswordFactory();
try {
return $passwordFactory->newFromCiphertext( $password );
} catch ( PasswordError $ex ) {
<?php
-
-use MediaWiki\MediaWikiServices;
-
/**
* Maintenance script to wrap all old-style passwords in a layered type
*
* @file
* @ingroup Maintenance
*/
+
require_once __DIR__ . '/Maintenance.php';
+use MediaWiki\MediaWikiServices;
+
/**
* Maintenance script to wrap all passwords of a certain type in a specified layered
* type that wraps around the old type.
}
public function execute() {
- $passwordFactory = new PasswordFactory();
- $passwordFactory->init( RequestContext::getMain()->getConfig() );
+ $passwordFactory = MediaWikiServices::getInstance()->getPasswordFactory();
$typeInfo = $passwordFactory->getTypes();
$layeredType = $this->getOption( 'type' );
'ConfigRepository' => [ 'ConfigRepository', \MediaWiki\Config\ConfigRepository::class ],
'MagicWordFactory' => [ 'MagicWordFactory', MagicWordFactory::class ],
'ContentLanguage' => [ 'ContentLanguage', Language::class ],
+ 'PasswordFactory' => [ 'PasswordFactory', PasswordFactory::class ],
];
}
<?php
+use MediaWiki\MediaWikiServices;
+
/**
* Wraps the user object, so we can also retain full access to properties
* like password if we log in via the API.
throw new MWException( "Passed User has an ID but is not in the database?" );
}
- $passwordFactory = new PasswordFactory();
- $passwordFactory->init( RequestContext::getMain()->getConfig() );
+ $passwordFactory = MediaWikiServices::getInstance()->getPasswordFactory();
if ( !$passwordFactory->newFromCiphertext( $row->user_password )->equals( $password ) ) {
$passwordHash = $passwordFactory->newFromPlaintext( $password );
$dbw->update(
<?php
+use MediaWiki\MediaWikiServices;
use Wikimedia\TestingAccessWrapper;
/**
$this->assertNotEquals( 0, $centralId, 'sanity check' );
$password = 'ngfhmjm64hv0854493hsj5nncjud2clk';
- $passwordFactory = new PasswordFactory();
- $passwordFactory->init( RequestContext::getMain()->getConfig() );
+ $passwordFactory = MediaWikiServices::getInstance()->getPasswordFactory();
// A is unsalted MD5 (thus fast) ... we don't care about security here, this is test only
$passwordHash = $passwordFactory->newFromPlaintext( $password );
$user = self::getMutableTestUser()->getUser();
$dbw = wfGetDB( DB_MASTER );
-
- $passwordFactory = new \PasswordFactory();
- $passwordFactory->init( \RequestContext::getMain()->getConfig() );
+ $config = MediaWikiServices::getInstance()->getMainConfig();
// A is unsalted MD5 (thus fast) ... we don't care about security here, this is test only
- $passwordFactory->setDefaultType( 'A' );
+ $passwordFactory = new \PasswordFactory( $config->get( 'PasswordConfig' ), 'A' );
+
$pwhash = $passwordFactory->newFromPlaintext( 'password' )->toString();
$provider = $this->getProvider();
* @covers PasswordFactory
*/
class PasswordFactoryTest extends MediaWikiTestCase {
+ public function testConstruct() {
+ $pf = new PasswordFactory();
+ $this->assertEquals( [ '' ], array_keys( $pf->getTypes() ) );
+ $this->assertEquals( '', $pf->getDefaultType() );
+
+ $pf = new PasswordFactory( [
+ 'foo' => [ 'class' => 'FooPassword' ],
+ 'bar' => [ 'class' => 'BarPassword', 'baz' => 'boom' ],
+ ], 'foo' );
+ $this->assertEquals( [ '', 'foo', 'bar' ], array_keys( $pf->getTypes() ) );
+ $this->assertArraySubset( [ 'class' => 'BarPassword', 'baz' => 'boom' ], $pf->getTypes()['bar'] );
+ $this->assertEquals( 'foo', $pf->getDefaultType() );
+ }
+
public function testRegister() {
$pf = new PasswordFactory;
$pf->register( 'foo', [ 'class' => InvalidPassword::class ] );
namespace MediaWiki\Session;
+use MediaWiki\MediaWikiServices;
use Psr\Log\LogLevel;
use MediaWikiTestCase;
use Wikimedia\TestingAccessWrapper;
}
public function addDBDataOnce() {
- $passwordFactory = new \PasswordFactory();
- $passwordFactory->init( \RequestContext::getMain()->getConfig() );
+ $passwordFactory = MediaWikiServices::getInstance()->getPasswordFactory();
$passwordHash = $passwordFactory->newFromPlaintext( 'foobaz' );
$sysop = static::getTestSysop()->getUser();
<?php
+use MediaWiki\MediaWikiServices;
use MediaWiki\Session\SessionManager;
use Wikimedia\ScopedCallback;
use Wikimedia\TestingAccessWrapper;
}
public function addDBData() {
- $passwordFactory = new \PasswordFactory();
- $passwordFactory->init( \RequestContext::getMain()->getConfig() );
+ $passwordFactory = MediaWikiServices::getInstance()->getPasswordFactory();
$passwordHash = $passwordFactory->newFromPlaintext( 'foobaz' );
$dbw = wfGetDB( DB_MASTER );
* @param string|null $password
*/
public function testSave( $password ) {
- $passwordFactory = new \PasswordFactory();
- $passwordFactory->init( \RequestContext::getMain()->getConfig() );
+ $passwordFactory = MediaWikiServices::getInstance()->getPasswordFactory();
$bp = BotPassword::newUnsaved( [
'centralId' => 42,