Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[13.x] Fix clients confidentiality #1782

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/ClientRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,9 @@ public function createPersonalAccessGrantClient(string $name, ?string $provider
/**
* Store a new password grant client.
*/
public function createPasswordGrantClient(string $name, ?string $provider = null): Client
public function createPasswordGrantClient(string $name, ?string $provider = null, bool $confidential = false): Client
{
return $this->create($name, ['password', 'refresh_token'], [], $provider);
return $this->create($name, ['password', 'refresh_token'], [], $provider, $confidential);
}

/**
Expand All @@ -171,7 +171,7 @@ public function createClientCredentialsGrantClient(string $name): Client
*/
public function createImplicitGrantClient(string $name, array $redirectUris): Client
{
return $this->create($name, ['implicit'], $redirectUris);
return $this->create($name, ['implicit'], $redirectUris, null, false);
}

/**
Expand Down
143 changes: 46 additions & 97 deletions src/Console/ClientCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class ClientCommand extends Command
{--name= : The name of the client}
{--provider= : The name of the user provider}
{--redirect_uri= : The URI to redirect to after authorization }
{--public : Create a public client (Auth code grant type only) }';
{--public : Create a public client (without secret) }';

/**
* The console command description.
Expand All @@ -34,158 +34,107 @@ class ClientCommand extends Command

/**
* Execute the console command.
*
* @param \Laravel\Passport\ClientRepository $clients
* @return void
*/
public function handle(ClientRepository $clients)
public function handle(ClientRepository $clients): void
{
if ($this->option('personal')) {
$this->createPersonalAccessClient($clients);
} elseif ($this->option('password')) {
$this->createPasswordClient($clients);
} elseif ($this->option('client')) {
$this->createClientCredentialsClient($clients);
} elseif ($this->option('implicit')) {
$this->createImplicitClient($clients);
} else {
$this->createAuthCodeClient($clients);
if (! $this->hasOption('name')) {
$this->input->setOption('name', $this->ask(
'What should we name the client?',
config('app.name')
));
}

$client = match (true) {
$this->option('personal') => $this->createPersonalAccessClient($clients),
$this->option('password') => $this->createPasswordClient($clients),
$this->option('client') => $this->createClientCredentialsClient($clients),
$this->option('implicit') => $this->createImplicitClient($clients),
default => $this->createAuthCodeClient($clients)
};

$this->components->info('New client created successfully.');

if ($client) {
$this->components->twoColumnDetail('Client ID', $client->getKey());

if ($client->confidential()) {
$this->components->twoColumnDetail('Client Secret', $client->plainSecret);
$this->components->warn('The client secret will not be shown again, so don\'t lose it!');
}
}
}

/**
* Create a new personal access client.
*
* @param \Laravel\Passport\ClientRepository $clients
* @return void
*/
protected function createPersonalAccessClient(ClientRepository $clients)
protected function createPersonalAccessClient(ClientRepository $clients): ?Client
{
$name = $this->option('name') ?: $this->ask(
'What should we name the client?',
config('app.name').' Personal Access Grant Client'
);

$provider = $this->option('provider') ?: $this->choice(
'Which user provider should this client use to retrieve users?',
collect(config('auth.guards'))->where('driver', 'passport')->pluck('provider')->all(),
config('auth.guards.api.provider')
);

$clients->createPersonalAccessGrantClient($name, $provider);
$clients->createPersonalAccessGrantClient($this->option('name'), $provider);

$this->components->info('Personal access client created successfully.');
return null;
}

/**
* Create a new password grant client.
*
* @param \Laravel\Passport\ClientRepository $clients
* @return void
*/
protected function createPasswordClient(ClientRepository $clients)
protected function createPasswordClient(ClientRepository $clients): Client
{
$name = $this->option('name') ?: $this->ask(
'What should we name the client?',
config('app.name').' Password Grant Client'
);

$provider = $this->option('provider') ?: $this->choice(
'Which user provider should this client use to retrieve users?',
collect(config('auth.guards'))->where('driver', 'passport')->pluck('provider')->all(),
config('auth.guards.api.provider')
);

$client = $clients->createPasswordGrantClient($name, $provider);
$confidential = $this->hasOption('public')
? ! $this->option('public')
: $this->confirm('Would you like to make this client confidential?');

$this->components->info('Password grant client created successfully.');

$this->outputClientDetails($client);
return $clients->createPasswordGrantClient($this->option('name'), $provider, $confidential);
}

/**
* Create a client credentials grant client.
*
* @param \Laravel\Passport\ClientRepository $clients
* @return void
*/
protected function createClientCredentialsClient(ClientRepository $clients)
protected function createClientCredentialsClient(ClientRepository $clients): Client
{
$name = $this->option('name') ?: $this->ask(
'What should we name the client?',
config('app.name').' Client Credentials Grant Client'
);

$client = $clients->createClientCredentialsGrantClient($name);

$this->components->info('New client created successfully.');

$this->outputClientDetails($client);
return $clients->createClientCredentialsGrantClient($this->option('name'));
}

/**
* Create an implicit grant client.
*
* @param \Laravel\Passport\ClientRepository $clients
* @return void
*/
protected function createImplicitClient(ClientRepository $clients)
protected function createImplicitClient(ClientRepository $clients): Client
{
$name = $this->option('name') ?: $this->ask(
'What should we name the client?',
config('app.name').' Implicit Grant Client'
);

$redirect = $this->option('redirect_uri') ?: $this->ask(
'Where should we redirect the request after authorization?',
url('/auth/callback')
);

$client = $clients->createImplicitGrantClient($name, explode(',', $redirect));

$this->components->info('New client created successfully.');

$this->outputClientDetails($client);
return $clients->createImplicitGrantClient($this->option('name'), explode(',', $redirect));
}

/**
* Create a authorization code client.
*
* @param \Laravel\Passport\ClientRepository $clients
* @return void
* Create an authorization code client.
*/
protected function createAuthCodeClient(ClientRepository $clients)
protected function createAuthCodeClient(ClientRepository $clients): Client
{
$name = $this->option('name') ?: $this->ask(
'What should we name the client?',
config('app.name')
);

$redirect = $this->option('redirect_uri') ?: $this->ask(
'Where should we redirect the request after authorization?',
url('/auth/callback')
);

$client = $clients->createAuthorizationCodeGrantClient(
$name, explode(',', $redirect), ! $this->option('public'),
);

$this->components->info('New client created successfully.');

$this->outputClientDetails($client);
}

/**
* Output the client's ID and secret key.
*
* @param \Laravel\Passport\Client $client
* @return void
*/
protected function outputClientDetails(Client $client)
{
$this->components->warn('Here is your new client secret. This is the only time it will be shown so don\'t lose it!');
$confidential = $this->hasOption('public')
? ! $this->option('public')
: $this->confirm('Would you like to make this client confidential?', true);

$this->components->twoColumnDetail('Client ID', $client->getKey());
$this->components->twoColumnDetail('Client Secret', $client->plainSecret);
return $clients->createAuthorizationCodeGrantClient(
$this->option('name'), explode(',', $redirect), $confidential,
);
}
}