GuzzleJsonAuth::canCreateAccounts()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
/**
3
 * GuzzleJsonAuth
4
 *
5
 * Licensed under the MIT license.
6
 * For full copyright and license information, please see the LICENSE.txt.
7
 *
8
 * @copyright Marc Würth
9
 * @license http://www.opensource.org/licenses/mit-license.php MIT License
10
 * @author Marc Würth <[email protected]>
11
 */
12
13
namespace MediaWiki\GuzzleJsonAuth;
14
15
use \GuzzleHttp\Client;
16
use \GuzzleHttp\Message\ResponseInterface;
17
18
/**
19
 * Authenticate with a JSON endpoint using a configurable Guzzle client
20
 *
21
 * To Setup the authentication, add the following lines to your
22
 * LocalSettings.php and change the values to your needs:
23
 *
24
 * # Setup GuzzleJsonAuth
25
 * $wgGuzzleJsonAuthUrl = 'http://yourapplication.com/your_json_endpoint';
26
 *
27
 * $wgGuzzleJsonRequestBaseKey = 'User';
28
 * $wgGuzzleJsonRequestUsernameKey = 'username';
29
 * $wgGuzzleJsonRequestPasswordKey = 'password';
30
 *
31
 * $wgGuzzleJsonResponseBaseKey = 'user';
32
 * $wgGuzzleJsonResponseUsernameKey = 'username';
33
 * $wgGuzzleJsonResponseRealNameKey = 'real_name';
34
 * $wgGuzzleJsonResponseEmailKey = 'email';
35
 *
36
 * // Load and initialize the GuzzleJsonAuth extension
37
 * require_once("$IP/extensions/GuzzleJsonAuth/GuzzleJsonAuth.php");
38
 * $wgAuth = new \MediaWiki\GuzzleJsonAuth\GuzzleJsonAuth();
39
 *
40
 * Authenticated users will be created in your Wikis database,
41
 * but without password.
42
 *
43
 * The authentication endpoint needs to return at least tne
44
 * username, real name and email of the authenticated user as result.
45
 * If the authentication failed, it must not return the username,
46
 * otherwise it the user will be logged in nonetheless.
47
 *
48
 * This extension will fall back to local authentication,
49
 * if the user could not be authenticated externally.
50
 *
51
 * @link http://www.mediawiki.org/wiki/Extension:Typo3Auth Inspired by
52
 * @todo Setup default values for the config settings where sensible
53
 */
54
class GuzzleJsonAuth extends \AuthPlugin
55
{
56
    /**
57
     * Contains the data of the authenticated user
58
     *
59
     * @var null|array
60
     */
61
    protected $_user = null;
62
63
    /**
64
     * Simply state the user in question exists without checking
65
     *
66
     * {@inheritDoc}
67
     */
68
    public function userExists($username)
69
    {
70
        return true;
71
    }
72
73
    /**
74
     * Authenticate with a JSON endpoint using a configurable Guzzle client
75
     *
76
     * {@inheritDoc}
77
     * @SuppressWarnings(PHPMD.Superglobals)
78
     */
79
    public function authenticate($username, $password)
80
    {
81
        $authUrl = $GLOBALS['wgGuzzleJsonAuthUrl'];
82
83
        // Prepare request
84
        $authData = $this->_setAuthData($username, $password);
85
        $options = array(
86
            'json' => $authData,
87
            'headers' => array(
88
                'content-type' => 'application/json',
89
                'Accept' => 'application/json',
90
            ),
91
        );
92
93
        // Send request
94
        $client = $this->_getGuzzleClient();
95
        $response = $client->post($authUrl, $options);
96
97
        // Extract user data from response
98
        $this->_extractUserData($response);
99
100
        // Authentication is successful if a username is returned
101
        if ($this->_getUserField('username')) {
102
            return true;
103
        }
104
105
        return false;
106
    }
107
108
    /**
109
     * Initialize the authenticated user with the data from the external DB
110
     *
111
     * {@inheritDoc}
112
     */
113
    public function initUser(&$user, $autocreate = false)
114
    {
115
        $user->setRealName($this->_getUserField('realName'));
116
        $user->setEmail($this->_getUserField('email'));
117
        $user->mEmailAuthenticated = wfTimestampNow();
118
    }
119
120
    /**
121
     * Update the authenticated user with the data from the external DB
122
     *
123
     * {@inheritDoc}
124
     */
125
    public function updateUser(&$user)
126
    {
127
        $user->setRealName($this->_getUserField('realName'));
128
        $user->setEmail($this->_getUserField('email'));
129
        $user->mEmailAuthenticated = wfTimestampNow();
130
        $user->saveSettings();
131
        return true;
132
    }
133
134
    /**
135
     * Auto create a new local account automatically
136
     * when asked to login a user who doesn't exist
137
     * locally but does in the external auth database
138
     *
139
     * {@inheritDoc}
140
     */
141
    public function autoCreate()
142
    {
143
        return true;
144
    }
145
146
    /**
147
     * Do not allow any property changes
148
     *
149
     * {@inheritDoc}
150
     */
151
    public function allowPropChange($prop = '')
152
    {
153
        return false;
154
    }
155
156
    /**
157
     * Do not allow to change the password
158
     *
159
     * {@inheritDoc}
160
     */
161
    public function allowPasswordChange()
162
    {
163
        return false;
164
    }
165
166
    /**
167
     * Do not store the password in the local DB
168
     *
169
     * {@inheritDoc}
170
     */
171
    public function allowSetLocalPassword()
172
    {
173
        return false;
174
    }
175
176
    /**
177
     * Disable setting the password
178
     *
179
     * {@inheritDoc}
180
     */
181
    public function setPassword($user, $password)
182
    {
183
        return false;
184
    }
185
186
    /**
187
     * Disable updating the external DB
188
     *
189
     * {@inheritDoc}
190
     */
191
    public function updateExternalDB($user)
192
    {
193
        return true;
194
    }
195
196
    /**
197
     * Disable updating the groups in the external DB
198
     *
199
     * {@inheritDoc}
200
     */
201
    public function updateExternalDBGroups($user, $addgroups, $delgroups = array())
202
    {
203
        return true;
204
    }
205
206
    /**
207
     * Disable creating accounts in the external DB
208
     *
209
     * {@inheritDoc}
210
     */
211
    public function canCreateAccounts()
212
    {
213
        return false;
214
    }
215
216
    /**
217
     * Disable adding user to the external DB
218
     *
219
     * {@inheritDoc}
220
     */
221
    public function addUser($user, $password, $email = '', $realname = '')
222
    {
223
        return false;
224
    }
225
226
    /**
227
     * Allow certain local user accounts, such as the Wiki Admin, to login
228
     *
229
     * {@inheritDoc}
230
     */
231
    public function strict()
232
    {
233
        return false;
234
    }
235
236
    /**
237
     * Disable strict user auth for all users
238
     *
239
     * {@inheritDoc}
240
     *
241
     * @todo Consider adding a configurable array of users who are allowed to be authenticated locally, set strict() to true then
242
     */
243
    public function strictUserAuth($username)
244
    {
245
        return false;
246
    }
247
248
    /**
249
     * Set the authentication data for the request.
250
     *
251
     * @param string $username The username to authenticate.
252
     * @param string $password The password to authenticate.
253
     * @return array The set authentication data.
254
     * @SuppressWarnings(PHPMD.Superglobals)
255
     */
256
    protected function _setAuthData($username, $password)
257
    {
258
        $requestBaseKey = $GLOBALS['wgGuzzleJsonRequestBaseKey'];
259
        $usernameKey = $GLOBALS['wgGuzzleJsonRequestUsernameKey'];
260
        $passwordKey = $GLOBALS['wgGuzzleJsonRequestPasswordKey'];
261
262
        $authData = array(
263
            $usernameKey => $username,
264
            $passwordKey => $password,
265
        );
266
        if ($requestBaseKey) {
267
            $authData = array($requestBaseKey => $authData);
268
        }
269
        return $authData;
270
    }
271
272
    /**
273
     * Get a Guzzle Client
274
     *
275
     * @return Client The Guzzle client.
276
     */
277
    protected function _getGuzzleClient()
278
    {
279
        return new Client();
280
    }
281
282
    /**
283
     * Extract the user data from the response
284
     *
285
     * @param ResponseInterface $response The Guzzle response object.
286
     * @return array The extracted user data with 'username', 'realName' & 'email'.
287
     * @SuppressWarnings(PHPMD.Superglobals)
288
     */
289
    protected function _extractUserData(ResponseInterface $response)
290
    {
291
        $responseJson = $response->json();
292
293
        $ResponseBaseKey = $GLOBALS['wgGuzzleJsonResponseBaseKey'];
294
        $usernameKey = $GLOBALS['wgGuzzleJsonResponseUsernameKey'];
295
        $realNameKey = $GLOBALS['wgGuzzleJsonResponseRealNameKey'];
296
        $emailKey = $GLOBALS['wgGuzzleJsonResponseEmailKey'];
297
298
        if (!empty($ResponseBaseKey)) {
299
            $responseJson = $responseJson[$ResponseBaseKey];
300
        }
301
302
        if (empty($responseJson)) {
303
            return $this->_populateUserArray();
304
        }
305
306
        return $this->_populateUserArray(
307
            $responseJson[$usernameKey],
308
            $responseJson[$realNameKey],
309
            $responseJson[$emailKey]
310
        );
311
    }
312
313
    /**
314
     * Populate the user array
315
     *
316
     * @param string $username The username of the user.
317
     * @param string $realName The real name of the user.
318
     * @param string $email The email of the user.
319
     * @return array The populated user array with 'username', 'realName' & 'email'.
320
     */
321
    protected function _populateUserArray($username = '', $realName = '', $email = '')
322
    {
323
        $this->_user = array(
324
            'username' => $username,
325
            'realName' => $realName,
326
            'email' => $email,
327
        );
328
329
        return $this->_user;
330
    }
331
332
    /**
333
     * Get a given user field
334
     *
335
     * @param string $fieldName The name of the field.
336
     * @return string The requested field.
337
     * @throws \BadMethodCallException If an invalid field is requested.
338
     */
339
    protected function _getUserField($fieldName)
340
    {
341
        if (!isset($this->_user[$fieldName])) {
342
            throw new \BadMethodCallException('Invalid field name ' . $fieldName);
343
        }
344
        return $this->_user[$fieldName];
345
    }
346
}
347