Completed
Push — master ( 0d9a84...e6b01d )
by Jacob
02:04
created

BaseGuard::user()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 18
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 5

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 18
ccs 15
cts 15
cp 1
rs 8.8571
cc 5
eloc 13
nc 4
nop 0
crap 5
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016 Canis.io
4
 * @license   MIT
5
 */
6
namespace Canis\Lumen\Jwt;
7
8
use Illuminate\Http\Request;
9
use Illuminate\Auth\GuardHelpers;
10
use Illuminate\Contracts\Auth\Factory as AuthFactory;
11
use Illuminate\Contracts\Auth\UserProvider;
12
use Illuminate\Contracts\Auth\Guard as GaurdContract;
13
use Canis\Lumen\Jwt\Exceptions\InvalidTokenException;
14
use Canis\Lumen\Jwt\Exceptions\InvalidAdapterException;
15
use Canis\Lumen\Jwt\Contracts\AdapterFactory as AdapterFactoryContract;
16
use Canis\Lumen\Jwt\Contracts\Processor as ProcessorContract;
17
use Canis\Lumen\Jwt\Contracts\Subject as SubjectContract;
18
19
abstract class BaseGuard
20
    implements GaurdContract, GuardInterface
0 ignored issues
show
Coding Style introduced by
The implements keyword must be on the same line as the class name
Loading history...
21
{
22
    use GuardHelpers;
23
24
    const JWT_GUARD_CLAIM = 'grd';
25
26
    /**
27
     * @var string
28
     */
29
    protected $id;
30
31
    /**
32
     * @var Request
33
     */
34
    protected $request;
35
36
    /**
37
     * Constructor
38
     *
39
     * @param UserProvider $provider
40
     * @param Request      $request
41
     */
42 18
    public function __construct($id, UserProvider $provider, Request $request)
43
    {
44 18
        $this->request = $request;
45 18
        $this->provider = $provider;
46 18
        $this->id = $id;
47 18
    }
48
49
    /**
50
     * Returns the adapter class name to use
51
     *
52
     * @return string
53
     */
54 11
    public function getAdapterFactoryClass()
55
    {
56 11
        $config = config('jwt');
57 11
        if (!isset($config['adapter'])) {
58 9
            $config['adapter'] = 'lcobucci';
59 9
        }
60 11
        if (class_exists($config['adapter'])) {
61 1
            $factoryClass = $config['adapter'];
62 1
        } else {
63 10
            $factoryClass = 'Canis\Lumen\Jwt\Adapters\\' . ucfirst($config['adapter']) . '\Factory';
64 10
            if (!class_exists($factoryClass)) {
65 1
                throw new InvalidAdapterException("{$config['adapter']} is not available");
66
            }
67
        }
68 10
        return $factoryClass;
69
    }
70
71
    /**
72
     * Returns the adapter factory object
73
     *
74
     * @return AdapterFactoryContract
75
     */
76 11
    protected function getAdapterFactory()
77
    {
78 11
        static $factory;
79 11
        if (!isset($factory)) {
80 11
            $config = config('jwt');
81 11
            $factoryClass = $this->getAdapterFactoryClass();
82 10
            $factory = new $factoryClass($config);
83 10
        }
84 10
        return $factory;
85
    }
86
87
    /**
88
     * Returns a token processor from the adapter factory
89
     *
90
     * @return ProcessorContract
91
     */
92 7
    protected function getProcessor()
93
    {
94 7
        return $this->getAdapterFactory()->getProcessor();
95
    }
96
97
    /**
98
     * Returns a token generator from the adapter factory
99
     *
100
     * @return GeneratorContract
101
     */
102 5
    protected function getGenerator()
103
    {
104 5
        return $this->getAdapterFactory()->getGenerator();
105
    }
106
107
    /**
108
     * Gets the provider
109
     *
110
     * @return UserProvider
111
     */
112 11
    public function getProvider()
113
    {
114 11
        return $this->provider;
115
    }
116
117
    /**
118
     * @inheritdoc
119
     */
120 3
    public function universalUserLogin(AuthFactory $auth, $claimValidation = [])
121
    {
122 3
        $token = $this->getBearerToken();
123 3
        $guard = false;
124 3
        if ($token !== false && $token->hasClaim(static::JWT_GUARD_CLAIM)) {
125 3
            $guard = $token->getClaim(static::JWT_GUARD_CLAIM);
126 3
            $user = $auth->guard($guard)->user();
127 3
            if ($user === null) {
128 1
                $guard = false;
129 1
            }
130 3
        }
131 3
        return $guard;
132
    }
133
134
    /**
135
     * @inheritdoc
136
     */
137 5
    public function user()
138
    {
139 5
        if (!is_null($this->user)) {
140 3
            return $this->user;
141
        }
142 5
        $user = null;
143 5
        $claimValidation = [static::JWT_GUARD_CLAIM => $this->id];
144 5
        $token = $this->getBearerToken();
145 5
        if ($token !== false) {
146 5
            $user = $this->getProvider()->retrieveById($token->getClaim('sub'));
147 5
            $processor = $this->getProcessor();
0 ignored issues
show
Unused Code introduced by
$processor is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
148 5
            if (!($user instanceof SubjectContract)
149 5
                || !$token->ensureClaimValues(array_merge($user->getJWTClaimValidation(), $claimValidation))) {
150 2
                $user = null;
151 2
            }
152 5
        }
153 5
        return $this->user = $user;
154
    }
155
156
    /**
157
     * Get's the bearer token from the request header
158
     * 
159
     * @return Token|boolean
160
     */
161 8
    public function getBearerToken()
162
    {
163 8
        $token = $this->request->bearerToken();
164 8
        if (empty($token)) {
165 2
            return false;
166
        }
167 6
        $processor = $this->getProcessor();
168 6
        return $processor($token);
169
    }
170
171
    /**
172
     * @inheritdoc
173
     */
174 2
    public function validate(array $credentials = [])
175
    {
176 2
        $user = $this->getProvider()->retrieveByCredentials($credentials);
177 2
        if ($this->hasValidCredentials($user, $credentials)) {
0 ignored issues
show
Bug introduced by
It seems like $user defined by $this->getProvider()->re...edentials($credentials) on line 176 can also be of type object<Illuminate\Contracts\Auth\Authenticatable>; however, Canis\Lumen\Jwt\BaseGuard::hasValidCredentials() does only seem to accept object<Canis\Lumen\Jwt\Authenticatable>|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
178 1
            return true;
179
        }
180 1
        return false;
181
    }
182
183
    /**
184
     * Determine if the user matches the credentials.
185
     *
186
     * @param  Authenticatable|null  $user
187
     * @param  array  $credentials
188
     * @return bool
189
     */
190 6
    protected function hasValidCredentials($user, $credentials)
191
    {
192 6
        return !is_null($user) && $this->getProvider()->validateCredentials($user, $credentials);
193
    }
194
195
    /**
196
     * Sets the Request
197
     *
198
     * @param Request $request
199
     */
200 1
    public function setRequest(Request $request)
201
    {
202 1
        $this->request = $request;
203 1
    }
204
205
    /**
206
     * Gets the request
207
     *
208
     * @return Request
209
     */
210 1
    public function getRequest()
211
    {
212 1
        return $this->request;
213
    }
214
215
    /**
216
     * Attempt to authenticate a user using the given credentials.
217
     *
218
     * @param  array  $credentials
219
     * @return bool|string
220
     */
221 4
    public function attempt(array $credentials = [])
222
    {
223 4
        $user = $this->getProvider()->retrieveByCredentials($credentials);
224 4
        if ($this->hasValidCredentials($user, $credentials)) {
0 ignored issues
show
Bug introduced by
It seems like $user defined by $this->getProvider()->re...edentials($credentials) on line 223 can also be of type object<Illuminate\Contracts\Auth\Authenticatable>; however, Canis\Lumen\Jwt\BaseGuard::hasValidCredentials() does only seem to accept object<Canis\Lumen\Jwt\Authenticatable>|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
225 3
            if (!($user instanceof SubjectContract)) {
226 1
                throw new InvalidTokenException("Unable to generate token");
227
            }
228 2
            $tokenGenerator = $this->getGenerator();
229 2
            $claims = $user->getJWTClaims();
230 2
            $claims['sub'] = $user->getJWTSubject();
231 2
            $claims[static::JWT_GUARD_CLAIM] = $this->id;
232 2
            if (!($token = $tokenGenerator($claims))) {
233 1
                throw new InvalidTokenException("Unable to generate token");
234
            }
235 1
            return $token;
236
        }
237 1
        return false;
238
    }
239
}
240