BaseGuard::user()   B
last analyzed

Complexity

Conditions 5
Paths 4

Size

Total Lines 17
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 5

Importance

Changes 5
Bugs 0 Features 0
Metric Value
c 5
b 0
f 0
dl 0
loc 17
ccs 14
cts 14
cp 1
rs 8.8571
cc 5
eloc 12
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\UserProvider;
11
use Illuminate\Contracts\Auth\Guard as GaurdContract;
12
use Illuminate\Contracts\Auth\Authenticatable;
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
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
     * @var array
38
     */
39
    protected $config;
40
41
    /**
42
     * @var array
43
     */
44
    private $factoryCache = [];
45
46
    /**
47
     * Constructor
48
     *
49
     * @param UserProvider $provider
50
     * @param Request      $request
51
     */
52 25
    public function __construct($id, UserProvider $provider, Request $request, array $config = [])
53
    {
54 25
        $this->request = $request;
55 25
        $this->provider = $provider;
56 25
        $this->config = $config;
57 25
        $this->id = $id;
58 25
    }
59
60
    /**
61
     * Returns the adapter class name to use
62
     *
63
     * @return string
64
     */
65 16
    public function getAdapterFactoryClass()
66
    {
67 16
        $config = config('jwt');
68 16
        if (!isset($config['adapter'])) {
69 14
            $config['adapter'] = 'lcobucci';
70 14
        }
71 16
        if (class_exists($config['adapter'])) {
72 1
            $factoryClass = $config['adapter'];
73 1
        } else {
74 15
            $factoryClass = 'Canis\Lumen\Jwt\Adapters\\' . ucfirst($config['adapter']) . '\Factory';
75 15
            if (!class_exists($factoryClass)) {
76 1
                throw new InvalidAdapterException("{$config['adapter']} is not available");
77
            }
78
        }
79 15
        return $factoryClass;
80
    }
81
82
    /**
83
     * Returns the adapter factory object
84
     *
85
     * @return AdapterFactoryContract
86
     */
87 16
    protected function getAdapterFactory()
88
    {
89 16
        if (!isset($this->factoryCache[$this->id])) {
90 16
            $config = config('jwt');
91 16
            if (isset($this->config['adapter'])) {
92 1
                $config = array_merge($config, $this->config['adapter']);
93 1
            }
94 16
            $factoryClass = $this->getAdapterFactoryClass();
95 15
            $this->factoryCache[$this->id] = new $factoryClass($config);
96 15
        }
97 15
        return $this->factoryCache[$this->id];
98
    }
99
100
    /**
101
     * Returns a token processor from the adapter factory
102
     *
103
     * @return ProcessorContract
104
     */
105 11
    protected function getProcessor()
106
    {
107 11
        return $this->getAdapterFactory()->getProcessor();
108
    }
109
110
    /**
111
     * Returns a token generator from the adapter factory
112
     *
113
     * @return GeneratorContract
114
     */
115 8
    protected function getGenerator()
116
    {
117 8
        return $this->getAdapterFactory()->getGenerator();
118
    }
119
120
    /**
121
     * Gets the provider
122
     *
123
     * @return UserProvider
124
     */
125 15
    public function getProvider()
126
    {
127 15
        return $this->provider;
128
    }
129
130
    /**
131
     * @inheritdoc
132
     */
133 7
    public function user()
134
    {
135 7
        if (!is_null($this->user)) {
136 5
            return $this->user;
137
        }
138 6
        $user = null;
139 6
        $token = $this->getBearerToken();
140 6
        if ($token !== false) {
141 5
            $user = $this->getProvider()->retrieveById($token->getClaim('sub'));
142 5
            $claimValidation = [static::JWT_GUARD_CLAIM => $this->id];
143 5
            if (!($user instanceof SubjectContract)
144 5
                || !$token->ensureClaimValues(array_merge($user->getJWTClaimValidation(), $claimValidation))) {
145 2
                $user = null;
146 2
            }
147 5
        }
148 6
        return $this->user = $user;
149
    }
150
151
    /**
152
     * @inheritdoc
153
     */
154 13
    public function getBearerToken($isRefresh = false)
155
    {
156 13
        $token = $this->request->bearerToken();
157 13
        if (empty($token)) {
158 3
            return false;
159
        }
160 10
        $processor = $this->getProcessor();
161 10
        return $processor($token, $isRefresh);
162
    }
163
164
    /**
165
     * @inheritdoc
166
     */
167 2
    public function validate(array $credentials = [])
168
    {
169 2
        $user = $this->getProvider()->retrieveByCredentials($credentials);
170 2
        if ($user instanceof Authenticatable && $this->hasValidCredentials($user, $credentials)) {
171 1
            return true;
172
        }
173 1
        return false;
174
    }
175
176
    /**
177
     * Determine if the user matches the credentials.
178
     *
179
     * @param  Authenticatable|null  $user
180
     * @param  array  $credentials
181
     * @return bool
182
     */
183 7
    protected function hasValidCredentials($user, $credentials)
184
    {
185 7
        return !is_null($user) && $this->getProvider()->validateCredentials($user, $credentials);
186
    }
187
188
    /**
189
     * Sets the Request
190
     *
191
     * @param Request $request
192
     */
193 1
    public function setRequest(Request $request)
194
    {
195 1
        $this->request = $request;
196 1
    }
197
198
    /**
199
     * Gets the request
200
     *
201
     * @return Request
202
     */
203 1
    public function getRequest()
204
    {
205 1
        return $this->request;
206
    }
207
208
    /**
209
     * Attempt to authenticate a user using the given credentials.
210
     *
211
     * @param  array  $credentials
212
     * @param  boolean $login
213
     * @return bool|Token
214
     */
215 5
    public function attempt(array $credentials = [], $login = true)
216
    {
217 5
        $user = $this->getProvider()->retrieveByCredentials($credentials);
218 5
        if ($user instanceof Authenticatable && $this->hasValidCredentials($user, $credentials)) {
219 4
            if ($login === true) {
220 4
                $this->login($user);
221 4
            }
222 4
            if (!($user instanceof SubjectContract)) {
223 1
                throw new InvalidTokenException("Unable to generate token");
224
            }
225 3
            return $this->generateToken($user);
226
        }
227 1
        return false;
228
    }
229
230
    /**
231
     * Log a user into the application.
232
     *
233
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
234
     */
235 6
    public function login(Authenticatable $user)
236
    {
237 6
        $this->setUser($user);
238 6
        return true;
239
    }
240
241
    /**
242
     * Clear user
243
     * @return boolean
244
     */
245 1
    public function logout()
246
    {
247 1
        $this->user = null;
248 1
        return true;
249
    }
250
251
    /**
252
     * Generate a new token
253
     * 
254
     * @param  SubjectContract $user
255
     * @return Token
256
     */
257 5
    protected function generateToken(SubjectContract $user)
258
    {
259 5
        $tokenGenerator = $this->getGenerator();
260 5
        $claims = $user->getJWTClaims();
261 5
        $claims['sub'] = $user->getJWTSubject();
262 5
        $claims[static::JWT_GUARD_CLAIM] = $this->id;
263 5
        if (!($token = $tokenGenerator($claims))) {
264 1
            throw new InvalidTokenException("Unable to generate token");
265
        }
266 4
        return $token;
267
    }
268
}
269