Passed
Pull Request — 2.2 (#20357)
by Wilmer
08:55
created

CompositeAuth   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 71
Duplicated Lines 0 %

Test Coverage

Coverage 88.89%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 27
c 2
b 0
f 0
dl 0
loc 71
ccs 24
cts 27
cp 0.8889
rs 10
wmc 16

3 Methods

Rating   Name   Duplication   Size   Complexity  
A beforeAction() 0 3 2
C authenticate() 0 37 12
A challenge() 0 5 2
1
<?php
2
3
/**
4
 * @link https://www.yiiframework.com/
5
 * @copyright Copyright (c) 2008 Yii Software LLC
6
 * @license https://www.yiiframework.com/license/
7
 */
8
9
namespace yii\filters\auth;
10
11
use Yii;
12
use yii\base\ActionFilter;
13
use yii\base\Controller;
14
use yii\base\InvalidConfigException;
15
16
/**
17
 * CompositeAuth is an action filter that supports multiple authentication methods at the same time.
18
 *
19
 * The authentication methods contained by CompositeAuth are configured via [[authMethods]],
20
 * which is a list of supported authentication class configurations.
21
 *
22
 * The following example shows how to support three authentication methods:
23
 *
24
 * ```php
25
 * public function behaviors()
26
 * {
27
 *     return [
28
 *         'compositeAuth' => [
29
 *             'class' => \yii\filters\auth\CompositeAuth::class,
30
 *             'authMethods' => [
31
 *                 \yii\filters\auth\HttpBasicAuth::class,
32
 *                 \yii\filters\auth\QueryParamAuth::class,
33
 *             ],
34
 *         ],
35
 *     ];
36
 * }
37
 * ```
38
 *
39
 * @author Qiang Xue <[email protected]>
40
 * @since 2.0
41
 */
42
class CompositeAuth extends AuthMethod
43
{
44
    /**
45
     * @var array the supported authentication methods. This property should take a list of supported
46
     * authentication methods, each represented by an authentication class or configuration.
47
     *
48
     * If this property is empty, no authentication will be performed.
49
     *
50
     * Note that an auth method class must implement the [[\yii\filters\auth\AuthInterface]] interface.
51
     */
52
    public $authMethods = [];
53
54
55
    /**
56
     * {@inheritdoc}
57
     */
58 13
    public function beforeAction($action)
59
    {
60 13
        return empty($this->authMethods) ? true : parent::beforeAction($action);
61
    }
62
63
    /**
64
     * {@inheritdoc}
65
     */
66 12
    public function authenticate($user, $request, $response)
67
    {
68 12
        foreach ($this->authMethods as $i => $auth) {
69 12
            if (!$auth instanceof AuthInterface) {
70 12
                $this->authMethods[$i] = $auth = Yii::createObject($auth);
71 12
                if (!$auth instanceof AuthInterface) {
72
                    throw new InvalidConfigException(get_class($auth) . ' must implement yii\filters\auth\AuthInterface');
73
                }
74
            }
75
76
            if (
77 12
                $this->owner instanceof Controller
78
                && (
79 12
                    !isset($this->owner->action)
80 12
                    || (
81 12
                        $auth instanceof ActionFilter
82 12
                        && !$auth->isActive($this->owner->action)
83 12
                    )
84
                )
85
            ) {
86 2
                continue;
87
            }
88
89 12
            $authUser = $auth->user;
0 ignored issues
show
Bug introduced by
Accessing user on the interface yii\filters\auth\AuthInterface suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
90 12
            if ($authUser != null && !$authUser instanceof \yii\web\User) {
91
                throw new InvalidConfigException(get_class($authUser) . ' must implement yii\web\User');
92 12
            } elseif ($authUser != null) {
93
                $user = $authUser;
94
            }
95
96 12
            $identity = $auth->authenticate($user, $request, $response);
97 11
            if ($identity !== null) {
98 7
                return $identity;
99
            }
100
        }
101
102 4
        return null;
103
    }
104
105
    /**
106
     * {@inheritdoc}
107
     */
108 3
    public function challenge($response)
109
    {
110 3
        foreach ($this->authMethods as $method) {
111
            /** @var AuthInterface $method */
112 3
            $method->challenge($response);
113
        }
114
    }
115
}
116