-
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 #41 from Allypost/feature/commands-rest
Add missing console commands for client management
- Loading branch information
Showing
20 changed files
with
690 additions
and
54 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
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,50 @@ | ||
<?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\Output\OutputInterface; | ||
use Symfony\Component\Console\Style\SymfonyStyle; | ||
use Trikoder\Bundle\OAuth2Bundle\Manager\ClientManagerInterface; | ||
|
||
final class DeleteClientCommand extends Command | ||
{ | ||
protected static $defaultName = 'trikoder:oauth2:delete-client'; | ||
private $clientManager; | ||
|
||
public function __construct(ClientManagerInterface $clientManager) | ||
{ | ||
parent::__construct(); | ||
$this->clientManager = $clientManager; | ||
} | ||
|
||
protected function configure(): void | ||
{ | ||
$this | ||
->setDescription('Deletes an oAuth2 client') | ||
->addArgument( | ||
'identifier', | ||
InputArgument::REQUIRED, | ||
'The client ID' | ||
) | ||
; | ||
} | ||
|
||
protected function execute(InputInterface $input, OutputInterface $output): int | ||
{ | ||
$io = new SymfonyStyle($input, $output); | ||
$identifier = $input->getArgument('identifier'); | ||
$client = $this->clientManager->find($identifier); | ||
if (null === $client) { | ||
$io->error(sprintf('oAuth2 client identified as "%s" does not exist', $identifier)); | ||
|
||
return 1; | ||
} | ||
$this->clientManager->remove($client); | ||
$io->success('Given oAuth2 client deleted successfully.'); | ||
|
||
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
<?php | ||
|
||
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\ClientFilter; | ||
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 ListClientsCommand extends Command | ||
{ | ||
public const ALLOWED_COLUMNS = ['identifier', 'secret', 'scope', 'redirect uri', 'grant type']; | ||
|
||
protected static $defaultName = 'trikoder:oauth2:list-clients'; | ||
private $clientManager; | ||
|
||
public function __construct(ClientManagerInterface $clientManager) | ||
{ | ||
parent::__construct(); | ||
$this->clientManager = $clientManager; | ||
} | ||
|
||
protected function configure(): void | ||
{ | ||
$this | ||
->setDescription('Lists existing oAuth2 clients') | ||
->addOption( | ||
'columns', | ||
null, | ||
InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, | ||
'Determine which columns are shown. Can be used multiple times to specify multiple columns.', | ||
self::ALLOWED_COLUMNS | ||
) | ||
->addOption( | ||
'redirect-uri', | ||
null, | ||
InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, | ||
'Finds by redirect uri for client. Use this option multiple times to filter by multiple redirect URIs.', | ||
[] | ||
) | ||
->addOption( | ||
'grant-type', | ||
null, | ||
InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, | ||
'Finds by allowed grant type for client. Use this option multiple times to filter by multiple grant types.', | ||
[] | ||
) | ||
->addOption( | ||
'scope', | ||
null, | ||
InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, | ||
'Finds by allowed scope for client. Use this option multiple times to find by multiple scopes.', | ||
[] | ||
) | ||
; | ||
} | ||
|
||
protected function execute(InputInterface $input, OutputInterface $output): int | ||
{ | ||
$criteria = $this->getFindByCriteria($input); | ||
$clients = $this->clientManager->list($criteria); | ||
$this->drawTable($input, $output, $clients); | ||
|
||
return 0; | ||
} | ||
|
||
private function getFindByCriteria(InputInterface $input): ClientFilter | ||
{ | ||
return | ||
ClientFilter | ||
::create() | ||
->addGrantCriteria(...array_map(function (string $grant): Grant { | ||
return new Grant($grant); | ||
}, $input->getOption('grant-type'))) | ||
->addRedirectUriCriteria(...array_map(function (string $redirectUri): RedirectUri { | ||
return new RedirectUri($redirectUri); | ||
}, $input->getOption('redirect-uri'))) | ||
->addScopeCriteria(...array_map(function (string $scope): Scope { | ||
return new Scope($scope); | ||
}, $input->getOption('scope'))) | ||
; | ||
} | ||
|
||
private function drawTable(InputInterface $input, OutputInterface $output, array $clients): void | ||
{ | ||
$io = new SymfonyStyle($input, $output); | ||
$columns = $this->getColumns($input); | ||
$rows = $this->getRows($clients, $columns); | ||
$io->table($columns, $rows); | ||
} | ||
|
||
private function getRows(array $clients, array $columns): array | ||
{ | ||
return array_map(function (Client $client) use ($columns): array { | ||
$values = [ | ||
'identifier' => $client->getIdentifier(), | ||
'secret' => $client->getSecret(), | ||
'scope' => implode(', ', $client->getScopes()), | ||
'redirect uri' => implode(', ', $client->getRedirectUris()), | ||
'grant type' => implode(', ', $client->getGrants()), | ||
]; | ||
|
||
return array_map(function (string $column) use ($values): string { | ||
return $values[$column]; | ||
}, $columns); | ||
}, $clients); | ||
} | ||
|
||
private function getColumns(InputInterface $input): array | ||
{ | ||
$allowedColumns = self::ALLOWED_COLUMNS; | ||
|
||
$requestedColumns = $input->getOption('columns'); | ||
$requestedColumns = array_map(function (string $column): string { | ||
return strtolower(trim($column)); | ||
}, $requestedColumns); | ||
|
||
return array_intersect($requestedColumns, $allowedColumns); | ||
} | ||
} |
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,86 @@ | ||
<?php | ||
|
||
namespace Trikoder\Bundle\OAuth2Bundle\Manager; | ||
|
||
use Trikoder\Bundle\OAuth2Bundle\Model\Grant; | ||
use Trikoder\Bundle\OAuth2Bundle\Model\RedirectUri; | ||
use Trikoder\Bundle\OAuth2Bundle\Model\Scope; | ||
|
||
final class ClientFilter | ||
{ | ||
/** | ||
* @var array | ||
*/ | ||
private $grants = []; | ||
/** | ||
* @var array | ||
*/ | ||
private $redirectUris = []; | ||
/** | ||
* @var array | ||
*/ | ||
private $scopes = []; | ||
|
||
public static function create(): self | ||
{ | ||
return new static(); | ||
} | ||
|
||
public function addGrantCriteria(Grant ...$grants): self | ||
{ | ||
return $this->addCriteria($this->grants, ...$grants); | ||
} | ||
|
||
public function addRedirectUriCriteria(RedirectUri ...$redirectUris): self | ||
{ | ||
return $this->addCriteria($this->redirectUris, ...$redirectUris); | ||
} | ||
|
||
public function addScopeCriteria(Scope ...$scopes): self | ||
{ | ||
return $this->addCriteria($this->scopes, ...$scopes); | ||
} | ||
|
||
private function addCriteria(&$field, ...$values): self | ||
{ | ||
if (0 === \count($values)) { | ||
return $this; | ||
} | ||
|
||
$field = array_merge($field, $values); | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* @return Grant[] | ||
*/ | ||
public function getGrants(): array | ||
{ | ||
return $this->grants; | ||
} | ||
|
||
/** | ||
* @return RedirectUri[] | ||
*/ | ||
public function getRedirectUris(): array | ||
{ | ||
return $this->redirectUris; | ||
} | ||
|
||
/** | ||
* @return Scope[] | ||
*/ | ||
public function getScopes(): array | ||
{ | ||
return $this->scopes; | ||
} | ||
|
||
public function hasFilters(): bool | ||
{ | ||
return | ||
!empty($this->grants) | ||
|| !empty($this->redirectUris) | ||
|| !empty($this->scopes); | ||
} | ||
} |
Oops, something went wrong.