diff --git a/routes/api.php b/routes/api.php index 56f984245..ffa4b29b9 100644 --- a/routes/api.php +++ b/routes/api.php @@ -55,7 +55,7 @@ Route::post('/projects/{uuid}/environments', [ProjectController::class, 'create_environment'])->middleware(['api.ability:write']); Route::delete('/projects/{uuid}/environments/{environment_name_or_uuid}', [ProjectController::class, 'delete_environment'])->middleware(['api.ability:write']); - Route::post('/projects', [ProjectController::class, 'create_project'])->middleware(['api.ability:read']); + Route::post('/projects', [ProjectController::class, 'create_project'])->middleware(['api.ability:write']); Route::patch('/projects/{uuid}', [ProjectController::class, 'update_project'])->middleware(['api.ability:write']); Route::delete('/projects/{uuid}', [ProjectController::class, 'delete_project'])->middleware(['api.ability:write']); @@ -86,7 +86,7 @@ Route::get('/servers/{uuid}/validate', [ServersController::class, 'validate_server'])->middleware(['api.ability:read']); - Route::post('/servers', [ServersController::class, 'create_server'])->middleware(['api.ability:read']); + Route::post('/servers', [ServersController::class, 'create_server'])->middleware(['api.ability:write']); Route::patch('/servers/{uuid}', [ServersController::class, 'update_server'])->middleware(['api.ability:write']); Route::delete('/servers/{uuid}', [ServersController::class, 'delete_server'])->middleware(['api.ability:write']); diff --git a/tests/Feature/ApiTokenPermissionTest.php b/tests/Feature/ApiTokenPermissionTest.php new file mode 100644 index 000000000..44efb7e06 --- /dev/null +++ b/tests/Feature/ApiTokenPermissionTest.php @@ -0,0 +1,75 @@ +team = Team::factory()->create(); + $this->user = User::factory()->create(); + $this->team->members()->attach($this->user->id, ['role' => 'owner']); + + session(['currentTeam' => $this->team]); +}); + +describe('POST /api/v1/projects', function () { + test('read-only token cannot create a project', function () { + $token = $this->user->createToken('read-only', ['read']); + + $response = $this->withHeaders([ + 'Authorization' => 'Bearer '.$token->plainTextToken, + 'Content-Type' => 'application/json', + ])->postJson('/api/v1/projects', [ + 'name' => 'Test Project', + ]); + + $response->assertStatus(403); + }); + + test('write token can create a project', function () { + $token = $this->user->createToken('write-token', ['write']); + + $response = $this->withHeaders([ + 'Authorization' => 'Bearer '.$token->plainTextToken, + 'Content-Type' => 'application/json', + ])->postJson('/api/v1/projects', [ + 'name' => 'Test Project', + ]); + + $response->assertStatus(201); + $response->assertJsonStructure(['uuid']); + }); + + test('root token can create a project', function () { + $token = $this->user->createToken('root-token', ['root']); + + $response = $this->withHeaders([ + 'Authorization' => 'Bearer '.$token->plainTextToken, + 'Content-Type' => 'application/json', + ])->postJson('/api/v1/projects', [ + 'name' => 'Test Project', + ]); + + $response->assertStatus(201); + $response->assertJsonStructure(['uuid']); + }); +}); + +describe('POST /api/v1/servers', function () { + test('read-only token cannot create a server', function () { + $token = $this->user->createToken('read-only', ['read']); + + $response = $this->withHeaders([ + 'Authorization' => 'Bearer '.$token->plainTextToken, + 'Content-Type' => 'application/json', + ])->postJson('/api/v1/servers', [ + 'name' => 'Test Server', + 'ip' => '1.2.3.4', + 'private_key_uuid' => 'fake-uuid', + ]); + + $response->assertStatus(403); + }); +});