mtvbrianking /
laravel-airtel-money
| 1 | <?php |
||||||
| 2 | |||||||
| 3 | namespace Bmatovu\AirtelMoney\Auth; |
||||||
| 4 | |||||||
| 5 | use Bmatovu\AirtelMoney\Auth\GrantTypes\GrantTypeInterface; |
||||||
| 6 | use Bmatovu\AirtelMoney\Auth\Repositories\TokenRepositoryInterface; |
||||||
| 7 | use Bmatovu\AirtelMoney\Support\Util; |
||||||
| 8 | use GuzzleHttp\Promise\RejectedPromise; |
||||||
| 9 | use Illuminate\Database\Eloquent\Model; |
||||||
| 10 | use Psr\Http\Message\RequestInterface; |
||||||
| 11 | |||||||
| 12 | class OAuth2Middleware |
||||||
| 13 | { |
||||||
| 14 | protected ?Model $token = null; |
||||||
| 15 | |||||||
| 16 | protected TokenRepositoryInterface $tokenRepository; |
||||||
| 17 | |||||||
| 18 | protected GrantTypeInterface $grantType; |
||||||
| 19 | |||||||
| 20 | protected ?GrantTypeInterface $refreshTokenGrantType; |
||||||
| 21 | |||||||
| 22 | 6 | public function getToken(): ?Model |
|||||
| 23 | { |
||||||
| 24 | // If token is not set try to get it from the persistent storage. |
||||||
| 25 | 6 | if ($this->token === null) { |
|||||
| 26 | 6 | $this->token = $this->tokenRepository->retrieve(); |
|||||
| 27 | } |
||||||
| 28 | |||||||
| 29 | // If storage token is not set or expired then try to acquire a new one... |
||||||
| 30 | 6 | if ($this->token === null || Util::isExpired($this->token->expires_at)) { |
|||||
| 31 | |||||||
| 32 | // Hydrate `rawToken` with a new access token |
||||||
| 33 | 4 | $this->token = $this->requestNewToken(); |
|||||
| 34 | } |
||||||
| 35 | |||||||
| 36 | 5 | return $this->token; |
|||||
| 37 | } |
||||||
| 38 | |||||||
| 39 | 8 | public function __construct( |
|||||
| 40 | GrantTypeInterface $grantType, |
||||||
| 41 | ?GrantTypeInterface $refreshTokenGrantType = null, |
||||||
| 42 | ?TokenRepositoryInterface $tokenRepository = null |
||||||
| 43 | ) { |
||||||
| 44 | 8 | $this->tokenRepository = $tokenRepository; |
|||||
| 45 | 8 | $this->grantType = $grantType; |
|||||
| 46 | 8 | $this->refreshTokenGrantType = $refreshTokenGrantType; |
|||||
| 47 | } |
||||||
| 48 | |||||||
| 49 | 8 | public function __invoke(callable $handler): \Closure |
|||||
| 50 | { |
||||||
| 51 | 8 | return function (RequestInterface $request, array $options) use ($handler) { |
|||||
| 52 | 8 | if (! $request->hasHeader('Authorization')) { |
|||||
| 53 | 6 | $request = $this->signRequest($request, $this->getToken()); |
|||||
| 54 | } |
||||||
| 55 | |||||||
| 56 | 7 | return $handler($request, $options)->then( |
|||||
| 57 | 7 | $this->onFulfilled($request, $options, $handler), |
|||||
| 58 | 7 | $this->onRejected($request, $options, $handler) |
|||||
| 59 | 7 | ); |
|||||
| 60 | 8 | }; |
|||||
| 61 | } |
||||||
| 62 | |||||||
| 63 | 7 | private function onFulfilled(RequestInterface $request, array $options, callable $handler): \Closure |
|||||
| 64 | { |
||||||
| 65 | 7 | return function ($response) use ($request, $options, $handler) { |
|||||
| 66 | // Only deal with Unauthorized response. |
||||||
| 67 | 6 | if ($response && $response->getStatusCode() != 401) { |
|||||
| 68 | 4 | return $response; |
|||||
| 69 | } |
||||||
| 70 | |||||||
| 71 | // If we already retried once, give up. |
||||||
| 72 | 2 | if ($request->hasHeader('X-Guzzle-Retry')) { |
|||||
| 73 | 1 | return $response; |
|||||
| 74 | } |
||||||
| 75 | |||||||
| 76 | // Delete the previous access token, if any |
||||||
| 77 | 1 | $this->tokenRepository->delete($this->token->access_token); |
|||||
| 78 | |||||||
| 79 | // Unset current token |
||||||
| 80 | 1 | $this->token = null; |
|||||
| 81 | |||||||
| 82 | // Acquire a new access token, and retry the request. |
||||||
| 83 | 1 | $this->token = $this->getToken(); |
|||||
| 84 | |||||||
| 85 | 1 | $request = $request->withHeader('X-Guzzle-Retry', '1'); |
|||||
| 86 | |||||||
| 87 | 1 | $request = $this->signRequest($request, $this->token); |
|||||
| 88 | |||||||
| 89 | 1 | return $handler($request, $options); |
|||||
| 90 | 7 | }; |
|||||
| 91 | } |
||||||
| 92 | |||||||
| 93 | 7 | private function onRejected(RequestInterface $request, array $options, callable $handler): \Closure |
|||||
|
0 ignored issues
–
show
The parameter
$options is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. Loading history...
The parameter
$request is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. Loading history...
|
|||||||
| 94 | { |
||||||
| 95 | 7 | return function ($reason) { |
|||||
| 96 | 1 | return new RejectedPromise($reason); |
|||||
| 97 | 7 | }; |
|||||
| 98 | } |
||||||
| 99 | |||||||
| 100 | 5 | protected function signRequest(RequestInterface $request, Model $token): RequestInterface |
|||||
| 101 | { |
||||||
| 102 | 5 | $authorization = $token->token_type.' '.$token->access_token; |
|||||
| 103 | |||||||
| 104 | 5 | return $request->withHeader('Authorization', $authorization); |
|||||
|
0 ignored issues
–
show
|
|||||||
| 105 | } |
||||||
| 106 | |||||||
| 107 | 4 | protected function requestNewToken(): Model |
|||||
| 108 | { |
||||||
| 109 | // Refresh an existing, but expired access token. |
||||||
| 110 | 4 | if ($this->refreshTokenGrantType && $this->token && $this->token->refresh_token) { |
|||||
| 111 | // Request new access token using the existing refresh token. |
||||||
| 112 | 1 | $api_token = $this->refreshTokenGrantType->getToken($this->token->refresh_token); |
|||||
| 113 | |||||||
| 114 | 1 | return $this->tokenRepository->create($api_token); |
|||||
| 115 | } |
||||||
| 116 | |||||||
| 117 | // Obtain new access token using the main grant type. |
||||||
| 118 | 3 | $api_token = $this->grantType->getToken(); |
|||||
| 119 | |||||||
| 120 | 2 | return $this->tokenRepository->create($api_token); |
|||||
| 121 | } |
||||||
| 122 | } |
||||||
| 123 |
This check looks for parameters that have been defined for a function or method, but which are not used in the method body.