-
Notifications
You must be signed in to change notification settings - Fork 114
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #53 from trikoder/clear-expired-tokens-command
Add a console command for removing expired tokens
- Loading branch information
Showing
14 changed files
with
581 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Trikoder\Bundle\OAuth2Bundle\Command; | ||
|
||
use Symfony\Component\Console\Command\Command; | ||
use Symfony\Component\Console\Input\InputInterface; | ||
use Symfony\Component\Console\Input\InputOption; | ||
use Symfony\Component\Console\Output\OutputInterface; | ||
use Symfony\Component\Console\Style\SymfonyStyle; | ||
use Trikoder\Bundle\OAuth2Bundle\Manager\AccessTokenManagerInterface; | ||
use Trikoder\Bundle\OAuth2Bundle\Manager\RefreshTokenManagerInterface; | ||
|
||
final class ClearExpiredTokensCommand extends Command | ||
{ | ||
protected static $defaultName = 'trikoder:oauth2:clear-expired-tokens'; | ||
|
||
/** | ||
* @var AccessTokenManagerInterface | ||
*/ | ||
private $accessTokenManager; | ||
|
||
/** | ||
* @var RefreshTokenManagerInterface | ||
*/ | ||
private $refreshTokenManager; | ||
|
||
public function __construct( | ||
AccessTokenManagerInterface $accessTokenManager, | ||
RefreshTokenManagerInterface $refreshTokenManager | ||
) { | ||
parent::__construct(); | ||
|
||
$this->accessTokenManager = $accessTokenManager; | ||
$this->refreshTokenManager = $refreshTokenManager; | ||
} | ||
|
||
protected function configure(): void | ||
{ | ||
$this | ||
->setDescription('Clears all expired access and/or refresh tokens') | ||
->addOption( | ||
'access-tokens-only', | ||
'a', | ||
InputOption::VALUE_NONE, | ||
'Clear only access tokens.' | ||
) | ||
->addOption( | ||
'refresh-tokens-only', | ||
'r', | ||
InputOption::VALUE_NONE, | ||
'Clear only refresh tokens.' | ||
) | ||
; | ||
} | ||
|
||
protected function execute(InputInterface $input, OutputInterface $output): int | ||
{ | ||
$io = new SymfonyStyle($input, $output); | ||
|
||
$clearExpiredAccessTokens = !$input->getOption('refresh-tokens-only'); | ||
$clearExpiredRefreshTokens = !$input->getOption('access-tokens-only'); | ||
|
||
if (!$clearExpiredAccessTokens && !$clearExpiredRefreshTokens) { | ||
$io->error('Please choose only one of the following options: "access-tokens-only", "refresh-tokens-only".'); | ||
|
||
return 1; | ||
} | ||
|
||
if (true === $clearExpiredAccessTokens) { | ||
$numOfClearedAccessTokens = $this->accessTokenManager->clearExpired(); | ||
$io->success(sprintf( | ||
'Cleared %d expired access token%s.', | ||
$numOfClearedAccessTokens, | ||
1 === $numOfClearedAccessTokens ? '' : 's' | ||
)); | ||
} | ||
|
||
if (true === $clearExpiredRefreshTokens) { | ||
$numOfClearedRefreshTokens = $this->refreshTokenManager->clearExpired(); | ||
$io->success(sprintf( | ||
'Cleared %d expired refresh token%s.', | ||
$numOfClearedRefreshTokens, | ||
1 === $numOfClearedRefreshTokens ? '' : 's' | ||
)); | ||
} | ||
|
||
return 0; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Trikoder\Bundle\OAuth2Bundle\Tests\Acceptance; | ||
|
||
use DateTime; | ||
use Symfony\Component\Console\Command\Command; | ||
use Symfony\Component\Console\Tester\CommandTester; | ||
use Trikoder\Bundle\OAuth2Bundle\Manager\AccessTokenManagerInterface; | ||
use Trikoder\Bundle\OAuth2Bundle\Manager\ClientManagerInterface; | ||
use Trikoder\Bundle\OAuth2Bundle\Manager\RefreshTokenManagerInterface; | ||
use Trikoder\Bundle\OAuth2Bundle\Manager\ScopeManagerInterface; | ||
use Trikoder\Bundle\OAuth2Bundle\Tests\Fixtures\FixtureFactory; | ||
|
||
final class ClearExpiredTokensCommandTest extends AbstractAcceptanceTest | ||
{ | ||
protected function setUp(): void | ||
{ | ||
parent::setUp(); | ||
|
||
timecop_freeze(new DateTime()); | ||
|
||
FixtureFactory::initializeFixtures( | ||
$this->client->getContainer()->get(ScopeManagerInterface::class), | ||
$this->client->getContainer()->get(ClientManagerInterface::class), | ||
$this->client->getContainer()->get(AccessTokenManagerInterface::class), | ||
$this->client->getContainer()->get(RefreshTokenManagerInterface::class) | ||
); | ||
} | ||
|
||
protected function tearDown(): void | ||
{ | ||
timecop_return(); | ||
|
||
parent::tearDown(); | ||
} | ||
|
||
public function testClearExpiredAccessAndRefreshTokens(): void | ||
{ | ||
$command = $this->command(); | ||
$commandTester = new CommandTester($command); | ||
|
||
$exitCode = $commandTester->execute([ | ||
'command' => $command->getName(), | ||
]); | ||
|
||
$this->assertSame(0, $exitCode); | ||
|
||
$output = $commandTester->getDisplay(); | ||
$this->assertStringContainsString('Cleared 1 expired access token.', $output); | ||
$this->assertStringContainsString('Cleared 1 expired refresh token.', $output); | ||
} | ||
|
||
public function testClearExpiredAccessTokens(): void | ||
{ | ||
$command = $this->command(); | ||
$commandTester = new CommandTester($command); | ||
|
||
$exitCode = $commandTester->execute([ | ||
'command' => $command->getName(), | ||
'--access-tokens-only' => true, | ||
]); | ||
|
||
$this->assertSame(0, $exitCode); | ||
|
||
$output = $commandTester->getDisplay(); | ||
$this->assertStringContainsString('Cleared 1 expired access token.', $output); | ||
$this->assertStringNotContainsString('Cleared 1 expired refresh token.', $output); | ||
} | ||
|
||
public function testClearExpiredRefreshTokens(): void | ||
{ | ||
$command = $this->command(); | ||
$commandTester = new CommandTester($command); | ||
|
||
$exitCode = $commandTester->execute([ | ||
'command' => $command->getName(), | ||
'--refresh-tokens-only' => true, | ||
]); | ||
|
||
$this->assertSame(0, $exitCode); | ||
|
||
$output = $commandTester->getDisplay(); | ||
$this->assertStringNotContainsString('Cleared 1 expired access token.', $output); | ||
$this->assertStringContainsString('Cleared 1 expired refresh token.', $output); | ||
} | ||
|
||
public function testErrorWhenBothOptionsAreUsed(): void | ||
{ | ||
$command = $this->command(); | ||
$commandTester = new CommandTester($command); | ||
|
||
$exitCode = $commandTester->execute([ | ||
'command' => $command->getName(), | ||
'--access-tokens-only' => true, | ||
'--refresh-tokens-only' => true, | ||
]); | ||
|
||
$this->assertSame(1, $exitCode); | ||
|
||
$output = $commandTester->getDisplay(); | ||
$this->assertStringContainsString('Please choose only one of the following options:', $output); | ||
} | ||
|
||
private function command(): Command | ||
{ | ||
return $this->application->find('trikoder:oauth2:clear-expired-tokens'); | ||
} | ||
} |
Oops, something went wrong.