|
28 | 28 | use League\OAuth2\Server\RequestEvent;
|
29 | 29 | use League\OAuth2\Server\ResponseTypes\DeviceCodeResponse;
|
30 | 30 | use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface;
|
| 31 | +use LogicException; |
31 | 32 | use Psr\Http\Message\ServerRequestInterface;
|
32 | 33 | use TypeError;
|
33 | 34 |
|
@@ -96,6 +97,7 @@ public function respondToDeviceAuthorizationRequest(ServerRequestInterface $requ
|
96 | 97 | );
|
97 | 98 |
|
98 | 99 | $response = new DeviceCodeResponse();
|
| 100 | + $response->setEncryptionKey($this->encryptionKey); |
99 | 101 |
|
100 | 102 | if ($this->includeVerificationUriComplete === true) {
|
101 | 103 | $response->includeVerificationUriComplete();
|
@@ -177,38 +179,58 @@ public function respondToAccessTokenRequest(
|
177 | 179 | */
|
178 | 180 | protected function validateDeviceCode(ServerRequestInterface $request, ClientEntityInterface $client): DeviceCodeEntityInterface
|
179 | 181 | {
|
180 |
| - $deviceCode = $this->getRequestParameter('device_code', $request); |
| 182 | + $encryptedDeviceCode = $this->getRequestParameter('device_code', $request); |
181 | 183 |
|
182 |
| - if (is_null($deviceCode)) { |
| 184 | + if (is_null($encryptedDeviceCode)) { |
183 | 185 | throw OAuthServerException::invalidRequest('device_code');
|
184 | 186 | }
|
185 | 187 |
|
186 |
| - $deviceCodeEntity = $this->deviceCodeRepository->getDeviceCodeEntityByDeviceCode( |
187 |
| - $deviceCode |
188 |
| - ); |
189 |
| - |
190 |
| - if ($deviceCodeEntity instanceof DeviceCodeEntityInterface === false) { |
191 |
| - $this->getEmitter()->emit(new RequestEvent(RequestEvent::USER_AUTHENTICATION_FAILED, $request)); |
| 188 | + try { |
| 189 | + $deviceCodePayload = json_decode($this->decrypt($encryptedDeviceCode)); |
| 190 | + } catch (LogicException $e) { |
| 191 | + throw OAuthServerException::invalidRequest('code', 'Cannot decrypt the device code', $e); |
| 192 | + } |
192 | 193 |
|
193 |
| - throw OAuthServerException::invalidGrant(); |
| 194 | + if (!property_exists($deviceCodePayload, 'device_code_id')) { |
| 195 | + throw OAuthServerException::invalidRequest('device_code', 'Device code malformed'); |
194 | 196 | }
|
195 | 197 |
|
196 |
| - if (time() > $deviceCodeEntity->getExpiryDateTime()->getTimestamp()) { |
| 198 | + if (time() > $deviceCodePayload->expire_time) { |
197 | 199 | throw OAuthServerException::expiredToken('device_code');
|
198 | 200 | }
|
199 | 201 |
|
200 |
| - if ($this->deviceCodeRepository->isDeviceCodeRevoked($deviceCode) === true) { |
| 202 | + if ($this->deviceCodeRepository->isDeviceCodeRevoked($deviceCodePayload->device_code_id) === true) { |
201 | 203 | throw OAuthServerException::invalidRequest('device_code', 'Device code has been revoked');
|
202 | 204 | }
|
203 | 205 |
|
204 |
| - if ($deviceCodeEntity->getClient()->getIdentifier() !== $client->getIdentifier()) { |
| 206 | + if ($deviceCodePayload->client_id !== $client->getIdentifier()) { |
205 | 207 | throw OAuthServerException::invalidRequest('device_code', 'Device code was not issued to this client');
|
206 | 208 | }
|
207 | 209 |
|
| 210 | + $deviceCodeEntity = $this->deviceCodeRepository->getDeviceCodeEntityByDeviceCode( |
| 211 | + $deviceCodePayload->device_code_id |
| 212 | + ); |
| 213 | + |
| 214 | + if ($deviceCodeEntity instanceof DeviceCodeEntityInterface === false) { |
| 215 | + $this->getEmitter()->emit(new RequestEvent(RequestEvent::USER_AUTHENTICATION_FAILED, $request)); |
| 216 | + |
| 217 | + throw OAuthServerException::invalidGrant(); |
| 218 | + } |
| 219 | + |
208 | 220 | if ($this->deviceCodePolledTooSoon($deviceCodeEntity->getLastPolledAt()) === true) {
|
209 | 221 | throw OAuthServerException::slowDown();
|
210 | 222 | }
|
211 | 223 |
|
| 224 | + $deviceCodeEntity->setIdentifier($deviceCodePayload->device_code_id); |
| 225 | + $deviceCodeEntity->setClient($client); |
| 226 | + $deviceCodeEntity->setExpiryDateTime((new DateTimeImmutable())->setTimestamp($deviceCodePayload->expire_time)); |
| 227 | + |
| 228 | + $scopes = $this->validateScopes($deviceCodePayload->scopes); |
| 229 | + |
| 230 | + foreach ($scopes as $scope) { |
| 231 | + $deviceCodeEntity->addScope($scope); |
| 232 | + } |
| 233 | + |
212 | 234 | return $deviceCodeEntity;
|
213 | 235 | }
|
214 | 236 |
|
|
0 commit comments