Experimental authentication plugin interface. Will require a little bit more work...
authorBrion Vibber <brion@users.mediawiki.org>
Tue, 16 Nov 2004 05:28:47 +0000 (05:28 +0000)
committerBrion Vibber <brion@users.mediawiki.org>
Tue, 16 Nov 2004 05:28:47 +0000 (05:28 +0000)
RELEASE-NOTES
includes/AuthPlugin.php [new file with mode: 0644]
includes/DefaultSettings.php
includes/Setup.php
includes/SpecialUserlogin.php
includes/User.php

index 733b3f5..820b1c8 100644 (file)
@@ -33,6 +33,7 @@ Major changes from 1.3.x:
 * New tag "<gallery>" 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 (file)
index 0000000..eb2d469
--- /dev/null
@@ -0,0 +1,111 @@
+<?php
+# Copyright (C) 2004 Brion Vibber <brion@pobox.com>
+# 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
index b4aedd4..58b6a25 100644 (file)
@@ -827,6 +827,11 @@ $wgLoggedInGroupId = 2;
 
 $wgWhitelistRead = array ( ':Accueil', ':Main_Page');
 
+/**
+ * Authentication plugin.
+ */
+$wgAuth = null;
+
 } else {
        die();
 }
index d096fda..f0d135f 100644 (file)
@@ -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.
index 89eedcb..463e82d 100644 (file)
@@ -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;
index 192e210..ac2bceb 100644 (file)
@@ -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;