On 7/17/2011 6:15 AM, Dmitriy Sintsov wrote:
Hi!
I am trying to port my old user rights restriction extension (which is
not in SVN) to be used with 1.17. As I know, when
$wgGroupPermissions['*']['read'] is true (so-called "public read
wiki"),
since v1.12 there is so-called shortcut path when Title::userCanRead()
is performed. Once it was a hard-coded codepath, now there is method's
static property $useShortcut (unfortunately local and not externally
accessible).
I have public-read wiki, which should restrict 'read' anonymous access
to NS_MAIN but allow anonymous 'read' to NS_PROJECT. I've set up my
extension in such way (worked with very old MW years before). When I use
my extension unmodified with 1.17, it skips extensions checks.
Now, I am trying to fix it. In my extension I use the following hook
handler:
static function BeforeInitialize(&$title,&$article,&$output,
&$user, $request, $mediaWiki ) {
global $wgGroupPermissions;
global $wgUser;
$saveWgUser = $wgUser;
$wgUser = new User();
# begin of set evil Title::$useShortcut to false
$saveAnonRead = $wgGroupPermissions['*']['read'];
$wgGroupPermissions['*']['read'] = false;
$Title = Title::newFromText( 'Version', NS_SPECIAL );
$Title->userCanRead();
$wgUser->clearInstanceCache( 'defaults' );
unset( $Title );
$wgUser = $saveWgUser;
$wgGroupPermissions['*']['read'] = $saveAnonRead;
# end of set evil Title::$useShortcut to false
return true;
}
It initialized $useShortcut static property in Title::userCanRead() to
false value successfully. However, extension does not work anyway. My
expectation that is because I temporarily make
$wgGroupPermissions['*']['read'] = false; before performing
$Title->useCanRead() in 'BeforeInitialize' hook handler. Also this is a
kind of hacky and not safe code. Why cant there be a method of Title
class which would allow to set $useShortcut, so the user access
extensions may work normally? Also, I've noticed that Extension:Lockdown
does not use this method. Will it work with public wiki, or it cannot
restrict anonymous access to "public read wikis" as well?
Dmitriy
The userCan hook fires off before the shortcut, so you should be using that
$result = null;
wfRunHooks( 'userCan', array( &$this, &$wgUser, 'read',
&$result ) );
if ( $result !== null ) {
return $result;
}
# Shortcut for public wikis, allows skipping quite a bit of code
if ( $useShortcut ) {
return true;
}
By setting $result in userCan, you can basically do whatever you want
(Extension:Lockdown uses userCan, I believe, which is why it works
properly). If for some reason you really can't or don't want to use the
userCan hook, set something like $wgRevokePermissions['invalid']['read']
= true; and $wgImplicitGroups[] = 'invalid'; (so that it won't show up
in group name dropdowns), but this is a really hacky workaround that
abuses an implementation detail, so it might change in the future.
Ryan