$wgGroupPermissions['sysop']['blockemail'] = true;
* ApiQueryBase::showHiddenUsersAddBlockInfo() is deprecated. Use
ApiQueryBlockInfoTrait instead.
+* PasswordReset is now a service, its direct instantiation is deprecated.
=== Other changes in 1.34 ===
* Added option to specify "Various authors" as author in extension credits using
* …
== Compatibility ==
-MediaWiki 1.34 requires PHP 7.2.0 or later. Although HHVM 3.18.5 or later is
-supported, it is generally advised to use PHP 7.2.0 or later for long term
-support. It also requires the following PHP extensions:
+MediaWiki 1.34 requires PHP 7.2.0 or later, and the following PHP extensions:
* ctype
* dom
"pear/mail": "1.4.1",
"pear/mail_mime": "1.10.2",
"pear/net_smtp": "1.8.1",
- "php": ">=5.6.99",
+ "php": ">=7.0.0",
"psr/container": "1.0.0",
"psr/log": "1.0.2",
"wikimedia/assert": "0.2.2",
use MediaWiki\FileBackend\FSFile\TempFSFileFactory;
use MediaWiki\FileBackend\LockManager\LockManagerGroupFactory;
use MediaWiki\Http\HttpRequestFactory;
+use PasswordReset;
use Wikimedia\Message\IMessageFormatterFactory;
use MediaWiki\Page\MovePageFactory;
use MediaWiki\Permissions\PermissionManager;
return $this->getService( 'PasswordFactory' );
}
+ /**
+ * @since 1.34
+ * @return PasswordReset
+ */
+ public function getPasswordReset() : PasswordReset {
+ return $this->getService( 'PasswordReset' );
+ }
+
/**
* @since 1.32
* @return StatsdDataFactoryInterface
/**
* Return the version of the installed PHP implementation.
*
- * @param string|false $impl By default, the function returns the info of the currently installed
- * PHP implementation. Using this parameter the caller can decide, what version info will be
- * returned. Valid values: HHVM, PHP
+ * TODO: Deprecate/remove this workaround now that HHVM isn't supported.
+ *
* @return array An array of information about the PHP implementation, containing:
* - 'version': The version of the PHP implementation (specific to the implementation, not
* the version of the implemented PHP version)
* - 'upgradeURL': The URL to the website of the implementation that contains
* upgrade/installation instructions.
*/
- function getPHPInfo( $impl = false ) {
- if (
- ( defined( 'HHVM_VERSION' ) && $impl !== 'PHP' ) ||
- $impl === 'HHVM'
- ) {
- return array(
- 'implementation' => 'HHVM',
- 'version' => defined( 'HHVM_VERSION' ) ? HHVM_VERSION : 'undefined',
- 'vendor' => 'Facebook',
- 'upstreamSupported' => '3.18.5',
- 'minSupported' => '3.18.5',
- 'upgradeURL' => 'https://docs.hhvm.com/hhvm/installation/introduction',
- );
- }
+ function getPHPInfo() {
return array(
'implementation' => 'PHP',
'version' => PHP_VERSION,
function checkRequiredPHPVersion() {
$phpInfo = $this->getPHPInfo();
$minimumVersion = $phpInfo['minSupported'];
- $otherInfo = $this->getPHPInfo( $phpInfo['implementation'] === 'HHVM' ? 'PHP' : 'HHVM' );
if ( version_compare( $phpInfo['version'], $minimumVersion ) < 0 ) {
$shortText = "MediaWiki $this->mwVersion requires at least {$phpInfo['implementation']}"
- . " version $minimumVersion or {$otherInfo['implementation']} version "
- . "{$otherInfo['minSupported']}, you are using {$phpInfo['implementation']} "
+ . " version $minimumVersion, you are using {$phpInfo['implementation']} "
. "{$phpInfo['version']}.";
$longText = "Error: You might be using an older {$phpInfo['implementation']} version "
. "({$phpInfo['implementation']} {$phpInfo['version']}). \n"
. "MediaWiki $this->mwVersion needs {$phpInfo['implementation']}"
- . " $minimumVersion or higher or {$otherInfo['implementation']} version "
- . "{$otherInfo['minSupported']}.\n\nCheck if you have a"
+ . " $minimumVersion or higher.\n\nCheck if you have a"
. " newer PHP executable with a different name.\n\n";
// phpcs:disable Generic.Files.LineLength
);
},
+ 'PasswordReset' => function ( MediaWikiServices $services ) : PasswordReset {
+ $options = new ServiceOptions( PasswordReset::$constructorOptions, $services->getMainConfig() );
+ return new PasswordReset(
+ $options,
+ AuthManager::singleton(),
+ $services->getPermissionManager(),
+ $services->getDBLoadBalancer(),
+ LoggerFactory::getInstance( 'authentication' )
+ );
+ },
+
'PerDbNameStatsdDataFactory' =>
function ( MediaWikiServices $services ) : StatsdDataFactoryInterface {
$config = $services->getMainConfig();
* @file
*/
-use MediaWiki\Auth\AuthManager;
use MediaWiki\MediaWikiServices;
/**
$this->requireOnlyOneParameter( $params, 'user', 'email' );
- $passwordReset = new PasswordReset(
- $this->getConfig(),
- AuthManager::singleton(),
- MediaWikiServices::getInstance()->getPermissionManager()
- );
+ $passwordReset = MediaWikiServices::getInstance()->getPasswordReset();
$status = $passwordReset->isAllowed( $this->getUser() );
if ( !$status->isOK() ) {
}
}
if ( !$this->isSignup() && $this->showExtraInformation() ) {
- $passwordReset = new PasswordReset(
- $this->getConfig(),
- AuthManager::singleton(),
- MediaWikiServices::getInstance()->getPermissionManager()
- );
+ $passwordReset = MediaWikiServices::getInstance()->getPasswordReset();
if ( $passwordReset->isAllowed( $this->getUser() )->isGood() ) {
$fieldDefinitions['passwordReset'] = [
'type' => 'info',
* @ingroup SpecialPage
*/
-use MediaWiki\Auth\AuthManager;
use MediaWiki\MediaWikiServices;
/**
private function getPasswordReset() {
if ( $this->passwordReset === null ) {
- $this->passwordReset = new PasswordReset(
- $this->getConfig(),
- AuthManager::singleton(),
- MediaWikiServices::getInstance()->getPermissionManager()
- );
+ $this->passwordReset = MediaWikiServices::getInstance()->getPasswordReset();
}
return $this->passwordReset;
}
use MediaWiki\Auth\AuthManager;
use MediaWiki\Auth\TemporaryPasswordAuthenticationRequest;
+use MediaWiki\Config\ServiceOptions;
+use MediaWiki\Logger\LoggerFactory;
+use MediaWiki\MediaWikiServices;
use MediaWiki\Permissions\PermissionManager;
use Psr\Log\LoggerAwareInterface;
+use Psr\Log\LoggerAwareTrait;
use Psr\Log\LoggerInterface;
-use MediaWiki\Logger\LoggerFactory;
+use Wikimedia\Rdbms\ILoadBalancer;
/**
* Helper class for the password reset functionality shared by the web UI and the API.
* functionality) to be enabled.
*/
class PasswordReset implements LoggerAwareInterface {
- /** @var Config */
+ use LoggerAwareTrait;
+
+ /** @var ServiceOptions|Config */
protected $config;
/** @var AuthManager */
protected $authManager;
/** @var PermissionManager */
- private $permissionManager;
+ protected $permissionManager;
- /** @var LoggerInterface */
- protected $logger;
+ /** @var ILoadBalancer */
+ protected $loadBalancer;
/**
* In-process cache for isAllowed lookups, by username.
*/
private $permissionCache;
+ public static $constructorOptions = [
+ 'EnableEmail',
+ 'PasswordResetRoutes',
+ ];
+
+ /**
+ * This class is managed by MediaWikiServices, don't instantiate directly.
+ *
+ * @param ServiceOptions|Config $config
+ * @param AuthManager $authManager
+ * @param PermissionManager $permissionManager
+ * @param ILoadBalancer|null $loadBalancer
+ * @param LoggerInterface|null $logger
+ */
public function __construct(
- Config $config,
+ $config,
AuthManager $authManager,
- PermissionManager $permissionManager
+ PermissionManager $permissionManager,
+ ILoadBalancer $loadBalancer = null,
+ LoggerInterface $logger = null
) {
$this->config = $config;
$this->authManager = $authManager;
$this->permissionManager = $permissionManager;
- $this->permissionCache = new MapCacheLRU( 1 );
- $this->logger = LoggerFactory::getInstance( 'authentication' );
- }
- /**
- * Set the logger instance to use.
- *
- * @param LoggerInterface $logger
- * @since 1.29
- */
- public function setLogger( LoggerInterface $logger ) {
+ if ( !$loadBalancer ) {
+ wfDeprecated( 'Not passing LoadBalancer to ' . __METHOD__, '1.34' );
+ $loadBalancer = MediaWikiServices::getInstance()->getDBLoadBalancer();
+ }
+ $this->loadBalancer = $loadBalancer;
+
+ if ( !$logger ) {
+ wfDeprecated( 'Not passing LoggerInterface to ' . __METHOD__, '1.34' );
+ $logger = LoggerFactory::getInstance( 'authentication' );
+ }
$this->logger = $logger;
+
+ $this->permissionCache = new MapCacheLRU( 1 );
}
/**
*/
protected function getUsersByEmail( $email ) {
$userQuery = User::getQueryInfo();
- $res = wfGetDB( DB_REPLICA )->select(
+ $res = $this->loadBalancer->getConnectionRef( DB_REPLICA )->select(
$userQuery['tables'],
$userQuery['fields'],
[ 'user_email' => $email ],
use MediaWiki\Block\DatabaseBlock;
use MediaWiki\Block\CompositeBlock;
use MediaWiki\Block\SystemBlock;
+use MediaWiki\Config\ServiceOptions;
use MediaWiki\Permissions\PermissionManager;
+use Psr\Log\NullLogger;
+use Wikimedia\Rdbms\ILoadBalancer;
/**
* @covers PasswordReset
* @group Database
*/
class PasswordResetTest extends MediaWikiTestCase {
+ private function makeConfig( $enableEmail, array $passwordResetRoutes = [] ) {
+ $hash = new HashConfig( [
+ 'EnableEmail' => $enableEmail,
+ 'PasswordResetRoutes' => $passwordResetRoutes,
+ ] );
+
+ return new ServiceOptions( PasswordReset::$constructorOptions, $hash );
+ }
+
/**
* @dataProvider provideIsAllowed
*/
public function testIsAllowed( $passwordResetRoutes, $enableEmail,
$allowsAuthenticationDataChange, $canEditPrivate, $block, $globalBlock, $isAllowed
) {
- $config = new HashConfig( [
- 'PasswordResetRoutes' => $passwordResetRoutes,
- 'EnableEmail' => $enableEmail,
- ] );
+ $config = $this->makeConfig( $enableEmail, $passwordResetRoutes );
$authManager = $this->getMockBuilder( AuthManager::class )->disableOriginalConstructor()
->getMock();
->with( $user, 'editmyprivateinfo' )
->willReturn( $canEditPrivate );
+ $loadBalancer = $this->getMockBuilder( ILoadBalancer::class )->getMock();
+
$passwordReset = new PasswordReset(
$config,
$authManager,
- $permissionManager
+ $permissionManager,
+ $loadBalancer,
+ new NullLogger()
);
$this->assertSame( $isAllowed, $passwordReset->isAllowed( $user )->isGood() );
}
public function testExecute_email() {
- $config = new HashConfig( [
- 'PasswordResetRoutes' => [ 'username' => true, 'email' => true ],
- 'EnableEmail' => true,
- ] );
+ $config = $this->makeConfig( true, [ 'username' => true, 'email' => true ] );
// Unregister the hooks for proper unit testing
$this->mergeMwGlobalArrayValue( 'wgHooks', [
->willReturn( Status::newGood() );
$authManager->expects( $this->exactly( 2 ) )->method( 'changeAuthenticationData' );
+ $permissionManager = $this->getMockBuilder( PermissionManager::class )
+ ->disableOriginalConstructor()
+ ->getMock();
+ $permissionManager->method( 'userHasRight' )->willReturn( true );
+
+ $loadBalancer = $this->getMockBuilder( ILoadBalancer::class )
+ ->getMock();
+
$request = new FauxRequest();
$request->setIP( '1.2.3.4' );
$performingUser = $this->getMockBuilder( User::class )->getMock();
$targetUser2->expects( $this->any() )->method( 'getEmail' )->willReturn( 'foo@bar.baz' );
$passwordReset = $this->getMockBuilder( PasswordReset::class )
- ->setConstructorArgs( [ $config, $authManager, $permissionManager ] )
->setMethods( [ 'getUsersByEmail' ] )
+ ->setConstructorArgs( [
+ $config,
+ $authManager,
+ $permissionManager,
+ $loadBalancer,
+ new NullLogger()
+ ] )
->getMock();
$passwordReset->expects( $this->any() )->method( 'getUsersByEmail' )->with( 'foo@bar.baz' )
->willReturn( [ $targetUser1, $targetUser2 ] );