Skip to content

Commit

Permalink
Account refreshing fix
Browse files Browse the repository at this point in the history
  • Loading branch information
sztyup committed Jul 1, 2020
1 parent c2278b4 commit 2a89a36
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 27 deletions.
81 changes: 58 additions & 23 deletions src/LAuth/AbstractProvider.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?php

declare(strict_types=1);

namespace Sztyup\LAuth;
Expand All @@ -11,8 +12,10 @@
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Psr\Http\Message\MessageInterface;
use Sztyup\LAuth\Entities\Account;
use Sztyup\LAuth\Events\ProviderLogin;
use Sztyup\LAuth\Events\ProviderUpdate;
use Sztyup\LAuth\Exceptions\InvalidStateException;

abstract class AbstractProvider implements ProviderInterface
Expand Down Expand Up @@ -80,26 +83,28 @@ public function callback(): ?Account

$this->em->flush();

if ($this->dispatcher->until(new ProviderLogin($providerUser, $account)) === false) {
return null;
}
$this->dispatcher->dispatch(new ProviderLogin($providerUser, $account));

return $account;
}

public function refresh(Account $account): Account
{
$tokens = $this->getTokensFromCode($account->getAccessToken());
if ($account->getRefreshToken() !== null) {
$tokenResponse = $this->getTokensFromRefreshToken($account->getRefreshToken());
} else {
$tokenResponse = null;
}

$providerUser = $this->getUserByAccessToken($tokens->accessToken);
$providerUser = $this->getUserByAccessToken($tokenResponse->accessToken);

$this->updateAccount($account, $providerUser, $tokens);
$this->updateAccount($account, $providerUser, $tokenResponse);

$account->setUpdatedAt(new DateTime());

$this->em->flush();

$this->dispatcher->dispatch(new ProviderLogin($providerUser, $account));
$this->dispatcher->dispatch(new ProviderUpdate($providerUser, $account));

return $account;
}
Expand Down Expand Up @@ -128,7 +133,11 @@ protected function matchExistingAccount(ProviderUser $providerUser): ?Account

abstract protected function createAccount(ProviderUser $providerUser, TokenResponse $tokens): Account;

abstract protected function updateAccount(Account $account, ProviderUser $providerUser, TokenResponse $tokens): void;
abstract protected function updateAccount(
Account $account,
ProviderUser $providerUser,
?TokenResponse $tokens
): void;

abstract protected function redirectUrl(string $state): string;

Expand All @@ -138,7 +147,7 @@ abstract protected function redirectUrl(string $state): string;
protected function checkState(): void
{
$expected = $this->request->session()->pull('state');
$given = $this->request->query->get('state');
$given = $this->request->query->get('state');

if ($expected !== $given) {
throw new InvalidStateException($expected, $given);
Expand All @@ -147,24 +156,50 @@ protected function checkState(): void

protected function getTokensFromCode(string $code): TokenResponse
{
$response = $this->guzzle->post($this->config['token_url'], [
'headers' => ['Accept' => 'application/json'],
'form_params' => [
'client_id' => $this->config['client_id'],
'client_secret' => $this->config['client_secret'],
'code' => $code,
'redirect_uri' => $this->config['redirect_url'],
$response = $this->guzzle->post(
$this->config['token_url'],
[
'headers' => ['Accept' => 'application/json'],
'form_params' => [
'client_id' => $this->config['client_id'],
'client_secret' => $this->config['client_secret'],
'code' => $code,
'redirect_uri' => $this->config['redirect_url'],
]
]
);

return $this->parseTokenResponse($response);
}

protected function getTokensFromRefreshToken(string $refreshToken): TokenResponse
{
$response = $this->guzzle->post(
$this->config['token_url'],
[
'headers' => ['Accept' => 'application/json'],
'form_params' => [
'grant_type' => 'refresh_token',
'refresh_token' => $refreshToken,
'client_id' => $this->config['client_id'],
'client_secret' => $this->config['client_secret'],
]
]
]);
);

return $this->parseTokenResponse($response);
}

$response = json_decode($response->getBody(), true);
protected function parseTokenResponse(MessageInterface $response): TokenResponse
{
$response = json_decode($response->getBody()->getContents(), true);

$return = new TokenResponse();
$return->accessToken = Arr::get($response, 'access_token');
$return->refreshToken = Arr::get($response, 'refresh_token');
$return->accessTokenExpiration = Arr::get($response, 'expires_in');
$tokenResponse = new TokenResponse();
$tokenResponse->accessToken = Arr::get($response, 'access_token');
$tokenResponse->refreshToken = Arr::get($response, 'refresh_token');
$tokenResponse->accessTokenExpiration = Arr::get($response, 'expires_in');

return $return;
return $tokenResponse;
}

abstract protected function getUserByAccessToken(string $accessToken): ProviderUser;
Expand Down
2 changes: 1 addition & 1 deletion src/LAuth/Entities/Account.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ public function setAccessToken(string $accessToken): Account
return $this;
}

public function getRefreshToken(): string
public function getRefreshToken(): ?string
{
return $this->refreshToken;
}
Expand Down
21 changes: 21 additions & 0 deletions src/LAuth/Events/ProviderUpdate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

namespace Sztyup\LAuth\Events;

use Sztyup\LAuth\Entities\Account;
use Sztyup\LAuth\ProviderUser;

class ProviderUpdate
{
public $user;

public $account;

public function __construct(ProviderUser $user, Account $account)
{
$this->user = $user;
$this->account = $account;
}
}
3 changes: 0 additions & 3 deletions src/LAuth/LAuth.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,6 @@ public function redirectToProvider(string $providerName)
return $provider->redirect();
}

/**
* @throws Exceptions\InvalidStateException
*/
public function handleProviderCallback(string $providerName): ?User
{
$provider = $this->providerRegistry->getProvider($providerName);
Expand Down
1 change: 1 addition & 0 deletions src/LAuth/ProviderRegistry.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public function loadClassMetadata(LoadClassMetadataEventArgs $event): void

protected function baseAccount(ClassMetadata $metadata): void
{
$metadata->discriminatorMap = []; // Delete auto generated map
foreach ($this->providers as $name => $class) {
$metadata->addDiscriminatorMapClass($name, $class::getAccountEntity());
}
Expand Down

0 comments on commit 2a89a36

Please sign in to comment.