Skip to content

Commit

Permalink
Merge branch 'billriess/8.x'
Browse files Browse the repository at this point in the history
  • Loading branch information
taylorotwell committed Apr 28, 2020
2 parents 4f52c4c + cdc37f0 commit 11d8533
Show file tree
Hide file tree
Showing 14 changed files with 201 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public function up()
$table->unsignedBigInteger('user_id')->nullable()->index();
$table->string('name');
$table->string('secret', 100)->nullable();
$table->string('provider')->nullable();
$table->text('redirect');
$table->boolean('personal_access_client');
$table->boolean('password_client');
Expand Down
11 changes: 10 additions & 1 deletion src/Bridge/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,31 @@ class Client implements ClientEntityInterface
*/
protected $identifier;

/**
* The client's provider.
*
* @var string
*/
public $provider;

/**
* Create a new client instance.
*
* @param string $identifier
* @param string $name
* @param string $redirectUri
* @param bool $isConfidential
* @param string|null $provider
* @return void
*/
public function __construct($identifier, $name, $redirectUri, $isConfidential = false)
public function __construct($identifier, $name, $redirectUri, $isConfidential = false, $provider = null)
{
$this->setIdentifier((string) $identifier);

$this->name = $name;
$this->isConfidential = $isConfidential;
$this->redirectUri = explode(',', $redirectUri);
$this->provider = $provider;
}

/**
Expand Down
6 changes: 5 additions & 1 deletion src/Bridge/ClientRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,11 @@ public function getClientEntity($clientIdentifier)
}

return new Client(
$clientIdentifier, $record->name, $record->redirect, $record->confidential()
$clientIdentifier,
$record->name,
$record->redirect,
$record->confidential(),
$record->provider
);
}

Expand Down
2 changes: 1 addition & 1 deletion src/Bridge/UserRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public function __construct(Hasher $hasher)
*/
public function getUserEntityByUserCredentials($username, $password, $grantType, ClientEntityInterface $clientEntity)
{
$provider = config('auth.guards.api.provider');
$provider = $clientEntity->provider ?: config('auth.guards.api.provider');

if (is_null($model = config('auth.providers.'.$provider.'.model'))) {
throw new RuntimeException('Unable to determine authentication model from configuration.');
Expand Down
4 changes: 3 additions & 1 deletion src/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,10 @@ class Client extends Model
*/
public function user()
{
$provider = $this->provider ?: config('auth.guards.api.provider');

return $this->belongsTo(
config('auth.providers.'.config('auth.guards.api.provider').'.model')
config("auth.providers.{$provider}.model")
);
}

Expand Down
11 changes: 7 additions & 4 deletions src/ClientRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,17 +104,19 @@ public function personalAccessClient()
* @param int $userId
* @param string $name
* @param string $redirect
* @param string|null $provider
* @param bool $personalAccess
* @param bool $password
* @param bool $confidential
* @return \Laravel\Passport\Client
*/
public function create($userId, $name, $redirect, $personalAccess = false, $password = false, $confidential = true)
public function create($userId, $name, $redirect, $provider = null, $personalAccess = false, $password = false, $confidential = true)
{
$client = Passport::client()->forceFill([
'user_id' => $userId,
'name' => $name,
'secret' => ($confidential || $personalAccess) ? Str::random(40) : null,
'provider' => $provider,
'redirect' => $redirect,
'personal_access_client' => $personalAccess,
'password_client' => $password,
Expand All @@ -136,7 +138,7 @@ public function create($userId, $name, $redirect, $personalAccess = false, $pass
*/
public function createPersonalAccessClient($userId, $name, $redirect)
{
return tap($this->create($userId, $name, $redirect, true), function ($client) {
return tap($this->create($userId, $name, $redirect, null, true), function ($client) {
$accessClient = Passport::personalAccessClient();
$accessClient->client_id = $client->id;
$accessClient->save();
Expand All @@ -149,11 +151,12 @@ public function createPersonalAccessClient($userId, $name, $redirect)
* @param int $userId
* @param string $name
* @param string $redirect
* @param string|null $provider
* @return \Laravel\Passport\Client
*/
public function createPasswordGrantClient($userId, $name, $redirect)
public function createPasswordGrantClient($userId, $name, $redirect, $provider = null)
{
return $this->create($userId, $name, $redirect, false, true);
return $this->create($userId, $name, $redirect, $provider, false, true);
}

/**
Expand Down
13 changes: 11 additions & 2 deletions src/Console/ClientCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class ClientCommand extends Command
{--password : Create a password grant client}
{--client : Create a client credentials grant client}
{--name= : The name of the client}
{--provider= : The name of the user provider}
{--redirect_uri= : The URI to redirect to after authorization }
{--user_id= : The user ID the client should be assigned to }
{--public : Create a public client (Auth code grant type only) }';
Expand Down Expand Up @@ -83,8 +84,16 @@ protected function createPasswordClient(ClientRepository $clients)
config('app.name').' Password Grant Client'
);

$providers = array_keys(config('auth.providers'));

$provider = $this->option('provider') ?: $this->choice(
'Which user provider should this client use to retrieve users?',
$providers,
in_array('users', $providers) ? 'users' : null
);

$client = $clients->createPasswordGrantClient(
null, $name, 'http://localhost'
null, $name, 'http://localhost', $provider
);

$this->info('Password grant client created successfully.');
Expand Down Expand Up @@ -136,7 +145,7 @@ protected function createAuthCodeClient(ClientRepository $clients)
);

$client = $clients->create(
$userId, $name, $redirect, false, false, ! $this->option('public')
$userId, $name, $redirect, null, false, false, ! $this->option('public')
);

$this->info('New client created successfully.');
Expand Down
4 changes: 3 additions & 1 deletion src/Console/InstallCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ class InstallCommand extends Command
*/
public function handle()
{
$provider = in_array('users', array_keys(config('auth.providers'))) ? 'users' : null;

$this->call('passport:keys', ['--force' => $this->option('force'), '--length' => $this->option('length')]);
$this->call('passport:client', ['--personal' => true, '--name' => config('app.name').' Personal Access Client']);
$this->call('passport:client', ['--password' => true, '--name' => config('app.name').' Password Grant Client']);
$this->call('passport:client', ['--password' => true, '--name' => config('app.name').' Password Grant Client', '--provider' => $provider]);
}
}
40 changes: 31 additions & 9 deletions src/Guards/TokenGuard.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
use Exception;
use Firebase\JWT\JWT;
use Illuminate\Container\Container;
use Illuminate\Contracts\Auth\UserProvider;
use Illuminate\Contracts\Debug\ExceptionHandler;
use Illuminate\Contracts\Encryption\Encrypter;
use Illuminate\Cookie\Middleware\EncryptCookies;
Expand All @@ -16,6 +15,7 @@
use Laminas\Diactoros\UploadedFileFactory;
use Laravel\Passport\ClientRepository;
use Laravel\Passport\Passport;
use Laravel\Passport\PassportUserProvider;
use Laravel\Passport\TokenRepository;
use Laravel\Passport\TransientToken;
use League\OAuth2\Server\Exception\OAuthServerException;
Expand All @@ -34,7 +34,7 @@ class TokenGuard
/**
* The user provider implementation.
*
* @var \Illuminate\Contracts\Auth\UserProvider
* @var \Laravel\Passport\PassportUserProvider
*/
protected $provider;

Expand Down Expand Up @@ -63,25 +63,43 @@ class TokenGuard
* Create a new token guard instance.
*
* @param \League\OAuth2\Server\ResourceServer $server
* @param \Illuminate\Contracts\Auth\UserProvider $provider
* @param \Laravel\Passport\PassportUserProvider $provider
* @param \Laravel\Passport\TokenRepository $tokens
* @param \Laravel\Passport\ClientRepository $clients
* @param \Illuminate\Contracts\Encryption\Encrypter $encrypter
* @return void
*/
public function __construct(ResourceServer $server,
UserProvider $provider,
TokenRepository $tokens,
ClientRepository $clients,
Encrypter $encrypter)
{
public function __construct(
ResourceServer $server,
PassportUserProvider $provider,
TokenRepository $tokens,
ClientRepository $clients,
Encrypter $encrypter
) {
$this->server = $server;
$this->tokens = $tokens;
$this->clients = $clients;
$this->provider = $provider;
$this->encrypter = $encrypter;
}

/**
* Determine if the requested provider matches the client's provider.
*
* @param \Illuminate\Http\Request $request
* @return bool
*/
protected function hasValidProvider(Request $request)
{
$client = $this->client($request);

if ($client && ! $client->provider) {
return true;
}

return $client && $client->provider === $this->provider->getProviderName();
}

/**
* Get the user for the incoming request.
*
Expand All @@ -90,6 +108,10 @@ public function __construct(ResourceServer $server,
*/
public function user(Request $request)
{
if (! $this->hasValidProvider($request)) {
return;
}

if ($request->bearerToken()) {
return $this->authenticateViaBearerToken($request);
} elseif ($request->cookie(Passport::cookie())) {
Expand Down
2 changes: 1 addition & 1 deletion src/Http/Middleware/CheckCredentials.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ protected function validate($psr, $scopes)
abstract protected function validateCredentials($token);

/**
* Validate token credentials.
* Validate token scopes.
*
* @param \Laravel\Passport\Token $token
* @param array $scopes
Expand Down
2 changes: 1 addition & 1 deletion src/PassportServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ protected function makeGuard(array $config)
return new RequestGuard(function ($request) use ($config) {
return (new TokenGuard(
$this->app->make(ResourceServer::class),
Auth::createUserProvider($config['provider']),
new PassportUserProvider(Auth::createUserProvider($config['provider']), $config['provider']),
$this->app->make(TokenRepository::class),
$this->app->make(ClientRepository::class),
$this->app->make('encrypter')
Expand Down
86 changes: 86 additions & 0 deletions src/PassportUserProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?php

namespace Laravel\Passport;

use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Auth\UserProvider;

class PassportUserProvider implements UserProvider
{
/**
* The user provider instance.
*
* @var \Illuminate\Contracts\Auth\UserProvider
*/
protected $provider;

/**
* The user provider name.
*
* @var string
*/
protected $providerName;

/**
* Create a new passport user provider.
*
* @param \Illuminate\Contracts\Auth\UserProvider $provider
* @param string $providerName
* @return void
*/
public function __construct(UserProvider $provider, $providerName)
{
$this->provider = $provider;
$this->providerName = $providerName;
}

/**
* {@inheritdoc}
*/
public function retrieveById($identifier)
{
return $this->provider->retrieveById($identifier);
}

/**
* {@inheritdoc}
*/
public function retrieveByToken($identifier, $token)
{
return $this->provider->retrieveByToken($identifier, $token);
}

/**
* {@inheritdoc}
*/
public function updateRememberToken(Authenticatable $user, $token)
{
$this->provider->updateRememberToken($user, $token);
}

/**
* {@inheritdoc}
*/
public function retrieveByCredentials(array $credentials)
{
return $this->provider->retrieveByCredentials($credentials);
}

/**
* {@inheritdoc}
*/
public function validateCredentials(Authenticatable $user, array $credentials)
{
return $this->provider->validateCredentials($user, $credentials);
}

/**
* Get the name of the user provider.
*
* @return string
*/
public function getProviderName()
{
return $this->providerName;
}
}
2 changes: 2 additions & 0 deletions tests/BridgeClientRepositoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,8 @@ class BridgeClientRepositoryTestClientStub

public $password_client = false;

public $provider = null;

public $grant_types;

public function firstParty()
Expand Down
Loading

0 comments on commit 11d8533

Please sign in to comment.