Completed
Push — master ( b029a9...ae7e79 )
by Patrick
03:01
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
 * Require the FlipsideSettings file
20
 */
21
if(isset($GLOBALS['FLIPSIDE_SETTINGS_LOC']))
22
{
23
    require_once($GLOBALS['FLIPSIDE_SETTINGS_LOC'].'/class.FlipsideSettings.php');
24
}
25
else
26
{
27
    require_once('/var/www/secure_settings/class.FlipsideSettings.php');
28
}
29
30
/**
31
 * A Singleton class to abstract access to the authentication providers.
32
 *
33
 * This class is the primary method to access user data, login, and other authenication information.
34
 */
35
class AuthProvider extends Singleton
36
{
37
    /** The authentication methods loaded by the provider */
38
    protected $methods;
39
40
    /**
41
     * Load the authentrication providers specified in the FlipsideSettings::$authProviders array
42
     */
43 View Code Duplication
    protected function __construct()
44
    {
45
        $this->methods = array();
46
        if(isset(FlipsideSettings::$authProviders))
47
        {
48
            $keys = array_keys(FlipsideSettings::$authProviders);
49
            $count = count($keys);
50
            for($i = 0; $i < $count; $i++)
51
            {
52
                $class = $keys[$i];
53
                array_push($this->methods, new $class(FlipsideSettings::$authProviders[$keys[$i]]));
54
            }
55
        }
56
    }
57
58
    /**
59
     * Get the Authenticator class instance by name
60
     *
61
     * @param string $methodName The class name of the Authenticator to get the instance for
62
     *
63
     * @return Auth\Authenticator|false The specified Authenticator class instance or false if it is not loaded
64
     */
65 View Code Duplication
    public function getAuthenticator($methodName)
66
    {
67
        $count = count($this->methods);
68
        for($i = 0; $i < $count; $i++)
69
        {
70
            if(strcasecmp(get_class($this->methods[$i]), $methodName) === 0)
71
            {
72
                return $this->methods[$i];
73
            }
74
        }
75
        return false;
76
    }
77
78
    /**
79
     * Get the Auth\User class instance for the specified login
80
     *
81
     * Unlike the AuthProvider::login() function. This function will not impact the SESSION
82
     *
83
     * @param string $username The username of the User
84
     * @param string $password The password of the User
85
     *
86
     * @return Auth\User|false The User with the specified credentials or false if the credentials are not valid
87
     */
88
    public function getUserByLogin($username, $password)
89
    {
90
        $res = false;
91
        $count = count($this->methods);
92
        for($i = 0; $i < $count; $i++)
93
        {
94
            $res = $this->methods[$i]->login($username, $password);
95
            if($res !== false)
96
            {
97
                return $this->methods[$i]->getUser($res);
98
            }
99
        }
100
        return $res;
101
    }
102
103
    /**
104
     * Use the provided credetials to log the user on
105
     *
106
     * @param string $username The username of the User
107
     * @param string $password The password of the User
108
     *
109
     * @return true|false true if the login was successful, false otherwise
110
     */
111
    public function login($username, $password)
112
    {
113
        $res = false;
114
        $count = count($this->methods);
115
        for($i = 0; $i < $count; $i++)
116
        {
117
            $res = $this->methods[$i]->login($username, $password);
118
            if($res !== false)
119
            {
120
                FlipSession::setVar('AuthMethod', get_class($this->methods[$i]));
121
                FlipSession::setVar('AuthData', $res);
122
                break;
123
            }
124
        }
125
        return $res;
126
    }
127
128
    /**
129
     * Determine if the user is still logged on from the session data
130
     *
131
     * @param stdClass $data The AuthData from the session
132
     * @param string $methodName The AuthMethod from the session
133
     *
134
     * @return true|false true if user is logged on, false otherwise
135
     */
136
    public function isLoggedIn($data, $methodName)
137
    {
138
        $auth = $this->getAuthenticator($methodName);
139
        return $auth->isLoggedIn($data);
140
    }
141
142
    /**
143
     * Obtain the currently logged in user from the session data
144
     *
145
     * @param stdClass $data The AuthData from the session
146
     * @param string $methodName The AuthMethod from the session
147
     *
148
     * @return Auth\User|false The User instance if user is logged on, false otherwise
149
     */
150
    public function getUser($data, $methodName)
151
    {
152
        $auth = $this->getAuthenticator($methodName);
153
        return $auth->getUser($data);
154
    }
155
156
    /**
157
     * Merge or set the returnValue as appropriate
158
     *
159
     * @param false|Auth\Group|Auth\User $returnValue The value to merge to
160
     * @param Auth\Group|Auth\User $res The value to merge from
161
     *
162
     * @return Auth\Group|false The merged returnValue
163
     */
164
    private function mergeResult(&$returnValue, $res)
165
    {
166
        if($res === false)
167
        {
168
            return;
169
        }
170
        if($returnValue === false)
171
        {
172
            $returnValue = $res;
173
            return;
174
        }
175
        $returnValue->merge($res);
176
    }
177
178
    /**
179
     * Calls the indicated function on each Authenticator and merges the result
180
     *
181
     * @param string $functionName The function to call
182
     * @param array $args The arguments for the function
183
     * @param string $checkField A field to check if it is set a certain way before calling the function
184
     * @param mixed $checkValue The value that field should be set to to not call the function
185
     *
186
     * @return Auth\Group|Auth\User|false The merged returnValue
187
     */
188 View Code Duplication
    private function callOnEach($functionName, $args, $checkField = false, $checkValue = false)
189
    {
190
        $ret = false;
191
        $count = count($this->methods);
192
        for($i = 0; $i < $count; $i++)
193
        {
194
            if($checkField)
195
            {
196
                if($this->methods[$i]->{$checkField} === $checkValue)
197
                {
198
                    continue;
199
                }
200
            }
201
            $res = call_user_func_array(array($this->methods[$i], $functionName), $args);
202
            $this->mergeResult($ret, $res);
203
        }
204
        return $ret;
205
    }
206
207
    /**
208
     * Calls the indicated function on each Authenticator and add the result
209
     *
210
     * @param string $functionName The function to call
211
     * @param string $checkField A field to check if it is set a certain way before calling the function
212
     * @param mixed $checkValue The value that field should be set to to not call the function
213
     *
214
     * @return integer The added returnValue
215
     */
216 View Code Duplication
    private function addFromEach($functionName, $checkField = false, $checkValue = false)
217
    {
218
        $retCount = 0;
219
        $count = count($this->methods);
220
        for($i = 0; $i < $count; $i++)
221
        {
222
            if($checkField)
223
            {
224
                if($this->methods[$i]->{$checkField} === $checkValue)
225
                {
226
                    continue;
227
                }
228
            }
229
            $res = call_user_func(array($this->methods[$i], $functionName));
230
            $retCount += $res;
231
        }
232
        return $retCount;
233
    }
234
235
    /**
236
     * Get an Auth\Group by its name
237
     *
238
     * @param string $name The name of the group
239
     * @param string $methodName The AuthMethod if information is desired only from a particular Auth\Authenticator
240
     *
241
     * @return Auth\Group|false The Group instance if a group with that name exists, false otherwise
242
     */
243
    public function getGroupByName($name, $methodName = false)
244
    {
245
        if($methodName === false)
246
        {
247
            return $this->callOnEach('getGroupByName', array($name));
248
        }
249
        $auth = $this->getAuthenticator($methodName);
250
        return $auth->getGroupByName($name);
251
    }
252
253
    /**
254
     * Get an array of Auth\User from a filtered set
255
     *
256
     * @param Data\Filter|boolean $filter The filter conditions or false to retreive all
257
     * @param array|boolean $methodName The user fields to obtain or false to obtain all
258
     * @param integer|boolean $top The number of users to obtain or false to obtain all
259
     * @param integer|boolean $skip The number of users to skip or false to skip none
260
     * @param array|boolean $orderby The field to sort by and the method to sort or false to not sort
261
     * @param string|boolean $methodName The AuthMethod if information is desired only from a particular Auth\Authenticator
262
     *
263
     * @return array|boolean An array of Auth\User objects or false if no users were found
264
     */
265 View Code Duplication
    public function getUsersByFilter($filter, $select = false, $top = false, $skip = false, $orderby = false, $methodName = false)
266
    {
267
        if($methodName === false)
268
        {
269
            return $this->callOnEach('getUsersByFilter', array($filter, $select, $top, $skip, $orderby), 'current');
270
        }
271
        $auth = $this->getAuthenticator($methodName);
272
        return $auth->getUsersByFilter($filter, $select, $top, $skip, $orderby);
273
    }
274
275
    /**
276
     * Get an array of Auth\PendingUser from a filtered set
277
     *
278
     * @param Data\Filter|false $filter The filter conditions or false to retreive all
279
     * @param array|false $methodName The user fields to obtain or false to obtain all
280
     * @param integer|false $top The number of users to obtain or false to obtain all
281
     * @param integer|false $skip The number of users to skip or false to skip none
282
     * @param array|false $orderby The field to sort by and the method to sort or false to not sort
283
     * @param string|false $methodName The AuthMethod if information is desired only from a particular Auth\Authenticator
284
     *
285
     * @return array|false An array of Auth\PendingUser objects or false if no pending users were found
286
     */
287 View Code Duplication
    public function getPendingUsersByFilter($filter, $select = false, $top = false, $skip = false, $orderby = false, $methodName = false)
288
    {
289
        if($methodName === false)
290
        {
291
            return $this->callOnEach('getPendingUsersByFilter', array($filter, $select, $top, $skip, $orderby), 'pending');
292
        }
293
        $auth = $this->getAuthenticator($methodName);
0 ignored issues
show
$methodName is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
294
        return $auth->getPendingUsersByFilter($filter, $select, $top, $skip, $orderby);
295
    }
296
297
    /**
298
     * Get an array of Auth\Group from a filtered set
299
     *
300
     * @param Data\Filter|false $filter The filter conditions or false to retreive all
301
     * @param array|false $methodName The group fields to obtain or false to obtain all
302
     * @param integer|false $top The number of groups to obtain or false to obtain all
303
     * @param integer|false $skip The number of groups to skip or false to skip none
304
     * @param array|false $orderby The field to sort by and the method to sort or false to not sort
305
     * @param string|false $methodName The AuthMethod if information is desired only from a particular Auth\Authenticator
306
     *
307
     * @return array|false An array of Auth\Group objects or false if no pending users were found
308
     */
309 View Code Duplication
    public function getGroupsByFilter($filter, $select = false, $top = false, $skip = false, $orderby = false, $methodName = false)
310
    {
311
        if($methodName === false)
312
        {
313
            return $this->callOnEach('getGroupsByFilter', array($filter, $select, $top, $skip, $orderby), 'current');
314
        }
315
        $auth = $this->getAuthenticator($methodName);
316
        return $auth->getGroupsByFilter($filter, $select, $top, $skip, $orderby);
317
    }
318
319
    /**
320
     * Get the number of currently active users on the system
321
     *
322
     * @param string|false $methodName The AuthMethod if information is desired only from a particular Auth\Authenticator
323
     *
324
     * @return integer The number of currently active users on the system
325
     */
326
    public function getActiveUserCount($methodName = false)
327
    {
328
        if($methodName === false)
329
        {
330
            return $this->addFromEach('getActiveUserCount', 'current');
331
        }
332
        $auth = $this->getAuthenticator($methodName);
333
        return $auth->getActiveUserCount();
334
    }
335
336
    /**
337
     * Get the number of currently pending users on the system
338
     *
339
     * @param string|false $methodName The AuthMethod if information is desired only from a particular Auth\Authenticator
340
     *
341
     * @return integer The number of currently pending users on the system
342
     */
343
    public function getPendingUserCount($methodName = false)
344
    {
345
        if($methodName === false)
346
        {
347
            return $this->addFromEach('getPendingUserCount', 'pending');
348
        }
349
        $auth = $this->getAuthenticator($methodName);
350
        return $auth->getPendingUserCount();
351
    }
352
353
    /**
354
     * Get the number of current groups on the system
355
     *
356
     * @param string|false $methodName The AuthMethod if information is desired only from a particular Auth\Authenticator
357
     *
358
     * @return integer The number of current groups on the system
359
     */
360
    public function getGroupCount($methodName = false)
361
    {
362
        if($methodName === false)
363
        {
364
            return $this->addFromEach('getGroupCount', 'current');
365
        }
366
        $auth = $this->getAuthenticator($methodName);
367
        return $auth->getGroupCount();
368
    }
369
370
    /**
371
     * Get the login links for all supplementary Authenitcation mechanisms
372
     *
373
     * This will return an array of links to any supplementary authentication mechanims. For example, Goodle is 
374
     * a supplementary authentication mechanism.
375
     *
376
     * @return array An array of suppmentary authentication mechanism links
377
     */
378
    public function getSupplementaryLinks()
379
    {
380
        $ret = array();
381
        $count = count($this->methods);
382 View Code Duplication
        for($i = 0; $i < $count; $i++)
383
        {
384
            if($this->methods[$i]->supplement === false)
385
            {
386
                continue;
387
            }
388
389
            array_push($ret, $this->methods[$i]->getSupplementLink());
390
        }
391
        return $ret;
392
    }
393
394
    /**
395
     * Impersonate the user specified
396
     *
397
     * This will replace the user in the session with the specified user. In order
398
     * to undo this operation a user must logout.
399
     *
400
     * @param array|Auth\User $userArray Data representing the user
401
     */
402
    public function impersonateUser($userArray)
403
    {
404
        if(!is_object($userArray))
405
        {
406
            $user = new $userArray['class']($userArray);
407
        }
408
        \FlipSession::setUser($user);
409
    }
410
411
    /**
412
     * Get the pending user reresented by the supplied hash
413
     *
414
     * @param string $hash The hash value representing the Penging User
415
     * @param string|false $methodName The AuthMethod if information is desired only from a particular Auth\Authenticator
416
     *
417
     * @return Auth\PendingUser|false The Auth\PendingUser instance or false if no user is matched by the provided hash
418
     */
419
    public function getTempUserByHash($hash, $methodName = false)
420
    {
421
        if($methodName === false)
422
        {
423
            $count = count($this->methods);
424
            for($i = 0; $i < $count; $i++)
425
            {
426
                if($this->methods[$i]->pending === false)
427
                {
428
                    continue;
429
                }
430
431
                $ret = $this->methods[$i]->getTempUserByHash($hash);
432
                if($ret !== false)
433
                {
434
                    return $ret;
435
                }
436
            }
437
            return false;
438
        }
439
        $auth = $this->getAuthenticator($methodName);
440
        return $auth->getTempUserByHash($hash);
441
    }
442
443
    /**
444
     * Create a pending user
445
     *
446
     * @param array $user An array of information about the user to create
447
     * @param string|false $methodName The AuthMethod if information is desired only from a particular Auth\Authenticator
448
     *
449
     * @return boolean true if the user was successfully created. Otherwise false.
450
     */
451
    public function createPendingUser($user, $methodName = false)
452
    {
453
        if($methodName === false)
454
        {
455
            $count = count($this->methods);
456
            for($i = 0; $i < $count; $i++)
457
            {
458
                if($this->methods[$i]->pending === false)
459
                {
460
                    continue;
461
                }
462
463
                $ret = $this->methods[$i]->createPendingUser($user);
464
                if($ret !== false)
465
                {
466
                    return true;
467
                }
468
            }
469
            return false;
470
        }
471
        $auth = $this->getAuthenticator($methodName);
472
        return $auth->createPendingUser($user);
473
    }
474
475
    /**
476
     * Convert a Auth\PendingUser into an Auth\User
477
     *
478
     * This will allow a previously pending user the ability to log on in the future as an active user. It will also
479
     * have the side effect of logging the user on now.
480
     *
481
     * @param Auth\PendingUser $user The user to turn into a current user
482
     * @param string|false $methodName The AuthMethod if information is desired only from a particular Auth\Authenticator
483
     *
484
     * @return boolean true if the user was successfully created. Otherwise false.
485
     */
486 View Code Duplication
    public function activatePendingUser($user, $methodName = false)
487
    {
488
        if($methodName === false)
489
        {
490
            $count = count($this->methods);
491
            for($i = 0; $i < $count; $i++)
492
            {
493
                if($this->methods[$i]->current === false)
494
                {
495
                    continue;
496
                }
497
498
                $ret = $this->methods[$i]->activatePendingUser($user);
499
                if($ret !== false)
500
                {
501
                    $this->impersonateUser($ret);
502
                    return true;
503
                }
504
            }
505
            return false;
506
        }
507
        $auth = $this->getAuthenticator($methodName);
508
        return $auth->activatePendingUser($user);
509
    }
510
511
    /**
512
     * Get a current user by a password reset hash
513
     *
514
     * @param string $hash The current password reset hash for the user
515
     * @param string|false $methodName The AuthMethod if information is desired only from a particular Auth\Authenticator
516
     *
517
     * @return Auth\User|false The user if the password reset hash is valid. Otherwise false.
518
     */
519 View Code Duplication
    public function getUserByResetHash($hash, $methodName = false)
520
    {
521
        if($methodName === false)
522
        {
523
            $count = count($this->methods);
524
            for($i = 0; $i < $count; $i++)
525
            {
526
                if($this->methods[$i]->current === false)
527
                {
528
                    continue;
529
                }
530
531
                $ret = $this->methods[$i]->getUserByResetHash($hash);
532
                if($ret !== false)
533
                {
534
                    return $ret;
535
                }
536
            }
537
            return false;
538
        }
539
        $auth = $this->getAuthenticator($methodName);
540
        if($auth === false)
541
        {
542
            return $this->getUserByResetHash($hash, false);
543
        }
544
        return $auth->getUserByResetHash($hash);
545
    }
546
547
    /**
548
     * Get the Auth\Authenticator by host name
549
     *
550
     * @param string $host The host name used by the supplemental authentication mechanism
551
     *
552
     * @return Auth\Authenticator|false The Authenticator if the host is supported by a loaded Authenticator. Otherwise false.
553
     */
554
    public function getSuplementalProviderByHost($host)
555
    {
556
        $count = count($this->methods);
557 View Code Duplication
        for($i = 0; $i < $count; $i++)
558
        {
559
            if($this->methods[$i]->supplement === false)
560
            {
561
                continue;
562
            }
563
564
            if($this->methods[$i]->getHostName() === $host)
565
            {
566
                return $this->methods[$i];
567
            }
568
        }
569
        return false;
570
    }
571
572
    public function deletePendingUsersByFilter($filter, $methodName = false)
573
    {
574
        $users = $this->getPendingUsersByFilter($filter, false, false, false, false, $methodName);
0 ignored issues
show
$methodName is of type boolean, but the function expects a false|array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
575
        if($users === false)
576
        {
577
            return false;
578
        }
579
        $count = count($users);
580
        for($i = 0; $i < $count; $i++)
581
        {
582
            $users[$i]->delete();
583
        }
584
        return true;
585
    }
586
587 View Code Duplication
    public function getUserByAccessCode($key, $methodName = false)
588
    {
589
        if($methodName === false)
590
        {
591
            $count = count($this->methods);
592
            for($i = 0; $i < $count; $i++)
593
            {
594
                if($this->methods[$i]->current === false)
595
                {
596
                    continue;
597
                }
598
599
                $ret = $this->methods[$i]->getUserByAccessCode($key);
600
                if($ret !== false)
601
                {
602
                    return $ret;
603
                }
604
            }
605
            return false;
606
        }
607
        $auth = $this->getAuthenticator($methodName);
608
        return $auth->getUserByAccessCode($key);
609
    }
610
}
611
/* vim: set tabstop=4 shiftwidth=4 expandtab: */
612