Fix PAT + oauth routes

pull/6637/head
Daniel Supernault 3 months ago
parent 9fe9b7eb32
commit 25d5142f12
No known key found for this signature in database
GPG Key ID: 23740873EE6F76A1

@ -0,0 +1,139 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Laravel\Passport\Passport;
use Laravel\Passport\Token;
class PersonalAccessTokenController extends Controller
{
public function scopes(Request $request): JsonResponse
{
$scopes = collect(Passport::scopes())
->filter(function ($scope) use ($request) {
return $this->userCanUseScope($request->user(), $scope->id);
})
->map(function ($scope) {
return [
'id' => $scope->id,
'description' => $scope->description,
];
})
->values();
return response()->json($scopes);
}
public function index(Request $request): JsonResponse
{
$tokens = $request->user()
->tokens()
->with('client')
->where('revoked', false)
->where(function ($query) {
$query->whereNull('expires_at')
->orWhere('expires_at', '>', now());
})
->latest('created_at')
->get()
->filter(function (Token $token) {
return $this->isPersonalAccessToken($token);
})
->map(function (Token $token) {
return $this->serializeToken($token);
})
->values();
return response()->json($tokens);
}
public function store(Request $request): JsonResponse
{
$allowedScopes = collect(Passport::scopeIds())
->filter(function (string $scope) use ($request) {
return $this->userCanUseScope($request->user(), $scope);
})
->values()
->all();
$validated = $request->validate([
'name' => ['required', 'string', 'min:2', 'max:255'],
'scopes' => ['nullable', 'array'],
'scopes.*' => ['string', Rule::in($allowedScopes)],
]);
$scopes = array_values(array_unique($validated['scopes'] ?? []));
$result = $request->user()->createToken(
$validated['name'],
$scopes
);
return response()->json([
'accessToken' => $result->accessToken,
'token' => $this->serializeToken($result->token),
]);
}
public function destroy(Request $request, string $token): JsonResponse
{
$token = $request->user()
->tokens()
->with('client')
->whereKey($token)
->firstOrFail();
abort_unless($this->isPersonalAccessToken($token), 404);
$token->revoke();
return response()->noContent();
}
private function serializeToken(Token $token): array
{
return [
'id' => $token->id,
'name' => $token->name,
'scopes' => $token->scopes ?? [],
'revoked' => (bool) $token->revoked,
'created_at' => optional($token->created_at)->toJSON(),
'updated_at' => optional($token->updated_at)->toJSON(),
'expires_at' => optional($token->expires_at)->toJSON(),
];
}
private function isPersonalAccessToken(Token $token): bool
{
$client = $token->client;
if (! $client) {
return false;
}
if (method_exists($client, 'hasGrantType')) {
return $client->hasGrantType('personal_access');
}
if (isset($client->personal_access_client)) {
return (bool) $client->personal_access_client;
}
return false;
}
private function userCanUseScope($user, string $scope): bool
{
if (str_starts_with($scope, 'admin:')) {
return (bool) (
$user->is_admin
?? false
);
}
return true;
}
}

@ -1,5 +1,7 @@
<?php
use Illuminate\Support\Facades\Route;
Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofactor', 'localization'])->group(function () {
Route::get('/', 'SiteController@home')->name('timeline.personal');
Route::redirect('/home', '/')->name('home');
@ -51,23 +53,23 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact
Route::group([
'as' => 'passport.',
'prefix' => config('passport.path', 'oauth'),
'prefix' => 'oauth',
], function () {
Route::post('/token', [
'uses' => '\App\Http\Controllers\OAuth\ApiTokenController@issueToken',
'as' => 'token',
'middleware' => 'throttle',
'middleware' => 'throttle:10,1',
]);
Route::get('/authorize', [
'uses' => '\Laravel\Passport\Http\Controllers\AuthorizationController@authorize',
'as' => 'authorizations.authorize',
'middleware' => 'web',
'middleware' => ['web', 'throttle:10,1']
]);
$guard = config('passport.guard', null);
Route::middleware(['web', $guard ? 'auth:'.$guard : 'auth'])->group(function () {
Route::middleware(['web', $guard ? 'auth:'.$guard : 'auth', 'validemail'])->group(function () {
Route::post('/token/refresh', [
'uses' => '\Laravel\Passport\Http\Controllers\TransientTokenController@refresh',
'as' => 'token.refresh',
@ -114,23 +116,25 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact
]);
Route::get('/scopes', [
'uses' => '\Laravel\Passport\Http\Controllers\ScopeController@all',
'uses' => 'PersonalAccessTokenController@scopes',
'as' => 'scopes.index',
]);
Route::get('/personal-access-tokens', [
'uses' => '\Laravel\Passport\Http\Controllers\PersonalAccessTokenController@forUser',
'uses' => 'PersonalAccessTokenController@index',
'as' => 'personal.tokens.index',
]);
Route::post('/personal-access-tokens', [
'uses' => '\Laravel\Passport\Http\Controllers\PersonalAccessTokenController@store',
'uses' => 'PersonalAccessTokenController@store',
'as' => 'personal.tokens.store',
'middleware' => 'twofactor',
]);
Route::delete('/personal-access-tokens/{token_id}', [
'uses' => '\Laravel\Passport\Http\Controllers\PersonalAccessTokenController@destroy',
'uses' => 'PersonalAccessTokenController@destroy',
'as' => 'personal.tokens.destroy',
'middleware' => 'twofactor',
]);
});

Loading…
Cancel
Save