'AuthP4', 'url' => 'http://public.perforce.com/wiki/index.php/AuthP4_%28MediaWiki_authentication_plugin%29', 'author' => 'Sam Stafford', 'description' => 'Authenticate via Perforce server', ); require_once('AuthPlugin.php'); class AuthP4 extends AuthPlugin { function AuthP4() { } function userExists( $username ) { $inf = array(); $err = array(); $user = escapeshellarg( wiki_to_p4( $username ) ); run_p4_s( "groups $user", $inf, $err ); return( count( $inf ) ); } function authenticate( $username, $password ) { global $wgP4EXEC; global $wgP4PORT; $inf = array(); $err = array(); $user = escapeshellarg( wiki_to_p4( $username ) ); $pass = $password; //passed thru pipe, not arg! $descriptors = array ( 0 => array("pipe", "r"), 1 => array("pipe", "w") ); $p4 = "$wgP4EXEC -p $wgP4PORT -u $user -s"; $loginproc = proc_open( "$p4 login -p", $descriptors, $pipes); if ( !is_resource( $loginproc ) ) { return false; } fwrite( $pipes[0], $pass ); fclose( $pipes[0] ); while ( !feof( $pipes[1] ) ) { sort_p4_s_output( fgets( $pipes[1] ), $inf, $err ); } fclose( $pipes[1] ); proc_close( $loginproc ); return( count( $inf ) ); } function modifyUITemplate( &$template ) { //Disable mail password (since it doesn't work), the //account creation (since we want registration to always //go through the Perforce account signup process), and the //domain box (since it's irrelevant). $template->set('useemail', false); $template->set('create', false); $template->set('domain', false); $template->set('usedomain', false); //Tweak "nologin" prompt to point at a custom page instead of //the disabled "create account" special page. global $wgP4PORT; global $wgServer; global $wgScriptPath; $reglink = $wgServer.$wgScriptPath.'/index.php?title=Registration'; $template->set('link', "Log in with the user/password you use on $wgP4PORT.
Don't have a registered Public Depot account? Register here."); } function updateUser( &$user ) { //Doesn't do anything, but needs to return true so MWiki //doesn't think there was a problem. return true; } function autoCreate() { //Create wiki accounts automagically if Perforce accounts //exists. This eliminates the need to set up wiki accounts //seperately. return true; } //Make people use "p4 passwd" for now. //This could be implemented with "p4 passwd $USER" //at some point if desired. function allowPasswordChange() { return false; } function setPassword( $user, $password ) { return false; } function updateExternalDB( $user ) { //Could be implemented with "p4 user -f USER", but //we'll leave it alone for now. Still needs to return //true or automatic account creation will fail. return true; } //Not allowed to use local-only accounts or create Perforce //accounts. function canCreateAccounts() { return false; } function addUser( $user, $password, $email='', $realname='' ) { return false; } function strict() { return true; } function initUser( &$user ) { //Called on account creation. //Pull fullname and email from Perforce. The user //may change them later if desired. $p4username = escapeshellarg( wiki_to_p4( $user->getName() ) ); $p4user = array(); run_p4_tag( "user -o $p4username", $p4user ); if ( isset( $p4user['Email'] ) ) { $user->setEmail( $p4user['Email'] ); } if ( isset( $p4user['FullName'] ) ) { $user->setRealName( $p4user['FullName'] ); } } function getCanonicalName( $username ) { //Force names to standard casing to prevent duplicates. $user = trim( $username ); $user = str_replace( "_", " ", $user ); // 'JOHN_DOE' -> 'JOHN DOE' $user = strtolower( $user ); // 'JOHN DOE' -> 'john doe' $user = ucwords( $user ); // 'john doe' -> 'John Doe' return $user; } } // end AuthPlugin class //Things below this line aren't part of the AuthPlugin interface. function run_p4_s( $command, &$info, &$error ) { global $wgP4EXEC; global $wgP4PORT; global $wgP4USER; global $wgP4PASSWD; $p4 = "$wgP4EXEC -p $wgP4PORT -u $wgP4USER -P $wgP4PASSWD -s"; $exit = false; $out = array(); exec( "$p4 $command", $out ); foreach( $out as $line ) { if ( $line == "exit: 1" ) { $exit = false; } elseif ( $line == "exit: 0" ) { $exit = true; } else sort_p4_s_output( $line, $info, $error ); } return $exit; } function run_p4_tag( $command, &$tagdict ) { global $wgP4EXEC; global $wgP4PORT; global $wgP4USER; global $wgP4PASSWD; $p4 = "$wgP4EXEC -p $wgP4PORT -u $wgP4USER -P $wgP4PASSWD -Ztag"; $out = array(); exec( "$p4 $command", $out ); foreach( $out as $line ) { sort_p4_tag_output( $line, $tagdict ); } } function sort_p4_s_output( $line, &$info, &$error ) { if ( substr( $line, 0, 6 ) == "info: " ) { array_push( $info, substr( $line, 6 ) ); } elseif ( substr( $line, 0, 7 ) == "error: " ) { array_push( $error, substr( $line, 7 ) ); } } function sort_p4_tag_output( $line, &$tagdict ) { if ( !substr( $line, 0, 4 ) == "... " ) { return; } $line = substr( $line, 4 ); $tagend = strpos( $line, " " ); $tag = substr( $line, 0, $tagend ); $data = substr( $line, $tagend + 1 ); $tagdict[$tag] = $data; } function wiki_to_p4( $user ) { $user = trim( $user ); $user = str_replace( " ", "_", $user ); $user = strtolower( $user ); return $user; } function testUserExists( $user ) { if ( AuthP4::userExists( $user ) ) { print( "$user exists.\n" ); } else { print( "$user does not exist.\n" ); } } function testAuthenticate( $user, $pass ) { if ( AuthP4::authenticate( $user, $pass ) ) { print( "$user authenticated with $pass\n" ); } else { print( "$user failed authentication with $pass\n" ); } } $wgAuth = new AuthP4(); ?>