42 private $loadBalancer;
52 parent::__construct( $params );
53 $this->loginOnly = !empty( $params[
'loginOnly'] );
54 $this->loadBalancer = $loadBalancer;
67 if ( $expiration ===
null || (
int)$expiration >= $now ) {
72 if ( (
int)$expiration + $grace < $now ) {
93 if ( $req->username ===
null || $req->password ===
null ) {
97 $username = $this->userNameUtils->getCanonical(
98 $req->username, UserRigorOptions::RIGOR_USABLE );
99 if ( $username ===
false ) {
103 $row = $this->loadBalancer->getConnection(
DB_REPLICA )->newSelectQueryBuilder()
104 ->select( [
'user_id',
'user_password',
'user_password_expires' ] )
106 ->where( [
'user_name' => $username ] )
107 ->caller( __METHOD__ )->fetchRow();
115 $oldRow = clone $row;
118 if ( preg_match(
'/^[0-9a-f]{32}$/', $row->user_password ) ) {
119 $row->user_password =
":B:{$row->user_id}:{$row->user_password}";
123 if ( !$status->isOK() ) {
128 $pwhash = $this->
getPassword( $row->user_password );
129 if ( !$pwhash->verify( $req->password ) ) {
133 $cp1252Password = iconv(
'UTF-8',
'WINDOWS-1252//TRANSLIT', $req->password );
134 if ( $cp1252Password === $req->password || !$pwhash->verify( $cp1252Password ) ) {
147 $dbw = $this->loadBalancer->getConnectionRef(
DB_PRIMARY );
150 [
'user_password' => $newHash->toString() ],
152 'user_id' => $oldRow->user_id,
153 'user_password' => $oldRow->user_password
167 $username = $this->userNameUtils->getCanonical(
168 $username, UserRigorOptions::RIGOR_USABLE );
169 if ( $username ===
false ) {
173 $row = $this->loadBalancer->getConnection(
DB_REPLICA )->newSelectQueryBuilder()
174 ->select( [
'user_password' ] )
176 ->where( [
'user_name' => $username ] )
177 ->caller( __METHOD__ )->fetchRow();
184 if ( preg_match(
'/^[0-9a-f]{32}$/', $row->user_password ) ) {
188 return !$this->
getPassword( $row->user_password ) instanceof \InvalidPassword;
192 $username = $this->userNameUtils->getCanonical(
193 $username, UserRigorOptions::RIGOR_USABLE );
194 if ( $username ===
false ) {
199 return (
bool)$this->loadBalancer->getConnection( $db )->newSelectQueryBuilder()
200 ->select( [
'user_id' ] )
202 ->where( [
'user_name' => $username ] )
203 ->options( $options )
204 ->caller( __METHOD__ )->fetchField();
212 if ( $this->loginOnly ) {
213 return \StatusValue::newGood(
'ignored' );
216 if ( get_class( $req ) === PasswordAuthenticationRequest::class ) {
218 return \StatusValue::newGood();
221 $username = $this->userNameUtils->getCanonical( $req->username,
222 UserRigorOptions::RIGOR_USABLE );
223 if ( $username !==
false ) {
224 $row = $this->loadBalancer->getConnection(
DB_PRIMARY )->newSelectQueryBuilder()
225 ->select( [
'user_id' ] )
227 ->where( [
'user_name' => $username ] )
228 ->caller( __METHOD__ )->fetchRow();
231 if ( $req->password !==
null ) {
232 if ( $req->password !== $req->retype ) {
233 $sv->fatal(
'badretype' );
243 return \StatusValue::newGood(
'ignored' );
247 $username = $req->username !==
null ?
248 $this->userNameUtils->getCanonical( $req->username, UserRigorOptions::RIGOR_USABLE )
250 if ( $username ===
false ) {
256 if ( get_class( $req ) === PasswordAuthenticationRequest::class ) {
257 if ( $this->loginOnly ) {
267 $dbw = $this->loadBalancer->getConnectionRef(
DB_PRIMARY );
271 'user_password' => $pwhash->toString(),
273 'user_password_expires' => $dbw->timestampOrNull( $expiry ),
275 [
'user_name' => $username ],
289 if ( !$this->loginOnly && $req && $req->username !==
null && $req->password !==
null ) {
290 if ( $req->password !== $req->retype ) {
291 $ret->fatal(
'badretype' );
303 throw new \BadMethodCallException(
'Shouldn\'t call this when accountCreationType() is NONE' );
307 if ( $req && $req->username !==
null && $req->password !==
null ) {
310 if ( $req->username !== $user->getName() ) {
312 $req->username = $user->getName();
315 $ret->createRequest = $req;
323 throw new \BadMethodCallException(
'Shouldn\'t call this when accountCreationType() is NONE' );
wfTimestampOrNull( $outputtype=TS_UNIX, $ts=null)
Return a formatted timestamp, or null if input is null.
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
static getDBOptions( $bitfield)
Get an appropriate DB index, options, and fallback DB index for a query.
static addCallableUpdate( $callable, $stage=self::POSTSEND, $dbw=null)
Add an update to the pending update queue that invokes the specified callback when run.
A class containing constants representing the names of configuration variables.
const LegacyEncoding
Name constant for the LegacyEncoding setting, for use with Config::get()
const PasswordExpireGrace
Name constant for the PasswordExpireGrace setting, for use with Config::get()
static newFatal( $message,... $parameters)
Factory function for fatal errors.
static newGood( $value=null)
Factory function for good results.
The User object encapsulates all of the user-specific settings (user_id, name, rights,...