Merge pull request #6639 from pixelfed/staging

Fix PAT
dev
dansup 2 weeks ago committed by GitHub
commit f3bb1b831b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,130 @@
<?php
namespace App\Passport;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Cache;
use Laravel\Passport\Client;
use Laravel\Passport\ClientRepository;
use Laravel\Passport\Passport;
use RuntimeException;
class CachedPersonalAccessClientRepository extends ClientRepository
{
public function personalAccessClient(string $provider): Client
{
$cacheKey = $this->cacheKey($provider);
$cachedClientId = Cache::get($cacheKey);
if ($cachedClientId) {
$client = $this->findValidClientById($cachedClientId, $provider);
if ($client) {
return $client;
}
Cache::forget($cacheKey);
}
$client = $this->discoverPersonalAccessClient($provider);
Cache::forever($cacheKey, $client->getKey());
return $client;
}
private function findValidClientById(string|int $clientId, string $provider): ?Client
{
$client = Passport::client()
->newQuery()
->whereKey($clientId)
->where('revoked', false)
->first();
if (! $client) {
return null;
}
if (! $this->clientMatchesProvider($client, $provider)) {
return null;
}
if (! $client->hasGrantType('personal_access')) {
return null;
}
return $client;
}
private function discoverPersonalAccessClient(string $provider): Client
{
$model = Passport::client();
$columns = $model
->getConnection()
->getSchemaBuilder()
->getColumnListing($model->getTable());
$hasGrantTypesColumn = in_array('grant_types', $columns, true);
$hasLegacyPersonalAccessColumn = in_array('personal_access_client', $columns, true);
if (! $hasGrantTypesColumn && ! $hasLegacyPersonalAccessColumn) {
throw new RuntimeException(
'Unable to discover Passport personal access client: missing grant_types and personal_access_client columns.'
);
}
$query = $model
->newQuery()
->where('revoked', false)
->where(function (Builder $query) use ($provider): void {
$query
->when($provider === config('auth.guards.api.provider'), function (Builder $query): void {
$query->orWhereNull('provider');
})
->orWhere('provider', $provider);
})
->where(function (Builder $query) use ($hasGrantTypesColumn, $hasLegacyPersonalAccessColumn): void {
if ($hasGrantTypesColumn) {
$query->orWhere('grant_types', 'like', '%"personal_access"%');
}
if ($hasLegacyPersonalAccessColumn) {
$query->orWhere('personal_access_client', true);
}
});
$client = $query
->latest('created_at')
->first();
if (! $client) {
throw new RuntimeException(
"Personal access client not found for [{$provider}] user provider. Please create one with passport:client --personal."
);
}
if (! $client->hasGrantType('personal_access')) {
throw new RuntimeException(
"Discovered Passport client [{$client->getKey()}] does not have the personal_access grant."
);
}
return $client;
}
private function clientMatchesProvider(Client $client, string $provider): bool
{
return $client->provider === $provider
|| (
$client->provider === null
&& $provider === config('auth.guards.api.provider')
);
}
private function cacheKey(string $provider): string
{
return 'pf:passport:personal-access-client-id:'.$provider;
}
}

@ -2,13 +2,22 @@
namespace App\Providers;
use App\Passport\CachedPersonalAccessClientRepository;
use Laravel\Passport\Bridge;
use Laravel\Passport\ClientRepository;
use Laravel\Passport\Passport;
use League\OAuth2\Server\AuthorizationServer;
use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface;
class PassportServiceProvider extends \Laravel\Passport\PassportServiceProvider
{
public function register(): void
{
parent::register();
$this->app->singleton(ClientRepository::class, CachedPersonalAccessClientRepository::class);
}
/**
* Make the authorization service instance.
*/

@ -64,12 +64,10 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact
Route::get('/authorize', [
'uses' => '\Laravel\Passport\Http\Controllers\AuthorizationController@authorize',
'as' => 'authorizations.authorize',
'middleware' => ['web', 'throttle:10,1']
'middleware' => ['web', 'throttle:10,1'],
]);
$guard = config('passport.guard', null);
Route::middleware(['web', $guard ? 'auth:'.$guard : 'auth', 'validemail'])->group(function () {
Route::middleware(['web', 'auth:web', 'validemail'])->group(function () {
Route::post('/token/refresh', [
'uses' => '\Laravel\Passport\Http\Controllers\TransientTokenController@refresh',
'as' => 'token.refresh',

Loading…
Cancel
Save