Skip to content

Commit 44fbdb7

Browse files
committed
Improve update command
1 parent eefadc7 commit 44fbdb7

File tree

3 files changed

+140
-149
lines changed

3 files changed

+140
-149
lines changed

docs/basic-setup.md

Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ Arguments:
2121
secret The client secret
2222

2323
Options:
24-
--redirect-uri[=REDIRECT-URI] Sets redirect uri for client. Use this option multiple times to set multiple redirect URIs. (multiple values allowed)
25-
--grant-type[=GRANT-TYPE] Sets allowed grant type for client. Use this option multiple times to set multiple grant types. (multiple values allowed)
26-
--scope[=SCOPE] Sets allowed scope for client. Use this option multiple times to set multiple scopes. (multiple values allowed)
24+
--redirect-uri=REDIRECT-URI Sets redirect uri for client. Use this option multiple times to set multiple redirect URIs. (multiple values allowed)
25+
--grant-type=GRANT-TYPE Sets allowed grant type for client. Use this option multiple times to set multiple grant types. (multiple values allowed)
26+
--scope=SCOPE Sets allowed scope for client. Use this option multiple times to set multiple scopes. (multiple values allowed)
2727
--public Creates a public client (a client which does not have a secret)
2828
--allow-plain-text-pkce Creates a client which is allowed to create an authorization code grant PKCE request with the "plain" code challenge method
2929
```
@@ -41,27 +41,17 @@ Usage:
4141
league:oauth2-server:update-client [options] [--] <identifier>
4242

4343
Arguments:
44-
identifier The client ID
44+
identifier The client identifier
4545

4646
Options:
47-
--redirect-uri[=REDIRECT-URI] Sets redirect uri for client. Use this option multiple times to set multiple redirect URIs. (multiple values allowed)
48-
--grant-type[=GRANT-TYPE] Sets allowed grant type for client. Use this option multiple times to set multiple grant types. (multiple values allowed)
49-
--scope[=SCOPE] Sets allowed scope for client. Use this option multiple times to set multiple scopes. (multiple values allowed)
50-
--name=[=NAME] Sets name for client.
51-
--deactivated If provided, it will deactivate the given client.
52-
```
53-
54-
#### Restrict which grant types a client can access
55-
56-
```sh
57-
$ bin/console league:oauth2-server:update-client --grant-type client_credentials foo
58-
```
59-
60-
#### Assign which scopes the client will receive
61-
62-
63-
```sh
64-
$ bin/console league:oauth2-server:update-client --scope create --scope read foo
47+
--add-redirect-uri=ADD-REDIRECT-URI Add allowed redirect uri to the client. (multiple values allowed)
48+
--remove-redirect-uri=REMOVE-REDIRECT-URI Remove allowed redirect uri to the client. (multiple values allowed)
49+
--add-grant-type=ADD-GRANT-TYPE Add allowed grant type to the client. (multiple values allowed)
50+
--remove-grant-type=REMOVE-GRANT-TYPE Remove allowed grant type to the client. (multiple values allowed)
51+
--add-scope=ADD-SCOPE Add allowed scope to the client. (multiple values allowed)
52+
--remove-scope=REMOVE-SCOPE Remove allowed scope to the client. (multiple values allowed)
53+
--activate Activate the client.
54+
--deactivate Deactivate the client.
6555
```
6656
6757
### Delete a client
@@ -89,10 +79,10 @@ Usage:
8979
league:oauth2-server:list-clients [options]
9080

9181
Options:
92-
--columns[=COLUMNS] Determine which columns are shown. Comma separated list. [default: "identifier, secret, scope, redirect uri, grant type"]
93-
--redirect-uri[=REDIRECT-URI] Finds by redirect uri for client. Use this option multiple times to filter by multiple redirect URIs. (multiple values allowed)
94-
--grant-type[=GRANT-TYPE] Finds by allowed grant type for client. Use this option multiple times to filter by multiple grant types. (multiple values allowed)
95-
--scope[=SCOPE] Finds by allowed scope for client. Use this option multiple times to find by multiple scopes. (multiple values allowed)__
82+
--columns=COLUMNS Determine which columns are shown. Comma separated list. [default: "identifier, secret, scope, redirect uri, grant type"]
83+
--redirect-uri=REDIRECT-URI Finds by redirect uri for client. Use this option multiple times to filter by multiple redirect URIs. (multiple values allowed)
84+
--grant-type=GRANT-TYPE Finds by allowed grant type for client. Use this option multiple times to filter by multiple grant types. (multiple values allowed)
85+
--scope=SCOPE Finds by allowed scope for client. Use this option multiple times to find by multiple scopes. (multiple values allowed)__
9686
```
9787
9888
## Configuring the Security layer

src/Command/UpdateClientCommand.php

Lines changed: 65 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
namespace League\Bundle\OAuth2ServerBundle\Command;
66

77
use League\Bundle\OAuth2ServerBundle\Manager\ClientManagerInterface;
8-
use League\Bundle\OAuth2ServerBundle\Model\AbstractClient;
98
use League\Bundle\OAuth2ServerBundle\Model\Grant;
109
use League\Bundle\OAuth2ServerBundle\Model\RedirectUri;
1110
use League\Bundle\OAuth2ServerBundle\Model\Scope;
@@ -36,45 +35,20 @@ protected function configure(): void
3635
{
3736
$this
3837
->setDescription('Updates an OAuth2 client')
39-
->addOption(
40-
'redirect-uri',
41-
null,
42-
InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
43-
'Sets redirect uri for client. Use this option multiple times to set multiple redirect URIs.',
44-
[]
45-
)
46-
->addOption(
47-
'grant-type',
48-
null,
49-
InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
50-
'Sets allowed grant type for client. Use this option multiple times to set multiple grant types.',
51-
[]
52-
)
53-
->addOption(
54-
'scope',
55-
null,
56-
InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
57-
'Sets allowed scope for client. Use this option multiple times to set multiple scopes.',
58-
[]
59-
)
60-
->addOption(
61-
'name',
62-
null,
63-
InputOption::VALUE_REQUIRED,
64-
'Sets name for client.',
65-
[]
66-
)
67-
->addOption(
68-
'deactivated',
69-
null,
70-
InputOption::VALUE_NONE,
71-
'If provided, it will deactivate the given client.'
72-
)
73-
->addArgument(
74-
'identifier',
75-
InputArgument::REQUIRED,
76-
'The client ID'
77-
)
38+
39+
->addOption('add-redirect-uri', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Add allowed redirect uri to the client.', [])
40+
->addOption('remove-redirect-uri', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Remove allowed redirect uri to the client.', [])
41+
42+
->addOption('add-grant-type', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Add allowed grant type to the client.', [])
43+
->addOption('remove-grant-type', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Remove allowed grant type to the client.', [])
44+
45+
->addOption('add-scope', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Add allowed scope to the client.', [])
46+
->addOption('remove-scope', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Remove allowed scope to the client.', [])
47+
48+
->addOption('activate', null, InputOption::VALUE_NONE, 'Activate the client.')
49+
->addOption('deactivate', null, InputOption::VALUE_NONE, 'Deactivate the client.')
50+
51+
->addArgument('identifier', InputArgument::REQUIRED, 'The client identifier')
7852
;
7953
}
8054

@@ -88,41 +62,67 @@ protected function execute(InputInterface $input, OutputInterface $output): int
8862
return 1;
8963
}
9064

91-
$client = $this->updateClientFromInput($client, $input);
65+
$client->setActive($this->getClientActiveFromInput($input, $client->isActive()));
66+
$client->setRedirectUris(...$this->getClientRelatedModelsFromInput($input, RedirectUri::class, $client->getRedirectUris(), 'redirect-uri'));
67+
$client->setGrants(...$this->getClientRelatedModelsFromInput($input, Grant::class, $client->getGrants(), 'grant-type'));
68+
$client->setScopes(...$this->getClientRelatedModelsFromInput($input, Scope::class, $client->getScopes(), 'scope'));
69+
9270
$this->clientManager->save($client);
9371

9472
$io->success('OAuth2 client updated successfully.');
9573

9674
return 0;
9775
}
9876

99-
private function updateClientFromInput(AbstractClient $client, InputInterface $input): AbstractClient
77+
private function getClientActiveFromInput(InputInterface $input, bool $actual): bool
10078
{
101-
$client->setActive(!$input->getOption('deactivated'));
102-
103-
/** @var list<string> $redirectUriStrings */
104-
$redirectUriStrings = $input->getOption('redirect-uri');
105-
/** @var list<string> $grantStrings */
106-
$grantStrings = $input->getOption('grant-type');
107-
/** @var list<string> $scopeStrings */
108-
$scopeStrings = $input->getOption('scope');
109-
110-
$client
111-
->setRedirectUris(...array_map(static function (string $redirectUri): RedirectUri {
112-
return new RedirectUri($redirectUri);
113-
}, $redirectUriStrings))
114-
->setGrants(...array_map(static function (string $grant): Grant {
115-
return new Grant($grant);
116-
}, $grantStrings))
117-
->setScopes(...array_map(static function (string $scope): Scope {
118-
return new Scope($scope);
119-
}, $scopeStrings))
120-
;
79+
$active = $actual;
80+
81+
if ($input->getOption('activate') && $input->getOption('deactivate')) {
82+
throw new \RuntimeException('Cannot specify "--activate" and "--deactivate" at the same time.');
83+
}
84+
85+
if ($input->getOption('activate')) {
86+
$active = true;
87+
}
12188

122-
if ($name = $input->getOption('name')) {
123-
$client->setName($name);
89+
if ($input->getOption('deactivate')) {
90+
$active = false;
12491
}
12592

126-
return $client;
93+
return $active;
94+
}
95+
96+
/**
97+
* @template T1 of RedirectUri
98+
* @template T2 of Grant
99+
* @template T3 of Scope
100+
*
101+
* @param class-string<T1>|class-string<T2>|class-string<T3> $modelFqcn
102+
*
103+
* @return list<T1>|list<T2>|list<T3>
104+
*
105+
* @psalm-suppress UnsafeInstantiation
106+
*/
107+
private function getClientRelatedModelsFromInput(InputInterface $input, string $modelFqcn, array $actual, string $argument): array
108+
{
109+
/** @var list<string> $toAdd */
110+
$toAdd = $input->getOption($addArgument = sprintf('add-%s', $argument));
111+
112+
/** @var list<string> $toRemove */
113+
$toRemove = $input->getOption($removeArgument = sprintf('remove-%s', $argument));
114+
115+
if ([] !== $colliding = array_intersect($toAdd, $toRemove)) {
116+
throw new \RuntimeException(sprintf('Cannot specify "%s" in either "--%s" and "--%s".', implode('", "', $colliding), $addArgument, $removeArgument));
117+
}
118+
119+
$filtered = array_filter($actual, static function ($model) use ($toRemove): bool {
120+
return !\in_array((string) $model, $toRemove);
121+
});
122+
123+
/** @var list<T1>|list<T2>|list<T3> */
124+
return array_merge($filtered, array_map(static function (string $value) use ($modelFqcn) {
125+
return new $modelFqcn($value);
126+
}, $toAdd));
127127
}
128128
}

0 commit comments

Comments
 (0)