-
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.
Add console commands for client management (#17)
* Add console commands for client management * Update docs with commands info
- Loading branch information
Showing
6 changed files
with
495 additions
and
16 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,112 @@ | ||
<?php | ||
|
||
namespace Trikoder\Bundle\OAuth2Bundle\Command; | ||
|
||
use Symfony\Component\Console\Command\Command; | ||
use Symfony\Component\Console\Input\InputArgument; | ||
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\ClientManagerInterface; | ||
use Trikoder\Bundle\OAuth2Bundle\Model\Client; | ||
use Trikoder\Bundle\OAuth2Bundle\Model\Grant; | ||
use Trikoder\Bundle\OAuth2Bundle\Model\RedirectUri; | ||
use Trikoder\Bundle\OAuth2Bundle\Model\Scope; | ||
|
||
final class CreateClientCommand extends Command | ||
{ | ||
protected static $defaultName = 'trikoder:oauth2:create-client'; | ||
|
||
private $clientManager; | ||
|
||
public function __construct(ClientManagerInterface $clientManager) | ||
{ | ||
parent::__construct(); | ||
|
||
$this->clientManager = $clientManager; | ||
} | ||
|
||
protected function configure() | ||
{ | ||
$this | ||
->setDescription('Creates a new oAuth2 client') | ||
->addOption( | ||
'redirect-uri', | ||
null, | ||
InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, | ||
'Sets redirect uri for client. Use this option multiple times to set multiple redirect URIs.', | ||
null | ||
) | ||
->addOption( | ||
'grant-type', | ||
null, | ||
InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, | ||
'Sets allowed grant type for client. Use this option multiple times to set multiple grant types.', | ||
null | ||
) | ||
->addOption( | ||
'scope', | ||
null, | ||
InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, | ||
'Sets allowed scope for client. Use this option multiple times to set multiple scopes.', | ||
null | ||
) | ||
->addArgument( | ||
'identifier', | ||
InputArgument::OPTIONAL, | ||
'The client identifier' | ||
) | ||
->addArgument( | ||
'secret', | ||
InputArgument::OPTIONAL, | ||
'The client secret' | ||
) | ||
; | ||
} | ||
|
||
protected function execute(InputInterface $input, OutputInterface $output) | ||
{ | ||
$io = new SymfonyStyle($input, $output); | ||
$client = $this->buildClientFromInput($input); | ||
$this->clientManager->save($client); | ||
$io->success('New oAuth2 client created successfully.'); | ||
|
||
$headers = ['Identifier', 'Secret']; | ||
$rows = [ | ||
[$client->getIdentifier(), $client->getSecret()], | ||
]; | ||
$io->table($headers, $rows); | ||
|
||
return 0; | ||
} | ||
|
||
private function buildClientFromInput(InputInterface $input) | ||
{ | ||
$identifier = $input->getArgument('identifier') ?? hash('md5', random_bytes(16)); | ||
$secret = $input->getArgument('secret') ?? hash('sha512', random_bytes(32)); | ||
|
||
$client = new Client($identifier, $secret); | ||
$client->setActive(true); | ||
|
||
$redirectUris = array_map( | ||
function (string $redirectUri) { return new RedirectUri($redirectUri); }, | ||
$input->getOption('redirect-uri') | ||
); | ||
$client->setRedirectUris(...$redirectUris); | ||
|
||
$grants = array_map( | ||
function (string $grant) { return new Grant($grant); }, | ||
$input->getOption('grant-type') | ||
); | ||
$client->setGrants(...$grants); | ||
|
||
$scopes = array_map( | ||
function (string $scope) { return new Scope($scope); }, | ||
$input->getOption('scope') | ||
); | ||
$client->setScopes(...$scopes); | ||
|
||
return $client; | ||
} | ||
} |
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 | ||
|
||
namespace Trikoder\Bundle\OAuth2Bundle\Command; | ||
|
||
use Symfony\Component\Console\Command\Command; | ||
use Symfony\Component\Console\Input\InputArgument; | ||
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\ClientManagerInterface; | ||
use Trikoder\Bundle\OAuth2Bundle\Model\Client; | ||
use Trikoder\Bundle\OAuth2Bundle\Model\Grant; | ||
use Trikoder\Bundle\OAuth2Bundle\Model\RedirectUri; | ||
use Trikoder\Bundle\OAuth2Bundle\Model\Scope; | ||
|
||
final class UpdateClientCommand extends Command | ||
{ | ||
protected static $defaultName = 'trikoder:oauth2:update-client'; | ||
|
||
private $clientManager; | ||
|
||
public function __construct(ClientManagerInterface $clientManager) | ||
{ | ||
parent::__construct(); | ||
|
||
$this->clientManager = $clientManager; | ||
} | ||
|
||
protected function configure() | ||
{ | ||
$this | ||
->setDescription('Updates an oAuth2 client') | ||
->addOption( | ||
'redirect-uri', | ||
null, | ||
InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, | ||
'Sets redirect uri for client. Use this option multiple times to set multiple redirect URIs.', | ||
null | ||
) | ||
->addOption( | ||
'grant-type', | ||
null, | ||
InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, | ||
'Sets allowed grant type for client. Use this option multiple times to set multiple grant types.', | ||
null | ||
) | ||
->addOption( | ||
'scope', | ||
null, | ||
InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, | ||
'Sets allowed scope for client. Use this option multiple times to set multiple scopes.', | ||
null | ||
) | ||
->addOption( | ||
'deactivated', | ||
null, | ||
InputOption::VALUE_NONE, | ||
'If provided, it will deactivate the given client.' | ||
) | ||
->addArgument( | ||
'identifier', | ||
InputArgument::REQUIRED, | ||
'The client ID' | ||
) | ||
; | ||
} | ||
|
||
protected function execute(InputInterface $input, OutputInterface $output) | ||
{ | ||
$io = new SymfonyStyle($input, $output); | ||
|
||
if (null === $client = $this->clientManager->find($input->getArgument('identifier'))) { | ||
$io->error(sprintf('oAuth2 client identified as "%s"', $input->getArgument('identifier'))); | ||
|
||
return 1; | ||
} | ||
|
||
$client = $this->updateClientFromInput($client, $input); | ||
$this->clientManager->save($client); | ||
$io->success('Given oAuth2 client updated successfully.'); | ||
|
||
return 0; | ||
} | ||
|
||
private function updateClientFromInput(Client $client, InputInterface $input): Client | ||
{ | ||
$client->setActive(!$input->getOption('deactivated')); | ||
|
||
$redirectUris = array_map( | ||
function (string $redirectUri) { return new RedirectUri($redirectUri); }, | ||
$input->getOption('redirect-uri') | ||
); | ||
$client->setRedirectUris(...$redirectUris); | ||
|
||
$grants = array_map( | ||
function (string $grant) { return new Grant($grant); }, | ||
$input->getOption('grant-type') | ||
); | ||
$client->setGrants(...$grants); | ||
|
||
$scopes = array_map( | ||
function (string $scope) { return new Scope($scope); }, | ||
$input->getOption('scope') | ||
); | ||
$client->setScopes(...$scopes); | ||
|
||
return $client; | ||
} | ||
} |
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,122 @@ | ||
<?php | ||
|
||
namespace Trikoder\Bundle\OAuth2Bundle\Tests\Acceptance; | ||
|
||
use Symfony\Component\Console\Tester\CommandTester; | ||
use Trikoder\Bundle\OAuth2Bundle\Manager\ClientManagerInterface; | ||
use Trikoder\Bundle\OAuth2Bundle\Model\Client; | ||
|
||
final class CreateClientCommandTest extends AbstractAcceptanceTest | ||
{ | ||
public function testCreateClient() | ||
{ | ||
$command = $this->application->find('trikoder:oauth2:create-client'); | ||
$commandTester = new CommandTester($command); | ||
$commandTester->execute([ | ||
'command' => $command->getName(), | ||
]); | ||
|
||
$output = $commandTester->getDisplay(); | ||
$this->assertContains('New oAuth2 client created successfully', $output); | ||
} | ||
|
||
public function testCreateClientWithIdentifier() | ||
{ | ||
$command = $this->application->find('trikoder:oauth2:create-client'); | ||
$commandTester = new CommandTester($command); | ||
$commandTester->execute([ | ||
'command' => $command->getName(), | ||
'identifier' => 'foobar', | ||
]); | ||
|
||
$output = $commandTester->getDisplay(); | ||
$this->assertContains('New oAuth2 client created successfully', $output); | ||
$this->assertContains('foobar', $output); | ||
|
||
$client = $this->client | ||
->getContainer() | ||
->get(ClientManagerInterface::class) | ||
->find('foobar'); | ||
$this->assertInstanceOf(Client::class, $client); | ||
} | ||
|
||
public function testCreateClientWithSecret() | ||
{ | ||
$command = $this->application->find('trikoder:oauth2:create-client'); | ||
$commandTester = new CommandTester($command); | ||
$commandTester->execute([ | ||
'command' => $command->getName(), | ||
'identifier' => 'foobar', | ||
'secret' => 'quzbaz', | ||
]); | ||
|
||
$output = $commandTester->getDisplay(); | ||
$this->assertContains('New oAuth2 client created successfully', $output); | ||
$client = $this->client | ||
->getContainer() | ||
->get(ClientManagerInterface::class) | ||
->find('foobar'); | ||
$this->assertInstanceOf(Client::class, $client); | ||
$this->assertSame('quzbaz', $client->getSecret()); | ||
} | ||
|
||
public function testCreateClientWithRedirectUris() | ||
{ | ||
$command = $this->application->find('trikoder:oauth2:create-client'); | ||
$commandTester = new CommandTester($command); | ||
$commandTester->execute([ | ||
'command' => $command->getName(), | ||
'identifier' => 'foobar', | ||
'--redirect-uri' => ['http://example.org', 'http://example.org'], | ||
]); | ||
|
||
$output = $commandTester->getDisplay(); | ||
$this->assertContains('New oAuth2 client created successfully', $output); | ||
$client = $this->client | ||
->getContainer() | ||
->get(ClientManagerInterface::class) | ||
->find('foobar'); | ||
$this->assertInstanceOf(Client::class, $client); | ||
$this->assertCount(2, $client->getRedirectUris()); | ||
} | ||
|
||
public function testCreateClientWithGrantTypes() | ||
{ | ||
$command = $this->application->find('trikoder:oauth2:create-client'); | ||
$commandTester = new CommandTester($command); | ||
$commandTester->execute([ | ||
'command' => $command->getName(), | ||
'identifier' => 'foobar', | ||
'--grant-type' => ['password', 'client_credentials'], | ||
]); | ||
|
||
$output = $commandTester->getDisplay(); | ||
$this->assertContains('New oAuth2 client created successfully', $output); | ||
$client = $this->client | ||
->getContainer() | ||
->get(ClientManagerInterface::class) | ||
->find('foobar'); | ||
$this->assertInstanceOf(Client::class, $client); | ||
$this->assertCount(2, $client->getGrants()); | ||
} | ||
|
||
public function testCreateClientWithScopes() | ||
{ | ||
$command = $this->application->find('trikoder:oauth2:create-client'); | ||
$commandTester = new CommandTester($command); | ||
$commandTester->execute([ | ||
'command' => $command->getName(), | ||
'identifier' => 'foobar', | ||
'--scope' => ['foo', 'bar'], | ||
]); | ||
|
||
$output = $commandTester->getDisplay(); | ||
$this->assertContains('New oAuth2 client created successfully', $output); | ||
$client = $this->client | ||
->getContainer() | ||
->get(ClientManagerInterface::class) | ||
->find('foobar'); | ||
$this->assertInstanceOf(Client::class, $client); | ||
$this->assertCount(2, $client->getScopes()); | ||
} | ||
} |
Oops, something went wrong.