Hi. I just signed up for the list, so this could probably be threaded
better, but I don't have the past messages. But, another admin on a
wiki I'm working on suggested this would be relevant to some ongoing
discussions.
We have our whole wiki protected in apache with AuthBasic, and have
matched everyone's wiki account to their apache account. We wanted to
log people in based on the AuthBasic name and password if possible, so
I wrote this change to User.php (from mediawiki-1.3.9):
#existing code shown for context. Starts at User.php, line 174 in
loadFromSession()
#the new code is all in the second else if
if ( isset( $_SESSION['wsUserID'] ) ) {
if ( 0 != $_SESSION['wsUserID'] ) {
$sId = $_SESSION['wsUserID'];
} else {
return new User();
}
} else if ( isset( $_COOKIE["{$wgDBname}UserID"] ) ) {
$sId = IntVal( $_COOKIE["{$wgDBname}UserID"] );
$_SESSION['wsUserID'] = $sId;
} else if ( isset( $_SERVER["PHP_AUTH_USER"]) ) {
# even if we can't find the user in the session
# we might be able to fake it using Basic-Auth information.
# Code largely stolen from SpecialUserlogin::processLogin()
# The way it gets input values was changed, and any of
# the fail conditions were changed to fail silently and
# return a new user, as this code block does when it can't
# identify any user from the session.
global $wgUser;
global $wgDeferredUpdateList;
$name = $_SERVER["PHP_AUTH_USER"];
$password = $_SERVER["PHP_AUTH_PW"];
$u = User::newFromName( $name );
if( is_null( $u ) ) {
return new User();
}
$id = $u->idForName();
if ( 0 == $id ) {
return new User();
}
$u->setId( $id );
$u->loadFromDatabase();
if (!$u->checkPassword( $password )) {
return new User();
}
# We've verified now, update the real record
#
# We don't have a remember toggle here. We'll
# assume we shouldn't remember... next time we
# can do this Basic-Auth hoopla again.
$r = 0;
$u->setOption( "rememberpassword", $r );
# Can't rely on $wgUser being set on return, as
# UserUpdate() depends on $wgUser. I'm not particularly
# clear on what $wgDeferredUpdateList does, but I
# don't want to break it.
$wgUser = $u;
$wgUser->setCookies();
$up = new UserUpdate();
array_push( $wgDeferredUpdateList, $up );
# don't have access to the cookie checking functions in this page.
# also, they may not be as critical, since we can just pull
# from Basic-Auth everytime.
wfDebug("Successfully logged in $wgUser->mName from Basic-Auth.");
return $u;
} else {
return new User();
}
# end of code
If someone could point me to a page on producing a .patch file from a
subversion repository, I'd be happy to post the patch in a file. It's
still a little rough, but I don't know enough about the internals to
know what needs to be smoothed out.
I was stuck for a while because I didn't realize how mediawiki gets
past this block in normal execution. But note that if the first two
ifs succeed (i.e. user has a valid id stored in SESSION) or if the
first else if is true (i.e. user has a valid id in a session cookie)
it will proceed to the rest of the method. The problem of course being
that we had a name and password only, no id, but wanted to log the
user in. This loadFromSession code was originally designed to work
only with an ongoing session or with a user that asked for their login
to be remembered in cookies between sessions, either case stores a
UserID as well as a UserName. The only code that logs a user in using
only a name and password that I found was in
SpecialUserlogin::processLogin().
I hope that helps, and I look forward to any feedback!
Dave