diff --git a/src/InteractsWithToken.php b/src/InteractsWithToken.php new file mode 100644 index 00000000..eb68c0e0 --- /dev/null +++ b/src/InteractsWithToken.php @@ -0,0 +1,52 @@ +getToken(); + if($token !== null) { + $this->getClient()->setAuthentication($token); + } + } + + /** + * Update the access_token last used in the job, + * along with the expiry time. + * + * @return void + */ + public function updateRefreshToken(): void + { + $client = $this->getClient(); + $token = $this->getToken(); + + // If it is an unauthenticated call, there is nothing to update + if (is_null($token)) + return; + + if (! $client->isAuthenticated()) + return; + + $last_auth = $client->getAuthentication(); + + // update the token + if (! empty($last_auth->getRefreshToken())) + $token->refresh_token = $last_auth->getRefreshToken(); + $token->token = $last_auth->getAccessToken() ?? '-'; + $token->expires_on = $last_auth->getExpiresOn(); + $token->save(); + } +} \ No newline at end of file diff --git a/src/Jobs/EsiBase.php b/src/Jobs/EsiBase.php index 69cdb83f..bf856528 100644 --- a/src/Jobs/EsiBase.php +++ b/src/Jobs/EsiBase.php @@ -29,6 +29,7 @@ use Seat\Eveapi\Exception\PermanentInvalidTokenException; use Seat\Eveapi\Exception\TemporaryEsiOutageException; use Seat\Eveapi\Exception\UnavailableEveServersException; +use Seat\Eveapi\InteractsWithToken; use Seat\Eveapi\Jobs\Middleware\CheckEsiRateLimit; use Seat\Eveapi\Jobs\Middleware\CheckEsiRouteStatus; use Seat\Eveapi\Jobs\Middleware\CheckServerStatus; @@ -46,6 +47,8 @@ */ abstract class EsiBase extends AbstractJob { + use InteractsWithToken; + /** * ANTI_RACE_DELAY prevents rapid job recycling with low queue depths. */ @@ -212,6 +215,11 @@ public function getToken(): ?RefreshToken return $this->token; } + protected function getClient(): EsiClient + { + return $this->esi; + } + /** * @return string */ @@ -299,17 +307,13 @@ public function retrieve(array $path_values = []): EsiResponse if (! is_null($this->page)) $this->esi->page($this->page); + $this->configureTokenForEsiClient(); + // Generally, we want to bubble up exceptions all the way to the // callee. However, in the case of this worker class, we need to // try and be vigilant with tokens that may have expired. So for // those cases we wrap in a try/catch. try { - if ($this->token) { - $this->token = $this->token->fresh(); - - $this->esi->setAuthentication($this->token); - } - $result = $this->esi->invoke($this->method, $this->endpoint, $path_values); // Update the refresh token we have stored in the database. @@ -398,35 +402,6 @@ public function warning(EsiResponse $response): void } } - /** - * Update the access_token last used in the job, - * along with the expiry time. - */ - public function updateRefreshToken(): void - { - - tap($this->token, function ($token) { - - // If no API call was made, the client would have never - // been instantiated and auth information never updated. - if (is_null($token)) - return; - - if (! $this->esi->isAuthenticated()) - return; - - $last_auth = $this->esi->getAuthentication(); - - if (! empty($last_auth->getRefreshToken())) - $token->refresh_token = $last_auth->getRefreshToken(); - - $token->token = $last_auth->getAccessToken() ?? '-'; - $token->expires_on = $last_auth->getExpiresOn(); - - $token->save(); - }); - } - /** * Check if there are any pages left in a response * based on the number of pages available and the diff --git a/src/Jobs/Token/RefreshAccessToken.php b/src/Jobs/Token/RefreshAccessToken.php index 7a74007d..3cb94f33 100644 --- a/src/Jobs/Token/RefreshAccessToken.php +++ b/src/Jobs/Token/RefreshAccessToken.php @@ -23,13 +23,18 @@ namespace Seat\Eveapi\Jobs\Token; use Illuminate\Contracts\Container\BindingResolutionException; +use Seat\Eseye\Exceptions\InvalidAuthenticationException; +use Seat\Eseye\Exceptions\InvalidContainerDataException; use Seat\Eseye\Exceptions\RequestFailedException; +use Seat\Eveapi\InteractsWithToken; use Seat\Eveapi\Jobs\AbstractJob; use Seat\Eveapi\Models\RefreshToken; use Seat\Services\Contracts\EsiClient; class RefreshAccessToken extends AbstractJob { + use InteractsWithToken; + /** * @var array */ @@ -41,7 +46,7 @@ class RefreshAccessToken extends AbstractJob protected $token; /** - * @var \Seat\Services\Contracts\EsiClient + * @var EsiClient */ protected EsiClient $esi; @@ -58,29 +63,27 @@ public function __construct(RefreshToken $token) /** * @return void + * @throws InvalidContainerDataException */ - public function handle() + public function handle(): void { - // normally the retrieve function passes the token down the esi stack, but we don't use retrieve - $this->esi->setAuthentication($this->token); - - try { - // get or renew access token - $this->esi->getValidAccessToken(); - } catch (RequestFailedException $e) { + // pass this token to the esi client + $this->configureTokenForEsiClient(); - } + // ensure we have a valid access token + $this->esi->getValidAccessToken(); - // save the new access token. the following logic is extracted from EsiBase - $this->token = $this->token->fresh(); // since the model might have been in the queue for a while, amke sure to get the latest info - $last_auth = $this->esi->getAuthentication(); // extract the access token info from eseye - - if (! empty($last_auth->getRefreshToken())) - $this->token->refresh_token = $last_auth->getRefreshToken(); + // make sure the new token is stored + $this->updateRefreshToken(); + } - $this->token->token = $last_auth->getAccessToken() ?? '-'; - $this->token->expires_on = $last_auth->getExpiresOn(); + function getClient(): EsiClient + { + return $this->esi; + } - $this->token->save(); + function getToken(): ?RefreshToken + { + return $this->token; } }