Extension:AuthDrupal

From MediaWiki.org

(Redirected from AuthDrupal)
Jump to: navigation, search

         

Manual on MediaWiki Extensions
List of MediaWiki Extensions
Crystal Clear action run.png
AuthDrupal

Release status: unknown

Implementation  User identity
Description Uses Drupal as signin master
Author(s)  Mitch Schwenk, Maarten van Dantzich
Last Version  0.6.1 (2008-07-02)
MediaWiki  1.11.x
License No license specified
Download http://thinkling.com/pub/src/AuthDrupal/AuthDrupal-0.6.1.tgz

check usage (experimental)

Contents

[edit] Overview

Signin integration for MediaWiki as slave of Drupal. (For the reverse setup, see Extension:DrupalIntegration.)

Reported to work using Drupal 4.7.x and 5.x, MediaWiki 1.9, 1.10, 1.11. Not yet tested with MediaWiki 1.12 or Drupal 6. I no longer have a need for AuthDrupal in my own projects, so I have not kept up with new releases. Please see the Discussion page for reports of updates by others. If someone would like to take over maintenance, please let me know.

This code supports single signin for users of a Drupal site and a MediaWiki site. It is set up so that users sign in to the Drupal site, and as a result they automatically become logged in to the wiki.

The code replaces the wiki's own log in/register/logout links with links to the drupal front page to to force users to go through Drupal. (See below.)

User entries are still created in the wiki's user table and are kept up to date on each login with email and real name.

The login integration works as follows: when the user signs in to Drupal, an extra cookie is created containing their identity. When the user visits the wiki, the wiki extension sees the cookie, extracts the username, and logs the user in. When the user logs out of the Drupal site, both the special cookie and any of the wiki's session cookies are removed so the user is also signed out of the wiki.

[edit] Credits

  • This implementation started with the code written by TazzyTazzy (Mitch Schwenk) <tazzytazzy2 (at) yahoo (dot) com> available at: DCCwiki.
  • Support for separate databases is based on Auth_phpBB.
  • Testing with Drupal 5.1 by Paul Coghlan
  • Testing with Drupal 5.1 and MediaWiki 1.10.1 by Michael Joseph

[edit] Known Issues

[edit] Bugs

  • Login/Logout links are modified based on the existence of the DRXtrArgs cookie, should instead be based on the actual user login status. To do this, the two login_link/logout_link hook functions should be combined, and inside the hook check for the cookie and/or $wgUser->getId() != 0. Thinkling 21:08, 1 April 2007 (UTC)
  • Should not keep the cookie domain setting in two places. It's currently in LocalSettings.php and in Mediawiki.module.
  • Currently there's logout code in both Mediawiki.module and in AuthDrupal.php. The code is now the same, need to test if doing it in both places is truly redundant.
  • Passwords are currently not copied into the MW database. If you use this extension and then decide the run the wiki as a standalone app with its own login system, you'll have to have passwords reset/emailed for everyone. When MW 1.10 ships, should change code to use $wgUser->setInternalPassword()
  • It's been reported that creating a new account in Drupal may log you in to the Drupal site, but does not call the hook function that sets the cookie necessary to log in to Mediawiki. If someone can confirm this and/or suggest a fix, please leave a note on the discussion page.
  • Users are matched based on usernames only. If you rename a user on the Drupal site, they will not be connected with their existing login in Mediawiki. If you delete a user and create a new one by the same name, Mediawiki will connect the new user with the old account of that name on the wiki side.

[edit] Missing Features

  • I have code implemented to disable editing of Real name and Email address in My Preferences but haven't gotten the patch in shape to be released yet.
  • Does NOT handle someone changing their username on the Drupal end. That user will be regarded as a new user by the wiki next time they sign in.
  • Should replace the "You have to log in to edit pages" message from code; the right way to do this would be to create a file with localizable messages and load those into the message cache, as e.g. Extension:Linksearch does.
  • When user clicks over to the Drupal page to log in, there's no mechanism to bring them back to the wiki page they came from. If anyone has tips on how to implement this, please leave a note on the talk page.

[edit] Other

The Drupal-specific issues should now be filed on Drupal.org.

[edit] Comments or Feedback?

If you have comments, questions, or improvements, please drop me a note via the discussion page, or email me via my user page.

[edit] Files

Please download the necessary files from [1]

[edit] Instructions

<!-- distributed with AuthDrupal v 0.6, 2008-0620 -->

If you are reading this in an INSTALL.txt file, then these instructions are for
the version of the files you have.

The latest version of these instructions and of the code can be found at
[http://www.mediawiki.org/w/index.php?title=Extension:AuthDrupal].

* download the AuthDrupal files and save or unpack them into
  wiki/extensions/AuthDrupal/

* put Mediawiki.module, Mediawiki.info, and a copy of AuthDrupalEncode.php into
  drupal/modules (yes, you want AuthDrupalEncode.php in both places).

* Add code in AddToLocalSettings.php to the end of your wiki/LocalSettings.php
  file. Change the database settings to match your setup.
  
  Change the cookie domain name  to the domain under which your Drupal and wiki
  are hosted.  If drupal and mediawiki use the same database, just set
  $wgAuthDrupal_UseExtDatabase = false and ignore most of the  _MySQL_ settings.

* You need to assign a key to use to encode the username to prevent spoofing.
  Make up a key string (something unique, think of it as a password) and set
  the same value for wgAuthDrupal_security_key in both LocalSettings.php
  and Mediawiki.module.
  
* Edit the other settings at the top of Mediawiki.module so that each item matches
  what you have set in LocalSettings.php. If you have multiple wikis sharing
  the same Drupal login, create a block of settings for each wiki. If you only
  have one wiki, delete the second example settings.

* To get rid of the "You must log in to edit pages" notice when a non-logged-in
  user clicks the Edit tab, do the following:

  ** Go to the article called "MediaWiki:Whitelistedittext".
  ** The edit box should be preloaded with this text: "You have to $1 to edit
     pages."
  ** Change this to the following (replace the url with whatever you've set for
     $wgAuthDrupal_LoginURL):

     You have to <span class="plainlinks">[http://mydomain.com log in]</span> to edit pages.

* go into Drupal admin pages and enable the Mediawiki module

Things should work at this point. If behavior is funny at first, delete the
cookies for your domain, and try it again with a fresh start.

Optional parts:

* you may want to ensure that account creation is blocked. Try going to
  /wiki/index.php?title=Special:Userlogin&type=signup
  (TODO: document how to turn off account creation)

* even though the extension can change the login/logout link to point to Drupal,
  that does not stop a savvy user from going to Special:Userlogin directly. You
  may want to edit .htaccess to redirect that URL. There are instructions for
  this at the bottom of this page:
  [http://wiki.case.edu/CaseWiki:External_Authentication]

[edit] If running on localhost

If you're using 'localhost' as your cookie domain, AuthDrupal may not work right. Edit the settings at the top of Mediawiki.module and set the cookie domain to an empty string there. That probably helps.

[edit] Replaced mcrypt

Version 0.6 no longer uses mcrypt to encode and decode the cookie containing the current user's username. The code now uses a homebrew encoding that should be hard for malicious users to spoof. If you're highly concerned about tight security, you may want to put support for mcrypt back in. (See 0.4 sources for the old version.)

[edit] Controlling behavior

These are global variables you CAN set in LocalSettings.php to control how AuthDrupal behaves:

# Do NOT copy the code from this section into your LocalSettings.php.
# This is documentation, not meant to be running code. Copy the code from the 
# section ''Edits to LocalSettings.php'', below.

 $wgAuthDrupal_ReplaceLogin	// true or false, replace MW login/logout links?
 $wgAuthDrupal_LoginURL         // 
 $wgAuthDrupal_LogoutURL
 
 $wgAuthDrupal_UseExtDatabase // true or false; are MW and Drupal in separate databases? 
 
 // OPTIONAL: if these are the same as your MediaWiki settings, leave them set as is
 $wgAuthDrupal_MySQL_Host     = $wgDBserver;         // Drupal MySQL Host Name.
 $wgAuthDrupal_MySQL_Username = $wgDBuser;           // Drupal MySQL Username.
 $wgAuthDrupal_MySQL_Password = $wgDBpassword;       // Drupal MySQL Password.
 
 // you'll want to set this to the database name:
 $wgAuthDrupal_MySQL_Database
 $wgAuthDrupal_TablePrefix	= "";
 $wgAuthDrupal_UserTable     = 'users';        // Name of your Drupal user table. (normally 'users')
 $wgAuthDrupal_RolesTable     	= 'role';       // Name of your Drupal user table. (normally 'role')
 $wgAuthDrupal_UsersRolesTable	= 'users_roles'; // Name of your Drupal user table. (normally 'users_roles')
 
 $wgAuthDrupal_LogMessages	// true or false, log messages to Drupal watchdog?
 $wgAuthDrupal_UID              // OPTIONAL userID to use when logging watchdog messages
 
 // in my Drupal install, I have enabled the profile extension to add 
 // first name and last name to user profiles. (I require them during signup)
 // This allows MW to pull in the real name from the Drupal profile.
 // If you don't have this, just leave GetRealNames set to false
 $wgAuthDrupal_GetRealNames  // true or false, get first + last name from Drupal profile extension?
 
 // $wgAuthDrupal_PropagateRoles :
 // Set this to true if you want Drupal user roles to be turned into Mediawiki
 // group membership. If you want ALL roles to be turned into groups, leave
 // $wgAuthDrupal_Roles empty. You can limit the roles that should be propagated 
 // by setting $wgAuthDrupal_Roles to an array containing names of roles to be
 // propagated, like $wgAuthDrupal_Roles = array( 'staff', 'member' );
 $wgAuthDrupal_PropagateRoles = false;
 $wgAuthDrupal_Roles = null;  // null means propagate all roles
 
 // OPTIONAL:
 $wgAuthDrupal_RealNames_fields_table; // set if different than 'profile_fields'
 $wgAuthDrupal_RealNames_values_table; // set if different than 'profile_values'
 $wgAuthDrupal_RealNames_first_name_field; // set if different than 'profile_first_name'
 $wgAuthDrupal_RealNames_last_name_field;  // set if different than 'profile_last_name'

[edit] Edits to LocalSettings.php

Please see the file AddToLocalSettings.php in the tarball for code to add to your LocalSettings.php and edit values as appropriate for your site.

[edit] Change History

  • v 0.6.1 - 2008-07
    • one of the files had whitespace after the closing php tag. oops! fixed.
  • v 0.6 - 2008-06
    • removed use of mcrypt and replaced with weaker home-grown username encoding.
    • made support for user roles optional, turned off by default, and now allows only some roles to be propagated. (This is not well tested.)
  • v 0.5 - 2007-09
    • corrected return values from hook functions as suggested by anisotropic in this comment
    • added support for pulling user roles from Drupal and setting them as group membership on the MW user object. updateUser() is now called for existing session as well as new session to ensure user roles are pulled fresh from Drupal.


  • 0.4: Added support to allow multiple wikis sharing the same Drupal login front page; user is always logged in to all at the same time and logged out from all at the same time. Thinkling 23:12, 29 July 2007 (UTC)
  • 0.3.2: Fix for MW 1.10.1 and some code reformatting.
  • IP address check removed. Code used to check that user's IP address has remained the same between login to Drupal and visit to the wiki. This meant e.g. if you moved to another wifi network with your laptop, the authentication would fail such that the login/logout links at the op were in an inconsistent state. Thinkling 21:11, 1 April 2007 (UTC)

[edit] Drupal 6.2 and MediaWiki 1.13+

In Authdrupal.php:

Change this line:

	$wgHooks['AutoAuthenticate'][] = 'Auth_drupal_autologin_hook'; /* Hook for magical authN */

To:

	// Twin Rose 5/16/2009
	// AutoAuthenticate was deprecated in MediaWiki 1.3 use "UserLoadFromSession"
	//$wgHooks['AutoAuthenticate'][] = 'Auth_drupal_autologin_hook'; /* Hook for magical authN */
	$wgHooks['UserLoadFromSession'][] = 'Auth_drupal_UserLoadFromSessionHook';

Then add this function after Auth_drupal_autologin_hook:

function Auth_drupal_UserLoadFromSessionHook($user, &$result) 
{
	global $wgUser;
	global $wgAuth;
	global $wgContLang;
 
	//! dbg wfDebug("##" . __FUNCTION__ . "\n"); //!dbg XXX remove
 
	// Give us a user, see if we're around
	// Twin Rose: 5/16/2009
	// We can't call static functiosn because we're calling it FROM a user object.
	// $tmpuser = User::newFromSession();
	// MJ: changed from $tmpuser->loadFromSession();
	//$tmpuser->mFrom = 'session';
	// Now lets check for drupal cookie
	$name = getCurrentDrupalUsername();
 
	if ( empty( $name ) ) {
		return false;
	}
 
	$user->mDataLoaded = false;
	$user->mFrom = 'name';
	$user->mName = $name;
	$rc = $user->load();
 
	// If there's a prior session, check that it matches the current Drupal user
	if ($rc && $user->isLoggedIn()) 
	{
		if ( $wgAuth->authenticate( $user->getName(), '' ) ) {
			//!dbg wfDebug("AuthDrupal: User " . $tmpuser->getName() . " already logged in\n");
 
			// update email, real name, etc.
			$wgAuth->updateUser( $user );
 
			return true;
 
		} else {
			// log out the existing user and continue below to start over
			$user->logout();
 
			// no return here--fall through to code below
		}
	}
 
	// is it a new user?
	if ( 0 == $user->getID() ) {
		// we have a new user to add...
		$drupal_user = $wgAuth->getDrupalUser( $name );
 
		if ( empty( $drupal_user ) ) {
			wfDebug( __FUNCTION__ . " AuthDrupal ERROR: " . $name . " not found in Drupal DB \n" );
			return false;
		}
 
		//!dbg wfDebug( "AuthDrupal: logging in NEW user " . $name . "\n" );
 
		// this mimicks what LoginForm::initUser() does (code identical to
		// regular login moved down to common code)
		$user->setName( $wgContLang->ucfirst( $drupal_user->name ) );
		$user->addToDatabase();
 
		// Update user count in site stats (stolen from SpecialUserlogin)
		$ssUpdate = new SiteStatsUpdate( 0, 0, 0, 0, 1 );
		$ssUpdate->doUpdate();
 
		// LoginForm::initUser() calls $wgAuth->initUser, but I don't see the point
		// $wgAuth->initUser( $u );
	} else {
		//!dbg wfDebug( "AuthDrupal: logging in existing user " . $name . "\n" );
 
	}
 
	// update email, real name, etc.
	$wgAuth->updateUser( $user );
 
	// Go ahead and log 'em in
	$user->setToken();
	$user->saveSettings();
	$user->setupSession();
	$user->setCookies();
 
	$message = 'MediWiki session (cookie) opened for <em>' . $name . '</em>.';
	$wgAuth->drupal_uid = $user->getID();
	$wgAuth->logit( $message );
 
	$return_user = $user;
	return true;
}

[edit] See also

Integration in the opposite direction: