Completed
Push — dev ( 8f8cd7...5b0430 )
by Tristan
16s
created

OidConnectGuard::setProvider()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
ccs 0
cts 2
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 2
1
<?php
2
0 ignored issues
show
Coding Style introduced by
Missing file doc comment
Loading history...
3
namespace App\Services\Auth;
4
5
use Illuminate\Http\Request;
6
use Illuminate\Contracts\Auth\Guard;
7
use Illuminate\Contracts\Auth\UserProvider;
8
use Illuminate\Contracts\Auth\Authenticatable;
9
use Illuminate\Auth\AuthenticationException;
10
use App\Services\Auth\JwtValidator;
11
use App\Services\Auth\RequestTokenParser;
12
use App\Services\Auth\Contracts\TokenRefresher;
13
use App\Exceptions\Auth\TokenStorageException;
14
use App\Exceptions\Auth\TokenRequestException;
15
16
class OidConnectGuard implements Guard {
0 ignored issues
show
Coding Style introduced by
Missing doc comment for class OidConnectGuard
Loading history...
Coding Style introduced by
Opening brace of a class must be on the line after the definition
Loading history...
17
18
    protected $request;
19
    protected $provider;
20
    protected $requestTokenParser;
21
    protected $jwtValidator;
22
    protected $tokenRefresher;
23
24
    protected $user;
25
26
    /**
27
     * Set to true when user() has already ran once.
28
     * @var bool
0 ignored issues
show
Coding Style introduced by
There must be exactly one blank line before the tags in a doc comment
Loading history...
29
     */
30
    protected $userAlreadyAttempted;
31
32
    /**
33
     * Create a new authentication guard.
34
     *
35
     *
36
     * @param UserProvider $provider
0 ignored issues
show
Coding Style introduced by
Expected 7 spaces after parameter type; 1 found
Loading history...
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
There must be exactly one blank line before the tags in a doc comment
Loading history...
37
     * @param RequestTokenParser $requestTokenParser
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
38
     * @param JwtValidator $jwtValidator
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 7 spaces after parameter type; 1 found
Loading history...
39
     * @param TokenRefresher $tokenRefresher
0 ignored issues
show
Coding Style introduced by
Expected 5 spaces after parameter type; 1 found
Loading history...
Coding Style introduced by
Missing parameter comment
Loading history...
40
     * @param Request $request
0 ignored issues
show
Coding Style introduced by
Expected 12 spaces after parameter type; 1 found
Loading history...
Coding Style introduced by
Missing parameter comment
Loading history...
41
     */
42
    public function __construct(UserProvider $provider,
43
            RequestTokenParser $requestTokenParser,
0 ignored issues
show
Coding Style introduced by
Multi-line function declaration not indented correctly; expected 8 spaces but found 12
Loading history...
44
            JwtValidator $jwtValidator,
0 ignored issues
show
Coding Style introduced by
Multi-line function declaration not indented correctly; expected 8 spaces but found 12
Loading history...
45
            TokenRefresher $tokenRefresher,
0 ignored issues
show
Coding Style introduced by
Multi-line function declaration not indented correctly; expected 8 spaces but found 12
Loading history...
46
            Request $request) {
0 ignored issues
show
Coding Style introduced by
Multi-line function declaration not indented correctly; expected 8 spaces but found 12
Loading history...
Coding Style introduced by
The closing parenthesis of a multi-line function declaration must be on a new line
Loading history...
47
        $this->request = $request;
48
        $this->provider = $provider;
49
        $this->requestTokenParser = $requestTokenParser;
50
        $this->jwtValidator = $jwtValidator;
51
        $this->tokenRefresher = $tokenRefresher;
52
        $this->user = NULL;
0 ignored issues
show
Coding Style introduced by
TRUE, FALSE and NULL must be lowercase; expected null, but found NULL.
Loading history...
53
        $this->userAlreadyAttempted = false;
54
    }
55
56
    /**
57
     * Determine if the current user is authenticated.
58
     *
59
     * @return bool
60
     */
61
    public function check() {
62
        return !is_null($this->user());
63
    }
64
65
    /**
66
     * Determine if the current user is a guest.
67
     *
68
     * @return bool
69
     */
70
    public function guest() {
71
        return !$this->check();
72
    }
73
74
    /**
75
     * Get the ID for the currently authenticated user.
76
     *
77
     * @return int|null
78
     */
79
    public function id()
80
    {
81
        if ($this->user()) {
82
            return $this->user()->getAuthIdentifier();
83
        }
84
    }
85
86
    /**
87
     * Set the current user.
88
     *
89
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 2 found
Loading history...
Coding Style introduced by
Missing parameter comment
Loading history...
90
     * @return void
0 ignored issues
show
Coding Style introduced by
Tag cannot be grouped with parameter tags in a doc comment
Loading history...
91
     */
92
    public function setUser(Authenticatable $user)
93
    {
94
        $this->user = $user;
95
    }
96
97
    public function user() {
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function user()
Loading history...
98
        // If we've already retrieved the user for the current request we can just
99
        // return it back immediately. We do not want to fetch the user data on
100
        // every call to this method because that would be tremendously slow.
101
        if (! is_null($this->user) || $this->userAlreadyAttempted) {
102
            return $this->user;
103
        }
104
105
        $this->userAlreadyAttempted = true;
106
        $user = null;
107
108
        try {
109
            $idToken = $this->requestTokenParser->parse($this->request);
110
        } catch (AuthenticationException $exception) {
111
            //Return a null user is enough, swallow the exception here
112
            debugbar()->warning($exception->getMessage());
113
            return $user;
114
        }
115
116
        if (!$this->jwtValidator->claimsAreValid($idToken) ||
117
                !$this->jwtValidator->signatureIsValid($idToken)) {
0 ignored issues
show
Coding Style introduced by
Each line in a multi-line IF statement must begin with a boolean operator
Loading history...
Coding Style introduced by
Closing parenthesis of a multi-line IF statement must be on a new line
Loading history...
Coding Style introduced by
Multi-line IF statement not indented correctly; expected 12 spaces but found 16
Loading history...
118
            debugbar()->warning("Bearer token exists but is not valid");
119
            return $user;
120
        }
121
122
        //At this point, token is definitely valid
123
        if ($this->jwtValidator->isExpired($idToken)) {
124
            debugbar()->info("Id token expired");
125
126
            $iss = $idToken->getClaim("iss");
127
            $sub = $idToken->getClaim("sub");
128
            try {
129
                $idToken = $this->tokenRefresher->refreshIDToken($iss, $sub);
130
                debugbar()->info("Refreshed id token");
131
132
            } catch (TokenStorageException $storageException) {
133
                debugbar()->warning($storageException->getMessage());
134
                return $user;
135
            } catch (TokenRequestException $requestException) {
136
                debugBar()->warning($requestException->getMessage());
137
                return $user;
138
            }
139
            $this->requestTokenParser->save($idToken);
140
        }
141
142
        $credentials = $idToken->getClaims();
143
144
        $user = $this->provider->retrieveByCredentials($credentials);
145
146
        $this->user = $user;
147
        return $user;
148
    }
149
150
    public function validate(array $credentials = array()): bool {
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function validate()
Loading history...
151
        debugbar()->info("in Guard.validate()");
152
        if (empty($credentials['id_token'])) {
153
            return false;
154
        }
155
        $token = $this->requestTokenParser->parseFromString($credentials['id_token']);
0 ignored issues
show
Unused Code introduced by
The assignment to $token is dead and can be removed.
Loading history...
156
157
        return $this->jwtValidator->claimsAreValid($idToken) &&
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $idToken seems to be never defined.
Loading history...
158
            !$this->jwtValidator->isExpired($idToken) &&
159
            $this->jwtValidator->signatureIsValid($idToken);
160
    }
161
162
    /**
163
     * Get the user provider used by the guard.
164
     *
165
     * @return \Illuminate\Contracts\Auth\UserProvider
166
     */
167
    public function getProvider()
168
    {
169
        return $this->provider;
170
    }
171
172
    /**
173
     * Set the user provider used by the guard.
174
     *
175
     * @param  \Illuminate\Contracts\Auth\UserProvider  $provider
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 2 found
Loading history...
Coding Style introduced by
Missing parameter comment
Loading history...
176
     * @return void
0 ignored issues
show
Coding Style introduced by
Tag cannot be grouped with parameter tags in a doc comment
Loading history...
177
     */
178
    public function setProvider(UserProvider $provider)
179
    {
180
        $this->provider = $provider;
181
    }
182
183
    /**
184
     * Determine if the current user is authenticated.
185
     *
186
     * @return \Illuminate\Contracts\Auth\Authenticatable
187
     *
188
     * @throws \Illuminate\Auth\AuthenticationException
189
     */
190
    public function authenticate()
191
    {
192
        if (! is_null($user = $this->user())) {
193
            return $user;
194
        }
195
196
        throw new AuthenticationException;
197
    }
198
}
199