From f5a1ac67984d44077ca132ce8f1ca0f5de1ea905 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Tue, 16 Nov 2004 05:28:47 +0000 Subject: [PATCH] Experimental authentication plugin interface. Will require a little bit more work to nail down all requirements. --- RELEASE-NOTES | 1 + includes/AuthPlugin.php | 111 ++++++++++++++++++++++++++++++++++ includes/DefaultSettings.php | 5 ++ includes/Setup.php | 5 ++ includes/SpecialUserlogin.php | 36 +++++++++-- includes/User.php | 9 +++ 6 files changed, 163 insertions(+), 4 deletions(-) create mode 100644 includes/AuthPlugin.php diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 733b3f5664..820b1c8d6b 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -33,6 +33,7 @@ Major changes from 1.3.x: * New tag "" to generate a table of image thumbnails * Installer die if it can not write LocalSettings.php (bug #733) * Various special pages no more show the rss/atom feed links (bug #705) +* Support for external authentication plug-ins * ... and more! === Caveats === diff --git a/includes/AuthPlugin.php b/includes/AuthPlugin.php new file mode 100644 index 0000000000..eb2d469f31 --- /dev/null +++ b/includes/AuthPlugin.php @@ -0,0 +1,111 @@ + +# http://www.mediawiki.org/ +# +# 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 + +/** + * 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... + * + * @package MediaWiki + */ + +class AuthPlugin { + /** + * 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 ) { + # Override this! + 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 ) { + # Override this! + 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. + * + * This is just a question, and shouldn't perform any actions. + * + * @return bool + * @access public + */ + function autoCreate() { + return false; + } + + /** + * 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 false; + } + + /** + * 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 ) { + # Override this to do something. + } +} + +?> \ No newline at end of file diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php index b4aedd4f02..58b6a25f8d 100644 --- a/includes/DefaultSettings.php +++ b/includes/DefaultSettings.php @@ -827,6 +827,11 @@ $wgLoggedInGroupId = 2; $wgWhitelistRead = array ( ':Accueil', ':Main_Page'); +/** + * Authentication plugin. + */ +$wgAuth = null; + } else { die(); } diff --git a/includes/Setup.php b/includes/Setup.php index d096fda718..f0d135f46a 100644 --- a/includes/Setup.php +++ b/includes/Setup.php @@ -217,6 +217,11 @@ foreach ( $wgSkinExtensionFunctions as $func ) { $func(); } +if( !is_object( $wgAuth ) ) { + require_once( 'AuthPlugin.php' ); + $wgAuth = new AuthPlugin(); +} + if( $wgCommandLineMode ) { # Used for some maintenance scripts; user session cookies can screw things up # when the database is in an in-between state. diff --git a/includes/SpecialUserlogin.php b/includes/SpecialUserlogin.php index 89eedcbe72..463e82d4a8 100644 --- a/includes/SpecialUserlogin.php +++ b/includes/SpecialUserlogin.php @@ -194,10 +194,25 @@ class LoginForm { } } + return $this->initUser( $u ); + } + + /** + * Actually add a user to the database. + * Give it a User object that has been initialised with a name. + * + * @param User $u + * @return User + * @access private + */ + function &initUser( &$u ) { $u->addToDatabase(); $u->setPassword( $this->mPassword ); $u->setEmail( $this->mEmail ); $u->setRealName( $this->mRealName ); + + global $wgAuth; + $wgAuth->initUser( $u ); if ( $this->mRemember ) { $r = 1; } else { $r = 0; } @@ -224,11 +239,24 @@ class LoginForm { } $id = $u->idForName(); if ( 0 == $id ) { - $this->mainLoginForm( wfMsg( 'nosuchuser', $u->getName() ) ); - return; + global $wgAuth; + /** + * If the external authentication plugin allows it, + * automatically create a new account for users that + * are externally defined but have not yet logged in. + */ + if( $wgAuth->autoCreate() && + $wgAuth->userExists( $u->getName() ) && + $wgAuth->authenticate( $u->getName(), $this->mPassword ) ) { + $u =& $this->initUser( $u ); + } else { + $this->mainLoginForm( wfMsg( 'nosuchuser', $u->getName() ) ); + return; + } + } else { + $u->setId( $id ); + $u->loadFromDatabase(); } - $u->setId( $id ); - $u->loadFromDatabase(); if (!$u->checkPassword( $this->mPassword )) { $this->mainLoginForm( wfMsg( 'wrongpassword' ) ); return; diff --git a/includes/User.php b/includes/User.php index 192e210894..ac2bceb388 100644 --- a/includes/User.php +++ b/includes/User.php @@ -1014,6 +1014,15 @@ class User { */ function checkPassword( $password ) { $this->loadFromDatabase(); + + global $wgAuth; + if( $wgAuth->authenticate( $this->getName(), $password ) ) { + return true; + } elseif( $wgAuth->strict() ) { + /* Auth plugin doesn't allow local authentication */ + return false; + } + $ep = $this->encryptPassword( $password ); if ( 0 == strcmp( $ep, $this->mPassword ) ) { return true; -- 2.20.1