Merge "Use Authority for revision audience where possible"

This commit is contained in:
jenkins-bot 2021-02-25 16:31:44 +00:00 committed by Gerrit Code Review
commit e585399247
14 changed files with 67 additions and 163 deletions

View file

@ -3302,11 +3302,7 @@ class EditPage implements IEditObject {
if ( $revRecord && $revRecord instanceof RevisionStoreRecord ) {
// Let sysop know that this will make private content public if saved
if ( !RevisionRecord::userCanBitfield(
$revRecord->getVisibility(),
RevisionRecord::DELETED_TEXT,
$user
) ) {
if ( !$revRecord->userCan( RevisionRecord::DELETED_TEXT, $user ) ) {
$out->addHtml(
Html::warningBox(
$out->msg( 'rev-deleted-text-permission', $this->mTitle->getPrefixedDBkey() )->parse(),

View file

@ -21,6 +21,7 @@
*/
use MediaWiki\Linker\LinkTarget;
use MediaWiki\MediaWikiServices;
use MediaWiki\Permissions\Authority;
use MediaWiki\Revision\RevisionRecord;
use Wikimedia\IPUtils;
@ -1098,8 +1099,8 @@ class Linker {
* @return string HTML fragment
*/
public static function revUserLink( $rev, $isPublic = false ) {
// TODO inject a user
$user = RequestContext::getMain()->getUser();
// TODO inject authority
$authority = RequestContext::getMain()->getAuthority();
if ( $rev instanceof Revision ) {
wfDeprecated( __METHOD__ . ' with a Revision object', '1.35' );
@ -1110,12 +1111,8 @@ class Linker {
if ( $revRecord->isDeleted( RevisionRecord::DELETED_USER ) && $isPublic ) {
$link = wfMessage( 'rev-deleted-user' )->escaped();
} elseif ( RevisionRecord::userCanBitfield(
$revRecord->getVisibility(),
RevisionRecord::DELETED_USER,
$user
) ) {
$revUser = $revRecord->getUser( RevisionRecord::FOR_THIS_USER, $user );
} elseif ( $revRecord->userCan( RevisionRecord::DELETED_USER, $authority ) ) {
$revUser = $revRecord->getUser( RevisionRecord::FOR_THIS_USER, $authority );
$link = self::userLink(
$revUser ? $revUser->getId() : 0,
$revUser ? $revUser->getName() : ''
@ -1139,8 +1136,8 @@ class Linker {
* @return string HTML
*/
public static function revUserTools( $rev, $isPublic = false, $useParentheses = true ) {
// TODO inject a user
$user = RequestContext::getMain()->getUser();
// TODO inject authority
$authority = RequestContext::getMain()->getAuthority();
if ( $rev instanceof Revision ) {
wfDeprecated( __METHOD__ . ' with a Revision object', '1.35' );
@ -1149,14 +1146,10 @@ class Linker {
$revRecord = $rev;
}
if ( RevisionRecord::userCanBitfield(
$revRecord->getVisibility(),
RevisionRecord::DELETED_USER,
$user
) &&
if ( $revRecord->userCan( RevisionRecord::DELETED_USER, $authority ) &&
( !$revRecord->isDeleted( RevisionRecord::DELETED_USER ) || !$isPublic )
) {
$revUser = $revRecord->getUser( RevisionRecord::FOR_THIS_USER, $user );
$revUser = $revRecord->getUser( RevisionRecord::FOR_THIS_USER, $authority );
$userId = $revUser ? $revUser->getId() : 0;
$userText = $revUser ? $revUser->getName() : '';
@ -1604,8 +1597,8 @@ class Linker {
public static function revComment( $rev, $local = false, $isPublic = false,
$useParentheses = true
) {
// TODO inject a user
$user = RequestContext::getMain()->getUser();
// TODO inject authority
$authority = RequestContext::getMain()->getAuthority();
if ( $rev instanceof Revision ) {
wfDeprecated( __METHOD__ . ' with a Revision object', '1.35' );
@ -1619,12 +1612,8 @@ class Linker {
}
if ( $revRecord->isDeleted( RevisionRecord::DELETED_COMMENT ) && $isPublic ) {
$block = " <span class=\"comment\">" . wfMessage( 'rev-deleted-comment' )->escaped() . "</span>";
} elseif ( RevisionRecord::userCanBitfield(
$revRecord->getVisibility(),
RevisionRecord::DELETED_COMMENT,
$user
) ) {
$comment = $revRecord->getComment( RevisionRecord::FOR_THIS_USER, $user );
} elseif ( $revRecord->userCan( RevisionRecord::DELETED_COMMENT, $authority ) ) {
$comment = $revRecord->getComment( RevisionRecord::FOR_THIS_USER, $authority );
$block = self::commentBlock(
$comment ? $comment->text : null,
$revRecord->getPageAsLinkTarget(),
@ -2192,13 +2181,13 @@ class Linker {
* if possible, otherwise the timestamp-based ID which may break after
* undeletion.
*
* @param User $user
* @param Authority $performer
* @param RevisionRecord|Revision $rev (RevisionRecord allowed since 1.35, Revision
* deprecated since 1.35)
* @param LinkTarget $title
* @return string HTML fragment
*/
public static function getRevDeleteLink( User $user, $rev, LinkTarget $title ) {
public static function getRevDeleteLink( Authority $performer, $rev, LinkTarget $title ) {
if ( $rev instanceof Revision ) {
wfDeprecated( __METHOD__ . ' with a Revision object', '1.35' );
$revRecord = $rev->getRevisionRecord();
@ -2206,18 +2195,13 @@ class Linker {
$revRecord = $rev;
}
$permissionManager = MediaWikiServices::getInstance()->getPermissionManager();
$canHide = $permissionManager->userHasRight( $user, 'deleterevision' );
$canHideHistory = $permissionManager->userHasRight( $user, 'deletedhistory' );
$canHide = $performer->isAllowed( 'deleterevision' );
$canHideHistory = $performer->isAllowed( 'deletedhistory' );
if ( !$canHide && !( $revRecord->getVisibility() && $canHideHistory ) ) {
return '';
}
if ( !RevisionRecord::userCanBitfield(
$revRecord->getVisibility(),
RevisionRecord::DELETED_RESTRICTED,
$user
) ) {
if ( !$revRecord->userCan( RevisionRecord::DELETED_RESTRICTED, $performer ) ) {
return self::revDeleteLinkDisabled( $canHide ); // revision was hidden from sysops
}
$prefixedDbKey = MediaWikiServices::getInstance()->getTitleFormatter()->

View file

@ -1096,7 +1096,7 @@ class Revision implements IDBAccessObject {
global $wgUser;
$user = $wgUser;
}
return RevisionRecord::userCanBitfield( $this->mRecord->getVisibility(), $field, $user );
return $this->mRecord->userCan( $field, $user );
}
/**

View file

@ -381,11 +381,7 @@ class HistoryPager extends ReverseChronologicalPager {
// If revision was hidden from sysops and we don't need the checkbox
// for anything else, disable it
if ( !$this->showTagEditUI
&& !RevisionRecord::userCanBitfield(
$visibility,
RevisionRecord::DELETED_RESTRICTED,
$user
)
&& !$revRecord->userCan( RevisionRecord::DELETED_RESTRICTED, $this->getAuthority() )
) {
$del = Xml::check( 'deleterevisions', false, [ 'disabled' => 'disabled' ] );
// Otherwise, enable the checkbox...
@ -394,13 +390,9 @@ class HistoryPager extends ReverseChronologicalPager {
[ 'name' => 'ids[' . $revRecord->getId() . ']' ] );
}
// User can only view deleted revisions...
} elseif ( $visibility && $this->getAuthority()->isAllowed( 'deletedhistory' ) ) {
} elseif ( $revRecord->getVisibility() && $this->getAuthority()->isAllowed( 'deletedhistory' ) ) {
// If revision was hidden from sysops, disable the link
if ( !RevisionRecord::userCanBitfield(
$visibility,
RevisionRecord::DELETED_RESTRICTED,
$user
) ) {
if ( !$revRecord->userCan( RevisionRecord::DELETED_RESTRICTED, $this->getAuthority() ) ) {
$del = Linker::revDeleteLinkDisabled( false );
// Otherwise, show the link...
} else {
@ -568,11 +560,7 @@ class HistoryPager extends ReverseChronologicalPager {
$cur = $this->historyPage->message['cur'];
$latest = $this->getWikiPage()->getLatest();
if ( $latest === $rev->getId()
|| !RevisionRecord::userCanBitfield(
$rev->getVisibility(),
RevisionRecord::DELETED_TEXT,
$this->getUser()
)
|| !$rev->userCan( RevisionRecord::DELETED_TEXT, $this->getAuthority() )
) {
return $cur;
} else {
@ -625,15 +613,8 @@ class HistoryPager extends ReverseChronologicalPager {
$this->getTitle()
);
if ( !RevisionRecord::userCanBitfield(
$prevRev->getVisibility(),
RevisionRecord::DELETED_TEXT,
$this->getUser()
) || !RevisionRecord::userCanBitfield(
$nextRev->getVisibility(),
RevisionRecord::DELETED_TEXT,
$this->getUser()
)
if ( !$prevRev->userCan( RevisionRecord::DELETED_TEXT, $this->getAuthority() ) ||
!$nextRev->userCan( RevisionRecord::DELETED_TEXT, $this->getAuthority() )
) {
return $last;
}
@ -672,11 +653,7 @@ class HistoryPager extends ReverseChronologicalPager {
$checkmark = [ 'checked' => 'checked' ];
} else {
# Check visibility of old revisions
if ( !RevisionRecord::userCanBitfield(
$rev->getVisibility(),
RevisionRecord::DELETED_TEXT,
$this->getUser()
) ) {
if ( !$rev->userCan( RevisionRecord::DELETED_TEXT, $this->getAuthority() ) ) {
$radio['disabled'] = 'disabled';
$checkmark = []; // We will check the next possible one
} elseif ( !$this->oldIdChecked ) {

View file

@ -153,14 +153,10 @@ class ApiComparePages extends ApiBase {
// @codeCoverageIgnoreEnd
// Handle revdel
if ( !$fromRev->audienceCan(
RevisionRecord::DELETED_TEXT, RevisionRecord::FOR_THIS_USER, $this->getUser()
) ) {
if ( !$fromRev->userCan( RevisionRecord::DELETED_TEXT, $this->getAuthority() ) ) {
$this->dieWithError( [ 'apierror-missingcontent-revid', $fromRev->getId() ], 'missingcontent' );
}
if ( !$toRev->audienceCan(
RevisionRecord::DELETED_TEXT, RevisionRecord::FOR_THIS_USER, $this->getUser()
) ) {
if ( !$toRev->userCan( RevisionRecord::DELETED_TEXT, $this->getAuthority() ) ) {
$this->dieWithError( [ 'apierror-missingcontent-revid', $toRev->getId() ], 'missingcontent' );
}

View file

@ -158,11 +158,7 @@ class ApiParse extends ApiBase {
$this->checkTitleUserPermissions( $rev->getPage(), 'read' );
if ( !$rev->audienceCan(
RevisionRecord::DELETED_TEXT,
RevisionRecord::FOR_THIS_USER,
$this->getUser()
) ) {
if ( !$rev->userCan( RevisionRecord::DELETED_TEXT, $this->getAuthority() ) ) {
$this->dieWithError(
[ 'apierror-permissiondenied', $this->msg( 'action-deletedtext' ) ]
);

View file

@ -219,7 +219,7 @@ abstract class ApiQueryRevisionsBase extends ApiQueryGeneratorBase {
private function checkRevDel( RevisionRecord $revision, $field ) {
$ret = $revision->isDeleted( $field ) ? self::IS_DELETED : 0;
if ( $ret ) {
$canSee = $revision->audienceCan( $field, RevisionRecord::FOR_THIS_USER, $this->getUser() );
$canSee = $revision->userCan( $field, $this->getAuthority() );
$ret |= ( $canSee ? 0 : self::CANNOT_VIEW );
}
return $ret;

View file

@ -430,8 +430,7 @@ class ChangesList extends ContextSource {
) {
$ts = $rev->getTimestamp();
$date = $lang->userTimeAndDate( $ts, $user );
if ( RevisionRecord::userCanBitfield(
$rev->getVisibility(),
if ( $rev->userCan(
RevisionRecord::DELETED_TEXT,
$user
) ) {

View file

@ -27,6 +27,7 @@ use MediaWiki\HookContainer\HookRunner;
use MediaWiki\Linker\LinkRenderer;
use MediaWiki\MediaWikiServices;
use MediaWiki\Page\WikiPageFactory;
use MediaWiki\Permissions\Authority;
use MediaWiki\Revision\RevisionRecord;
use MediaWiki\Revision\RevisionStore;
use MediaWiki\Revision\SlotRecord;
@ -572,23 +573,21 @@ class DifferenceEngine extends ContextSource {
* It is the caller's responsibility to call
* $this->getUserPermissionErrors or similar checks.
*
* @param User $user
* @param Authority $performer
* @return bool
*/
public function isUserAllowedToSeeRevisions( $user ) {
public function isUserAllowedToSeeRevisions( Authority $performer ) {
$this->loadRevisionData();
// $this->mNewRev will only be falsy if a loading error occurred
// (in which case the user is allowed to see).
$allowed = !$this->mNewRevisionRecord || RevisionRecord::userCanBitfield(
$this->mNewRevisionRecord->getVisibility(),
$allowed = !$this->mNewRevisionRecord || $this->mNewRevisionRecord->userCan(
RevisionRecord::DELETED_TEXT,
$user
$performer
);
if ( $this->mOldRevisionRecord &&
!RevisionRecord::userCanBitfield(
$this->mOldRevisionRecord->getVisibility(),
!$this->mOldRevisionRecord->userCan(
RevisionRecord::DELETED_TEXT,
$user
$performer
)
) {
$allowed = false;
@ -1193,20 +1192,17 @@ class DifferenceEngine extends ContextSource {
if ( !$this->loadRevisionData() ) {
return false;
} elseif ( $this->mOldRevisionRecord &&
!RevisionRecord::userCanBitfield(
$this->mOldRevisionRecord->getVisibility(),
!$this->mOldRevisionRecord->userCan(
RevisionRecord::DELETED_TEXT,
$this->getUser()
$this->getAuthority()
)
) {
return false;
} elseif ( $this->mNewRevisionRecord &&
!RevisionRecord::userCanBitfield(
$this->mNewRevisionRecord->getVisibility(),
!$this->mNewRevisionRecord->userCan(
RevisionRecord::DELETED_TEXT,
$this->getUser()
)
) {
$this->getAuthority()
) ) {
return false;
}
// Short-circuit
@ -1754,13 +1750,7 @@ class DifferenceEngine extends ContextSource {
* @return bool whether the user can see and edit the revision.
*/
private function userCanEdit( RevisionRecord $revRecord ) {
$user = $this->getUser();
if ( !RevisionRecord::userCanBitfield(
$revRecord->getVisibility(),
RevisionRecord::DELETED_TEXT,
$user
) ) {
if ( !$revRecord->userCan( RevisionRecord::DELETED_TEXT, $this->getAuthority() ) ) {
return false;
}

View file

@ -420,11 +420,7 @@ class Article implements Page {
}
}
if ( !RevisionRecord::userCanBitfield(
$this->mRevisionRecord->getVisibility(),
RevisionRecord::DELETED_TEXT,
$this->getContext()->getUser()
) ) {
if ( !$this->mRevisionRecord->userCan( RevisionRecord::DELETED_TEXT, $this->getContext()->getAuthority() ) ) {
wfDebug( __METHOD__ . " failed to retrieve content of revision " .
$this->mRevisionRecord->getId() );
@ -1479,10 +1475,9 @@ class Article implements Page {
// Show link to view it if it exists and the user has permission to view it.
$pa = new PageArchive( $title, $this->getContext()->getConfig() );
$revRecord = $pa->getArchivedRevisionRecord( $oldid );
if ( $revRecord && $revRecord->audienceCan(
if ( $revRecord && $revRecord->userCan(
RevisionRecord::DELETED_TEXT,
RevisionRecord::FOR_THIS_USER,
$contextUser
$this->getContext()->getAuthority()
) ) {
$text = wfMessage(
'missing-revision-permission', $oldid,
@ -1541,10 +1536,9 @@ class Article implements Page {
// Used in wikilinks, should not contain whitespaces
$titleText = $this->getTitle()->getPrefixedDBkey();
// If the user is not allowed to see it...
if ( !RevisionRecord::userCanBitfield(
$this->mRevisionRecord->getVisibility(),
if ( !$this->mRevisionRecord->userCan(
RevisionRecord::DELETED_TEXT,
$user
$this->getContext()->getAuthority()
) ) {
$outputPage->addHtml(
Html::warningBox(

View file

@ -79,18 +79,16 @@ class RevDelRevisionItem extends RevDelItem {
}
public function canView() {
return RevisionRecord::userCanBitfield(
$this->getRevisionRecord()->getVisibility(),
return $this->getRevisionRecord()->userCan(
RevisionRecord::DELETED_RESTRICTED,
$this->list->getUser()
$this->list->getAuthority()
);
}
public function canViewContent() {
return RevisionRecord::userCanBitfield(
$this->getRevisionRecord()->getVisibility(),
return $this->getRevisionRecord()->userCan(
RevisionRecord::DELETED_TEXT,
$this->list->getUser()
$this->list->getAuthority()
);
}
@ -227,7 +225,7 @@ class RevDelRevisionItem extends RevDelItem {
public function getApiData( ApiResult $result ) {
$revRecord = $this->getRevisionRecord();
$user = $this->list->getUser();
$authority = $this->list->getAuthority();
$ret = [
'id' => $revRecord->getId(),
'timestamp' => wfTimestamp( TS_ISO_8601, $revRecord->getTimestamp() ),
@ -235,23 +233,15 @@ class RevDelRevisionItem extends RevDelItem {
'commenthidden' => (bool)$revRecord->isDeleted( RevisionRecord::DELETED_COMMENT ),
'texthidden' => (bool)$revRecord->isDeleted( RevisionRecord::DELETED_TEXT ),
];
if ( RevisionRecord::userCanBitfield(
$revRecord->getVisibility(),
RevisionRecord::DELETED_USER,
$user
) ) {
$revUser = $revRecord->getUser( RevisionRecord::FOR_THIS_USER, $user );
if ( $revRecord->userCan( RevisionRecord::DELETED_USER, $authority ) ) {
$revUser = $revRecord->getUser( RevisionRecord::FOR_THIS_USER, $authority );
$ret += [
'userid' => $revUser ? $revUser->getId() : 0,
'user' => $revUser ? $revUser->getName() : '',
];
}
if ( RevisionRecord::userCanBitfield(
$revRecord->getVisibility(),
RevisionRecord::DELETED_COMMENT,
$user
) ) {
$revComment = $revRecord->getComment( RevisionRecord::FOR_THIS_USER, $user );
if ( $revRecord->userCan( RevisionRecord::DELETED_COMMENT, $authority ) ) {
$revComment = $revRecord->getComment( RevisionRecord::FOR_THIS_USER, $authority );
$ret += [
'comment' => $revComment ? $revComment->text : ''
];

View file

@ -73,19 +73,17 @@ class RevisionItem extends RevisionItemBase {
/** @inheritDoc */
public function canView() {
return RevisionRecord::userCanBitfield(
$this->getRevisionRecord()->getVisibility(),
return $this->getRevisionRecord()->userCan(
RevisionRecord::DELETED_RESTRICTED,
$this->context->getUser()
$this->context->getAuthority()
);
}
/** @inheritDoc */
public function canViewContent() {
return RevisionRecord::userCanBitfield(
$this->getRevisionRecord()->getVisibility(),
return $this->getRevisionRecord()->userCan(
RevisionRecord::DELETED_TEXT,
$this->context->getUser()
$this->context->getAuthority()
);
}

View file

@ -337,11 +337,7 @@ class SpecialMergeHistory extends SpecialPage {
}
# Last link
if ( !RevisionRecord::userCanBitfield(
$revRecord->getVisibility(),
RevisionRecord::DELETED_TEXT,
$user
) ) {
if ( !$revRecord->userCan( RevisionRecord::DELETED_TEXT, $this->getContext()->getAuthority() ) ) {
$last = $this->msg( 'last' )->escaped();
} elseif ( isset( $this->prevId[$row->rev_id] ) ) {
$last = $linkRenderer->makeKnownLink(

View file

@ -512,11 +512,7 @@ class SpecialUndelete extends SpecialPage {
if ( $revRecord->isDeleted( RevisionRecord::DELETED_TEXT ) ) {
// Used in wikilinks, should not contain whitespaces
$titleText = $this->mTargetObj->getPrefixedDBkey();
if ( !RevisionRecord::userCanBitfield(
$revRecord->getVisibility(),
RevisionRecord::DELETED_TEXT,
$user
) ) {
if ( !$revRecord->userCan( RevisionRecord::DELETED_TEXT, $this->getContext()->getAuthority() ) ) {
$msg = $revRecord->isDeleted( RevisionRecord::DELETED_RESTRICTED )
? [ 'rev-suppressed-text-permission', $titleText ]
: [ 'rev-deleted-text-permission', $titleText ];
@ -1096,11 +1092,7 @@ class SpecialUndelete extends SpecialPage {
if ( $this->mCanView ) {
$titleObj = $this->getPageTitle();
# Last link
if ( !RevisionRecord::userCanBitfield(
$revRecord->getVisibility(),
RevisionRecord::DELETED_TEXT,
$this->getUser()
) ) {
if ( !$revRecord->userCan( RevisionRecord::DELETED_TEXT, $this->getContext()->getAuthority() ) ) {
$pageLink = htmlspecialchars( $this->getLanguage()->userTimeAndDate( $ts, $user ) );
$last = $this->msg( 'diff' )->escaped();
} elseif ( $remaining > 0 || ( $earliestLiveTime && $ts > $earliestLiveTime ) ) {
@ -1223,11 +1215,7 @@ class SpecialUndelete extends SpecialPage {
$user = $this->getUser();
$time = $this->getLanguage()->userTimeAndDate( $ts, $user );
if ( !RevisionRecord::userCanBitfield(
$revRecord->getVisibility(),
RevisionRecord::DELETED_TEXT,
$user
) ) {
if ( !$revRecord->userCan( RevisionRecord::DELETED_TEXT, $this->getContext()->getAuthority() ) ) {
// TODO The condition cannot be true when the function is called
return '<span class="history-deleted">' . htmlspecialchars( $time ) . '</span>';
}