refactor(api): check token abilities through the token in ApiAbility (#12193)

This commit is contained in:
Andras Bacsai
2026-10-18 23:16:38 +02:00
committed by GitHub
parent 09cfe2d211
commit ecce3cb9b4
2 changed files with 16 additions and 2 deletions
+1 -2
View File
@@ -25,8 +25,7 @@ class ApiAbility extends CheckForAnyAbility
$teamId = data_get($token, 'team_id');
if ($teamId !== null && ! $request->user()->isAdminOfTeam((int) $teamId)) {
$tokenAbilities = $token->abilities ?? [];
$disallowed = array_intersect($tokenAbilities, self::MEMBER_DISALLOWED_ABILITIES);
$disallowed = array_filter(self::MEMBER_DISALLOWED_ABILITIES, fn (string $ability) => $token->can($ability));
if (! empty($disallowed)) {
return response()->json([
@@ -1,10 +1,12 @@
<?php
use App\Http\Middleware\ApiAbility;
use App\Livewire\Security\ApiTokens;
use App\Models\InstanceSettings;
use App\Models\Team;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\Request;
use Livewire\Features\SupportLockedProperties\CannotUpdateLockedPropertyException;
use Livewire\Livewire;
@@ -201,6 +203,19 @@ describe('ApiAbility middleware — member with elevated token blocked', functio
->assertStatus(403);
});
test('ApiAbility evaluates member token abilities through the token', function () {
session(['currentTeam' => $this->team]);
$token = $this->member->createToken('token', ['*']);
$this->member->withAccessToken($token->accessToken);
$request = Request::create('/api/v1/projects');
$request->setUserResolver(fn () => $this->member);
$response = (new ApiAbility)->handle($request, fn () => response('ok'), 'read');
expect($response->getStatusCode())->toBe(403);
});
test('member read token passes on non-zero team', function () {
session(['currentTeam' => $this->team]);
$token = $this->member->createToken('read-token', ['read']);