Page MenuHomePhabricator

0001-Don-t-expose-usernames-if-user-is-hidden.patch

Authored By
Soda
Sep 12 2023, 8:22 PM
Size
19 KB
Referenced Files
None
Subscribers
None

0001-Don-t-expose-usernames-if-user-is-hidden.patch

From e23634cac9f4313435dfdf6210e811f422b8ef07 Mon Sep 17 00:00:00 2001
From: Sohom <sohomdatta1+git@gmail.com>
Date: Wed, 23 Aug 2023 22:18:50 +0530
Subject: [PATCH] Don't expose usernames if user is hidden
- Remove user_name and user info from 'pagetriagelist' API
- Add user_hidden field to 'pagetriagelist' API
- Modify pagetriage toolbar to handle cases where no username
is provided
- Modify Special:NewPagesFeed to gracefully handle cases where
the username is hidden
- Add a special case in the Special:NewPagesFeed vue version
for hidden usernames (where other information is availiable)
Bug: T344359
Change-Id: I5714f69a70909e3c3e7322e5f3be62d837e4d1cc
---
extension.json | 14 ++++++-
i18n/en.json | 2 +
i18n/qqq.json | 2 +
includes/Api/ApiPageTriageList.php | 37 +++++++++++++++----
.../components/ListContent.vue | 1 +
.../components/ListItem.vue | 14 ++++++-
.../models/ext.pageTriage.article.js | 7 +++-
.../ext.pageTriage.listItem.css | 5 +++
.../ext.pageTriage.listItem.underscore | 8 +++-
.../ext.pageTriage.views.toolbar/ToolView.js | 1 +
.../articleInfo.js | 10 ++++-
.../articleInfo.underscore | 8 +++-
modules/ext.pageTriage.views.toolbar/mark.js | 3 +-
modules/ext.pageTriage.views.toolbar/tags.js | 2 +-
.../ext.pageTriage.views.toolbar/wikiLove.js | 7 +++-
15 files changed, 104 insertions(+), 17 deletions(-)
diff --git a/extension.json b/extension.json
index 3895ce32..7a0dd9f0 100644
--- a/extension.json
+++ b/extension.json
@@ -15,7 +15,12 @@
"MediaWiki": ">= 1.41"
},
"APIModules": {
- "pagetriagelist": "MediaWiki\\Extension\\PageTriage\\Api\\ApiPageTriageList",
+ "pagetriagelist": {
+ "class": "MediaWiki\\Extension\\PageTriage\\Api\\ApiPageTriageList",
+ "services": [
+ "UserFactory"
+ ]
+ },
"pagetriagestats": "MediaWiki\\Extension\\PageTriage\\Api\\ApiPageTriageStats",
"pagetriageaction": {
"class": "MediaWiki\\Extension\\PageTriage\\Api\\ApiPageTriageAction",
@@ -239,8 +244,11 @@
"pagetriage-mark-as-unreviewed",
"pagetriage-info-title",
"pagetriage-byline",
+ "rev-deleted-user",
+ "pagetriage-byline-hidden-username",
"pagetriage-byline-new-editor",
"pagetriage-articleinfo-byline",
+ "pagetriage-articleinfo-byline-hidden-username",
"pagetriage-articleinfo-byline-new-editor",
"pipe-separator",
"pagetriage-edits",
@@ -390,6 +398,8 @@
"pagetriage-recreated",
"pagetriage-no-author",
"pagetriage-byline",
+ "pagetriage-byline-hidden-username",
+ "rev-deleted-user",
"pagetriage-byline-new-editor",
"pagetriage-editcount",
"pagetriage-author-not-autoconfirmed",
@@ -587,6 +597,7 @@
"pagetriage-no-author",
"pagetriage-no-pages",
"pagetriage-byline",
+ "pagetriage-byline-hidden-username",
"pagetriage-byline-heading",
"pagetriage-byline-new-editor",
"pagetriage-byline-new-editor-heading",
@@ -602,6 +613,7 @@
"pagetriage-unreviewed-article-count",
"pagetriage-reviewed-article-count-past-week",
"pagetriage-unreviewed-draft-count",
+ "rev-deleted-user",
"pagetriage-sort-by",
"pagetriage-newest",
"pagetriage-oldest",
diff --git a/i18n/en.json b/i18n/en.json
index edfd73f8..552f7e4d 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -34,9 +34,11 @@
"pagetriage-no-author": "No author information present",
"pagetriage-byline": "Created by $1 ($2$3$4)",
"pagetriage-byline-heading": "Created by {{GENDER:$1}}",
+ "pagetriage-byline-hidden-username": "Created by $1",
"pagetriage-byline-new-editor": "Created by new editor $1 ($2$3$4)",
"pagetriage-byline-new-editor-heading": "Created by a {{GENDER:$1|new editor}}",
"pagetriage-articleinfo-byline": "This page was created on $1 by $2 ($3$4$5)",
+ "pagetriage-articleinfo-byline-hidden-username": "This page was created on $1 by $2",
"pagetriage-articleinfo-byline-new-editor": "This page was created on $1 by new editor $2 ($3$4$5)",
"pagetriage-editcount": "$1 {{PLURAL:$1|edit|edits}} since $2",
"pagetriage-author-not-autoconfirmed": "New editor",
diff --git a/i18n/qqq.json b/i18n/qqq.json
index 7e4b3415..66e0e54d 100644
--- a/i18n/qqq.json
+++ b/i18n/qqq.json
@@ -53,10 +53,12 @@
"pagetriage-recreated": "Label indicating a page was previously deleted.",
"pagetriage-no-author": "Error message for missing page author information",
"pagetriage-byline": "Text indicating the page author.\n*$1 is a link to the author's user page.\n*$2 is a link to the author's talk page.\n*$3 is a separator character.\n*$4 is a link to the author's contributions.",
+ "pagetriage-byline-hidden-username": "Text indicating that a article was created by a author whoes name has been removed. This message is immediately followed by rev-deleted-user.",
"pagetriage-byline-heading": "Text indicating the page author. Parameters:\n* $1 - the author's username, used for GENDER support.",
"pagetriage-byline-new-editor": "Text indicating the page author (for when the author is a new editor). $1 is a link to the author's user page, $2 is a link to the author's talk page, $3 is a separator character, $4 is a link to the author's contributions.",
"pagetriage-byline-new-editor-heading": "Text indicating the page author (for when the author is a new editor). Parameters:\n* $1 - the 'author's username, used for GENDER support.",
"pagetriage-articleinfo-byline": "Text indicating the page author. $1 is the article creation date, $2 is a link to the author's user page, $3 is a link to the author's talk page, $4 is a separator character. $5 is a link to the author's contributions.",
+ "pagetriage-articleinfo-byline-hidden-username": "Text indicating that a article was created by a author whoes name has been removed in the article info section of the pagetriage toolbar. This message is immediately followed by rev-deleted-user.",
"pagetriage-articleinfo-byline-new-editor": "Text indicating the page author (for when the author is a new editor). Parameters:\n* $1 is the article creation date.\n* $2 is a link to the author's user page.\n* $3 is a link to the author's talk page.\n* $4 is a separator character\n* $5 is a link to the author's contributions.",
"pagetriage-editcount": "Display of page author's editing experience. $1 is total edit count, $2 is author's join date",
"pagetriage-author-not-autoconfirmed": "String indicating that the author was not yet autoconfirmed when the page was last edited",
diff --git a/includes/Api/ApiPageTriageList.php b/includes/Api/ApiPageTriageList.php
index a1e25ada..f6382cd1 100644
--- a/includes/Api/ApiPageTriageList.php
+++ b/includes/Api/ApiPageTriageList.php
@@ -3,12 +3,14 @@
namespace MediaWiki\Extension\PageTriage\Api;
use ApiBase;
+use ApiMain;
use ApiResult;
use MediaWiki\Extension\PageTriage\ArticleMetadata;
use MediaWiki\Extension\PageTriage\OresMetadata;
use MediaWiki\Extension\PageTriage\PageTriageUtil;
use MediaWiki\Logger\LoggerFactory;
use MediaWiki\Title\Title;
+use MediaWiki\User\UserFactory;
use ORES\Services\ORESServices;
use SpecialPage;
use Wikimedia\ParamValidator\ParamValidator;
@@ -22,6 +24,18 @@ use Wikimedia\ParamValidator\TypeDef\IntegerDef;
*/
class ApiPageTriageList extends ApiBase {
+ /** @var UserFactory */
+ private UserFactory $userFactory;
+
+ /**
+ * @param ApiMain $query
+ * @param string $moduleName
+ */
+ public function __construct( ApiMain $query, string $moduleName, UserFactory $userFactory ) {
+ $this->userFactory = $userFactory;
+ parent::__construct( $query, $moduleName );
+ }
+
public function execute() {
// Get the API parameters and store them
$opts = $this->extractRequestParams();
@@ -72,12 +86,20 @@ class ApiPageTriageList extends ApiBase {
$metaData[$page]['creation_date']
);
- // Page creator
- $metaData[$page] += $this->createUserInfo(
- $metaData[$page]['user_name'],
- $userPageStatus,
- 'creator'
- );
+ if ( $metaData[$page]['user_name'] ) {
+ // Page creator
+ $user = $this->userFactory->newFromName( $metaData[$page]['user_name'] );
+ if ( $user && $user->isHidden() ) {
+ $metaData[$page]['user_name'] = null;
+ $metaData[$page]['creator_hidden'] = true;
+ } else {
+ $metaData[$page] += $this->createUserInfo(
+ $metaData[$page]['user_name'],
+ $userPageStatus,
+ 'creator'
+ );
+ }
+ }
// Page reviewer
if ( $metaData[$page]['reviewer'] ) {
@@ -103,7 +125,7 @@ class ApiPageTriageList extends ApiBase {
}
$metaData[$page][ApiResult::META_BC_BOOLS] = [
- 'creator_user_page_exist', 'creator_user_talk_page_exist',
+ 'creator_hidden', 'creator_user_page_exist', 'creator_user_talk_page_exist',
'reviewer_user_page_exist', 'reviewer_user_talk_page_exist',
];
@@ -219,6 +241,7 @@ class ApiPageTriageList extends ApiBase {
$prefix . '_user_talk_page_exist' => isset( $userPageStatus[$userTalkPage->getPrefixedDBkey()] ),
$prefix . '_contribution_page' => $userContribsPage->getPrefixedText(),
$prefix . '_contribution_page_url' => $userContribsPage->getFullURL(),
+ $prefix . '_hidden' => false,
];
}
diff --git a/modules/ext.pageTriage.list/components/ListContent.vue b/modules/ext.pageTriage.list/components/ListContent.vue
index 7385fff3..d79d2ae7 100644
--- a/modules/ext.pageTriage.list/components/ListContent.vue
+++ b/modules/ext.pageTriage.list/components/ListContent.vue
@@ -58,6 +58,7 @@ const listItemPropFormatter = ( pageInfo ) => {
listItemProps.revCount = parseInt( pageInfo.rev_count );
listItemProps.creationDateUTC = pageInfo.creation_date_utc;
listItemProps.creatorName = pageInfo.user_name;
+ listItemProps.creatorHidden = pageInfo.creator_hidden;
listItemProps.creatorAutoConfirmed = pageInfo.user_autoconfirmed === '1';
listItemProps.creatorRegistrationUTC = pageInfo.user_creation_date;
listItemProps.creatorUserId = parseInt( pageInfo.user_id );
diff --git a/modules/ext.pageTriage.list/components/ListItem.vue b/modules/ext.pageTriage.list/components/ListItem.vue
index 2a42cd54..45edb46a 100644
--- a/modules/ext.pageTriage.list/components/ListItem.vue
+++ b/modules/ext.pageTriage.list/components/ListItem.vue
@@ -58,14 +58,21 @@
</div>
<div class="mwe-vue-pt-info-row">
<div>
- <span v-if="creatorName">
+ <span v-if="creatorName || creatorHidden">
<creator-byline
+ v-if="creatorName"
:creator-name="creatorName"
+ :creator-hidden="creatorHidden"
:creator-user-id="creatorUserId"
:creator-auto-confirmed="creatorAutoConfirmed"
:creator-user-page-exists="creatorUserPageExists"
:creator-talk-page-exists="creatorTalkPageExists"
></creator-byline>
+ <template v-else>
+ <span class="mwe-pt-history-suppressed">
+ {{ $i18n( 'pagetriage-byline-hidden-username', $i18n( 'rev-deleted-user' ) ) }}
+ </span>
+ </template>
<span v-if="creatorUserId > 0">
{{ $i18n( 'pagetriage-dot-separator' ).text() }}
{{ $i18n( 'pagetriage-editcount', creatorEditCount, creatorRegistrationPretty ).text() }}
@@ -185,6 +192,7 @@ module.exports = {
*/
// Creator information tags
creatorUserId: { type: Number, required: true },
+ creatorHidden: { type: Boolean, required: true },
creatorName: { type: String, required: true },
creatorEditCount: { type: Number, required: true },
creatorRegistrationUTC: {
@@ -436,4 +444,8 @@ module.exports = {
.cdx-icon.cdx-info-chip__icon--warning {
color: @color-warning;
}
+.mwe-pt-history-suppressed {
+ text-decoration-line: line-through;
+ text-decoration-style: double;
+}
</style>
diff --git a/modules/ext.pageTriage.util/models/ext.pageTriage.article.js b/modules/ext.pageTriage.util/models/ext.pageTriage.article.js
index 0c61a0f1..01f0b1b6 100644
--- a/modules/ext.pageTriage.util/models/ext.pageTriage.article.js
+++ b/modules/ext.pageTriage.util/models/ext.pageTriage.article.js
@@ -106,7 +106,12 @@ const Article = Backbone.Model.extend( {
article.get( 'creator_user_page_exist' )
)
);
- article.set( 'user_contribs_title', article.get( 'creator_contribution_page' ) );
+ } else if ( article.get( 'creator_hidden' ) ) {
+ article.set( 'author_byline_html', mw.msg( 'pagetriage-byline-hidden-username', mw.msg( 'rev-deleted-user' ) ) );
+ article.set(
+ 'user_title_url',
+ mw.msg( 'rev-deleted-user' )
+ );
}
// Are there any PageTriage messages on the talk page?
diff --git a/modules/ext.pageTriage.views.list/ext.pageTriage.listItem.css b/modules/ext.pageTriage.views.list/ext.pageTriage.listItem.css
index 4d8f89e5..5016727f 100644
--- a/modules/ext.pageTriage.views.list/ext.pageTriage.listItem.css
+++ b/modules/ext.pageTriage.views.list/ext.pageTriage.listItem.css
@@ -123,6 +123,11 @@
display: table-cell;
}
+.mwe-pt-history-suppressed {
+ text-decoration-line: line-through;
+ text-decoration-style: double;
+}
+
.mwe-pt-potential-issues {
display: table-cell;
text-align: right;
diff --git a/modules/ext.pageTriage.views.list/ext.pageTriage.listItem.underscore b/modules/ext.pageTriage.views.list/ext.pageTriage.listItem.underscore
index 34cd4944..aa2c3446 100644
--- a/modules/ext.pageTriage.views.list/ext.pageTriage.listItem.underscore
+++ b/modules/ext.pageTriage.views.list/ext.pageTriage.listItem.underscore
@@ -105,7 +105,13 @@
<div class="mwe-pt-info-row">
<div class="mwe-pt-author">
<% if ( typeof( user_name ) !== "undefined" ) { %>
- <%= author_byline_html %>
+ <% if ( !creator_hidden ) { %>
+ <%= author_byline_html %>
+ <% } else { %>
+ <span class="mwe-pt-history-suppressed">
+ <%= author_byline_html %>
+ </span>
+ <% } %>
<!-- user_id is undefined or '0' for IP users -->
<% if ( typeof ( user_id ) != 'undefined' && Number( user_id ) !== 0 ) { %>
&#xb7;
diff --git a/modules/ext.pageTriage.views.toolbar/ToolView.js b/modules/ext.pageTriage.views.toolbar/ToolView.js
index 74a96746..f2544fec 100644
--- a/modules/ext.pageTriage.views.toolbar/ToolView.js
+++ b/modules/ext.pageTriage.views.toolbar/ToolView.js
@@ -267,6 +267,7 @@ module.exports = Backbone.View.extend( {
pageid: mw.config.get( 'wgArticleId' ),
title: mw.config.get( 'wgPageName' ),
creator: this.model.get( 'user_name' ),
+ creatorHidden: this.model.get( 'creator_hidden' ),
reviewed: reviewed
}, data );
},
diff --git a/modules/ext.pageTriage.views.toolbar/articleInfo.js b/modules/ext.pageTriage.views.toolbar/articleInfo.js
index 9b9ef2af..28eef292 100644
--- a/modules/ext.pageTriage.views.toolbar/articleInfo.js
+++ b/modules/ext.pageTriage.views.toolbar/articleInfo.js
@@ -109,6 +109,8 @@ module.exports = ToolView.extend( {
url.toString()
);
+ const offset = parseInt( mw.user.options.get( 'timecorrection' ).split( '|' )[ 1 ] );
+
// creator information
if ( this.model.get( 'user_name' ) ) {
// show new editor message only if the user is not anonymous and not autoconfirmed
@@ -119,7 +121,6 @@ module.exports = ToolView.extend( {
bylineMessage = 'pagetriage-articleinfo-byline';
}
- const offset = parseInt( mw.user.options.get( 'timecorrection' ).split( '|' )[ 1 ] );
// put it all together in the byline
// The following messages are used here:
// * pagetriage-articleinfo-byline-new-editor
@@ -150,6 +151,13 @@ module.exports = ToolView.extend( {
)
).parse();
this.model.set( 'articleByline_html', articleByline );
+ } else if ( this.model.get( 'creator_hidden' ) ) {
+ this.model.set( 'articleByline_html', mw.msg( 'pagetriage-articleinfo-byline-hidden-username', moment.utc(
+ this.model.get( 'creation_date_utc' ),
+ 'YYYYMMDDHHmmss'
+ ).utcOffset( offset ).format(
+ mw.msg( 'pagetriage-info-timestamp-date-format' )
+ ), mw.msg( 'rev-deleted-user' ) ) );
}
const stats = [
diff --git a/modules/ext.pageTriage.views.toolbar/articleInfo.underscore b/modules/ext.pageTriage.views.toolbar/articleInfo.underscore
index 9a7ce587..9760e289 100644
--- a/modules/ext.pageTriage.views.toolbar/articleInfo.underscore
+++ b/modules/ext.pageTriage.views.toolbar/articleInfo.underscore
@@ -23,7 +23,13 @@
<!-- author info -->
<span class="mwe-pt-author">
<% if( typeof( user_name ) != 'undefined' ) { %>
- <%= articleByline_html %>
+ <% if ( !creator_hidden ) { %>
+ <%= articleByline_html %>
+ <% } else { %>
+ <span class="mwe-pt-history-suppressed">
+ <%= articleByline_html %>
+ </span>
+ <% } %>
<div>
<!-- if user is registered (user_id is 0 for IP users) -->
<% if( typeof user_id != 'undefined' && Number( user_id ) !== 0 ) { %>
diff --git a/modules/ext.pageTriage.views.toolbar/mark.js b/modules/ext.pageTriage.views.toolbar/mark.js
index 4d347924..ea221f07 100644
--- a/modules/ext.pageTriage.views.toolbar/mark.js
+++ b/modules/ext.pageTriage.views.toolbar/mark.js
@@ -221,6 +221,7 @@ module.exports = ToolView.extend( {
status = this.model.get( 'patrol_status' ) === '0' ? 'reviewed' : 'unreviewed',
hasPreviousReviewer = this.model.get( 'ptrp_last_reviewed_by' ) > 0,
articleCreator = this.model.get( 'user_name' ),
+ articleCreatorHidden = this.model.get( 'creator_hidden' ),
previousReviewer = hasPreviousReviewer ? this.model.get( 'reviewer' ) : '';
let noteTarget = articleCreator,
notePlaceholder = 'pagetriage-message-for-creator-default-note',
@@ -239,7 +240,7 @@ module.exports = ToolView.extend( {
notePlaceholder = 'pagetriage-message-for-creator-default-note';
}
- if ( mw.config.get( 'wgUserName' ) === articleCreator ) {
+ if ( mw.config.get( 'wgUserName' ) === articleCreator || articleCreatorHidden ) {
numRecipients--;
noteTarget = previousReviewer;
noteRecipientRole = 'reviewer';
diff --git a/modules/ext.pageTriage.views.toolbar/tags.js b/modules/ext.pageTriage.views.toolbar/tags.js
index 45ebfc61..b1d9a896 100644
--- a/modules/ext.pageTriage.views.toolbar/tags.js
+++ b/modules/ext.pageTriage.views.toolbar/tags.js
@@ -308,7 +308,7 @@ module.exports = ToolView.extend( {
if ( this.selectedTagCount > 0 ) {
$( '#mwe-pt-tag-submit-button' ).button( 'enable' );
$( '#mwe-pt-checkbox-mark-reviewed-wrapper' ).show();
- if ( mw.config.get( 'wgUserName' ) !== this.model.get( 'user_name' ) ) {
+ if ( mw.config.get( 'wgUserName' ) !== this.model.get( 'user_name' ) && !this.model.get( 'creator_hidden' ) ) {
$( '#mwe-pt-tag-note' ).show();
}
} else {
diff --git a/modules/ext.pageTriage.views.toolbar/wikiLove.js b/modules/ext.pageTriage.views.toolbar/wikiLove.js
index f493b069..22fe7d0a 100644
--- a/modules/ext.pageTriage.views.toolbar/wikiLove.js
+++ b/modules/ext.pageTriage.views.toolbar/wikiLove.js
@@ -26,11 +26,14 @@ module.exports = ToolView.extend( {
render: function () {
// get the article's creator
const creator = this.model.get( 'user_name' );
+ const creatorHidden = this.model.get( 'creator_hidden' );
// get the last 20 editors of the article
const contributorArray = [];
this.model.revisions.each( function ( revision ) {
- contributorArray.push( revision.get( 'user' ) );
+ if ( typeof ( revision.get( 'userhidden' ) ) === 'undefined' ) {
+ contributorArray.push( revision.get( 'user' ) );
+ }
} );
// count how many times each editor edited the article
@@ -54,7 +57,7 @@ module.exports = ToolView.extend( {
// set the Learn More link URL
$( '#mwe-pt-wikilove .mwe-pt-flyout-help-link' ).attr( 'href', this.moduleConfig.helplink );
- if ( mw.user.getName() !== creator ) {
+ if ( mw.user.getName() !== creator && !creatorHidden ) {
// add the creator info to the top of the list
$( '#mwe-pt-article-contributor-list' ).append(
'<input type="checkbox" class="mwe-pt-recipient-checkbox" value="' + _.escape( creator ) + '"/>' +
--
2.42.0

File Metadata

Mime Type
text/x-diff
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
11390093
Default Alt Text
0001-Don-t-expose-usernames-if-user-is-hidden.patch (19 KB)

Event Timeline