Yurik has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/179401

Change subject: Allow impersonate= parameter for admin users
......................................................................

Allow impersonate= parameter for admin users

* Will allow admin to see what a user would see
* Only affects lua functions, not the core
* isSiteAdmin() will return false

Change-Id: Id2251f8828f8b3ac0980c96019206b3437f2883c
---
M includes/LuaLibrary.php
M includes/PortalSpecialPage.php
2 files changed, 71 insertions(+), 43 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/ZeroPortal 
refs/changes/01/179401/1

diff --git a/includes/LuaLibrary.php b/includes/LuaLibrary.php
index 3a4db7f..e5a13c4 100644
--- a/includes/LuaLibrary.php
+++ b/includes/LuaLibrary.php
@@ -17,6 +17,9 @@
        /** @var IContextSource */
        private static $context = null;
 
+       /** @var string|null */
+       private static $impersonate = null;
+
        /** @var mixed */
        private static $result = null;
 
@@ -35,38 +38,39 @@
 
        /**
         * @param IContextSource $context
+        * @param null|string $impersonate allows admin-mode impersonation of 
users
         */
-       public static function setContext( $context ) {
+       public static function setContext( $context, $impersonate = null ) {
                self::$context = $context;
+               self::$impersonate = $impersonate;
        }
 
        /**
         * @return IContextSource
         * @throws Scribunto_LuaError
         */
-       public static function getContext() {
+       private static function assertZeroPortal() {
                if ( !self::$context ) {
                        // Something is seriously wrong - it shouldn't even be 
possible to call this function
                        throw new Scribunto_LuaError( 'This function is only 
available in Special:ZeroPortal' );
                }
-               return self::$context;
        }
 
        /**
         * Finishes up the invocation, clean up context, and overrides output 
if needed
         */
        public static function endInvoke() {
-               $ctx = self::getContext();
-               $out = $ctx->getOutput();
-               $req = $ctx->getRequest();
+               self::assertZeroPortal();
+               $out = self::$context->getOutput();
+               $req = self::$context->getRequest();
                $resp = $req->response();
-               self::setContext( null ); // Ensure that subsequent lua 
invocations don't permit
+               self::setContext( null ); // Ensure that subsequent lua 
invocations are not permitted
 
                if ( !$req->wasPosted() ) {
                        $expiryUnixTime = time() + 300; // default 300 seconds 
caching
                        $resp->header( 'Expires: ' . wfTimestamp( TS_RFC2822, 
$expiryUnixTime ) );
 
-                       $cacheMode = $ctx->getUser()->isAnon() ? 'public' : 
'private';
+                       $cacheMode = self::$context->getUser()->isAnon() ? 
'public' : 'private';
                        $resp->header( 'Cache-Control: ' . $cacheMode . ', 
must-revalidate, max-age=0' );
                }
 
@@ -127,6 +131,7 @@
         * @return string[]|false[]
         */
        public function getAllowedAccountIds() {
+               self::assertZeroPortal();
                $configs = array();
                $name = $this->isSiteAdminInt() ? true : 
$this->getUsernameInt();
                if ( $name ) {
@@ -147,6 +152,7 @@
         * @throws Scribunto_LuaError
         */
        public function getUsername() {
+               self::assertZeroPortal();
                return array( $this->getUsernameInt() );
        }
 
@@ -158,6 +164,7 @@
         * @throws Scribunto_LuaError
         */
        public function getRawParameter( $name = null, $default = null ) {
+               self::assertZeroPortal();
                $funcName = self::luaNamespace . __FUNCTION__;
                $this->checkType( $funcName, 1, $name, 'string' );
                if ( $default !== null ) {
@@ -166,7 +173,7 @@
                if ( substr( $name, 0, 2 ) !== 'zp' ) {
                        throw new Scribunto_LuaError( "bad argument #1 to 
'$funcName' (name must start with 'zp')" );
                }
-               return array( self::getContext()->getRequest()->getVal( $name, 
$default ) );
+               return array( self::$context->getRequest()->getVal( $name, 
$default ) );
        }
 
        /**
@@ -177,6 +184,7 @@
         */
        public function isAllowedToSee( $xcs = null ) {
                // First validate parameter, than analyze
+               self::assertZeroPortal();
                $this->checkType( self::luaNamespace . __FUNCTION__, 1, $xcs, 
'string' );
                $title = new TitleValue( NS_ZERO, $xcs );
 
@@ -198,6 +206,7 @@
         * @throws Scribunto_LuaError
         */
        public function isSiteAdmin() {
+               self::assertZeroPortal();
                return array( $this->isSiteAdminInt() );
        }
 
@@ -245,7 +254,7 @@
         * @param string|null $result
         */
        public function setRawResult( $result = null ) {
-               self::getContext(); // ensure special page is enabled
+               self::assertZeroPortal();
                $this->checkTypeOptional( self::luaNamespace . __FUNCTION__, 1, 
$result, 'string', null );
                self::$result = $result;
        }
@@ -256,7 +265,8 @@
         * @throws Scribunto_LuaError
         */
        public function wasPosted() {
-               return array( self::getContext()->getRequest()->wasPosted() );
+               self::assertZeroPortal();
+               return array( self::$context->getRequest()->wasPosted() );
        }
 
        /**
@@ -265,7 +275,11 @@
         * @throws Scribunto_LuaError
         */
        private function isSiteAdminInt() {
-               return PortalSpecialPage::isUserZeroAdmin( 
self::getContext()->getUser() );
+               if ( self::$impersonate ) {
+                       return false;
+               } else {
+                       return PortalSpecialPage::isUserZeroAdmin( 
self::$context->getUser() );
+               }
        }
 
        /**
@@ -274,7 +288,10 @@
         * @throws Scribunto_LuaError
         */
        public function getUsernameInt() {
-               $user = self::getContext()->getUser();
+               if ( self::$impersonate ) {
+                       return self::$impersonate;
+               }
+               $user = self::$context->getUser();
                if ( $user->isAnon() ) {
                        return false;
                } else {
diff --git a/includes/PortalSpecialPage.php b/includes/PortalSpecialPage.php
index 3533d52..e30da30 100644
--- a/includes/PortalSpecialPage.php
+++ b/includes/PortalSpecialPage.php
@@ -46,6 +46,46 @@
 
                $user = $this->getUser();
                $isUserZeroAdmin = self::isUserZeroAdmin( $user );
+               $module = 'Portal';
+               $func = 'main';
+               $impersonate = null;
+               if ( $isUserZeroAdmin ) {
+                       try {
+                               // Zero administrators can use 'portal' 
parameter to change title of the startup module
+                               $portal = $this->getRequest()->getVal( 'portal' 
);
+                               if ( $portal ) {
+                                       $parts = explode( '|', $portal, 3 );
+                                       if ( count( $parts ) > 2 ) {
+                                               throw new Exception( 
'<h1>Error: bad "portal" value</h1>' );
+                                       }
+                                       $portal = trim( $parts[0] );
+                                       if ( count( $parts ) > 1 ) {
+                                               $func = trim( $parts[1] );
+                                               if ( !preg_match( 
'`^[_a-zA-Z][_a-zA-Z0-9]*$`', $func ) ) {
+                                                       throw new Exception( 
'Invalid function name ' . $func );
+                                               }
+                                       }
+                                       $t = new TitleValue( NS_MODULE, $portal 
);
+                                       $out->setHTMLTitle( 'Module:' . 
$t->getText() . '|' . $func );
+                                       $module = $t->getDBkey();
+                               }
+                               // Zero administrators can use 'portal' 
parameter to see what another user would see
+                               $impersonate = $this->getRequest()->getVal( 
'impersonate' );
+                               if ( $impersonate !== null ) {
+                                       $u = User::newFromName( $impersonate );
+                                       if ( !$u ) {
+                                               throw new Exception( 
'<h1>Error: bad "impersonate" value</h1>' );
+                                       }
+                                       if ( !$u->getId() ) {
+                                               throw new Exception( 
'<h1>Error: Impersonation user does not exist</h1>' );
+                                       }
+                                       $impersonate = $u->getName();
+                               }
+                       } catch ( Exception $e ) {
+                               $out->addHTML( '<h1>Error: ' . 
htmlspecialchars( $e->getMessage() ) . '</h1>' );
+                               return;
+                       }
+               }
 
                // todo: delete all parameter handling once we start using Lua 
extension functions
                if ( !$user->isAnon() ) {
@@ -68,36 +108,7 @@
                $state = self::encodeParameter( $this->getRequest()->getVal( 
's' ) );
                $user = self::encodeParameter( $user->isAnon() ? false : 
$user->getName() );
 
-
-               $module = 'Portal';
-               $func = 'main';
-               if ( $isUserZeroAdmin ) {
-                       // Zero administrators can use 'portal' parameter to 
change title of the startup module
-                       $portal = $this->getRequest()->getVal( 'portal' );
-                       if ( $portal ) {
-                               try {
-                                       $parts = explode( '|', $portal, 3 );
-                                       if ( count( $parts ) > 2 ) {
-                                               throw new Exception( 
'<h1>Error: bad "portal" value</h1>' );
-                                       }
-                                       $portal = trim( $parts[0] );
-                                       if ( count( $parts ) > 1 ) {
-                                               $func = trim( $parts[1] );
-                                               if ( !preg_match( 
'`^[_a-zA-Z][_a-zA-Z0-9]*$`', $func ) ) {
-                                                       throw new Exception( 
'Invalid function name ' . $func );
-                                               }
-                                       }
-                                       $t = new TitleValue( NS_MODULE, $portal 
);
-                               } catch ( Exception $e ) {
-                                       $out->addHTML( '<h1>Error: ' . 
htmlspecialchars( $e->getMessage() ) . '</h1>' );
-                                       return;
-                               }
-                               $out->setHTMLTitle( 'Module:' . $t->getText() . 
'|' . $func );
-                               $module = $t->getDBkey();
-                       }
-               }
-
-               LuaLibrary::setContext( $this->getContext() );
+               LuaLibrary::setContext( $this->getContext(), $impersonate );
                // todo: delete all extra parameters once we start using Lua 
extension functions
                $out->addWikiText( 
"{{#invoke:$module|$func|$configs|$state|$user}}" );
                $done = LuaLibrary::endInvoke();

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Id2251f8828f8b3ac0980c96019206b3437f2883c
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/ZeroPortal
Gerrit-Branch: master
Gerrit-Owner: Yurik <[email protected]>

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

Reply via email to