diff --git a/app/Livewire/Server/DockerImages.php b/app/Livewire/Server/DockerImages.php index e9f6b5bef8..c552002219 100644 --- a/app/Livewire/Server/DockerImages.php +++ b/app/Livewire/Server/DockerImages.php @@ -31,6 +31,7 @@ class DockerImages extends Component { try { $this->server = Server::ownedByCurrentTeam()->whereUuid($server_uuid)->firstOrFail(); + $this->authorize('view', $this->server); $this->parameters = get_route_parameters(); } catch (\Throwable) { return redirect()->route('server.index'); @@ -39,6 +40,7 @@ class DockerImages extends Component public function load(): void { + $this->authorize('view', $this->server); try { if (! $this->server->isFunctional()) { return; diff --git a/tests/Feature/ServerDockerImagesAuthorizationTest.php b/tests/Feature/ServerDockerImagesAuthorizationTest.php new file mode 100644 index 0000000000..8d50c24b8e --- /dev/null +++ b/tests/Feature/ServerDockerImagesAuthorizationTest.php @@ -0,0 +1,52 @@ + InstanceSettings::updateOrCreate(['id' => 0], [])); + $this->team = Team::factory()->create(); + $this->user = User::factory()->create(); + $this->team->members()->attach($this->user->id, ['role' => 'owner']); + $privateKey = PrivateKey::factory()->create(['team_id' => $this->team->id]); + $this->server = Server::factory()->create(['team_id' => $this->team->id, 'private_key_id' => $privateKey->id]); + $this->server->settings->update(['is_reachable' => true, 'is_usable' => true]); + $this->actingAs($this->user); + session(['currentTeam' => $this->team]); + Process::fake([ + '*docker image ls*' => Process::result(output: json_encode(['Repository' => 'nginx', 'Tag' => '1.27', 'ID' => 'sha256:'.str_repeat('a', 64), 'Size' => '1MB', 'CreatedSince' => 'now'])), + '*' => Process::result(output: ''), + ]); +}); + +afterEach(function () { + Server::flushIdentityMap(); +}); + +it('does not list images for a user removed from the server team after mount', function () { + $component = Livewire::test(DockerImages::class, ['server_uuid' => $this->server->uuid]); + + $this->team->members()->detach($this->user->id); + $this->user->refresh(); + + $component->call('load') + ->assertForbidden(); + + Process::assertNothingRan(); +}); + +it('still lists images for a member of the server team', function () { + Livewire::test(DockerImages::class, ['server_uuid' => $this->server->uuid]) + ->call('load') + ->assertSet('images.0.reference', 'nginx:1.27'); +});