Completed
Push — master ( 9d09aa...80b42f )
by Jacob
02:05
created

BaseGuard   A

Complexity

Total Complexity 30

Size/Duplication

Total Lines 212
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Test Coverage

Coverage 100%

Importance

Changes 10
Bugs 1 Features 0
Metric Value
wmc 30
c 10
b 1
f 0
lcom 1
cbo 7
dl 0
loc 212
ccs 78
cts 78
cp 1
rs 10

14 Methods

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