Thread:Project:Support desk/SMF Mediawiki integration - cant log in to mediawiki/reply (2)

As far as I know I am not using an extension. Here is the text of the file SMF_Auth

<?php

/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */

/**    * This file makes MediaWiki use a SMF user database to     * authenticate with. This forces users to have a SMF account * in order to log into the wiki. This should also force the user to    * be in a group called wiki. *    * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by    * the Free Software Foundation; either version 2 of the License, or     * (at your option) any later version. *    * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. *    * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * http://www.gnu.org/copyleft/gpl.html *    * @package MediaWiki * @subpackage Auth_SMF * @author Nicholas Dunnaway * @copyright 2004-2007 php|uber.leet * @license http://www.gnu.org/copyleft/gpl.html * @CVS: $Id: Auth_SMF.php,v 1.3 2007/04/05 22:17:56 nkd Exp $ * @link http://uber.leetphp.com * @version $Revision: 1.3 $ *    */

error_reporting(E_ALL); // Debug

// First check if class has already been defined. if (!class_exists('AuthPlugin')) {       /**         * Auth Plugin *        */        require_once './includes/AuthPlugin.php'; }

/**    * Handles the Authentication with the SMF database. *    * @package MediaWiki * @subpackage Auth_SMF */   class Auth_SMF extends AuthPlugin {

/**        * Add a user to the external authentication database. * Return true if successful. *        * NOTE: We are not allowed to add users to SMF from the * wiki so this always returns false. *        * @param User $user * @param string $password * @return bool * @access public */       function addUser( $user, $password ) {           return false; }

/**        * Can users change their passwords? *        * @return bool */       function allowPasswordChange {           return true; }

/**        * Check if a username+password pair is a valid login. * The name will be normalized to MediaWiki's requirements, so        * you might need to munge it (for instance, for lowercase initial         * letters). *        * @param string $username * @param string $password * @return bool * @access public * @todo Check if the password is being changed when it contains a slash or an escape char. */       function authenticate($username, $password) {

// Connect to the database. $fresMySQLConnection = $this->connect;

// Clean $username and force lowercase username. $username = htmlentities(strtolower($username), ENT_QUOTES, 'UTF-8'); $username = str_replace('&#039;', '\\\'', $username); // Allow apostrophes (Escape them though)

// Check MySQLVersion if ($GLOBALS['gstrMySQLVersion'] >= 4.1) {               // Check Database for username and password. $fstrMySQLQuery = 'SELECT `memberName`, `passwd` FROM `'. $GLOBALS['wgSMF_UserTB']. '`                                  WHERE `memberName` = CONVERT( _utf8 \'' . $username . '\' USING latin1 ) COLLATE latin1_swedish_ci LIMIT 1'; }           else {               // Check Database for username and password. $fstrMySQLQuery = 'SELECT `memberName`, `passwd` FROM `'. $GLOBALS['wgSMF_UserTB']. '`                                  WHERE `memberName` = \''. $username. '\'                                  LIMIT 1'; }

// Query Database. $fresMySQLResult = mysql_query($fstrMySQLQuery, $fresMySQLConnection) or die($this->mySQLError('Unable to view external table'));

while($faryMySQLResult = mysql_fetch_array($fresMySQLResult)) {               // print $this->md5_hmac($password, $username). ':' . $faryMySQLResult['passwd']. ' '; // Debug

// Check if password submited matches the SMF password. // Also check if user is a member of the SMF group 'wiki'. if ($this->md5_hmac($password, $username) == //<-                   $faryMySQLResult['passwd'] && $this->isMemberOfWikiGroup($username)) {                   return true; }           }            return false; }

/**        * Return true if the wiki should create a new local account automatically * when asked to login a user who doesn't exist locally but does in the * external auth database. *        * If you don't automatically create accounts, you must still create * accounts in some way. It's not possible to authenticate without * a local account. *        * This is just a question, and shouldn't perform any actions. *        * NOTE: I have set this to true to allow the wiki to create accounts. *      Without an accout in the wiki database a user will never be         *       able to login and use the wiki. I think the password does not *      matter as long as authenticate returns true. *        * @return bool * @access public */       function autoCreate {           return true; }

/**        * Check to see if external accounts can be created. * Return true if external accounts can be created. *        * NOTE: We are not allowed to add users to SMF from the * wiki so this always returns false. *        * @return bool * @access public */       function canCreateAccounts {           return false; }

/**        * Connect to the database. All of these settings are from the * LocalSettings.php file. This assumes that the SMF uses the same * database/server as the wiki. *        * {@source } * @return resource */       function connect {           // Check if the SMF tables are in a different database then the Wiki. if ($GLOBALS['wgSMF_UseExtDatabase'] == true) {

// Connect to database. I supress the error here. $fresMySQLConnection = @mysql_connect($GLOBALS['wgSMF_MySQL_Host'],                                                     $GLOBALS['wgSMF_MySQL_Username'],                                                      $GLOBALS['wgSMF_MySQL_Password'],                                                      true);

// Check if we are connected to the database. if (!$fresMySQLConnection) {                   $this->mySQLError('There was a problem when connecting to the SMF database. ' .                                      'Check your Host, Username, and Password settings. '); }

// Select Database $db_selected = mysql_select_db($GLOBALS['wgSMF_MySQL_Database'], $fresMySQLConnection);

// Check if we were able to select the database. if (!$db_selected) {                   $this->mySQLError('There was a problem when connecting to the SMF database. ' .                                      'The database ' . $GLOBALS['wgSMF_MySQL_Database'] .                                      ' was not found. '); }

}           else {

// Connect to database. $fresMySQLConnection = mysql_connect($GLOBALS['wgDBserver'],                                                    $GLOBALS['wgDBuser'],                                                     $GLOBALS['wgDBpassword'],                                                     true);

// Check if we are connected to the database. if (!$fresMySQLConnection) {                   $this->mySQLError('There was a problem when connecting to the SMF database. ' .                                      'Check your Host, Username, and Password settings. '); }

// Select Database: This assumes the wiki and SMF are in the same database. $db_selected = mysql_select_db($GLOBALS['wgDBname']);

// Check if we were able to select the database. if (!$db_selected) {                   $this->mySQLError('There was a problem when connecting to the SMF database. ' .                                      'The database ' . $GLOBALS['wgDBname'] . ' was not found. '); }

}

$GLOBALS['gstrMySQLVersion'] = substr(mysql_get_server_info, 0, 3); // Get the mysql version.

return $fresMySQLConnection; }

/**        * If you want to munge the case of an account name before the final * check, now is your chance. */       function getCanonicalName( $username ) {

// Connect to the database. $fresMySQLConnection = $this->connect;

// Clean $username and force lowercase username. $username = htmlentities(strtolower($username), ENT_QUOTES, 'UTF-8'); $username = str_replace('&#039;', '\\\'', $username); // Allow apostrophes (Escape them though)

// Check MySQLVersion if ($GLOBALS['gstrMySQLVersion'] >= 4.1) {

// Check Database for username. We will return the correct casing of the name. $fstrMySQLQuery = 'SELECT `memberName` FROM `'. $GLOBALS['wgSMF_UserTB']. '`                                  WHERE `memberName` = CONVERT( _utf8 \'' . $username . '\' USING latin1 ) COLLATE latin1_swedish_ci LIMIT 1'; }           else {

// Check Database for username. We will return the correct casing of the name. $fstrMySQLQuery = 'SELECT `memberName` FROM `'. $GLOBALS['wgSMF_UserTB']. '`                                  WHERE `memberName` = \''. $username. '\'                                  LIMIT 1'; }

// Query Database. $fresMySQLResult = mysql_query($fstrMySQLQuery, $fresMySQLConnection) or die($this->mySQLError('Unable to view external table'));

while($faryMySQLResult = mysql_fetch_assoc($fresMySQLResult)) {               return ucfirst($faryMySQLResult['memberName']); }       }

/**        * When creating a user account, optionally fill in preferences and such. * For instance, you might pull the email address or real name from the * external user database. *        * The User object is passed by reference so it can be modified; don't         * forget the & on your function declaration. *        * NOTE: This gets the email address from SMF for the wiki account. *        * @param User $user * @access public */       function initUser(&$user) {

// Connect to the database. $fresMySQLConnection = $this->connect;

// Clean $username and force lowercase username. $username = htmlentities(strtolower($user->mName), ENT_QUOTES, 'UTF-8'); $username = str_replace('&#039;', '\\\'', $username); // Allow apostrophes (Escape them though)

// Check MySQLVersion if ($GLOBALS['gstrMySQLVersion'] >= 4.1) {               // Check Database for username and email address. $fstrMySQLQuery = 'SELECT `memberName`, `emailAddress`, `realName` FROM `'. $GLOBALS['wgSMF_UserTB']. '`                                  WHERE `memberName` = CONVERT( _utf8 \'' . $username . '\' USING latin1 ) COLLATE latin1_swedish_ci LIMIT 1'; }           else {               // Check Database for username and email address. $fstrMySQLQuery = 'SELECT `memberName`, `emailAddress`, `realName` FROM `'. $GLOBALS['wgSMF_UserTB']. '`                                  WHERE `memberName` = \''. $username. '\'                                  LIMIT 1'; }

// Query Database. $fresMySQLResult = mysql_query($fstrMySQLQuery, $fresMySQLConnection) or die($this->mySQLError('Unable to view external table'));

while($faryMySQLResult = mysql_fetch_array($fresMySQLResult)) {               $user->mEmail       = $faryMySQLResult['emailAddress']; // Set Email Address. $user->mRealName   = $faryMySQLResult['realName'];     // Set Real Name. }

}

/**        * Checks if the user is a member of the SMF group called wiki. *        * @param string $username * @access public * @return bool * @todo Remove 2nd connection to database. For function isMemberOfWikiGroup *        */        function isMemberOfWikiGroup($username) {           // In LocalSettings.php you can control if being // a member of a wiki is required or not. if (isset($GLOBALS['wgSMF_UseWikiGroup']) && $GLOBALS['wgSMF_UseWikiGroup'] === false) {               return true; }

// Connect to the database. $fresMySQLConnection = $this->connect;

// Check MySQL Version if ($GLOBALS['gstrMySQLVersion'] >= 4.1) {               // Get all the groups the user is a member of. $fstrMySQLQuery = 'SELECT `additionalGroups`, `ID_GROUP` FROM `'. $GLOBALS['wgSMF_UserTB']. '`                                  WHERE `memberName` = CONVERT( _utf8 \'' . $username . '\' USING latin1 ) COLLATE latin1_swedish_ci LIMIT 1'; }           else {               // Get all the groups the user is a member of. $fstrMySQLQuery = 'SELECT `additionalGroups`, `ID_GROUP` FROM `'. $GLOBALS['wgSMF_UserTB']. '`                                  WHERE `memberName` = \''. $username. '\'                                  LIMIT 1'; }

// Query Database. $fresMySQLResult = mysql_query($fstrMySQLQuery, $fresMySQLConnection) or die($this->mySQLError('Unable to view external table'));

while($faryMySQLResult = mysql_fetch_array($fresMySQLResult)) {               $faryTmp   = explode(',', $faryMySQLResult['additionalGroups']); // This is a Comma Sep List $faryTmp[] = $faryMySQLResult['ID_GROUP']; }

// Get all the groups the user is a member of. $fstrMySQLQuery = 'SELECT `ID_GROUP` FROM `'. $GLOBALS['wgSMF_GroupsTB']. '`                              WHERE `groupName` = \''. $GLOBALS['wgSMF_WikiGroupName']. '\'                              LIMIT 1';

// Query Database. $fresMySQLResult = mysql_query($fstrMySQLQuery, $fresMySQLConnection) or die($this->mySQLError('Unable to view external table'));

if (empty($fresMySQLResult)) {               die($this->mySQLError('Config Error, Unable to find group called '. $GLOBALS['wgSMF_WikiGroupName'])); }

while($faryMySQLResult = mysql_fetch_array($fresMySQLResult)) {               $fstrWikiID = $faryMySQLResult['ID_GROUP']; }

// Check if the user group was found. if (empty($fstrWikiID) || !isset($fstrWikiID)) {               die($this->mySQLError('Config Error, Unable to find group called '. $GLOBALS['wgSMF_WikiGroupName'])); }

if (array_search($fstrWikiID, $faryTmp) !== false) {               return true; // User is in Wiki group. }           else {               return false; // User is not in Wiki group. }       }

/**        * This is the MD5 Encryption SMF uses for passwords. Taken from Load.php *        * @param string $data * @param string $key * @return string */       function md5_hmac($data, $key) {           // Check if the user has the cfg file setup correctly. if (!isset($GLOBALS['wgSMF_Version'])) {               die(' Error: You did not set $wgSMF_Version in your LocalSettings.php file.

Please read the README file that came with the Auth_SMF plug-in for more info. ');           }

if (empty($GLOBALS['wgSMF_Version'])) {               die(' Error: You did not set $wgSMF_Version in your LocalSettings.php file.

Please read the README file that came with the Auth_SMF plug-in for more info. ');           }

// Check that a valid version was passed. if ($GLOBALS['wgSMF_Version'] != '1.0' && $GLOBALS['wgSMF_Version'] != '1.1') {               die(' Error: Value passed in $wgSMF_Version is not valid.

Please read the README file that came with the Auth_SMF plug-in for more info. ');           }

if ($GLOBALS['wgSMF_Version'] == '1.0') {               $key = strtolower($key); $key = str_pad(strlen($key) <= 64 ? $key : pack('H*', md5($key)), 64, chr(0x00)); return md5(($key ^ str_repeat(chr(0x5c), 64)) . pack('H*', md5(($key ^ str_repeat(chr(0x36), 64)). $data))); }

if ($GLOBALS['wgSMF_Version'] == '1.1') {               return sha1(strtolower($key) . $data); }

// This should never happen. die(' Error: Value passed in $wgSMF_Version is not valid.

Please read the README file that came with the Auth_SMF plug-in for more info. ');       }

/**        * Modify options in the login template. *        * NOTE: Turned off some Template stuff here. Anyone who knows where * to find all the template options please let me know. I was only able * to find a few. *        * @param UserLoginTemplate $template * @access public */       function modifyUITemplate( &$template ) {           $template->set('usedomain',   false); // We do not want a domain name. $template->set('create',     false); // Remove option to create new accounts from the wiki. $template->set('useemail',   false); // Disable the mail new password box. }

/**        * This prints an error when a MySQL error is found. *        * @param string $message * @access public */       function mySQLError( $message ) {           echo $message. ' ';           echo 'MySQL Error Number: '. mysql_errno. ' ';           echo 'MySQL Error Message: '. mysql_error. '

';           exit; }

/**        * Set the domain this plugin is supposed to use when authenticating. *        * NOTE: We do not use this. *        * @param string $domain * @access public */       function setDomain( $domain ) {           $this->domain = $domain; }

/**        * Set the given password in the authentication database. * Return true if successful. *        * NOTE: We only allow the user to change their password via phpBB. *        * @param string $password * @return bool * @access public */       function setPassword( $password ) {           return true; }

/**        * Return true to prevent logins that don't authenticate here from being * checked against the local database's password fields. *        * This is just a question, and shouldn't perform any actions. *        * Note: This forces a user to pass Authentication with the above *      function authenticate. So if a user changes their SMF *      password, their old one will not work to log into the wiki. *      Wiki does not have a way to update it's password when SMF *      does. This however does not matter. *        * @return bool * @access public */       function strict {           return true; }

/**        * Update user information in the external authentication database. * Return true if successful. *        * @param $user User object. * @return bool * @public */       function updateExternalDB( $user ) {           return true; }

/**        * When a user logs in, optionally fill in preferences and such. * For instance, you might pull the email address or real name from the * external user database. *        * The User object is passed by reference so it can be modified; don't         * forget the & on your function declaration. *        * NOTE: Not useing right now. *        * @param User $user * @access public */       function updateUser( &$user ) {           return true; }

/**        * Check whether there exists a user account with the given name. * The name will be normalized to MediaWiki's requirements, so        * you might need to munge it (for instance, for lowercase initial         * letters). *        * NOTE: MediaWiki checks its database for the username. If it has *      no record of the username it then asks. "Is this really a        *       valid username?" If not then MediaWiki fails Authentication. *        * @param string $username * @return bool * @access public * @todo write this function. */       function userExists($username) {           // Connect to the database. $fresMySQLConnection = $this->connect;

// Clean $username and force lowercase username. $username = htmlentities(strtolower($username), ENT_QUOTES, 'UTF-8'); $username = str_replace('&#039;', '\\\'', $username); // Allow apostrophes (Escape them though)

// Check MySQL Version if ($GLOBALS['gstrMySQLVersion'] >= 4.1) {               // Check Database for username. $fstrMySQLQuery = 'SELECT `memberName` FROM `'. $GLOBALS['wgSMF_UserTB']. '`                                  WHERE `memberName` = CONVERT( _utf8 \'' . $username . '\' USING latin1 ) COLLATE latin1_swedish_ci LIMIT 1'; }           else {               // Check Database for username. $fstrMySQLQuery = 'SELECT `memberName` FROM `'. $GLOBALS['wgSMF_UserTB']. '`                                  WHERE `memberName` = \''. $username. '\'                                  LIMIT 1'; }

// Query Database. $fresMySQLResult = mysql_query($fstrMySQLQuery, $fresMySQLConnection) or die($this->mySQLError('Unable to view external table'));

while($faryMySQLResult = mysql_fetch_array($fresMySQLResult)) {               // print htmlentities(strtolower($username), ENT_QUOTES, 'UTF-8'). ' : ' . htmlentities(strtolower($faryMySQLResult['username']), ENT_QUOTES, 'UTF-8'); // Debug

// Double check match. if (htmlentities(strtolower($username), ENT_QUOTES, 'UTF-8') ==                   htmlentities(strtolower($faryMySQLResult['memberName']), ENT_QUOTES, 'UTF-8')) {                   return true; // Pass }           }            return false; // Fail }

/**        * Check to see if the specific domain is a valid domain. *        * @param string $domain * @return bool * @access public */       function validDomain( $domain ) {           return true; }

}

?>