use MediaWiki\Auth\AuthenticationRequest;
use MediaWiki\User\UserIdentity;
use MediaWiki\Logger\LoggerFactory;
+use Wikimedia\Assert\Assert;
use Wikimedia\IPSet;
use Wikimedia\ScopedCallback;
use Wikimedia\Rdbms\Database;
*/
public function trackBlockWithCookie() {
$block = $this->getBlock();
- if ( $block && $this->getRequest()->getCookie( 'BlockID' ) === null ) {
- $config = RequestContext::getMain()->getConfig();
- $shouldSetCookie = false;
- if ( $this->isAnon() && $config->get( 'CookieSetOnIpBlock' ) ) {
- // If user is logged-out, set a cookie to track the Block
- $shouldSetCookie = in_array( $block->getType(), [
- Block::TYPE_IP, Block::TYPE_RANGE
- ] );
- if ( $shouldSetCookie ) {
- $block->setCookie( $this->getRequest()->response() );
- }
- } elseif ( $this->isLoggedIn() && $config->get( 'CookieSetOnAutoblock' ) ) {
- $shouldSetCookie = $block->getType() === Block::TYPE_USER && $block->isAutoblocking();
- if ( $shouldSetCookie ) {
- $block->setCookie( $this->getRequest()->response() );
- }
- }
+ if ( $block && $this->getRequest()->getCookie( 'BlockID' ) === null
+ && $block->shouldTrackWithCookie( $this->isAnon() )
+ ) {
+ $block->setCookie( $this->getRequest()->response() );
}
}
}
}
+ /** @var array|null */
+ private static $defOpt = null;
+ /** @var string|null */
+ private static $defOptLang = null;
+
+ /**
+ * Reset the process cache of default user options. This is only necessary
+ * if the wiki configuration has changed since defaults were calculated,
+ * and as such should only be performed inside the testing suite that
+ * regularly changes wiki configuration.
+ */
+ public static function resetGetDefaultOptionsForTestsOnly() {
+ Assert::invariant( defined( 'MW_PHPUNIT_TEST' ), 'Unit tests only' );
+ self::$defOpt = null;
+ self::$defOptLang = null;
+ }
+
/**
* Combine the language default options with any site-specific options
* and add the default language variants.
public static function getDefaultOptions() {
global $wgNamespacesToBeSearchedDefault, $wgDefaultUserOptions, $wgDefaultSkin;
- static $defOpt = null;
- static $defOptLang = null;
-
$contLang = MediaWikiServices::getInstance()->getContentLanguage();
- if ( $defOpt !== null && $defOptLang === $contLang->getCode() ) {
+ if ( self::$defOpt !== null && self::$defOptLang === $contLang->getCode() ) {
// The content language does not change (and should not change) mid-request, but the
// unit tests change it anyway, and expect this method to return values relevant to the
// current content language.
- return $defOpt;
+ return self::$defOpt;
}
- $defOpt = $wgDefaultUserOptions;
+ self::$defOpt = $wgDefaultUserOptions;
// Default language setting
- $defOptLang = $contLang->getCode();
- $defOpt['language'] = $defOptLang;
+ self::$defOptLang = $contLang->getCode();
+ self::$defOpt['language'] = self::$defOptLang;
foreach ( LanguageConverter::$languagesWithVariants as $langCode ) {
if ( $langCode === $contLang->getCode() ) {
- $defOpt['variant'] = $langCode;
+ self::$defOpt['variant'] = $langCode;
} else {
- $defOpt["variant-$langCode"] = $langCode;
+ self::$defOpt["variant-$langCode"] = $langCode;
}
}
// since extensions may change the set of searchable namespaces depending
// on user groups/permissions.
foreach ( $wgNamespacesToBeSearchedDefault as $nsnum => $val ) {
- $defOpt['searchNs' . $nsnum] = (bool)$val;
+ self::$defOpt['searchNs' . $nsnum] = (bool)$val;
}
- $defOpt['skin'] = Skin::normalizeKey( $wgDefaultSkin );
+ self::$defOpt['skin'] = Skin::normalizeKey( $wgDefaultSkin );
- Hooks::run( 'UserGetDefaultOptions', [ &$defOpt ] );
+ Hooks::run( 'UserGetDefaultOptions', [ &self::$defOpt ] );
- return $defOpt;
+ return self::$defOpt;
}
/**
/**
* Get blocking information
- * @param bool $bFromReplica Whether to check the replica DB first.
+ * @param bool $fromReplica Whether to check the replica DB first.
* To improve performance, non-critical checks are done against replica DBs.
* Check when actually saving should be done against master.
*/
- private function getBlockedStatus( $bFromReplica = true ) {
+ private function getBlockedStatus( $fromReplica = true ) {
global $wgProxyWhitelist, $wgApplyIpBlocksToXff, $wgSoftBlockRanges;
if ( $this->mBlockedby != -1 ) {
# user is not immune to autoblocks/hardblocks, and they are the current user so we
# know which IP address they're actually coming from
$ip = null;
- if ( !$this->isAllowed( 'ipblock-exempt' ) ) {
- $sessionUser = RequestContext::getMain()->getUser();
- // the session user is set up towards the end of Setup.php. Until then,
- // assume it's a logged-out user.
- $globalUserName = $sessionUser->isSafeToLoad()
- ? $sessionUser->getName()
- : IP::sanitizeIP( $sessionUser->getRequest()->getIP() );
- if ( $this->getName() === $globalUserName ) {
- $ip = $this->getRequest()->getIP();
- }
+ $sessionUser = RequestContext::getMain()->getUser();
+ // the session user is set up towards the end of Setup.php. Until then,
+ // assume it's a logged-out user.
+ $globalUserName = $sessionUser->isSafeToLoad()
+ ? $sessionUser->getName()
+ : IP::sanitizeIP( $sessionUser->getRequest()->getIP() );
+ if ( $this->getName() === $globalUserName && !$this->isAllowed( 'ipblock-exempt' ) ) {
+ $ip = $this->getRequest()->getIP();
}
// User/IP blocking
- $block = Block::newFromTarget( $this, $ip, !$bFromReplica );
+ $block = Block::newFromTarget( $this, $ip, !$fromReplica );
// Cookie blocking
if ( !$block instanceof Block ) {
$xff = $this->getRequest()->getHeader( 'X-Forwarded-For' );
$xff = array_map( 'trim', explode( ',', $xff ) );
$xff = array_diff( $xff, [ $ip ] );
- $xffblocks = Block::getBlocksForIPList( $xff, $this->isAnon(), !$bFromReplica );
+ $xffblocks = Block::getBlocksForIPList( $xff, $this->isAnon(), !$fromReplica );
$block = Block::chooseBlock( $xffblocks, $xff );
if ( $block instanceof Block ) {
# Mangle the reason to alert the user that the block
# originated from matching the X-Forwarded-For header.
- $block->mReason = wfMessage( 'xffblockreason', $block->mReason )->plain();
+ $block->setReason( wfMessage( 'xffblockreason', $block->getReason() )->plain() );
}
}
wfDebug( __METHOD__ . ": Found block.\n" );
$this->mBlock = $block;
$this->mBlockedby = $block->getByName();
- $this->mBlockreason = $block->mReason;
- $this->mHideName = $block->mHideName;
+ $this->mBlockreason = $block->getReason();
+ $this->mHideName = $block->getHideName();
$this->mAllowUsertalk = $block->isUsertalkEditAllowed();
} else {
$this->mBlock = null;
// Set the user limit key
if ( $userLimit !== false ) {
+ // phan is confused because &can-bypass's value is a bool, so it assumes
+ // that $userLimit is also a bool here.
+ // @phan-suppress-next-line PhanTypeInvalidExpressionArrayDestructuring
list( $max, $period ) = $userLimit;
wfDebug( __METHOD__ . ": effective user limit: $max in {$period}s\n" );
$keys[$cache->makeKey( 'limiter', $action, 'user', $id )] = $userLimit;
$triggered = false;
foreach ( $keys as $key => $limit ) {
+ // phan is confused because &can-bypass's value is a bool, so it assumes
+ // that $userLimit is also a bool here.
+ // @phan-suppress-next-line PhanTypeInvalidExpressionArrayDestructuring
list( $max, $period ) = $limit;
$summary = "(limit $max in {$period}s)";
$count = $cache->get( $key );
/**
* Check if user is blocked
*
- * @param bool $bFromReplica Whether to check the replica DB instead of
+ * @param bool $fromReplica Whether to check the replica DB instead of
* the master. Hacked from false due to horrible probs on site.
* @return bool True if blocked, false otherwise
*/
- public function isBlocked( $bFromReplica = true ) {
- return $this->getBlock( $bFromReplica ) instanceof Block &&
+ public function isBlocked( $fromReplica = true ) {
+ return $this->getBlock( $fromReplica ) instanceof Block &&
$this->getBlock()->appliesToRight( 'edit' );
}
/**
* Get the block affecting the user, or null if the user is not blocked
*
- * @param bool $bFromReplica Whether to check the replica DB instead of the master
+ * @param bool $fromReplica Whether to check the replica DB instead of the master
* @return Block|null
*/
- public function getBlock( $bFromReplica = true ) {
- $this->getBlockedStatus( $bFromReplica );
+ public function getBlock( $fromReplica = true ) {
+ $this->getBlockedStatus( $fromReplica );
return $this->mBlock instanceof Block ? $this->mBlock : null;
}
* @param Title $title Title to check
* @param bool $fromReplica Whether to check the replica DB instead of the master
* @return bool
+ * @throws MWException
+ *
+ * @deprecated since 1.33,
+ * use MediaWikiServices::getInstance()->getPermissionManager()->isBlockedFrom(..)
+ *
*/
public function isBlockedFrom( $title, $fromReplica = false ) {
- $blocked = $this->isHidden();
-
- if ( !$blocked ) {
- $block = $this->getBlock( $fromReplica );
- if ( $block ) {
- // Special handling for a user's own talk page. The block is not aware
- // of the user, so this must be done here.
- if ( $title->equals( $this->getTalkPage() ) ) {
- $blocked = $block->appliesToUsertalk( $title );
- } else {
- $blocked = $block->appliesToTitle( $title );
- }
- }
- }
-
- // only for the purpose of the hook. We really don't need this here.
- $allowUsertalk = $this->mAllowUsertalk;
-
- Hooks::run( 'UserIsBlockedFrom', [ $this, $title, &$blocked, &$allowUsertalk ] );
-
- return $blocked;
+ return MediaWikiServices::getInstance()->getPermissionManager()
+ ->isBlockedFrom( $this, $title, $fromReplica );
}
/**
[ 'LOCK IN SHARE MODE' ]
);
$loaded = false;
- if ( $this->mId ) {
- if ( $this->loadFromDatabase( self::READ_LOCKING ) ) {
- $loaded = true;
- }
+ if ( $this->mId && $this->loadFromDatabase( self::READ_LOCKING ) ) {
+ $loaded = true;
}
if ( !$loaded ) {
throw new MWException( $fname . ": hit a key conflict attempting " .
// XXX it's not clear whether central ID providers are supposed to obey this
return $this->getName() === $user->getName();
}
+
+ /**
+ * Checks if usertalk is allowed
+ *
+ * @return bool
+ */
+ public function isAllowUsertalk() {
+ return $this->mAllowUsertalk;
+ }
+
}