Merge "(bug 38556) Add header and footer messages to MediaWiki's info action"
[lhc/web/wiklou.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;
54
55 /**
56 * @var DatabaseBase
57 */
58 private $mDb;
59
60 /**
61 * @param $name string
62 * @return bool
63 */
64 protected function initFromName( $name ) {
65 # We might not need the 'usable' bit, but let's be safe. Theoretically
66 # this might return wrong results for old versions, but it's probably
67 # good enough.
68 $name = User::getCanonicalName( $name, 'usable' );
69
70 if ( !is_string( $name ) ) {
71 return false;
72 }
73
74 return $this->initFromCond( array( 'user_name' => $name ) );
75 }
76
77 /**
78 * @param $id int
79 * @return bool
80 */
81 protected function initFromId( $id ) {
82 return $this->initFromCond( array( 'user_id' => $id ) );
83 }
84
85 /**
86 * @param $cond array
87 * @return bool
88 */
89 private function initFromCond( $cond ) {
90 global $wgExternalAuthConf;
91
92 $this->mDb = DatabaseBase::factory( $wgExternalAuthConf['DBtype'],
93 array(
94 'host' => $wgExternalAuthConf['DBserver'],
95 'user' => $wgExternalAuthConf['DBuser'],
96 'password' => $wgExternalAuthConf['DBpassword'],
97 'dbname' => $wgExternalAuthConf['DBname'],
98 'tablePrefix' => $wgExternalAuthConf['DBprefix'],
99 )
100 );
101
102 $row = $this->mDb->selectRow(
103 'user',
104 array(
105 'user_name', 'user_id', 'user_password', 'user_email',
106 'user_email_authenticated'
107 ),
108 $cond,
109 __METHOD__
110 );
111 if ( !$row ) {
112 return false;
113 }
114 $this->mRow = $row;
115
116 return true;
117 }
118
119 # TODO: Implement initFromCookie().
120
121 public function getId() {
122 return $this->mRow->user_id;
123 }
124
125 /**
126 * @return string
127 */
128 public function getName() {
129 return $this->mRow->user_name;
130 }
131
132 public function authenticate( $password ) {
133 # This might be wrong if anyone actually uses the UserComparePasswords hook
134 # (on either end), so don't use this if you those are incompatible.
135 return User::comparePasswords( $this->mRow->user_password, $password,
136 $this->mRow->user_id );
137 }
138
139 public function getPref( $pref ) {
140 # @todo FIXME: Return other prefs too. Lots of global-riddled code that does
141 # this normally.
142 if ( $pref === 'emailaddress'
143 && $this->row->user_email_authenticated !== null ) {
144 return $this->mRow->user_email;
145 }
146 return null;
147 }
148
149 /**
150 * @return array
151 */
152 public function getGroups() {
153 # @todo FIXME: Untested.
154 $groups = array();
155 $res = $this->mDb->select(
156 'user_groups',
157 'ug_group',
158 array( 'ug_user' => $this->mRow->user_id ),
159 __METHOD__
160 );
161 foreach ( $res as $row ) {
162 $groups[] = $row->ug_group;
163 }
164 return $groups;
165 }
166
167 # TODO: Implement setPref().
168 }