jenkins-bot has submitted this change and it was merged.

Change subject: Provide page text and edit summary when filtering file uploads
......................................................................


Provide page text and edit summary when filtering file uploads

This allows filters using `action='upload'` to use the variables
`summary`, `new_wikitext` and several others that previously were only
provided when editing pages (`action='edit'`).

This is achieved using the new UploadVerifyUpload hook, introduced in
MediaWiki core in change Ie68801b307de8456e1753ba54a29c34c8063bc36.

`action='upload'` is now only used when publishing an upload, and not
for uploads to stash. A new `action='stashupload'` is introduced,
which is used for all uploads, including uploads to stash. This
behaves like `action='upload'` used to, and only provides file
metadata variables.

Filter authors should use `action='stashupload'` when a file can be
checked based only on the file contents, and `action='upload'` only
when the wikitext edit needs to be examined too.

Bug: T87381
Bug: T89252
Bug: T139848
Change-Id: I9654f82ecda82e4917fd0ac6b364b947a1434c73
---
M AbuseFilter.hooks.php
M extension.json
2 files changed, 84 insertions(+), 19 deletions(-)

Approvals:
  MarkTraceur: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/AbuseFilter.hooks.php b/AbuseFilter.hooks.php
index b8cf7dc..0d98a75 100644
--- a/AbuseFilter.hooks.php
+++ b/AbuseFilter.hooks.php
@@ -689,32 +689,65 @@
        }
 
        /**
-        * Handler for the UploadVerifyFile hook
-        *
-        * @param $upload UploadBase
-        * @param $mime
-        * @param $error array
-        *
+        * @param UploadBase $upload
+        * @param User $user
+        * @param array $props
+        * @param string $comment
+        * @param string $pageText
+        * @param array &$error
+        * @return bool
+        */
+       public static function onUploadVerifyUpload( UploadBase $upload, User 
$user,
+               array $props, $comment, $pageText, &$error
+       ) {
+               return self::filterUpload( 'upload', $upload, $user, $props, 
$comment, $pageText, $error );
+       }
+
+       /**
+        * @param UploadBase $upload
+        * @param string $mime
+        * @param array &$error
         * @return bool
         */
        public static function onUploadVerifyFile( $upload, $mime, &$error ) {
-               global $wgUser;
+               global $wgUser, $wgVersion;
 
-               $vars = new AbuseFilterVariableHolder;
+               // On MW 1.27 and older, this is the only hook we can use, even 
though it's deficient.
+               // On MW 1.28 and newer, we use UploadVerifyUpload to check 
file uploads, and this one only
+               // to check file uploads to stash. If a filter doesn't need to 
check the page contents or
+               // upload comment, it can use `action='stashupload'` to provide 
better experience to e.g.
+               // UploadWizard (rejecting files immediately, rather than after 
the user adds the details).
+               $action = version_compare( $wgVersion, '1.28', '<' ) ? 'upload' 
: 'stashupload';
+
+               // UploadBase makes it absolutely impossible to get these out 
of it, even though it knows them.
+               $props = FSFile::getPropsFromPath( $upload->getTempPath() );
+
+               return self::filterUpload( $action, $upload, $wgUser, $props, 
null, null, $error );
+       }
+
+       /**
+        * Implementation for UploadVerifyFile and UploadVerifyUpload hooks.
+        *
+        * @param string $action 'upload' or 'stashupload'
+        * @param UploadBase $upload
+        * @param User $user User performing the action
+        * @param array $props File properties, as returned by 
FSFile::getPropsFromPath()
+        * @param string|null $summary Upload log comment (also used as edit 
summary)
+        * @param string|null $text File description page text (only used for 
new uploads)
+        * @param array &$error
+        * @return bool
+        */
+       public static function filterUpload( $action, UploadBase $upload, User 
$user,
+               array $props, $summary, $text, &$error
+       ) {
                $title = $upload->getTitle();
 
-               if ( !$title ) {
-                       // If there's no valid title assigned to the upload
-                       // it wont proceed anyway, so no point in filtering it.
-                       return true;
-               }
-
+               $vars = new AbuseFilterVariableHolder;
                $vars->addHolders(
-                       AbuseFilter::generateUserVars( $wgUser ),
+                       AbuseFilter::generateUserVars( $user ),
                        AbuseFilter::generateTitleVars( $title, 'ARTICLE' )
                );
-
-               $vars->setVar( 'ACTION', 'upload' );
+               $vars->setVar( 'ACTION', $action );
 
                // We use the hexadecimal version of the file sha1.
                // Use UploadBase::getTempFileSha1Base36 so that we don't have 
to calculate the sha1 sum again
@@ -723,14 +756,45 @@
                $vars->setVar( 'file_sha1', $sha1 );
                $vars->setVar( 'file_size', $upload->getFileSize() );
 
-               // UploadBase makes it absolutely impossible to get these out 
of it, even though it knows them.
-               $props = FSFile::getPropsFromPath( $upload->getTempPath() );
                $vars->setVar( 'file_mime', $props['mime'] );
                $vars->setVar( 'file_mediatype', 
MimeMagic::singleton()->getMediaType( null, $props['mime'] ) );
                $vars->setVar( 'file_width', $props['width'] );
                $vars->setVar( 'file_height', $props['height'] );
                $vars->setVar( 'file_bits_per_channel', $props['bits'] );
 
+               // We only have the upload comment and page text when using the 
UploadVerifyUpload hook
+               if ( $summary !== null && $text !== null ) {
+                       // This block is adapted from self::filterEdit()
+                       if ( $title->exists() ) {
+                               $page = WikiPage::factory( $title );
+                               $revision = $page->getRevision();
+                               if ( !$revision ) {
+                                       return true;
+                               }
+
+                               $oldcontent = $revision->getContent( 
Revision::RAW );
+                               $oldtext = AbuseFilter::contentToString( 
$oldcontent );
+
+                               // Cache article object so we can share a parse 
operation
+                               $articleCacheKey = $title->getNamespace() . ':' 
. $title->getText();
+                               
AFComputedVariable::$articleCache[$articleCacheKey] = $page;
+
+                               // Page text is ignored for uploads when the 
page already exists
+                               $text = $oldtext;
+                       } else {
+                               $page = null;
+                               $oldtext = '';
+                       }
+
+                       // Load vars for filters to check
+                       $vars->setVar( 'summary', $summary );
+                       $vars->setVar( 'minor_edit', false );
+                       $vars->setVar( 'old_wikitext', $oldtext );
+                       $vars->setVar( 'new_wikitext', $text );
+                       // TODO: set old_content and new_content vars, use them
+                       $vars->addHolders( AbuseFilter::getEditVars( $title, 
$page ) );
+               }
+
                $filter_result = AbuseFilter::filterAction( $vars, $title );
 
                if ( !$filter_result->isOK() ) {
diff --git a/extension.json b/extension.json
index fb0f4a3..032ccf1 100644
--- a/extension.json
+++ b/extension.json
@@ -179,6 +179,7 @@
                "LoadExtensionSchemaUpdates": 
"AbuseFilterHooks::onLoadExtensionSchemaUpdates",
                "ContributionsToolLinks": 
"AbuseFilterHooks::onContributionsToolLinks",
                "UploadVerifyFile": "AbuseFilterHooks::onUploadVerifyFile",
+               "UploadVerifyUpload": "AbuseFilterHooks::onUploadVerifyUpload",
                "MakeGlobalVariablesScript": 
"AbuseFilterHooks::onMakeGlobalVariablesScript",
                "ArticleSaveComplete": 
"AbuseFilterHooks::onArticleSaveComplete",
                "UserMergeAccountFields": 
"AbuseFilterHooks::onUserMergeAccountFields",

-- 
To view, visit https://gerrit.wikimedia.org/r/295254
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I9654f82ecda82e4917fd0ac6b364b947a1434c73
Gerrit-PatchSet: 2
Gerrit-Project: mediawiki/extensions/AbuseFilter
Gerrit-Branch: master
Gerrit-Owner: Bartosz Dziewoński <[email protected]>
Gerrit-Reviewer: Anomie <[email protected]>
Gerrit-Reviewer: Bartosz Dziewoński <[email protected]>
Gerrit-Reviewer: Brian Wolff <[email protected]>
Gerrit-Reviewer: Gergő Tisza <[email protected]>
Gerrit-Reviewer: Jackmcbarn <[email protected]>
Gerrit-Reviewer: Jforrester <[email protected]>
Gerrit-Reviewer: MarkTraceur <[email protected]>
Gerrit-Reviewer: Se4598 <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to