Completed
Pull Request — master (#83)
by Patrick
07:23 queued 04:54
created

class.AuthProvider.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * AuthProvider class
4
 *
5
 * This file describes the AuthProvider Singleton
6
 *
7
 * PHP version 5 and 7
8
 *
9
 * @author Patrick Boyd / [email protected]
10
 * @copyright Copyright (c) 2015, Austin Artistic Reconstruction
11
 * @license http://www.apache.org/licenses/ Apache 2.0 License
12
 */
13
14
/**
15
 * Allow other classes to be loaded as needed
16
 */
17
require_once('Autoload.php');
18
19
/**
20
 * A Singleton class to abstract access to the authentication providers.
21
 *
22
 * This class is the primary method to access user data, login, and other authenication information.
23
 */
24
class AuthProvider extends Provider
25
{
26
    /**
27
     * Load the authentrication providers specified in the Settings $authProviders array
28
     *
29
     * @SuppressWarnings("StaticAccess")
30
     */
31
    protected function __construct()
32
    {
33
        $settings = \Settings::getInstance();
34
        $this->methods = $settings->getClassesByPropName('authProviders');
35
    }
36
37
    /**
38
     * Get the Auth\User class instance for the specified login
39
     *
40
     * Unlike the AuthProvider::login() function. This function will not impact the SESSION
41
     *
42
     * @param string $username The username of the User
43
     * @param string $password The password of the User
44
     *
45
     * @return Auth\User|false The User with the specified credentials or false if the credentials are not valid
46
     */
47
    public function getUserByLogin($username, $password)
48
    {
49
        $res = false;
50
        $count = count($this->methods);
51
        for($i = 0; $i < $count; $i++)
52
        {
53
            $res = $this->methods[$i]->login($username, $password);
54
            if($res !== false)
55
            {
56
                return $this->methods[$i]->getUser($res);
57
            }
58
        }
59
        return $res;
60
    }
61
62
    /**
63
     * Use the provided credetials to log the user on
64
     *
65
     * @param string $username The username of the User
66
     * @param string $password The password of the User
67
     *
68
     * @return true|false true if the login was successful, false otherwise
69
     */
70
    public function login($username, $password)
71
    {
72
        $res = false;
73
        $count = count($this->methods);
74
        for($i = 0; $i < $count; $i++)
75
        {
76
            $res = $this->methods[$i]->login($username, $password);
77
            if($res !== false)
78
            {
79
                FlipSession::setVar('AuthMethod', get_class($this->methods[$i]));
80
                FlipSession::setVar('AuthData', $res);
81
                break;
82
            }
83
        }
84
        return $res;
85
    }
86
87
    /**
88
     * Determine if the user is still logged on from the session data
89
     *
90
     * @param stdClass $data The AuthData from the session
91
     * @param string $methodName The AuthMethod from the session
92
     *
93
     * @return true|false true if user is logged on, false otherwise
94
     */
95
    public function isLoggedIn($data, $methodName)
96
    {
97
        $auth = $this->getMethodByName($methodName);
98
        return $auth->isLoggedIn($data);
99
    }
100
101
    /**
102
     * Obtain the currently logged in user from the session data
103
     *
104
     * @param stdClass $data The AuthData from the session
105
     * @param string $methodName The AuthMethod from the session
106
     *
107
     * @return Auth\User|false The User instance if user is logged on, false otherwise
108
     */
109
    public function getUser($data, $methodName)
110
    {
111
        $auth = $this->getMethodByName($methodName);
112
        return $auth->getUser($data);
113
    }
114
115
    /**
116
     * Merge or set the returnValue as appropriate
117
     *
118
     * @param false|Auth\Group|Auth\User $returnValue The value to merge to
119
     * @param Auth\Group|Auth\User $res The value to merge from
120
     *
121
     * @return Auth\Group|false The merged returnValue
122
     */
123
    public function mergeResult(&$returnValue, $res)
124
    {
125
        if($res === false)
126
        {
127
            return;
128
        }
129
        if($returnValue === false)
130
        {
131
            $returnValue = $res;
132
            return;
133
        }
134
        $returnValue->merge($res);
135
    }
136
137
    /**
138
     * Get an Auth\Group by its name
139
     *
140
     * @param string $name The name of the group
141
     * @param string $methodName The AuthMethod if information is desired only from a particular Auth\Authenticator
142
     *
143
     * @return Auth\Group|false The Group instance if a group with that name exists, false otherwise
144
     */
145 View Code Duplication
    public function getGroupByName($name, $methodName = false)
146
    {
147
        if($methodName === false)
148
        {
149
            return $this->callOnEach('getGroupByName', array($name));
150
        }
151
        $auth = $this->getMethodByName($methodName);
152
        return $auth->getGroupByName($name);
153
    }
154
155
    /**
156
     * Get an array of Auth\User from a filtered set
157
     *
158
     * @param Data\Filter|boolean $filter The filter conditions or false to retreive all
159
     * @param array|boolean $select The user fields to obtain or false to obtain all
160
     * @param integer|boolean $top The number of users to obtain or false to obtain all
161
     * @param integer|boolean $skip The number of users to skip or false to skip none
162
     * @param array|boolean $orderby The field to sort by and the method to sort or false to not sort
163
     * @param string|boolean $methodName The AuthMethod if information is desired only from a particular Auth\Authenticator
164
     *
165
     * @return array|boolean An array of Auth\User objects or false if no users were found
166
     */
167
    public function getUsersByFilter($filter, $select = false, $top = false, $skip = false, $orderby = false, $methodName = false)
168
    {
169
        return $this->callFunction($methodName, 'getUsersByFilter', array($filter, $select, $top, $skip, $orderby), 
170
                                    'current', false, array($this, 'mergeResult'));
171
    }
172
173
    /**
174
     * Get an array of Auth\PendingUser from a filtered set
175
     *
176
     * @param Data\Filter|boolean $filter The filter conditions or false to retreive all
177
     * @param array|boolean $select The user fields to obtain or false to obtain all
178
     * @param integer|boolean $top The number of users to obtain or false to obtain all
179
     * @param integer|boolean $skip The number of users to skip or false to skip none
180
     * @param array|boolean $orderby The field to sort by and the method to sort or false to not sort
181
     * @param string|boolean $methodName The AuthMethod if information is desired only from a particular Auth\Authenticator
182
     *
183
     * @return array|boolean An array of Auth\PendingUser objects or false if no pending users were found
184
     */
185
    public function getPendingUsersByFilter($filter, $select = false, $top = false, $skip = false, $orderby = false, $methodName = false)
186
    {
187
        return $this->callFunction($methodName, 'getPendingUsersByFilter', array($filter, $select, $top, $skip, $orderby),
188
                                    'pending', false, array($this, 'mergeResult'));
189
    }
190
191
    /**
192
     * Get an array of Auth\Group from a filtered set
193
     *
194
     * @param Data\Filter|false $filter The filter conditions or false to retreive all
195
     * @param array|false $select The group fields to obtain or false to obtain all
196
     * @param integer|false $top The number of groups to obtain or false to obtain all
197
     * @param integer|false $skip The number of groups to skip or false to skip none
198
     * @param array|false $orderby The field to sort by and the method to sort or false to not sort
199
     * @param string|false $methodName The AuthMethod if information is desired only from a particular Auth\Authenticator
200
     *
201
     * @return array|false An array of Auth\Group objects or false if no pending users were found
202
     */
203
    public function getGroupsByFilter($filter, $select = false, $top = false, $skip = false, $orderby = false, $methodName = false)
204
    {
205
        return $this->callFunction($methodName, 'getGroupsByFilter', array($filter, $select, $top, $skip, $orderby),
206
                                    'current', false, array($this, 'mergeResult'));
207
    }
208
209
    /**
210
     * Get the number of currently active users on the system
211
     *
212
     * @param string|false $methodName The AuthMethod if information is desired only from a particular Auth\Authenticator
213
     *
214
     * @return integer The number of currently active users on the system
215
     */
216
    public function getActiveUserCount($methodName = false)
217
    {
218
        if($methodName === false)
219
        {
220
            return $this->addFromEach('getActiveUserCount', 'current');
221
        }
222
        $auth = $this->getMethodByName($methodName);
223
        return $auth->getActiveUserCount();
224
    }
225
226
    /**
227
     * Get the number of currently pending users on the system
228
     *
229
     * @param string|false $methodName The AuthMethod if information is desired only from a particular Auth\Authenticator
230
     *
231
     * @return integer The number of currently pending users on the system
232
     */
233
    public function getPendingUserCount($methodName = false)
234
    {
235
        if($methodName === false)
236
        {
237
            return $this->addFromEach('getPendingUserCount', 'pending');
238
        }
239
        $auth = $this->getMethodByName($methodName);
240
        return $auth->getPendingUserCount();
241
    }
242
243
    /**
244
     * Get the number of current groups on the system
245
     *
246
     * @param string|false $methodName The AuthMethod if information is desired only from a particular Auth\Authenticator
247
     *
248
     * @return integer The number of current groups on the system
249
     */
250
    public function getGroupCount($methodName = false)
251
    {
252
        if($methodName === false)
253
        {
254
            return $this->addFromEach('getGroupCount', 'current');
255
        }
256
        $auth = $this->getMethodByName($methodName);
257
        return $auth->getGroupCount();
258
    }
259
260
    /**
261
     * Get the login links for all supplementary Authenitcation mechanisms
262
     *
263
     * This will return an array of links to any supplementary authentication mechanims. For example, Goodle is 
264
     * a supplementary authentication mechanism.
265
     *
266
     * @return array An array of suppmentary authentication mechanism links
267
     */
268
    public function getSupplementaryLinks()
269
    {
270
        $ret = array();
271
        $count = count($this->methods);
272 View Code Duplication
        for($i = 0; $i < $count; $i++)
273
        {
274
            if($this->methods[$i]->supplement === false)
275
            {
276
                continue;
277
            }
278
279
            array_push($ret, $this->methods[$i]->getSupplementLink());
280
        }
281
        return $ret;
282
    }
283
284
    /**
285
     * Impersonate the user specified
286
     *
287
     * This will replace the user in the session with the specified user. In order
288
     * to undo this operation a user must logout.
289
     *
290
     * @param array|Auth\User $userArray Data representing the user
291
     */
292
    public function impersonateUser($userArray)
293
    {
294
        if(!is_object($userArray))
295
        {
296
            $userArray = new $userArray['class']($userArray);
297
        }
298
        \FlipSession::setUser($userArray);
299
    }
300
301
    /**
302
     * Get the pending user reresented by the supplied hash
303
     *
304
     * @param string $hash The hash value representing the Penging User
305
     * @param string|false $methodName The AuthMethod if information is desired only from a particular Auth\Authenticator
306
     *
307
     * @return Auth\PendingUser|false The Auth\PendingUser instance or false if no user is matched by the provided hash
308
     */
309 View Code Duplication
    public function getTempUserByHash($hash, $methodName = false)
310
    {
311
        if($methodName === false)
312
        {
313
            return $this->callOnEach('getTempUserByHash', array($hash), 'pending');
314
        }
315
        $auth = $this->getMethodByName($methodName);
316
        return $auth->getTempUserByHash($hash);
317
    }
318
319
    /**
320
     * Create a pending user
321
     *
322
     * @param array $user An array of information about the user to create
323
     * @param string|false $methodName The AuthMethod if information is desired only from a particular Auth\Authenticator
324
     *
325
     * @return boolean true if the user was successfully created. Otherwise false.
326
     */
327 View Code Duplication
    public function createPendingUser($user, $methodName = false)
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
328
    {
329
        if($methodName === false)
330
        {
331
            $count = count($this->methods);
332
            for($i = 0; $i < $count; $i++)
333
            {
334
                if($this->methods[$i]->pending === false)
335
                {
336
                    continue;
337
                }
338
339
                $ret = $this->methods[$i]->createPendingUser($user);
340
                if($ret !== false)
341
                {
342
                    return true;
343
                }
344
            }
345
            return false;
346
        }
347
        $auth = $this->getMethodByName($methodName);
348
        return $auth->createPendingUser($user);
349
    }
350
351
    /**
352
     * Convert a Auth\PendingUser into an Auth\User
353
     *
354
     * This will allow a previously pending user the ability to log on in the future as an active user. It will also
355
     * have the side effect of logging the user on now.
356
     *
357
     * @param Auth\PendingUser $user The user to turn into a current user
358
     * @param string|false $methodName The AuthMethod if information is desired only from a particular Auth\Authenticator
359
     *
360
     * @return boolean true if the user was successfully created. Otherwise false.
361
     */
362 View Code Duplication
    public function activatePendingUser($user, $methodName = false)
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
363
    {
364
        if($methodName === false)
365
        {
366
            $count = count($this->methods);
367
            for($i = 0; $i < $count; $i++)
368
            {
369
                if($this->methods[$i]->current === false)
370
                {
371
                    continue;
372
                }
373
374
                $ret = $this->methods[$i]->activatePendingUser($user);
375
                if($ret !== false)
376
                {
377
                    $this->impersonateUser($ret);
378
                    return true;
379
                }
380
            }
381
            return false;
382
        }
383
        $auth = $this->getMethodByName($methodName);
384
        return $auth->activatePendingUser($user);
385
    }
386
387
    /**
388
     * Get a current user by a password reset hash
389
     *
390
     * @param string $hash The current password reset hash for the user
391
     * @param string|false $methodName The AuthMethod if information is desired only from a particular Auth\Authenticator
392
     *
393
     * @return Auth\User|false The user if the password reset hash is valid. Otherwise false.
394
     */
395
    public function getUserByResetHash($hash, $methodName = false)
396
    {
397
        if($methodName === false)
398
        {
399
            return $this->callOnEach('getUserByResetHash', array($hash), 'current');
400
        }
401
        $auth = $this->getMethodByName($methodName);
402
        if($auth === false)
403
        {
404
            return $this->getUserByResetHash($hash, false);
405
        }
406
        return $auth->getUserByResetHash($hash);
407
    }
408
409
    /**
410
     * Get the Auth\Authenticator by host name
411
     *
412
     * @param string $host The host name used by the supplemental authentication mechanism
413
     *
414
     * @return Auth\Authenticator|false The Authenticator if the host is supported by a loaded Authenticator. Otherwise false.
415
     */
416
    public function getSuplementalProviderByHost($host)
417
    {
418
        $count = count($this->methods);
419 View Code Duplication
        for($i = 0; $i < $count; $i++)
420
        {
421
            if($this->methods[$i]->supplement === false)
422
            {
423
                continue;
424
            }
425
426
            if($this->methods[$i]->getHostName() === $host)
427
            {
428
                return $this->methods[$i];
429
            }
430
        }
431
        return false;
432
    }
433
434
    /**
435
     * Delete any pending users that match the filter
436
     *
437
     * @param \Data\Filter|boolean $filter The filter to delete with or false to delete all
438
     * @param string|boolean $methodName The AuthMethod if information is desired only from a particular Auth\Authenticator
439
     *
440
     * @return boolean True if the users were deleted, false otherwise
441
     */
442
    public function deletePendingUsersByFilter($filter, $methodName = false)
443
    {
444
        $users = $this->getPendingUsersByFilter($filter, false, false, false, false, $methodName);
445
        if($users === false)
446
        {
447
            return false;
448
        }
449
        $count = count($users);
450
        for($i = 0; $i < $count; $i++)
451
        {
452
            $users[$i]->delete();
453
        }
454
        return true;
455
    }
456
457
    /**
458
     * Get the user by the one time access code
459
     *
460
     * @param string $key The user's access code
461
     * @param string|boolean $methodName The AuthMethod if information is desired only from a particular Auth\Authenticator
462
     *
463
     * @return boolean|\Auth\User The User specified by the access code or false otherwise
464
     */
465 View Code Duplication
    public function getUserByAccessCode($key, $methodName = false)
466
    {
467
        if($methodName === false)
468
        {
469
            return $this->callOnEach('getUserByAccessCode', array($key), 'current');
470
        }
471
        $auth = $this->getMethodByName($methodName);
472
        return $auth->getUserByAccessCode($key);
473
    }
474
}
475
/* vim: set tabstop=4 shiftwidth=4 expandtab: */
476