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