fix(api): expose cloud tokens with sensitive read access
Show cloud provider token values only when the API request has sensitive read permission, and cover read, read:sensitive, and root token behavior.
This commit is contained in:
parent
db23ee76fd
commit
fb13a6cdc0
2 changed files with 66 additions and 1 deletions
|
|
@ -16,9 +16,14 @@ private function removeSensitiveData($token)
|
|||
{
|
||||
$token->makeHidden([
|
||||
'id',
|
||||
'token',
|
||||
]);
|
||||
|
||||
if (request()->attributes->get('can_read_sensitive', false) === true) {
|
||||
$token->makeVisible([
|
||||
'token',
|
||||
]);
|
||||
}
|
||||
|
||||
return serializeApiResponse($token);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
|
||||
use App\Models\CloudProviderToken;
|
||||
use App\Models\InstanceSettings;
|
||||
use App\Models\Team;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
|
|
@ -9,6 +10,8 @@
|
|||
uses(RefreshDatabase::class);
|
||||
|
||||
beforeEach(function () {
|
||||
InstanceSettings::forceCreate(['id' => 0, 'is_api_enabled' => true]);
|
||||
|
||||
// Create a team with owner
|
||||
$this->team = Team::factory()->create();
|
||||
$this->user = User::factory()->create();
|
||||
|
|
@ -69,6 +72,63 @@
|
|||
$response = $this->getJson('/api/v1/cloud-tokens');
|
||||
$response->assertStatus(401);
|
||||
});
|
||||
|
||||
test('read token does not include provider token values', function () {
|
||||
CloudProviderToken::create([
|
||||
'team_id' => $this->team->id,
|
||||
'name' => 'Hidden Token',
|
||||
'provider' => 'hetzner',
|
||||
'token' => 'hidden-cloud-provider-token',
|
||||
]);
|
||||
|
||||
$readToken = $this->user->createToken('read-token', ['read'])->plainTextToken;
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'Authorization' => 'Bearer '.$readToken,
|
||||
'Content-Type' => 'application/json',
|
||||
])->getJson('/api/v1/cloud-tokens');
|
||||
|
||||
$response->assertSuccessful();
|
||||
expect($response->getContent())->not->toContain('"token":');
|
||||
});
|
||||
|
||||
test('read sensitive token includes provider token values', function () {
|
||||
CloudProviderToken::create([
|
||||
'team_id' => $this->team->id,
|
||||
'name' => 'Visible Token',
|
||||
'provider' => 'hetzner',
|
||||
'token' => 'visible-cloud-provider-token',
|
||||
]);
|
||||
|
||||
$readSensitiveToken = $this->user->createToken('read-sensitive-token', ['read', 'read:sensitive'])->plainTextToken;
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'Authorization' => 'Bearer '.$readSensitiveToken,
|
||||
'Content-Type' => 'application/json',
|
||||
])->getJson('/api/v1/cloud-tokens');
|
||||
|
||||
$response->assertSuccessful();
|
||||
$response->assertJsonFragment(['token' => 'visible-cloud-provider-token']);
|
||||
});
|
||||
|
||||
test('root token includes provider token values', function () {
|
||||
CloudProviderToken::create([
|
||||
'team_id' => $this->team->id,
|
||||
'name' => 'Root Visible Token',
|
||||
'provider' => 'hetzner',
|
||||
'token' => 'root-visible-cloud-provider-token',
|
||||
]);
|
||||
|
||||
$rootToken = $this->user->createToken('root-token', ['root'])->plainTextToken;
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'Authorization' => 'Bearer '.$rootToken,
|
||||
'Content-Type' => 'application/json',
|
||||
])->getJson('/api/v1/cloud-tokens');
|
||||
|
||||
$response->assertSuccessful();
|
||||
$response->assertJsonFragment(['token' => 'root-visible-cloud-provider-token']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /api/v1/cloud-tokens/{uuid}', function () {
|
||||
|
|
|
|||
Loading…
Reference in a new issue