]> scripts.mit.edu Git - autoinstalls/mediawiki.git/blob - includes/extauth/MediaWiki.php
MediaWiki 1.17.0
[autoinstalls/mediawiki.git] / includes / extauth / MediaWiki.php
1 <?php
2 /**
3  * External authentication with external MediaWiki database.
4  *
5  * Copyright © 2009 Aryeh Gregor
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  * http://www.gnu.org/copyleft/gpl.html
21  *
22  * @file
23  */
24
25 /**
26  * This class supports authentication against an external MediaWiki database,
27  * probably any version back to 1.5 or something.  Example configuration:
28  *
29  *   $wgExternalAuthType = 'ExternalUser_MediaWiki';
30  *   $wgExternalAuthConf = array(
31  *       'DBtype' => 'mysql',
32  *       'DBserver' => 'localhost',
33  *       'DBname' => 'wikidb',
34  *       'DBuser' => 'quasit',
35  *       'DBpassword' => 'a5Cr:yf9u-6[{`g',
36  *       'DBprefix' => '',
37  *   );
38  *
39  * All fields must be present.  These mean the same things as $wgDBtype, 
40  * $wgDBserver, etc.  This implementation is quite crude; it could easily 
41  * support multiple database servers, for instance, and memcached, and it 
42  * probably has bugs.  Kind of hard to reuse code when things might rely on who 
43  * knows what configuration globals.
44  *
45  * If either wiki uses the UserComparePasswords hook, password authentication 
46  * might fail unexpectedly unless they both do the exact same validation.  
47  * There may be other corner cases like this where this will fail, but it 
48  * should be unlikely.
49  *
50  * @ingroup ExternalUser
51  */
52 class ExternalUser_MediaWiki extends ExternalUser {
53         private $mRow, $mDb;
54
55         protected function initFromName( $name ) {
56                 # We might not need the 'usable' bit, but let's be safe.  Theoretically 
57                 # this might return wrong results for old versions, but it's probably 
58                 # good enough.
59                 $name = User::getCanonicalName( $name, 'usable' );
60
61                 if ( !is_string( $name ) ) {
62                         return false;
63                 }
64
65                 return $this->initFromCond( array( 'user_name' => $name ) );
66         }
67
68         protected function initFromId( $id ) {
69                 return $this->initFromCond( array( 'user_id' => $id ) );
70         }
71
72         private function initFromCond( $cond ) {
73                 global $wgExternalAuthConf;
74
75                 $this->mDb = DatabaseBase::newFromType( $wgExternalAuthConf['DBtype'],
76                         array(
77                                 'server'      => $wgExternalAuthConf['DBserver'],
78                                 'user'        => $wgExternalAuthConf['DBuser'],
79                                 'password'    => $wgExternalAuthConf['DBpassword'],
80                                 'dbname'      => $wgExternalAuthConf['DBname'],
81                                 'tableprefix' => $wgExternalAuthConf['DBprefix'],
82                         )
83                 );
84
85                 $row = $this->mDb->selectRow(
86                         'user',
87                         array(
88                                 'user_name', 'user_id', 'user_password', 'user_email',
89                                 'user_email_authenticated'
90                         ),
91                         $cond,
92                         __METHOD__
93                 );
94                 if ( !$row ) {
95                         return false;
96                 }
97                 $this->mRow = $row;
98
99                 return true;
100         }
101
102         # TODO: Implement initFromCookie().
103
104         public function getId() {
105                 return $this->mRow->user_id;
106         }
107
108         public function getName() {
109                 return $this->mRow->user_name;
110         }
111
112         public function authenticate( $password ) {
113                 # This might be wrong if anyone actually uses the UserComparePasswords hook 
114                 # (on either end), so don't use this if you those are incompatible.
115                 return User::comparePasswords( $this->mRow->user_password, $password,
116                         $this->mRow->user_id ); 
117         }
118
119         public function getPref( $pref ) {
120                 # FIXME: Return other prefs too.  Lots of global-riddled code that does 
121                 # this normally.
122                 if ( $pref === 'emailaddress'
123                 && $this->row->user_email_authenticated !== null ) {
124                         return $this->mRow->user_email;
125                 }
126                 return null;
127         }
128
129         public function getGroups() {
130                 # FIXME: Untested.
131                 $groups = array();
132                 $res = $this->mDb->select(
133                         'user_groups',
134                         'ug_group',
135                         array( 'ug_user' => $this->mRow->user_id ),
136                         __METHOD__
137                 );
138                 foreach ( $res as $row ) {
139                         $groups[] = $row->ug_group;
140                 }
141                 return $groups;
142         }
143
144         # TODO: Implement setPref().
145 }