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