mirror of
https://github.com/coollabsio/coolify.git
synced 2026-11-12 15:53:46 -04:00
test(api): cover member access to the cloud provider token list
A team member with a read token gets 403 on GET /api/v1/cloud-tokens and an error from the MCP cloud_provider list_tokens action.
This commit is contained in:
@@ -80,6 +80,27 @@ describe('GET /api/v1/cloud-tokens', function () {
|
||||
$response->assertJsonCount(1);
|
||||
});
|
||||
|
||||
test('rejects a team member with a read token', function () {
|
||||
CloudProviderToken::factory()->create([
|
||||
'team_id' => $this->team->id,
|
||||
'name' => 'Production Hetzner',
|
||||
'provider' => 'hetzner',
|
||||
]);
|
||||
|
||||
$member = User::factory()->create();
|
||||
$this->team->members()->attach($member->id, ['role' => 'member']);
|
||||
session(['currentTeam' => $this->team]);
|
||||
$memberToken = $member->createToken('member-read', ['read'])->plainTextToken;
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'Authorization' => 'Bearer '.$memberToken,
|
||||
'Content-Type' => 'application/json',
|
||||
])->getJson('/api/v1/cloud-tokens');
|
||||
|
||||
$response->assertForbidden();
|
||||
expect($response->getContent())->not->toContain('Production Hetzner');
|
||||
});
|
||||
|
||||
test('rejects request without authentication', function () {
|
||||
$response = $this->getJson('/api/v1/cloud-tokens');
|
||||
$response->assertStatus(401);
|
||||
|
||||
@@ -7,6 +7,7 @@ use App\Mcp\Tools\CoolifyHelp;
|
||||
use App\Models\Application;
|
||||
use App\Models\ApplicationDeploymentQueue;
|
||||
use App\Models\ApplicationPreview;
|
||||
use App\Models\CloudProviderToken;
|
||||
use App\Models\Environment;
|
||||
use App\Models\EnvironmentVariable;
|
||||
use App\Models\GithubApp;
|
||||
@@ -903,6 +904,35 @@ test('list_applications list_databases list_services server_uuid filters use des
|
||||
->not->toContain($otherServerService->uuid);
|
||||
});
|
||||
|
||||
test('cloud_provider list_tokens rejects a team member with a read token', function () {
|
||||
CloudProviderToken::factory()->create([
|
||||
'team_id' => $this->team->id,
|
||||
'name' => 'Production Hetzner',
|
||||
'provider' => 'hetzner',
|
||||
]);
|
||||
|
||||
$member = User::factory()->create();
|
||||
$this->team->members()->attach($member->id, ['role' => 'member']);
|
||||
session(['currentTeam' => $this->team]);
|
||||
$memberToken = $member->createToken('member-read', ['read'])->plainTextToken;
|
||||
auth()->forgetGuards();
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'Content-Type' => 'application/json',
|
||||
'Accept' => 'application/json, text/event-stream',
|
||||
'Authorization' => 'Bearer '.$memberToken,
|
||||
])->postJson('/mcp', [
|
||||
'jsonrpc' => '2.0',
|
||||
'id' => 1,
|
||||
'method' => 'tools/call',
|
||||
'params' => ['name' => 'cloud_provider', 'arguments' => (object) ['action' => 'list_tokens']],
|
||||
]);
|
||||
|
||||
$response->assertOk();
|
||||
expect($response->json('result.isError'))->toBeTrue()
|
||||
->and($response->getContent())->not->toContain('Production Hetzner');
|
||||
});
|
||||
|
||||
test('list_tags and get_current_team and list_team_members are team scoped', function () {
|
||||
Tag::create(['name' => 'prod', 'team_id' => $this->team->id]);
|
||||
Tag::create(['name' => 'theirs', 'team_id' => Team::factory()->create()->id]);
|
||||
|
||||
Reference in New Issue
Block a user