Go to the documentation of this file.
83 $this->centralId = (int)$row->bp_user;
84 $this->appId = $row->bp_app_id;
85 $this->token = $row->bp_token;
95 public static function getDB( $db ) {
98 $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
135 $row = $db->selectRow(
137 [
'bp_user',
'bp_app_id',
'bp_token',
'bp_restrictions',
'bp_grants' ],
142 return $row ?
new self( $row,
true,
$flags ) :
null;
158 if ( isset( $data[
'user'] ) && ( !$data[
'user'] instanceof
User ) ) {
164 'bp_app_id' => isset( $data[
'appId'] ) ? trim( $data[
'appId'] ) :
'',
165 'bp_token' =>
'**unsaved**',
167 'bp_grants' => $data[
'grants'] ?? [],
171 $row->bp_app_id ===
'' ||
172 strlen( $row->bp_app_id ) > self::APPID_MAXLENGTH ||
174 !is_array( $row->bp_grants )
179 $row->bp_restrictions = $row->bp_restrictions->toJson();
182 if ( isset( $data[
'user'] ) ) {
187 } elseif ( isset( $data[
'username'] ) ) {
191 } elseif ( isset( $data[
'centralId'] ) ) {
192 $row->bp_user = $data[
'centralId'];
194 if ( !$row->bp_user ) {
198 return new self( $row,
false,
$flags );
260 $password = $db->selectField(
263 [
'bp_user' => $this->centralId,
'bp_app_id' => $this->appId ],
267 if ( $password ===
false ) {
271 $passwordFactory = MediaWikiServices::getInstance()->getPasswordFactory();
273 return $passwordFactory->newFromCiphertext( $password );
297 if ( $operation !==
'insert' && $operation !==
'update' ) {
298 throw new UnexpectedValueException(
299 "Expected 'insert' or 'update'; got '{$operation}'."
312 if ( strlen(
$restrictions ) > self::RESTRICTIONS_MAXLENGTH ) {
313 $res->fatal(
'botpasswords-toolong-restrictions' );
318 if ( strlen(
$grants ) > self::GRANTS_MAXLENGTH ) {
319 $res->fatal(
'botpasswords-toolong-grants' );
322 if ( !
$res->isGood() ) {
332 if ( $password !==
null ) {
333 $fields[
'bp_password'] = $password->toString();
334 } elseif ( $operation ===
'insert' ) {
340 if ( $operation ===
'insert' ) {
341 $dbw->insert(
'bot_passwords', $fields + $conds, __METHOD__, [
'IGNORE' ] );
344 $dbw->update(
'bot_passwords', $fields, $conds, __METHOD__ );
347 $ok = (bool)$dbw->affectedRows();
349 $this->token = $dbw->selectField(
'bot_passwords',
'bp_token', $conds, __METHOD__ );
356 return Status::newFatal(
"botpasswords-{$operation}-failed", $this->appId );
363 public function delete() {
368 'bp_user' => $this->centralId,
369 'bp_app_id' => $this->appId,
373 $ok = (bool)$dbw->affectedRows();
375 $this->token =
'**unsaved**';
415 return (
bool)$dbw->affectedRows();
451 return (
bool)$dbw->affectedRows();
461 max( self::PASSWORD_MINLENGTH, $config->get(
'MinimalPasswordLength' ) ) );
476 if ( strlen( $password ) >= self::PASSWORD_MINLENGTH && strpos( $username, $sep ) !==
false ) {
478 if ( preg_match(
'/^[0-9a-w]{' . self::PASSWORD_MINLENGTH .
',}$/', $password ) ) {
479 return [ $username, $password ];
481 } elseif ( strlen( $password ) > self::PASSWORD_MINLENGTH && strpos( $password, $sep ) !==
false ) {
482 $segments = explode( $sep, $password );
483 $password = array_pop( $segments );
484 $appId = implode( $sep, $segments );
485 if ( preg_match(
'/^[0-9a-w]{' . self::PASSWORD_MINLENGTH .
',}$/', $password ) ) {
486 return [ $username . $sep .
$appId, $password ];
506 $provider = SessionManager::singleton()->getProvider( BotPasswordSessionProvider::class );
513 if ( strpos( $username, $sep ) ===
false ) {
516 list( $name,
$appId ) = explode( $sep, $username, 2 );
520 if ( !$user || $user->isAnon() ) {
524 if ( $user->isLocked() ) {
531 'type' =>
'botpassword',
534 $result = $throttle->increase( $user->getName(), $request->
getIP(), __METHOD__ );
536 $msg =
wfMessage(
'login-throttled' )->durationParams( $result[
'wait'] );
549 $status = $bp->getRestrictions()->check( $request );
550 if ( !$status->isOK() ) {
555 $passwordObj = $bp->getPassword();
560 if ( !$passwordObj->verify( $password ) ) {
566 $throttle->clear( $user->getName(), $request->
getIP() );
570 Status::newGood( $provider->newSessionForRequest( $user, $bp, $request ) ) );
586 if ( $user instanceof
User ) {
587 $name = $user->getName();
596 if ( $status->
isGood() ) {
597 $response = AuthenticationResponse::newPass( $name );
599 $response = AuthenticationResponse::newFail( $status->
getMessage() );
601 Hooks::runner()->onAuthManagerLoginAuthenticateAudit( $response, $user, $name, $extraData );
A class to check request restrictions expressed as a JSON object.
static newFatal( $message,... $parameters)
Factory function for fatal errors.
getUserCentralId()
Get the central user ID.
string bool $wgBotPasswordsDatabase
Database name for the bot_passwords table.
static getLocalClusterInstance()
Get the main cluster-local cache object.
static canonicalizeLoginData( $username, $password)
There are two ways to login with a bot password: "username@appId", "password" and "username",...
Utility class for bot passwords.
static getSeparator()
Get the separator for combined user name + app ID.
getMessage( $shortContext=false, $longContext=false, $lang=null)
Get a bullet list of the errors as a Message object.
string bool $wgBotPasswordsCluster
Cluster for the bot_passwords table If false, the normal cluster will be used.
static generatePassword( $config)
Returns a (raw, unhashed) random password string.
Show an error when any operation involving passwords fails to run.
isInvalid()
Whether the password is currently invalid.
static newFromName( $name, $validate='valid')
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
static getDBOptions( $bitfield)
Get an appropriate DB index, options, and fallback DB index for a query.
Represents an invalid password hash.
static getDB( $db)
Get a database connection for the bot passwords database.
static invalidateAllPasswordsForCentralId( $centralId)
Invalidate all passwords for a user, by central ID.
Interface for database access objects.
__construct( $row, $isSaved, $flags=self::READ_NORMAL)
save( $operation, Password $password=null)
Save the BotPassword to the database.
Generic operation result class Has warning/error list, boolean status and arbitrary value.
isGood()
Returns whether the operation completed and didn't have any error or warnings.
isSaved()
Indicate whether this is known to be saved.
static newUnsaved(array $data, $flags=self::READ_NORMAL)
Create an unsaved BotPassword.
toJson( $pretty=false)
Return the restrictions as a JSON string.
const RESTRICTIONS_MAXLENGTH
Maximum length of the json representation of restrictions.
$wgUserrightsInterwikiDelimiter
Character used as a delimiter when testing for interwiki userrights (In Special:UserRights,...
const PASSWORD_MINLENGTH
Minimum length for a bot password.
const TOKEN_LENGTH
Number of characters required for the user_token field.
static newFromUser(User $user, $appId, $flags=self::READ_NORMAL)
Load a BotPassword from the database.
static generateRandomPasswordString(int $minLength=10)
Generate a random string suitable for a password.
static newGood( $value=null)
Factory function for good results.
static invalidateAllPasswordsForUser( $username)
Invalidate all passwords for a user, by name.
static runner()
Get a HookRunner instance for calling hooks using the new interfaces.
$wgPasswordAttemptThrottle
Limit password attempts to X attempts per Y seconds per IP per account.
static generateHex( $chars)
Generate a run of cryptographically random data and return it in hexadecimal string format.
static newFromCentralId( $centralId, $appId, $flags=self::READ_NORMAL)
Load a BotPassword from the database.
static login( $username, $password, WebRequest $request)
Try to log the user in.
The WebRequest class encapsulates getting at data passed in the URL or via a POSTed form stripping il...
getIP()
Work out the IP address based on various globals For trusted proxies, use the XFF client IP (first of...
static newInvalidPassword()
Create an InvalidPassword.
static loginHook( $user, $bp, Status $status)
Call AuthManagerLoginAuthenticateAudit.
static newFromJson( $json)
const GRANTS_MAXLENGTH
Maximum length of the json representation of grants.
static removeAllPasswordsForUser( $username)
Remove all passwords for a user, by name.
bool $wgEnableBotPasswords
Whether to enable bot passwords.
Represents a password hash for use in authentication.
static factory( $providerId=null)
Fetch a CentralIdLookup.
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
static removeAllPasswordsForCentralId( $centralId)
Remove all passwords for a user, by central ID.
MWRestrictions $restrictions