blockDisablesLogin = (bool)$params['blockDisablesLogin']; } } /** @inheritDoc */ protected function postInitSetup() { if ( $this->blockDisablesLogin === null ) { $this->blockDisablesLogin = $this->config->get( MainConfigNames::BlockDisablesLogin ); } } /** @inheritDoc */ public function getAuthenticationRequests( $action, array $options ) { return []; } /** @inheritDoc */ public function beginSecondaryAuthentication( $user, array $reqs ) { if ( !$this->blockDisablesLogin ) { return AuthenticationResponse::newAbstain(); } $block = $user->getBlock(); // Ignore IP blocks and partial blocks, $wgBlockDisablesLogin was meant for // blocks banning specific users. if ( $block && $block->isSitewide() && $block->isBlocking( $user ) ) { return AuthenticationResponse::newFail( new \Message( 'login-userblocked', [ $user->getName() ] ) ); } else { return AuthenticationResponse::newPass(); } } /** @inheritDoc */ public function beginSecondaryAccountCreation( $user, $creator, array $reqs ) { return AuthenticationResponse::newAbstain(); } /** @inheritDoc */ public function testUserForCreation( $user, $autocreate, array $options = [] ) { // isBlockedFromCreateAccount() does not return non-accountcreation blocks, but we need them // in the $wgBlockDisablesLogin case; getBlock() is unreliable for IP blocks. So we need both. $blocks = [ 'local-createaccount' => $user->isBlockedFromCreateAccount(), 'local' => $user->getBlock(), ]; foreach ( $blocks as $type => $block ) { /** @var AbstractBlock $block */ if ( $block && $block->isSitewide() // This method is for checking a given account/username, not the current user, so // ignore IP blocks; they will be checked elsewhere via authorizeCreateAccount(). // FIXME: special-case autocreation which doesn't do that check. Should it? && ( $block->isBlocking( $user ) || $autocreate ) && ( // Should blocks that prevent account creation also prevent autocreation? // We'll go with yes here. $block->isCreateAccountBlocked() // A successful autocreation means the user is logged in, so we must make sure to // honor $wgBlockDisablesLogin. If it's enabled, sitewide blocks are expected to // prevent login regardless of their flags. || ( $autocreate && $this->blockDisablesLogin ) ) // FIXME: ideally on autocreation we'd figure out if the user has the ipblock-exempt // or globalblock-exempt right via some central authorization system like // CentralAuth global groups. But at this point the local account doesn't exist // yet so there is no way to do that. There should probably be some separate hook // to fetch user rights for a central user. // FIXME: T249444: there should probably be a way to force autocreation through blocks ) { $language = \RequestContext::getMain()->getUser()->isSafeToLoad() ? \RequestContext::getMain()->getLanguage() : MediaWikiServices::getInstance()->getContentLanguage(); // Block::getPermissionsError() is deprecated but actually works for global blocks, // unlike its replacement. $context = new DerivativeContext( RequestContext::getMain() ); $context->setLanguage( $language ); $context->setUser( $user ); return StatusValue::newFatal( ...$block->getPermissionsError( $context ) ); } } return StatusValue::newGood(); } }