Extension:Vanilla Authentication
|
Vanilla Authentication Release status: stable |
|
|---|---|
| Implementation | User identity |
| Description | |
| Author(s) | Daniel Gravenor Kai Backman |
| MediaWiki | 1.6+ |
| License | No license specified |
| Download | see below |
| Check usage and version matrix | |
Vanilla Authentication is an authentication plugin designed to use Lussumo's Vanilla forum software userbase. The work is based off of the vBulletin/Users Integration.
Working on: MediaWiki 1.6 and Vanilla 1.0
Features:
- Allows you to run MediaWiki with your Vanilla user database
- Disallows users who do not have specified roles in Vanilla user database
- Sets users to sysop status in MediaWiki if they have a specific role in Vanilla user database
- Removes users from sysop status in MediaWiki if they no longer have a specific role in Vanilla user database
- For same-database setups, allows easy installation
How To [edit]
- Open your wiki/LocalSettings.php file
- Insert the following code at the end of the file, before the ?>:
# Vanilla integration script
require_once("AuthPlugin_Vanilla.php");
// if Vanilla and MediaWiki are not installed on the same database
// change these values to reflect your Vanilla database information
$wgAuth = new AuthPlugin_Vanilla($wgDBserver, $wgDBuser, $wgDBpassword, $wgDBname, "LUM_");
If you are running Vanilla and MediaWiki in the same database, then it already uses the connection information. If you are not running Vanilla and MediaWiki in the same database, please change the strings to reflect your Vanilla database information. In either case, the last value is whatever your Vanilla table prefix is.
- Insert this code below the require_once( "includes/DefaultSettings.php" ); at the top of the LocalSettings.php file:
# Disabling new user registrations $wgWhitelistAccount = array ( "sysop" => 1, "developer" => 1 ); # Disabling anonymous edits $wgGroupPermissions['*']['createaccount'] = false; $wgGroupPermissions['*']['read'] = false; $wgGroupPermissions['*']['edit'] = false; $wgGroupPermissions['*']['createpage'] = false; $wgGroupPermissions['*']['createtalk'] = true; $wgWhitelistRead = array ("Special:Userlogin");
This prevents people from registering new accounts on the wiki, requiring people to register on Vanilla. It also prevents anonymous edits. This code may only work on MediaWiki 1.6.x and above.
- Copy this AuthPlugin_Vanilla.php file and put it in your main wiki directory, ie: /wiki/AuthPlugin_Vanilla.php
<?php /** * Authentication plugin interface. Instantiate a subclass of AuthPlugin * and set $wgAuth to it to authenticate against some external tool. * * The default behavior is not to do anything, and use the local user * database for all authentication. A subclass can require that all * accounts authenticate externally, or use it only as a fallback; also * you can transparently create internal wiki accounts the first time * someone logs in who can be authenticated externally. * * This interface is new, and might change a bit before 1.4.0 final is * done... * * Vanilla model by David Cramer [http://www.davidcramer.net/] * AuthPlugin extension by Daniel Gravenor c/o HolisticEarth.org * AuthPlugin original by Kai Backman * * @package MediaWiki */ require_once("includes/AuthPlugin.php"); class AuthPlugin_Vanilla extends AuthPlugin { // Create a persistent DB connection var $vanilla_database; function AuthPlugin_Vanilla($host, $username, $password, $dbname, $prefix) { $this->vanilla_database = mysql_pconnect($host, $username, $password); mysql_select_db($dbname, $this->vanilla_database); $this->vanilla_prefix = $prefix; // set the usergroups for those who can edit the wiki $this->allowed_usergroups = Array(3, 4, 5, 6); // set the usergroups for the administrators $this->admin_usergroups = Array(5, 6); $this->user_rights = Array("sysop"); // search pattern to only accept alphanumeric or underscore characters in usernames // if they have illegal characters, their name cannot exist, period $this->searchpattern = "/[^a-zA-Z0-9]+/"; } /** * 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). * * @param string $username * @return bool * @access public */ function userExists($username ) { // if no illegal characters are found in their username, then check to see if they exist if (!preg_match($this->searchpattern, $username)) { $username = addslashes($username); $vanilla_find_user_query = "SELECT RoleID FROM " . $this->vanilla_prefix . "User WHERE Name LIKE '" . $username . "'"; $vanilla_find_result = mysql_query($vanilla_find_user_query, $this->vanilla_database); // make sure that there is only one person with the username if (mysql_num_rows($vanilla_find_result) == 1) { $vanilla_userinfo = mysql_fetch_assoc($vanilla_find_result); mysql_free_result($vanilla_find_result); // Only registered and admins. Banned and unregistered don't belong here. if (in_array($vanilla_userinfo['RoleID'], $this->allowed_usergroups)) { return true; } } } // if no one is registered with that username, or there are more than 1 entries // or they have illegal characters return false (they do not exist) return false; } /** * 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 */ function authenticate($username, $password) { // if their name does not contain any illegal characters, let them try to login if (!preg_match($this->searchpattern, $username)) { $username = addslashes($username); $vanilla_find_user_query = "SELECT Password, RoleID FROM " . $this->vanilla_prefix . "User WHERE Name LIKE '" . $username . "'"; $vanilla_find_result = mysql_query($vanilla_find_user_query, $this->vanilla_database); if (mysql_num_rows($vanilla_find_result) == 1) { $vanilla_userinfo = mysql_fetch_assoc($vanilla_find_result); mysql_free_result($vanilla_find_result); // Only registered and admins. Banned and unregistered don't belong here. if (in_array($vanilla_userinfo['RoleID'], $this->allowed_usergroups)) { if(md5($password) == $vanilla_userinfo['Password']) return true; } } } return false; } /** * 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. * * @param User $user * @access public */ function updateUser( &$user ) { # Override this and do something $vanilla_find_user_query = "SELECT RoleID FROM " . $this->vanilla_prefix . "User WHERE Name LIKE'" . addslashes($user->mName) . "'"; $vanilla_find_result = mysql_query($vanilla_find_user_query, $this->vanilla_database) or die("Could not find username"); if(mysql_num_rows($vanilla_find_result) == 1) { $vanilla_userinfo = mysql_fetch_assoc($vanilla_find_result); mysql_free_result($vanilla_find_result); if (in_array($vanilla_userinfo['RoleID'], $this->admin_usergroups) || $admin_secondary === true) { // if a user is not a sysop, make them a sysop if (!in_array("sysop", $user->getEffectiveGroups())) { $user->addGroup('sysop'); return true; } } // if the user is not an administrator, but they were, and they are still a sysop, remove their sysop status if (!in_array($vanilla_userinfo['RoleID'], $this->admin_usergroups) && $admin_secondary === false) { if (in_array("sysop", $user->getEffectiveGroups())) { $user->removeGroup('sysop'); 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. * * @return bool * @access public */ function autoCreate() { 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. * * @return bool * @access public */ function strict() { return true; } /** * 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. * * @param User $user * @access public */ function initUser( &$user ) { $vanilla_find_user_query = "SELECT Email, RoleID FROM " . $this->vanilla_prefix . "User WHERE Name LIKE '" . addslashes($user->mName) . "'"; $vanilla_find_result = mysql_query($vanilla_find_user_query, $this->vanilla_database); if(mysql_num_rows($vanilla_find_result) == 1) { $vanilla_userinfo = mysql_fetch_assoc($vanilla_find_result); mysql_free_result($vanilla_find_result); $user->mEmail = $vanilla_userinfo['Email']; $user->mEmailAuthenticated = wfTimestampNow(); } } } ?>
Note that the above won't work if you're using the latest version of Vanilla released in fall 2008, because the password hashes are no longer using md5. See this page for more information.
There is, however, a hack you can use to get this to work. Assuming that your vanilla installation is in a directory called "forum" under your mediawiki directory, add the following to the top of the above file:
require_once("forum/library/People/People.Class.PasswordHash.php");
Then replace the following line in the above file:
if(md5($password) == $vanilla_userinfo['Password']) return true;
with this:
// The params here are taken from the default values of // PASSWORD_HASH_ITERATION and PASSWORD_HASH_PORTABLE in appg/settings.php. $pwHash = new PasswordHash(8, 1); if ($pwHash->CheckPassword($password, $vanilla_userinfo['Password'])) return true;
