97 lines
3.3 KiB
PHP
97 lines
3.3 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Livewire\Modals\AddSshKey;
|
|
use App\Models\Server;
|
|
use App\Models\User;
|
|
use App\Services\FleetService;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Livewire\Livewire;
|
|
use Mockery;
|
|
use Tests\TestCase;
|
|
|
|
class AddSshKeyTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
protected function tearDown(): void
|
|
{
|
|
Mockery::close();
|
|
parent::tearDown();
|
|
}
|
|
|
|
private function server(): Server
|
|
{
|
|
return Server::create(['name' => 'box', 'ip' => '10.0.0.9', 'ssh_port' => 22, 'status' => 'online']);
|
|
}
|
|
|
|
/** Mock FleetService and capture the public key actually passed to addAuthorizedKey(). */
|
|
private function captureInstalledKey(string &$captured): void
|
|
{
|
|
$fleet = Mockery::mock(FleetService::class);
|
|
$fleet->shouldReceive('addAuthorizedKey')->once()
|
|
->andReturnUsing(function ($s, $pub) use (&$captured) {
|
|
$captured = $pub;
|
|
});
|
|
app()->instance(FleetService::class, $fleet);
|
|
}
|
|
|
|
public function test_the_form_renders_the_name_field_without_a_leaked_key(): void
|
|
{
|
|
$this->actingAs(User::factory()->create());
|
|
|
|
Livewire::test(AddSshKey::class, ['serverId' => $this->server()->id])
|
|
->assertSee(__('modals.add_ssh_key.name_label'))
|
|
->assertDontSee('add_ssh_key.name_label'); // the translation must resolve, not leak the key
|
|
}
|
|
|
|
public function test_the_name_becomes_the_key_comment(): void
|
|
{
|
|
$this->actingAs(User::factory()->create());
|
|
$server = $this->server();
|
|
$captured = '';
|
|
$this->captureInstalledKey($captured);
|
|
|
|
Livewire::test(AddSshKey::class, ['serverId' => $server->id])
|
|
->set('keyName', 'Backup Laptop')
|
|
->set('publicKey', 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIabc old-comment')
|
|
->call('save');
|
|
|
|
// The pasted comment is replaced by the operator's name so the key is identifiable.
|
|
$this->assertSame('ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIabc Backup Laptop', $captured);
|
|
}
|
|
|
|
public function test_a_name_with_newlines_cannot_inject_a_second_key(): void
|
|
{
|
|
$this->actingAs(User::factory()->create());
|
|
$server = $this->server();
|
|
$captured = '';
|
|
$this->captureInstalledKey($captured);
|
|
|
|
Livewire::test(AddSshKey::class, ['serverId' => $server->id])
|
|
->set('keyName', "Evil\nssh-ed25519 INJECTED")
|
|
->set('publicKey', 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIabc')
|
|
->call('save');
|
|
|
|
// Newline collapsed → the would-be injected key stays a harmless comment on ONE line.
|
|
$this->assertStringNotContainsString("\n", $captured);
|
|
$this->assertSame('ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIabc Evil ssh-ed25519 INJECTED', $captured);
|
|
}
|
|
|
|
public function test_without_a_name_the_pasted_comment_is_kept(): void
|
|
{
|
|
$this->actingAs(User::factory()->create());
|
|
$server = $this->server();
|
|
$captured = '';
|
|
$this->captureInstalledKey($captured);
|
|
|
|
Livewire::test(AddSshKey::class, ['serverId' => $server->id])
|
|
->set('keyName', '')
|
|
->set('publicKey', 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIabc original@host')
|
|
->call('save');
|
|
|
|
$this->assertSame('ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIabc original@host', $captured);
|
|
}
|
|
}
|