Samwilson has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/398784 )

Change subject: Regenerate graphs even when user is not permitted to upload
......................................................................

Regenerate graphs even when user is not permitted to upload

This adds a new feature whereby graph images can be regenerated
and uploaded to the wiki even when the user viewing them does
not have upload permission. This means that one need not grant
upload permission to users who just need to edit graphs (i.e. they
already are allowed to edit wikitext) and is also of use to other
extensions such as SemanticResultFormats and Genealogy which
create dynamic graphs that need to be re-rendered by anonymous
users.

The upload is done by a new 'GraphViz' user, whose name is defined
by the 'graphviz-upload-user' system message.

This change also fixes a few minor deprecations and bugs such as
the error message shown when there is no filename known.

Bug: T176594
Change-Id: Idc72ff953a82229665e4aa1798eaf785750cab45
---
M i18n/en.json
M i18n/qqq.json
M includes/GraphViz.php
M includes/UploadFromLocalFile.php
M includes/UploadLocalFile.php
M tests/phpunit/GraphVizTest.php
6 files changed, 75 insertions(+), 20 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/GraphViz 
refs/changes/84/398784/1

diff --git a/i18n/en.json b/i18n/en.json
index 10d772f..5c38016 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -25,5 +25,6 @@
        "graphviz-unrecognized-preparse-value": "The preparse value \"$1\" is 
unrecognized.",
        "graphviz-category-desc": "$1 contains pages created by the GraphViz 
extension.",
        "graphviz-subcategory-desc": "$1 contains pages created using the $2 
command.",
-       "graphviz-map-desc": "= ImageMap =\nWhen including this image in a wiki 
page, use the following mark-up to enable links:\n 
<nowiki>\n<imagemap>\nFile:$1\n$2</imagemap>\n</nowiki>\nSee 
[https://www.mediawiki.org/wiki/Extension:ImageMap ImageMap] for more 
information."
+       "graphviz-map-desc": "= ImageMap =\nWhen including this image in a wiki 
page, use the following mark-up to enable links:\n 
<nowiki>\n<imagemap>\nFile:$1\n$2</imagemap>\n</nowiki>\nSee 
[https://www.mediawiki.org/wiki/Extension:ImageMap ImageMap] for more 
information.",
+       "graphviz-upload-user": "GraphViz"
 }
diff --git a/i18n/qqq.json b/i18n/qqq.json
index a8267e8..e201986 100644
--- a/i18n/qqq.json
+++ b/i18n/qqq.json
@@ -26,5 +26,6 @@
        "graphviz-unrecognized-preparse-value": "Used as error message.  
Parameters:\n* $1 - attribute name",
        "graphviz-category-desc": "GraphViz category page text.  Parameters:\n* 
$1 - GraphViz category tag",
        "graphviz-subcategory-desc": "GraphViz subcategory page text.  
Parameters:\n* $1 - GraphViz subcategory tag\n* $2 - graph render command 
associated with subcategory",
-       "graphviz-map-desc": "Do not translate the tags <code><nowiki></code>, 
<code><imagemap></code>, <code></imagemap></code> or <code></nowiki></code>.  
Parameters:\n* $1 - image file name\n* $2 - image map shape, coordinates and 
URL (0 or more lines)"
+       "graphviz-map-desc": "Do not translate the tags <code><nowiki></code>, 
<code><imagemap></code>, <code></imagemap></code> or <code></nowiki></code>.  
Parameters:\n* $1 - image file name\n* $2 - image map shape, coordinates and 
URL (0 or more lines)",
+       "graphviz-upload-user": "The username of the user that graph images 
should be uploaded as (if the current user doesn't have permission)"
 }
diff --git a/includes/GraphViz.php b/includes/GraphViz.php
index c1f5d91..7524a50 100644
--- a/includes/GraphViz.php
+++ b/includes/GraphViz.php
@@ -29,6 +29,7 @@
 use ImageMap;
 use MWException;
 use Parser;
+use PPFrame;
 use Sanitizer;
 use User;
 
@@ -475,13 +476,15 @@
         * - The optional "format" attribute allows the user to specify the 
image type from
         * among those supported for the graph language.  @ref Files.
         *
-        * @param[in] Parser $parser
+        * @param Parser $parser The parser.
+        *
+        * @param PPFrame $frame The preprocessor frame.
         *
         * @return string HTML of a graph image and optional map or an HTML 
error message.
         *
         * @author Keith Welter et al.
         */
-       protected static function render( $input, $args, $parser, $frame ) {
+       protected static function render( $input, $args, Parser $parser, 
PPFrame $frame ) {
                global $wgUser;
 
                // sanity check the input
@@ -536,11 +539,18 @@
                        $imageType = $settings->defaultImageType;
                }
 
-               // determine user...
+               // Determine user. If the current user can't upload (e.g. this 
graph generation is being
+               // done by an extension and no user is logged in) then fall 
back to the GraphViz user as
+               // defined by the system message.
                // In testing I found that $parser->getUser() did not give the 
logged-in user when doing an edit preview.
                // So, I've gone against the recommended practice and used the 
global which gave the desired results.
                $user = $wgUser;
                $userName = $user->getName();
+               if ( !in_array( 'upload', $user->getRights() ) ) {
+                       $userName = wfMessage( 'graphviz-upload-user' 
)->parse();
+                       $user = User::newSystemUser( $userName );
+                       $user->addGroup( 'user' );
+               }
 
                // instantiate an object to hold the graph rendering parameters
                $graphParms = new GraphRenderParms( $renderer, $graphName, 
$userName, $imageType, $sourceAndMapDir, $imageDir );
@@ -634,6 +644,7 @@
                        }
 
                        $upload = new UploadFromLocalFile;
+                       $upload->setUser( $user );
 
                        // check if the upload is allowed for the intended 
title (the image file must exist prior to this check)
                        if ( !UploadLocalFile::isUploadAllowedForTitle(
diff --git a/includes/UploadFromLocalFile.php b/includes/UploadFromLocalFile.php
index c40062e..1ef2449 100644
--- a/includes/UploadFromLocalFile.php
+++ b/includes/UploadFromLocalFile.php
@@ -6,6 +6,7 @@
 use RepoGroup;
 use Status;
 use UploadBase;
+use User;
 
 /**
  * Supports local file uploads in the absence of a WebRequest.
@@ -15,6 +16,18 @@
  * @author Keith Welter
  */
 class UploadFromLocalFile extends UploadBase {
+
+       /** @var User */
+       protected $user;
+
+       /**
+        * Set the user to use for the upload.
+        * @param User $user
+        */
+       public function setUser( User $user ) {
+               $this->user = $user;
+       }
+
        /**
         * This function is a no-op because a WebRequest is not used.
         * It exists here because it is abstract in UploadBase.
@@ -51,9 +64,6 @@
         * @return Status Indicating the whether the upload succeeded.
         */
        public function performUpload2( $comment ) {
-               global $wgUser;
-               $user = $wgUser;
-
                $this->getLocalFile()->load( File::READ_LATEST );
                $props = $this->mFileProps;
 
@@ -63,7 +73,8 @@
                        $this->mTempPath,
                        $comment,
                        $props,
-                       File::DELETE_SOURCE
+                       File::DELETE_SOURCE,
+                       $this->user
                );
 
                if ( $status->isGood() ) {
diff --git a/includes/UploadLocalFile.php b/includes/UploadLocalFile.php
index 847c1de..ef2b5fa 100644
--- a/includes/UploadLocalFile.php
+++ b/includes/UploadLocalFile.php
@@ -43,6 +43,7 @@
 use Status;
 use Title;
 use UploadBase;
+use User;
 
 /**
  * Implements local file uploads in the absence of a WebRequest in conjunction 
with UploadFromLocalFile.
@@ -194,11 +195,11 @@
        /**
         * Based on SpecialUpload::showUploadError.
         *
-        * @param[in] string $message message to be included in the result
-        * @param[in] string $filename is the name of the file for which upload 
verification failed.
-        * @return string upload error message.
+        * @param string $message Message to be included in the result.
+        * @param string $filename The name of the file for which upload 
verification failed (if any).
+        * @return string Upload error message.
         */
-       static function getUploadErrorMessage( $message, $filename ) {
+       static function getUploadErrorMessage( $message, $filename = '' ) {
                return wfMessage( 'graphviz-uploaderror', $filename )->text() . 
$message;
        }
 
@@ -255,7 +256,9 @@
         *
         * @return bool true if the upload succeeds, false if it fails.
         */
-       static function uploadWithoutFilePage( $upload, $desiredDestName, 
$localPath, $removeLocalFile ) {
+       static function uploadWithoutFilePage(
+               UploadFromLocalFile $upload, $desiredDestName, $localPath, 
$removeLocalFile
+       ) {
                // Initialize path info
                $fileSize = filesize( $localPath );
                $upload->initializePathInfo( $desiredDestName, $localPath, 
$fileSize, $removeLocalFile );
@@ -284,7 +287,7 @@
         * @return Status On success, the value member contains the
         *     archive name, or an empty string if it was a new file.
         */
-       function upload2( $src, $comment, $props, $flags ) {
+       function upload2( $src, $comment, $props, $flags, User $user ) {
                if ( $this->getRepo()->getReadOnlyReason() !== false ) {
                        return $this->readOnlyFatalStatus();
                }
@@ -294,7 +297,7 @@
                $options = [];
                $handler = MediaHandler::getHandler( $props['mime'] );
                if ( $handler ) {
-                       $options['headers'] = $handler->getStreamHeaders( 
$props['metadata'] );
+                       $options['headers'] = $handler->getContentHeaders( 
$props['metadata'] );
                } else {
                        $options['headers'] = [];
                }
@@ -310,7 +313,7 @@
                        // Once the second operation goes through, then the 
current version was
                        // updated and we must therefore update the DB too.
                        $oldver = $status->value;
-                       if ( !$this->recordUpload3( $oldver, $comment, $props ) 
) {
+                       if ( !$this->recordUpload3( $oldver, $comment, $props, 
$user ) ) {
                                $status->fatal( 'filenotfound', $srcPath );
                        }
                }
@@ -325,11 +328,10 @@
         * @param string $oldver
         * @param string $comment
         * @param bool|array $props
+        * @param User $user The user (either the current user, or the special 
GraphViz user).
         * @return bool
         */
-       function recordUpload3( $oldver, $comment, $props ) {
-               global $wgUser;
-               $user = $wgUser;
+       function recordUpload3( $oldver, $comment, $props, User $user ) {
 
                $dbw = $this->repo->getMasterDB();
 
diff --git a/tests/phpunit/GraphVizTest.php b/tests/phpunit/GraphVizTest.php
index 26ee1d8..09f4d28 100644
--- a/tests/phpunit/GraphVizTest.php
+++ b/tests/phpunit/GraphVizTest.php
@@ -4,7 +4,9 @@
 
 use MediaWiki\Extension\GraphViz\GraphViz;
 use MediaWikiTestCase;
+use ParserOptions;
 use ReflectionClass;
+use WikiPage;
 
 /**
  *  @group GraphViz
@@ -44,4 +46,31 @@
                $result = $sanitizeDotInput->invokeArgs( $graphviz, [ &$input, 
&$errorText ] );
                $this->assertFalse( $result, "shapefile should be rejected" );
        }
+
+       public function testCreateGraph() {
+               $dotSource = '<graphviz>digraph testGraph { A -> B 
}</graphviz>';
+
+               // First try as the test user.
+               $user = $this->getTestUser( [ 'sysop' ] )->getUser();
+               //$parserOptions1 = ParserOptions::newFromUser( $user );
+               $parserOptions1 = ParserOptions::newCanonical( $user );
+               $this->setMwGlobals( 'wgUser', $user );
+               $testTitle = $this->insertPage('GraphViz test 1', $dotSource);
+               $testPage = new WikiPage( $testTitle['title'] );
+               $this->assertRegExp(
+                       
'|src=".*/6/6c/GraphViz_test_1_digraph_testGraph_dot.png"|',
+                       $testPage->getParserOutput( $parserOptions1 )->getText()
+               );
+
+               // Then as anon.
+               $parserOptions2 = ParserOptions::newFromAnon();
+               $this->setMwGlobals( 'wgUser', $parserOptions2->getUser() );
+               $testTitle2 = $this->insertPage('GraphViz test 2', $dotSource);
+               $testPage2 = new WikiPage( $testTitle2['title'] );
+               $this->assertRegExp(
+                       
'|src=".*/3/3b/GraphViz_test_2_digraph_testGraph_dot.png"|',
+                       $testPage2->getParserOutput( $parserOptions2, null, 
true )->getText()
+               );
+
+       }
 }

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Idc72ff953a82229665e4aa1798eaf785750cab45
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/GraphViz
Gerrit-Branch: master
Gerrit-Owner: Samwilson <s...@samwilson.id.au>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to