/**
* Get/set whether the Block prevents a given action
- * @param string $action
- * @param bool|null $x
- * @return bool
+ *
+ * @param string $action Action to check
+ * @param bool|null $x Value for set, or null to just get value
+ * @return bool|null Null for unrecognized rights.
*/
public function prevents( $action, $x = null ) {
+ global $wgBlockDisablesLogin;
+ $res = null;
switch ( $action ) {
case 'edit':
# For now... <evil laugh>
- return true;
-
+ $res = true;
+ break;
case 'createaccount':
- return wfSetVar( $this->mCreateAccount, $x );
-
+ $res = wfSetVar( $this->mCreateAccount, $x );
+ break;
case 'sendemail':
- return wfSetVar( $this->mBlockEmail, $x );
-
+ $res = wfSetVar( $this->mBlockEmail, $x );
+ break;
case 'editownusertalk':
- return wfSetVar( $this->mDisableUsertalk, $x );
-
- default:
- return null;
+ $res = wfSetVar( $this->mDisableUsertalk, $x );
+ break;
+ case 'read':
+ $res = false;
+ break;
}
+ if ( !$res && $wgBlockDisablesLogin ) {
+ // If a block would disable login, then it should
+ // prevent any action that all users cannot do
+ $anon = new User;
+ $res = $anon->isAllowed( $action ) ? $res : true;
+ }
+
+ return $res;
}
/**
* @return array List of errors
*/
private function checkUserBlock( $action, $user, $errors, $rigor, $short ) {
+ global $wgEmailConfirmToEdit, $wgBlockDisablesLogin;
// Account creation blocks handled at userlogin.
// Unblocking handled in SpecialUnblock
if ( $rigor === 'quick' || in_array( $action, [ 'createaccount', 'unblock' ] ) ) {
return $errors;
}
- global $wgEmailConfirmToEdit;
+ // Optimize for a very common case
+ if ( $action === 'read' && !$wgBlockDisablesLogin ) {
+ return $errors;
+ }
if ( $wgEmailConfirmToEdit && !$user->isEmailConfirmed() ) {
$errors[] = [ 'confirmedittext' ];
$checks = [
'checkPermissionHooks',
'checkReadPermissions',
+ 'checkUserBlock', // for wgBlockDisablesLogin
];
# Don't call checkSpecialsAndNSPermissions or checkCSSandJSPermissions
# here as it will lead to duplicate error messages. This is okay to do
Hooks::run( 'UserGetRights', [ $this, &$this->mRights ] );
// Force reindexation of rights when a hook has unset one of them
$this->mRights = array_values( array_unique( $this->mRights ) );
+
+ // If block disables login, we should also remove any
+ // extra rights blocked users might have, in case the
+ // blocked user has a pre-existing session (T129738).
+ // This is checked here for cases where people only call
+ // $user->isAllowed(). It is also checked in Title::checkUserBlock()
+ // to give a better error message in the common case.
+ $config = RequestContext::getMain()->getConfig();
+ if (
+ $this->isLoggedIn() &&
+ $config->get( 'BlockDisablesLogin' ) &&
+ $this->isBlocked()
+ ) {
+ $anon = new User;
+ $this->mRights = array_intersect( $this->mRights, $anon->getRights() );
+ }
}
return $this->mRights;
}