Completed
Push — master ( e3f775...b25e7b )
by Patrick
03:18
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
    protected function __construct()
30
    {
31
        $settings = \Settings::getInstance();
32
        $this->methods = $settings->getClassesByPropName('authProviders');
33
    }
34
35
    /**
36
     * Get the Auth\User class instance for the specified login
37
     *
38
     * Unlike the AuthProvider::login() function. This function will not impact the SESSION
39
     *
40
     * @param string $username The username of the User
41
     * @param string $password The password of the User
42
     *
43
     * @return Auth\User|false The User with the specified credentials or false if the credentials are not valid
44
     */
45
    public function getUserByLogin($username, $password)
46
    {
47
        $res = false;
48
        $count = count($this->methods);
49
        for($i = 0; $i < $count; $i++)
50
        {
51
            $res = $this->methods[$i]->login($username, $password);
52
            if($res !== false)
53
            {
54
                return $this->methods[$i]->getUser($res);
55
            }
56
        }
57
        return $res;
58
    }
59
60
    /**
61
     * Use the provided credetials to log the user on
62
     *
63
     * @param string $username The username of the User
64
     * @param string $password The password of the User
65
     *
66
     * @return true|false true if the login was successful, false otherwise
67
     */
68
    public function login($username, $password)
69
    {
70
        $res = false;
71
        $count = count($this->methods);
72
        for($i = 0; $i < $count; $i++)
73
        {
74
            $res = $this->methods[$i]->login($username, $password);
75
            if($res !== false)
76
            {
77
                FlipSession::setVar('AuthMethod', get_class($this->methods[$i]));
78
                FlipSession::setVar('AuthData', $res);
79
                break;
80
            }
81
        }
82
        return $res;
83
    }
84
85
    /**
86
     * Determine if the user is still logged on from the session data
87
     *
88
     * @param stdClass $data The AuthData from the session
89
     * @param string $methodName The AuthMethod from the session
90
     *
91
     * @return true|false true if user is logged on, false otherwise
92
     */
93
    public function isLoggedIn($data, $methodName)
94
    {
95
        $auth = $this->getMethodByName($methodName);
96
        return $auth->isLoggedIn($data);
97
    }
98
99
    /**
100
     * Obtain the currently logged in user from the session data
101
     *
102
     * @param stdClass $data The AuthData from the session
103
     * @param string $methodName The AuthMethod from the session
104
     *
105
     * @return Auth\User|false The User instance if user is logged on, false otherwise
106
     */
107
    public function getUser($data, $methodName)
108
    {
109
        $auth = $this->getMethodByName($methodName);
110
        return $auth->getUser($data);
111
    }
112
113
    /**
114
     * Merge or set the returnValue as appropriate
115
     *
116
     * @param false|Auth\Group|Auth\User $returnValue The value to merge to
117
     * @param Auth\Group|Auth\User $res The value to merge from
118
     *
119
     * @return Auth\Group|false The merged returnValue
120
     */
121
    private function mergeResult(&$returnValue, $res)
122
    {
123
        if($res === false)
124
        {
125
            return;
126
        }
127
        if($returnValue === false)
128
        {
129
            $returnValue = $res;
130
            return;
131
        }
132
        $returnValue->merge($res);
133
    }
134
135
    /**
136
     * Calls the indicated function on each Authenticator and merges the result
137
     *
138
     * @param string $functionName The function to call
139
     * @param array $args The arguments for the function
140
     * @param string $checkField A field to check if it is set a certain way before calling the function
141
     * @param mixed $checkValue The value that field should be set to to not call the function
142
     *
143
     * @return Auth\Group|Auth\User|false The merged returnValue
144
     */
145 View Code Duplication
    private function callOnEach($functionName, $args, $checkField = false, $checkValue = false)
146
    {
147
        $ret = false;
148
        $count = count($this->methods);
149
        for($i = 0; $i < $count; $i++)
150
        {
151
            if($checkField !== false)
152
            {
153
                if($this->methods[$i]->{$checkField} === $checkValue)
154
                {
155
                    continue;
156
                }
157
            }
158
            $res = call_user_func_array(array($this->methods[$i], $functionName), $args);
159
            $this->mergeResult($ret, $res);
160
        }
161
        return $ret;
162
    }
163
164
    /**
165
     * Calls the indicated function on each Authenticator and add the result
166
     *
167
     * @param string $functionName The function to call
168
     * @param string $checkField A field to check if it is set a certain way before calling the function
169
     * @param mixed $checkValue The value that field should be set to to not call the function
170
     *
171
     * @return integer The added returnValue
172
     */
173 View Code Duplication
    private function addFromEach($functionName, $checkField = false, $checkValue = false)
174
    {
175
        $retCount = 0;
176
        $count = count($this->methods);
177
        for($i = 0; $i < $count; $i++)
178
        {
179
            if($checkField !== false)
180
            {
181
                if($this->methods[$i]->{$checkField} === $checkValue)
182
                {
183
                    continue;
184
                }
185
            }
186
            $res = call_user_func(array($this->methods[$i], $functionName));
187
            $retCount += $res;
188
        }
189
        return $retCount;
190
    }
191
192
    /**
193
     * Get an Auth\Group by its name
194
     *
195
     * @param string $name The name of the group
196
     * @param string $methodName The AuthMethod if information is desired only from a particular Auth\Authenticator
197
     *
198
     * @return Auth\Group|false The Group instance if a group with that name exists, false otherwise
199
     */
200
    public function getGroupByName($name, $methodName = false)
201
    {
202
        if($methodName === false)
203
        {
204
            return $this->callOnEach('getGroupByName', array($name));
205
        }
206
        $auth = $this->getMethodByName($methodName);
207
        return $auth->getGroupByName($name);
208
    }
209
210
    /**
211
     * Get an array of Auth\User from a filtered set
212
     *
213
     * @param Data\Filter|boolean $filter The filter conditions or false to retreive all
214
     * @param array|boolean $select The user fields to obtain or false to obtain all
215
     * @param integer|boolean $top The number of users to obtain or false to obtain all
216
     * @param integer|boolean $skip The number of users to skip or false to skip none
217
     * @param array|boolean $orderby The field to sort by and the method to sort or false to not sort
218
     * @param string|boolean $methodName The AuthMethod if information is desired only from a particular Auth\Authenticator
219
     *
220
     * @return array|boolean An array of Auth\User objects or false if no users were found
221
     */
222 View Code Duplication
    public function getUsersByFilter($filter, $select = false, $top = false, $skip = false, $orderby = false, $methodName = false)
223
    {
224
        if($methodName === false)
225
        {
226
            return $this->callOnEach('getUsersByFilter', array($filter, $select, $top, $skip, $orderby), 'current');
227
        }
228
        $auth = $this->getMethodByName($methodName);
229
        return $auth->getUsersByFilter($filter, $select, $top, $skip, $orderby);
230
    }
231
232
    /**
233
     * Get an array of Auth\PendingUser from a filtered set
234
     *
235
     * @param Data\Filter|boolean $filter The filter conditions or false to retreive all
236
     * @param array|boolean $select The user fields to obtain or false to obtain all
237
     * @param integer|boolean $top The number of users to obtain or false to obtain all
238
     * @param integer|boolean $skip The number of users to skip or false to skip none
239
     * @param array|boolean $orderby The field to sort by and the method to sort or false to not sort
240
     * @param string|boolean $methodName The AuthMethod if information is desired only from a particular Auth\Authenticator
241
     *
242
     * @return array|boolean An array of Auth\PendingUser objects or false if no pending users were found
243
     */
244 View Code Duplication
    public function getPendingUsersByFilter($filter, $select = false, $top = false, $skip = false, $orderby = false, $methodName = false)
245
    {
246
        if($methodName === false)
247
        {
248
            return $this->callOnEach('getPendingUsersByFilter', array($filter, $select, $top, $skip, $orderby), 'pending');
249
        }
250
        $auth = $this->getMethodByName($methodName);
251
        return $auth->getPendingUsersByFilter($filter, $select, $top, $skip, $orderby);
252
    }
253
254
    /**
255
     * Get an array of Auth\Group from a filtered set
256
     *
257
     * @param Data\Filter|false $filter The filter conditions or false to retreive all
258
     * @param array|false $select The group fields to obtain or false to obtain all
259
     * @param integer|false $top The number of groups to obtain or false to obtain all
260
     * @param integer|false $skip The number of groups to skip or false to skip none
261
     * @param array|false $orderby The field to sort by and the method to sort or false to not sort
262
     * @param string|false $methodName The AuthMethod if information is desired only from a particular Auth\Authenticator
263
     *
264
     * @return array|false An array of Auth\Group objects or false if no pending users were found
265
     */
266 View Code Duplication
    public function getGroupsByFilter($filter, $select = false, $top = false, $skip = false, $orderby = false, $methodName = false)
267
    {
268
        if($methodName === false)
269
        {
270
            return $this->callOnEach('getGroupsByFilter', array($filter, $select, $top, $skip, $orderby), 'current');
271
        }
272
        $auth = $this->getMethodByName($methodName);
273
        return $auth->getGroupsByFilter($filter, $select, $top, $skip, $orderby);
274
    }
275
276
    /**
277
     * Get the number of currently active users on the system
278
     *
279
     * @param string|false $methodName The AuthMethod if information is desired only from a particular Auth\Authenticator
280
     *
281
     * @return integer The number of currently active users on the system
282
     */
283
    public function getActiveUserCount($methodName = false)
284
    {
285
        if($methodName === false)
286
        {
287
            return $this->addFromEach('getActiveUserCount', 'current');
288
        }
289
        $auth = $this->getMethodByName($methodName);
290
        return $auth->getActiveUserCount();
291
    }
292
293
    /**
294
     * Get the number of currently pending users on the system
295
     *
296
     * @param string|false $methodName The AuthMethod if information is desired only from a particular Auth\Authenticator
297
     *
298
     * @return integer The number of currently pending users on the system
299
     */
300
    public function getPendingUserCount($methodName = false)
301
    {
302
        if($methodName === false)
303
        {
304
            return $this->addFromEach('getPendingUserCount', 'pending');
305
        }
306
        $auth = $this->getMethodByName($methodName);
307
        return $auth->getPendingUserCount();
308
    }
309
310
    /**
311
     * Get the number of current groups on the system
312
     *
313
     * @param string|false $methodName The AuthMethod if information is desired only from a particular Auth\Authenticator
314
     *
315
     * @return integer The number of current groups on the system
316
     */
317
    public function getGroupCount($methodName = false)
318
    {
319
        if($methodName === false)
320
        {
321
            return $this->addFromEach('getGroupCount', 'current');
322
        }
323
        $auth = $this->getMethodByName($methodName);
324
        return $auth->getGroupCount();
325
    }
326
327
    /**
328
     * Get the login links for all supplementary Authenitcation mechanisms
329
     *
330
     * This will return an array of links to any supplementary authentication mechanims. For example, Goodle is 
331
     * a supplementary authentication mechanism.
332
     *
333
     * @return array An array of suppmentary authentication mechanism links
334
     */
335
    public function getSupplementaryLinks()
336
    {
337
        $ret = array();
338
        $count = count($this->methods);
339 View Code Duplication
        for($i = 0; $i < $count; $i++)
340
        {
341
            if($this->methods[$i]->supplement === false)
342
            {
343
                continue;
344
            }
345
346
            array_push($ret, $this->methods[$i]->getSupplementLink());
347
        }
348
        return $ret;
349
    }
350
351
    /**
352
     * Impersonate the user specified
353
     *
354
     * This will replace the user in the session with the specified user. In order
355
     * to undo this operation a user must logout.
356
     *
357
     * @param array|Auth\User $userArray Data representing the user
358
     */
359
    public function impersonateUser($userArray)
360
    {
361
        if(!is_object($userArray))
362
        {
363
            $userArray = new $userArray['class']($userArray);
364
        }
365
        \FlipSession::setUser($userArray);
366
    }
367
368
    /**
369
     * Get the pending user reresented by the supplied hash
370
     *
371
     * @param string $hash The hash value representing the Penging User
372
     * @param string|false $methodName The AuthMethod if information is desired only from a particular Auth\Authenticator
373
     *
374
     * @return Auth\PendingUser|false The Auth\PendingUser instance or false if no user is matched by the provided hash
375
     */
376
    public function getTempUserByHash($hash, $methodName = false)
377
    {
378
        if($methodName === false)
379
        {
380
            $count = count($this->methods);
381
            for($i = 0; $i < $count; $i++)
382
            {
383
                if($this->methods[$i]->pending === false)
384
                {
385
                    continue;
386
                }
387
388
                $ret = $this->methods[$i]->getTempUserByHash($hash);
389
                if($ret !== false)
390
                {
391
                    return $ret;
392
                }
393
            }
394
            return false;
395
        }
396
        $auth = $this->getMethodByName($methodName);
397
        return $auth->getTempUserByHash($hash);
398
    }
399
400
    /**
401
     * Create a pending user
402
     *
403
     * @param array $user An array of information about the user to create
404
     * @param string|false $methodName The AuthMethod if information is desired only from a particular Auth\Authenticator
405
     *
406
     * @return boolean true if the user was successfully created. Otherwise false.
407
     */
408
    public function createPendingUser($user, $methodName = false)
409
    {
410
        if($methodName === false)
411
        {
412
            $count = count($this->methods);
413
            for($i = 0; $i < $count; $i++)
414
            {
415
                if($this->methods[$i]->pending === false)
416
                {
417
                    continue;
418
                }
419
420
                $ret = $this->methods[$i]->createPendingUser($user);
421
                if($ret !== false)
422
                {
423
                    return true;
424
                }
425
            }
426
            return false;
427
        }
428
        $auth = $this->getMethodByName($methodName);
429
        return $auth->createPendingUser($user);
430
    }
431
432
    /**
433
     * Convert a Auth\PendingUser into an Auth\User
434
     *
435
     * This will allow a previously pending user the ability to log on in the future as an active user. It will also
436
     * have the side effect of logging the user on now.
437
     *
438
     * @param Auth\PendingUser $user The user to turn into a current user
439
     * @param string|false $methodName The AuthMethod if information is desired only from a particular Auth\Authenticator
440
     *
441
     * @return boolean true if the user was successfully created. Otherwise false.
442
     */
443 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...
444
    {
445
        if($methodName === false)
446
        {
447
            $count = count($this->methods);
448
            for($i = 0; $i < $count; $i++)
449
            {
450
                if($this->methods[$i]->current === false)
451
                {
452
                    continue;
453
                }
454
455
                $ret = $this->methods[$i]->activatePendingUser($user);
456
                if($ret !== false)
457
                {
458
                    $this->impersonateUser($ret);
459
                    return true;
460
                }
461
            }
462
            return false;
463
        }
464
        $auth = $this->getMethodByName($methodName);
465
        return $auth->activatePendingUser($user);
466
    }
467
468
    /**
469
     * Get a current user by a password reset hash
470
     *
471
     * @param string $hash The current password reset hash for the user
472
     * @param string|false $methodName The AuthMethod if information is desired only from a particular Auth\Authenticator
473
     *
474
     * @return Auth\User|false The user if the password reset hash is valid. Otherwise false.
475
     */
476 View Code Duplication
    public function getUserByResetHash($hash, $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...
477
    {
478
        if($methodName === false)
479
        {
480
            $count = count($this->methods);
481
            for($i = 0; $i < $count; $i++)
482
            {
483
                if($this->methods[$i]->current === false)
484
                {
485
                    continue;
486
                }
487
488
                $ret = $this->methods[$i]->getUserByResetHash($hash);
489
                if($ret !== false)
490
                {
491
                    return $ret;
492
                }
493
            }
494
            return false;
495
        }
496
        $auth = $this->getMethodByName($methodName);
497
        if($auth === false)
498
        {
499
            return $this->getUserByResetHash($hash, false);
500
        }
501
        return $auth->getUserByResetHash($hash);
502
    }
503
504
    /**
505
     * Get the Auth\Authenticator by host name
506
     *
507
     * @param string $host The host name used by the supplemental authentication mechanism
508
     *
509
     * @return Auth\Authenticator|false The Authenticator if the host is supported by a loaded Authenticator. Otherwise false.
510
     */
511
    public function getSuplementalProviderByHost($host)
512
    {
513
        $count = count($this->methods);
514 View Code Duplication
        for($i = 0; $i < $count; $i++)
515
        {
516
            if($this->methods[$i]->supplement === false)
517
            {
518
                continue;
519
            }
520
521
            if($this->methods[$i]->getHostName() === $host)
522
            {
523
                return $this->methods[$i];
524
            }
525
        }
526
        return false;
527
    }
528
529
    /**
530
     * Delete any pending users that match the filter
531
     *
532
     * @param \Data\Filter|boolean $filter The filter to delete with or false to delete all
533
     * @param string|boolean $methodName The AuthMethod if information is desired only from a particular Auth\Authenticator
534
     *
535
     * @return boolean True if the users were deleted, false otherwise
536
     */
537
    public function deletePendingUsersByFilter($filter, $methodName = false)
538
    {
539
        $users = $this->getPendingUsersByFilter($filter, false, false, false, false, $methodName);
540
        if($users === false)
541
        {
542
            return false;
543
        }
544
        $count = count($users);
545
        for($i = 0; $i < $count; $i++)
546
        {
547
            $users[$i]->delete();
548
        }
549
        return true;
550
    }
551
552
    /**
553
     * Get the user by the one time access code
554
     *
555
     * @param string $key The user's access code
556
     * @param string|boolean $methodName The AuthMethod if information is desired only from a particular Auth\Authenticator
557
     *
558
     * @return boolean|\Auth\User The User specified by the access code or false otherwise
559
     */
560
    public function getUserByAccessCode($key, $methodName = false)
561
    {
562
        if($methodName === false)
563
        {
564
            $count = count($this->methods);
565
            for($i = 0; $i < $count; $i++)
566
            {
567
                if($this->methods[$i]->current === false)
568
                {
569
                    continue;
570
                }
571
572
                $ret = $this->methods[$i]->getUserByAccessCode($key);
573
                if($ret !== false)
574
                {
575
                    return $ret;
576
                }
577
            }
578
            return false;
579
        }
580
        $auth = $this->getMethodByName($methodName);
581
        return $auth->getUserByAccessCode($key);
582
    }
583
}
584
/* vim: set tabstop=4 shiftwidth=4 expandtab: */
585