Extension:VBulletin/Users Integration

From MediaWiki.org
Jump to: navigation, search
MediaWiki extensions manual
Crystal Clear action run.png
VBulletin/Users Integration

Release status: stable

Implementation User identity
Description integrates vBulletin users with MediaWiki . Restricts editing pages to registered users with a single LOGIN shared with vB!
Author(s) m:User:LarryEitel ???
Latest version 3.5.4
MediaWiki 1.6.3
License No license specified
Download No link

Translate the VBulletin/Users Integration extension if it is available at translatewiki.net

Check usage and version matrix; code metrics
Wikimedia-logo-meta.png

This page was moved from MetaWiki.
It probably requires cleanup – please feel free to help out. In addition, some links on the page may be red; respective pages might be found at Meta. Remove this template once cleanup is complete.


Working Example[edit | edit source]

I have taken Kai Backman's MediaWiki authentication plugin idea, fixed coding errors, and expanded greatly on it.

Working on: vBulletin 3.5.4 and MediaWiki 1.6.3

Features:

  • Allows you to run MediaWiki with your vBulletin user database
  • Disallows users with invalid username characters
  • Disallows users who are not part of specified usergroups
  • Sets users to sysop status in MediaWiki if they are part of a specified admin usergroup
  • Removes users from sysop status in MediaWiki if they no longer are a part of a specified admin usergroup
  • For same-database setups, allows easy installation

Possible Future Features[edit | edit source]

These are possible features for inclusion in the how-to in the future. They have not been investigated for their feasibility, but are here to let you know they have been requested and I am thinking about them. If you know how to add the features, please let us know.

  • No-login required (automatic) integration
  • Option: User profile field points to, or has option to link to vBulletin profile
  • To register, link the user to vBulletin's registration script on the login pages

How To[edit | edit source]

  • Install Reynaldovb's Restrict usernames to alphanumeric and underscore plugin, and disallow both spaces and underscores (vbulletin 3.7+ use the admincp / Options / Username Regular Expression field to ensure the username conforms to a certain format).
  • Optional: On boards that already have existing users, somehow have their usernames changed so that they are only alphanumeric. This is required if you wish your users to be able to login and edit the wiki using their vBulletin username. The reason you have to do this is because MediaWiki has some Restrictions on what can go in a page title, and as usernames have to be passed as page titles, they also have to adhere to the same restrictions. If you do not change the usernames, I have included a check to not allow users to login if their username contains non-alphanumeric characters.
  • Open your wiki/LocalSettings.php file
  • Insert the following code at the end of the file, before the ?>:
# vBulletin integration script
require_once("AuthPlugin_vBulletin.php");
// if vBulletin and MediaWiki are not installed on the same database
// change these values to reflect your vBulletin database information
$wgAuth = new AuthPlugin_vBulletin($wgDBserver, $wgDBuser, $wgDBpassword, $wgDBname, "vb_");

If you are running vBulletin and MediaWiki in the same database, then it already uses the connection information. If you are not running vBulletin and MediaWiki in the same database, please change the strings to reflect your vBulletin database information. In either case, the last value is whatever your vBulletin 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;
$wgWhitelistRead = array ("Special:Userlogin");

This prevents people from registering new accounts on the wiki, requiring people to register on vBulletin. It also prevents anonymous edits. This code may only work on MediaWiki 1.5.x and above, but I am unsure.

  • Copy this AuthPlugin_vBulletin.php file and put it in your main wiki directory, ie: /wiki/AuthPlugin_vBulletin.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...
 *
 * AuthPlugin extension by Daniel Gravenor c/o HolisticEarth.org
 * AuthPlugin original by Kai Backman
 *
 * @package MediaWiki
 */
require_once("includes/AuthPlugin.php");
 
class AuthPlugin_vBulletin extends AuthPlugin {
 
	// Create a persistent DB connection
	var $vb_database;
 
	function AuthPlugin_vBulletin($host, $username, $password, $dbname, $prefix) {
		$this->vb_database = mysql_pconnect($host, $username, $password);
		mysql_select_db($dbname, $this->vb_database);
		$this->vb_prefix = $prefix;
		// set the usergroups for those who can edit the wiki
		$this->allowed_usergroups = Array(2, 5, 6, 7);
		// set the usergroups for the administrators
		$this->admin_usergroups = Array(6, 9);
		$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);
			$vb_find_user_query = "SELECT usergroupid FROM " . $this->vb_prefix . "user WHERE LOWER(username)=LOWER('" . $username . "')";
			$vb_find_result = mysql_query($vb_find_user_query, $this->vb_database);
			// make sure that there is only one person with the username
			if (mysql_num_rows($vb_find_result) == 1) {
				$vb_userinfo = mysql_fetch_assoc($vb_find_result);
				mysql_free_result($vb_find_result);
				// Only registered and admins. Banned and unregistered don't belong here.
				if (in_array($vb_userinfo['usergroupid'], $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);
			$vb_find_user_query = "SELECT password, salt, usergroupid FROM " . $this->vb_prefix . "user WHERE LOWER(username)=LOWER('" . $username . "')";
			$vb_find_result = mysql_query($vb_find_user_query, $this->vb_database);
			if (mysql_num_rows($vb_find_result) == 1) {
				$vb_userinfo = mysql_fetch_assoc($vb_find_result);
				mysql_free_result($vb_find_result);
				// Only registered and admins. Banned and unregistered don't belong here.
				if (in_array($vb_userinfo['usergroupid'], $this->allowed_usergroups)) {
					if(md5(md5($password) .  $vb_userinfo['salt']) == $vb_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
		$vb_find_user_query = "SELECT usergroupid, membergroupids FROM " . $this->vb_prefix . "user WHERE LOWER(username)=LOWER('" . addslashes($user->mName) . "')";
		$vb_find_result = mysql_query($vb_find_user_query, $this->vb_database) or die("Could not find username");
		if(mysql_num_rows($vb_find_result) == 1) {
			$vb_userinfo = mysql_fetch_assoc($vb_find_result);
			mysql_free_result($vb_find_result);
			// go through the users member groups to see if one of them is administrative
			$user_membergroups = explode(",", $vb_userinfo['membergroupids']);
			$admin_secondary = FALSE;
			for ($x = 0; $x < count($user_membergroups); $x++) {
				if (in_array($user_membergroups[$x], $this->admin_usergroups)) $admin_secondary = TRUE;
			}
 
			if (in_array($vb_userinfo['usergroupid'], $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($vb_userinfo['usergroupid'], $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 ) { 
		$vb_find_user_query = "SELECT email, usergroupid FROM " . $this->vb_prefix . "user WHERE LOWER(username)=LOWER('" . addslashes($user->mName) . "')";
		$vb_find_result = mysql_query($vb_find_user_query, $this->vb_database);
		if(mysql_num_rows($vb_find_result) == 1) {
			$vb_userinfo = mysql_fetch_assoc($vb_find_result);
			mysql_free_result($vb_find_result);
			$user->mEmail = $vb_userinfo['email'];
			$user->mEmailAuthenticated = wfTimestampNow();
		}
	}
}

MediaWiki (MW)[edit | edit source]

Anonymous / Guest Visitors[edit | edit source]

In vB, a nice feature is to track the non-registered visitors. You can see how many members AND GUESTS on presently at the site... even down to the thread level.

It occurs to me that whenever someone goes to MW, it triggers a vB session and/or logs them in if there is a cookie. The reason is that some, actually more and more, people are going directly to the MW. I would like to make sure that the site stats as to who has been to the domain are maintained site-wide.

Login[edit | edit source]

  • If attempt is made to perform a function that requires login, redirect to vB to login.
  • Afterward, return user to page from where he came from.
Files to modify

Registration[edit | edit source]

  • Redirect user to vB for registration.
  • Use the following details to create a MW user (with link back to vB)
    • vB:userid
    • vB:username
    • vB:timezoneoffset
    • vB:salt
    • email authentification. Handled through vB.
    • vB:usergroupid. Need to validate that user has had email authenticated. Decision to only allow validated users to update wiki pages.
    • vB:email? Maybe not because all email will be done using vB email address.
    • vB:field? Disable e-mail from other users. See (http://www.noblood.org/forum/profile.php?do=editoptions)
    • Real Name: If user has entered their real name, use that or else default to vB username
    • MW:Nickname = vB:username
  • Ignore MW password, use vB only
  • vB:membergroupids, this contains the groups that the user is a member of. We need to map these to MW:user_groups
  • vB:usergroup, this contains the NAME of the groups that will be mapped to the MW:user_groups
Files to modify

Passwords[edit | edit source]

  • Only use vB

Authentication Method[edit | edit source]

Here is some base code for authenticating. This is not a working example, it is only a starting point.

This code needs to be modified to accommodate MediaWiki's needs by setting cookies. The query also may need to be enhanced to to look for things MediaWiki uses in its cookies/sessions. Thanks to Alfarin over at vb.com for this start.

$query = "
   SELECT
       userid, password, salt
   FROM
       [table-prefix]user
   WHERE
       username = '" . addslashes($_POST['username']) . "' 
   LIMIT 1;";
   // execute the query using mediaWiki's database object, retrieve the results, etc. 
   // ...
   // ...
   // ...
   // assume result stored in $data[]
 if (md5( $_POST['password'] . $salt ) == $data['password']) {
   // authentication successful, set cokies as
   setcookies("bbuserid", $data['userid']);
   setcookies("bbpassword", md5($data['password'] . "YOURLICENSENUMBERHERE"));
 } else {
   // authentication failed
   // redirect to error page
}  

Preferences[edit | edit source]

  • Default switches ON for:
    • Send me an email on page changes
    • Send me an email when my user talk page is changed
  • Need to disable certain options (preferences) that are now handled by vB
    • User dialog: Real name, email, nickname, raw signature, language
    • Password dialog: disable all, Use vB instead
    • Email dialog: Disable e-mail from other users (Use vB switch for that)
    • Skin dialog: Disable all (default to MonoBook)
    • Time zone dialog: Disable, use vB

Email User[edit | edit source]

  • Link in MW toolbox: Special:Emailuser/<username> to link to vB's function (vB/sendmessage.php?do=mailmember&u=#####) for this.
  • OR since email addresses are synchronized with MW, make no change.

Email Notifications[edit | edit source]

  • Use the email from MW since email addresses are synchronized.

Links back to vB[edit | edit source]

  • MW User: page to provide (in header, right-justified) a link automatically to vB user profile and link to email or PM.
    • In localsettings.php, provide for user defined icon path to define vB user profile link AND one for link to vB/MW email function
  • In preferences, user data dialog: Add link to vB user control panel (profile)

MW Special Pages[edit | edit source]

  • Special:Listusers: We need to add a link/icon next to each listed user to their vB profile.

Useful Extension Proposals[edit | edit source]

  • <vb>username=johndoe;fld=userTblFieldName</vb> Return vB user table field value
  • <email>username=johndoe</email> Return site defined icon that links to vB email user feature.


Skin/Style Issues[edit | edit source]

  • Question: Make MW the entry point with link to vB OR make vB the entry point to site?
    • If MW is the entry point..
      • Need to add key userCP type menu options
      • Need (IMHO) to present key vB type info on front page such as Who's Online!!!! Since MW caches pages, where/how to inject some real-time info into page? Turn off caching? Insert 'live' content AFTER footer? :(

vBulletin (vB)[edit | edit source]

vB Functions That Affect MW[edit | edit source]

  • User updates password
  • User changes email
  • User toggles switch to accept emails from others
  • User changes timezoneoffset
  • User changes real name fields
  • User changes homepage, or other fields

Sessions[edit | edit source]

  • Need to keep vB sessions alive so that we can see who's online whether they are in MW or in vB

Integration Issues[edit | edit source]

The largest problem with integrating vBulletin and MediaWiki is the use of characters not allowed in the MediaWiki namespace. In MediaWiki, the characters allowed in a username are the same that are allowed in a page name, and you can find those on the Help:Page name page.

There are two easy possibilities, which I have not explored or found information on:

  • If you have a small vB membership, renaming people's usernames so that they do not have the unwanted characters. In this case you will also want to edit vBulletin's registration function to disallow unwanted characters as well.
  • Making any links to a user's page link to their user page on vBulletin. Theoretically, this would allow people to keep their usernames intact, while not interfering with the MediaWiki namespace.

See also[edit | edit source]