From 069f80c175c6adb82cd8c47c695a577f5d052522 Mon Sep 17 00:00:00 2001
From: Alexander Vorwerk <zabe@avorwerk.net>
Date: Tue, 23 Aug 2022 16:18:58 +0200
Subject: [PATCH] SECURITY: do not render suppressed usernames at
 Special:CheckUser

Bug: T311337
Change-Id: I3a23f71a4ee20b612afbf96a91d8dc70518052be
---
 .../Pagers/AbstractCheckUserPager.php         |  2 +-
 .../Pagers/CheckUserGetEditsPager.php         | 50 ++++++++++++++-----
 2 files changed, 38 insertions(+), 14 deletions(-)

diff --git a/src/CheckUser/Pagers/AbstractCheckUserPager.php b/src/CheckUser/Pagers/AbstractCheckUserPager.php
index c3b4e491..de7446df 100644
--- a/src/CheckUser/Pagers/AbstractCheckUserPager.php
+++ b/src/CheckUser/Pagers/AbstractCheckUserPager.php
@@ -98,7 +98,7 @@ abstract class AbstractCheckUserPager extends RangeChronologicalPager {
 	protected $templateParser;
 
 	/** @var UserFactory */
-	private $userFactory;
+	protected $userFactory;
 
 	/**
 	 * @param FormOptions $opts
diff --git a/src/CheckUser/Pagers/CheckUserGetEditsPager.php b/src/CheckUser/Pagers/CheckUserGetEditsPager.php
index 91ceac18..5c3a4216 100644
--- a/src/CheckUser/Pagers/CheckUserGetEditsPager.php
+++ b/src/CheckUser/Pagers/CheckUserGetEditsPager.php
@@ -18,6 +18,7 @@ use MediaWiki\CheckUser\TokenQueryManager;
 use MediaWiki\CommentFormatter\CommentFormatter;
 use MediaWiki\Linker\LinkRenderer;
 use MediaWiki\Logger\LoggerFactory;
+use MediaWiki\Revision\RevisionRecord;
 use MediaWiki\Revision\RevisionStore;
 use MediaWiki\SpecialPage\SpecialPageFactory;
 use MediaWiki\User\UserEditTracker;
@@ -49,6 +50,9 @@ class CheckUserGetEditsPager extends AbstractCheckUserPager {
 	/** @var array */
 	protected $formattedRevisionComments = [];
 
+	/** @var array */
+	protected $usernameVisibility = [];
+
 	/** @var LoggerInterface */
 	private $logger;
 
@@ -147,20 +151,34 @@ class CheckUserGetEditsPager extends AbstractCheckUserPager {
 		$templateParams['timestamp'] =
 			$this->getLanguage()->userTime( wfTimestamp( TS_MW, $row->cuc_timestamp ), $this->getUser() );
 		// Userlinks
-		$user = new UserIdentityValue( $row->cuc_user ?? 0, $row->cuc_user_text );
-		if ( !IPUtils::isIPAddress( $user ) && !$user->isRegistered() ) {
-			$templateParams['userLinkClass'] = 'mw-checkuser-nonexistent-user';
+		$user = new UserIdentityValue( $row->cuc_user, $row->cuc_user_text );
+		if ( $row->cuc_type == RC_EDIT || $row->cuc_type == RC_NEW ) {
+			$hidden = !$this->usernameVisibility[$row->cuc_this_oldid];
+		} else {
+			$hidden = $this->userFactory->newFromUserIdentity( $user )->isHidden()
+				&& !$this->getAuthority()->isAllowed( 'hideuser' );
+		}
+		if ( $hidden ) {
+			$templateParams['userLink'] = Html::element(
+				'span',
+				[ 'class' => 'history-deleted' ],
+				$this->msg( 'rev-deleted-user' )->text()
+			);
+		} else {
+			if ( !IPUtils::isIPAddress( $user ) && !$user->isRegistered() ) {
+				$templateParams['userLinkClass'] = 'mw-checkuser-nonexistent-user';
+			}
+			$templateParams['userLink'] = Linker::userLink( $user->getId(), $row->cuc_user_text, $row->cuc_user_text );
+			$templateParams['userToolLinks'] = Linker::userToolLinksRedContribs(
+				$user->getId(),
+				$row->cuc_user_text,
+				$this->userEditTracker->getUserEditCount( $user ),
+				// don't render parentheses in HTML markup (CSS will provide)
+				false
+			);
+			// Add any block information
+			$templateParams['flags'] = $this->flagCache[$row->cuc_user_text];
 		}
-		$templateParams['userLink'] = Linker::userLink( $user->getId(), $row->cuc_user_text, $row->cuc_user_text );
-		$templateParams['userToolLinks'] = Linker::userToolLinksRedContribs(
-			$user->getId(),
-			$row->cuc_user_text,
-			$this->userEditTracker->getUserEditCount( $user ),
-			// don't render parentheses in HTML markup (CSS will provide)
-			false
-		);
-		// Add any block information
-		$templateParams['flags'] = $this->flagCache[$row->cuc_user_text];
 		// Action text, hackish ...
 		$templateParams['actionText'] = $this->commentFormatter->format( $row->cuc_actiontext );
 		// Comment
@@ -397,6 +415,12 @@ class CheckUserGetEditsPager extends AbstractCheckUserPager {
 					$missingRevisions[$row->cuc_this_oldid] = '';
 				} else {
 					$revisions[$row->cuc_this_oldid] = $revRecord;
+
+					$this->usernameVisibility[$row->cuc_this_oldid] = RevisionRecord::userCanBitfield(
+						$revRecord->getVisibility(),
+						RevisionRecord::DELETED_USER,
+						$this->getAuthority()
+					);
 				}
 			}
 		}
-- 
2.37.0 (Apple Git-136)

