use MediaWiki\Auth\AuthManager;
use MediaWiki\Auth\TemporaryPasswordAuthenticationRequest;
+use Psr\Log\LoggerAwareInterface;
+use Psr\Log\LoggerInterface;
+use MediaWiki\Logger\LoggerFactory;
/**
* Helper class for the password reset functionality shared by the web UI and the API.
* EmailNotificationSecondaryAuthenticationProvider (or something providing equivalent
* functionality) to be enabled.
*/
-class PasswordReset {
+class PasswordReset implements LoggerAwareInterface {
/** @var Config */
protected $config;
/** @var AuthManager */
protected $authManager;
+ /** @var LoggerInterface */
+ protected $logger;
+
/**
* In-process cache for isAllowed lookups, by username. Contains pairs of StatusValue objects
* (for false and true value of $displayPassword, respectively).
$this->config = $config;
$this->authManager = $authManager;
$this->permissionCache = new HashBagOStuff( [ 'maxKeys' => 1 ] );
+ $this->logger = LoggerFactory::getInstance( 'authentication' );
+ }
+
+ /**
+ * Set the logger instance to use.
+ *
+ * @param LoggerInterface $logger
+ * @since 1.29
+ */
+ public function setLogger( LoggerInterface $logger ) {
+ $this->logger = $logger;
}
/**
if ( $resetRoutes['username'] && $username ) {
$method = 'username';
$users = [ User::newFromName( $username ) ];
+ $email = null;
} elseif ( $resetRoutes['email'] && $email ) {
if ( !Sanitizer::validateEmail( $email ) ) {
return StatusValue::newFatal( 'passwordreset-invalidemail' );
}
$method = 'email';
$users = $this->getUsersByEmail( $email );
+ $username = null;
} else {
// The user didn't supply any data
return StatusValue::newFatal( 'passwordreset-nodata' );
'Capture' => $displayPassword ? '1' : null,
];
if ( !Hooks::run( 'SpecialPasswordResetOnSubmit', [ &$users, $data, &$error ] ) ) {
- return StatusValue::newFatal( wfMessage( $error ) );
+ return StatusValue::newFatal( Message::newFromSpecifier( $error ) );
}
if ( !$users ) {
}
}
+ $logContext = [
+ 'requestingIp' => $ip,
+ 'requestingUser' => $performingUser->getName(),
+ 'targetUsername' => $username,
+ 'targetEmail' => $email,
+ 'actualUser' => $firstUser->getName(),
+ 'capture' => $displayPassword,
+ ];
+
if ( !$result->isGood() ) {
+ $this->logger->info(
+ "{requestingUser} attempted password reset of {actualUser} but failed",
+ $logContext + [ 'errors' => $result->getErrors() ]
+ );
return $result;
}
}
}
+ if ( $displayPassword ) {
+ // The password capture thing is scary, so log
+ // at a higher warning level.
+ $this->logger->warning(
+ "{requestingUser} did password reset of {actualUser} with password capturing!",
+ $logContext
+ );
+ } else {
+ $this->logger->info(
+ "{requestingUser} did password reset of {actualUser}",
+ $logContext
+ );
+ }
+
return StatusValue::newGood( $passwords );
}
* @throws MWException On unexpected database errors
*/
protected function getUsersByEmail( $email ) {
- $res = wfGetDB( DB_SLAVE )->select(
+ $res = wfGetDB( DB_REPLICA )->select(
'user',
User::selectFields(),
[ 'user_email' => $email ],