77 lines
2.3 KiB
PHP
77 lines
2.3 KiB
PHP
<?php
|
|
|
|
namespace App\Tools;
|
|
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Prism\Prism\Tool;
|
|
|
|
/**
|
|
* Lese- und Schreibzugriff in storage/app/public/files. Sandboxed - keine
|
|
* Path-Traversal über '..' möglich.
|
|
*/
|
|
class FileManagerTool
|
|
{
|
|
protected string $base = 'files';
|
|
|
|
public function asPrismTool(): Tool
|
|
{
|
|
return (new Tool)
|
|
->as('file_manager')
|
|
->for('Liest oder schreibt Dateien im Fox-Sandbox-Verzeichnis. action ist "read", "write" oder "list".')
|
|
->withStringParameter('action', 'Eine der Aktionen: read, write, list')
|
|
->withStringParameter('path', 'Relativer Pfad innerhalb der Sandbox (für list leer)')
|
|
->withStringParameter('content', 'Inhalt zum Schreiben (nur bei action=write)')
|
|
->using(fn (string $action, string $path = '', string $content = '') => $this->execute($action, $path, $content));
|
|
}
|
|
|
|
public function execute(string $action, string $path = '', string $content = ''): string
|
|
{
|
|
$safe = $this->safePath($path);
|
|
|
|
return match ($action) {
|
|
'read' => $this->read($safe),
|
|
'write' => $this->write($safe, $content),
|
|
'list' => $this->list($safe),
|
|
default => "Unbekannte Aktion: {$action}",
|
|
};
|
|
}
|
|
|
|
protected function read(string $path): string
|
|
{
|
|
$disk = Storage::disk('public');
|
|
if (! $disk->exists($path)) {
|
|
return "Datei nicht gefunden: {$path}";
|
|
}
|
|
|
|
return (string) $disk->get($path);
|
|
}
|
|
|
|
protected function write(string $path, string $content): string
|
|
{
|
|
Storage::disk('public')->put($path, $content);
|
|
|
|
return "Geschrieben: {$path} (".strlen($content).' Bytes)';
|
|
}
|
|
|
|
protected function list(string $path): string
|
|
{
|
|
$disk = Storage::disk('public');
|
|
$files = $disk->files($path ?: $this->base);
|
|
$dirs = $disk->directories($path ?: $this->base);
|
|
|
|
$lines = array_merge(
|
|
array_map(fn ($d) => "[dir] {$d}", $dirs),
|
|
array_map(fn ($f) => "[file] {$f}", $files),
|
|
);
|
|
|
|
return $lines ? implode("\n", $lines) : '(leer)';
|
|
}
|
|
|
|
protected function safePath(string $path): string
|
|
{
|
|
$path = ltrim(str_replace(['..', '\\'], '', $path), '/');
|
|
|
|
return str_starts_with($path, $this->base) ? $path : $this->base.'/'.$path;
|
|
}
|
|
}
|