- Add `FileOwnership` to encapsulate file owner and group information. - Add `ProcessUser` to represent and manage system process user details. - Enhance ownership matching and debugging with structured data objects. - Include new documentation on file ownership handling and permission improvements. - Prepare infrastructure for enriched error handling in filesystem operations.
6.7 KiB
6.7 KiB
FilePermissionException Verbesserungs-Plan
Ziel
Verbesserung der FilePermissionException um detaillierte Permission- und User-Informationen f?r besseres Debugging.
Problem-Analyse
Aktueller Zustand
Die FilePermissionException gibt momentan nur minimale Informationen:
FilePermissionException::delete($path, 'Directory is not writable: ' . $dir);
// Output: "Permission denied for delete on file: /path/to/file (Directory is not writable: /path/to/dir)"
Fehlende Informationen:
- Aktuelle Permissions der Datei/Verzeichnisses
- Owner/Group der Datei
- Aktueller Process-User
- Erwartete Permissions
- Octal-Darstellung der Permissions
Verf?gbare Infrastruktur
? PermissionChecker hat bereits getDiagnosticInfo():
- Liefert owner, group, permissions, parent_dir info
- Nutzt
posix_getpwuid()undposix_getgrgid()
? ExceptionContext hat withData(), withDebug(), withMetadata()
? posix_geteuid() verf?gbar f?r Process-User
L?sungsplan
L?sung 1: Erweitere FilePermissionException (HOHE PRIORIT?T)
Neue statische Factory-Methoden mit Permission-Details:
public static function delete(
string $path,
?string $reason = null,
?PermissionChecker $permissionChecker = null
): self {
$diagnosticInfo = $permissionChecker?->getDiagnosticInfo($path) ?? [];
$currentUser = self::getCurrentUserInfo();
return new self(
path: $path,
operation: 'delete',
reason: $reason,
diagnosticInfo: $diagnosticInfo,
currentUser: $currentUser
);
}
Neue Properties:
?array $diagnosticInfo- Permission-Details vom PermissionChecker?array $currentUser- Aktueller Process-User Info
Verbesserte Message-Formatierung:
$message = "Permission denied for {$operation} on file: {$path}";
if ($reason) {
$message .= " ({$reason})";
}
// Add detailed info if available
if ($this->diagnosticInfo) {
$message .= sprintf(
"\n File owner: %s, group: %s, permissions: %s",
$this->diagnosticInfo['owner'] ?? 'unknown',
$this->diagnosticInfo['group'] ?? 'unknown',
$this->diagnosticInfo['permissions'] ?? 'unknown'
);
if (isset($this->diagnosticInfo['parent_dir'])) {
$parentInfo = $permissionChecker?->getDiagnosticInfo($this->diagnosticInfo['parent_dir']) ?? [];
$message .= sprintf(
"\n Parent directory: %s (owner: %s, permissions: %s)",
$this->diagnosticInfo['parent_dir'],
$parentInfo['owner'] ?? 'unknown',
$parentInfo['permissions'] ?? 'unknown'
);
}
}
if ($this->currentUser) {
$message .= sprintf(
"\n Current process user: %s (uid: %d, gid: %d)",
$this->currentUser['name'],
$this->currentUser['uid'],
$this->currentUser['gid']
);
}
L?sung 2: Helper-Methode f?r Process-User Info
Neue private Methode in FilePermissionException:
private static function getCurrentUserInfo(): ?array
{
if (!function_exists('posix_geteuid')) {
return null;
}
$uid = posix_geteuid();
$gid = posix_getegid();
$userInfo = posix_getpwuid($uid);
$groupInfo = posix_getgrgid($gid);
return [
'uid' => $uid,
'gid' => $gid,
'name' => $userInfo['name'] ?? 'unknown',
'group' => $groupInfo['name'] ?? 'unknown',
];
}
L?sung 3: Integration in FileStorage-Methoden
Anpassung aller FilePermissionException Aufrufe:
Vorher:
if (! is_writable($dir)) {
throw FilePermissionException::delete($path, 'Directory is not writable: ' . $dir);
}
Nachher:
if (! is_writable($dir)) {
throw FilePermissionException::delete(
path: $path,
reason: 'Directory is not writable: ' . $dir,
permissionChecker: $this->permissions
);
}
Betroffene Stellen:
FileStorage::get()- read exceptionFileStorage::put()- write exception, createDirectory exceptionFileStorage::delete()- delete exceptionFileStorage::createDirectory()- createDirectory exception- Alle anderen Stellen, die FilePermissionException werfen
L?sung 4: ExceptionContext erweitern
Erweiterte Context-Daten in Exception:
$context = ExceptionContext::forOperation('file.permission', 'filesystem')
->withData([
'path' => $path,
'operation' => $operation,
'reason' => $reason,
])
->withDebug([
'file_permissions' => $diagnosticInfo['permissions'] ?? null,
'file_owner' => $diagnosticInfo['owner'] ?? null,
'file_group' => $diagnosticInfo['group'] ?? null,
'parent_dir' => $diagnosticInfo['parent_dir'] ?? null,
'parent_writable' => $diagnosticInfo['parent_writable'] ?? null,
])
->withMetadata([
'current_user' => $currentUser,
'file_exists' => $diagnosticInfo['exists'] ?? false,
'is_file' => $diagnosticInfo['is_file'] ?? false,
'is_dir' => $diagnosticInfo['is_dir'] ?? false,
]);
Implementierungsreihenfolge
- ? L?sung 2 - Helper-Methode f?r Process-User (einfach, keine Dependencies)
- ? L?sung 1 - Erweitere FilePermissionException Constructor und Factory-Methoden
- ? L?sung 3 - Integration in FileStorage-Methoden
- ? L?sung 4 - ExceptionContext erweitern
Beispiel-Output
Vorher:
Permission denied for delete on file: /var/www/html/storage/cache/file.cache.php (Directory is not writable: /var/www/html/storage/cache)
Nachher:
Permission denied for delete on file: /var/www/html/storage/cache/file.cache.php (Directory is not writable: /var/www/html/storage/cache)
File owner: www-data, group: www-data, permissions: drwxrwxr-x
Parent directory: /var/www/html/storage/cache (owner: root, permissions: drwxr-xr-x)
Current process user: www-data (uid: 33, gid: 33)
Vorteile
- Besseres Debugging: Sofort sichtbar, welche Permissions falsch sind
- User-Info: Zeigt Owner-Mismatch sofort
- Context: Vollst?ndige Permission-Info in Exception-Context f?r Logging
- R?ckw?rtskompatibel: Alte Aufrufe funktionieren weiterhin (optional Parameter)
Performance-?berlegungen
getDiagnosticInfo()ist relativ teuer (mehrerestat()Calls)- L?sung: Nur bei Exception-Throw aufrufen (nicht bei jedem Check)
- Optional: K?nnte in
withDebug()ausgelagert werden, wenn Performance kritisch ist
Testing
- Unit-Tests: FilePermissionException mit Permission-Details
- Integration-Tests: FileStorage-Methoden mit verschiedenen Permission-Szenarien
- E2E-Tests: Cache-Operationen mit Permission-Problemen
Dokumentation
Nach Implementierung aktualisieren:
docs/claude/error-handling.md- FilePermissionException mit Detailsdocs/deployment/cache-configuration.md- Exception-Beispiele