presseportale/app/Console/Commands/BackfillPortalRole.php
Kevin Adametz 1503d3a7ed Fix: rollenlose aktive Nutzer -> Backfill-Command + Import-Nachlauf
Problem: Ein eingeloggter Nutzer ohne admin/editor/customer-Rolle wird per
redirectUsersTo auf die Startseite geleitet und haengt dort fest. Ursache
sind Alt-Konten, deren Rollen-Zuweisung nie lief (frueher Import bzw. ein
nach dem User-Insert fehlgeschlagener Rollen-Sync).

- Neues Command users:backfill-portal-role (--role, --dry-run): weist aktiven,
  komplett rollenlosen Nutzern die customer-Rolle zu. api-only-Konten haben
  bereits eine Rolle und bleiben unangetastet; inaktive werden uebersprungen.
- legacy:import ruft den Backfill nach dem User-Schritt automatisch auf
  (self-heal, da updateOrCreate + Rollen-Sync nicht atomar sind).

Analyse-Ergebnis nebenbei: In der aktuellen DB war nur genau 1 echter Fall
(bereits gefixt); die zuvor genannten ~167 waren fast alle api-only (gewollt
ohne Portal-Zugriff). Command laeuft daher jetzt sauber auf 0.

Test: BackfillPortalRoleTest (customer-Zuweisung, Rollen-Erhalt bei
customer/api-only, Ueberspringen Inaktiver, dry-run).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 09:23:56 +00:00

62 lines
2.1 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Console\Commands;
use App\Models\User;
use App\Services\Auth\UserRolePermissionSyncService;
use Illuminate\Console\Command;
/**
* Weist aktiven, komplett rollenlosen Nutzern eine Portal-Rolle zu.
*
* Hintergrund: Guest-/Auth-Redirects lenken einen eingeloggten Nutzer ohne
* admin/editor/customer-Rolle auf die Startseite (bootstrap/app.php →
* redirectUsersTo). Legacy-Importe oder ein fehlgeschlagener Rollen-Sync nach
* dem User-Insert können solche „hängenden" Konten erzeugen. Dieser Nachlauf
* heilt sie. api-only-Konten besitzen bereits eine Rolle und werden bewusst
* NICHT angefasst (kein Portal-Zugriff gewollt).
*/
class BackfillPortalRole extends Command
{
protected $signature = 'users:backfill-portal-role
{--role=customer : Zuzuweisende Rolle}
{--dry-run : Nur zählen, nichts schreiben}';
protected $description = 'Weist aktiven, rollenlosen Nutzern eine Portal-Rolle (Standard: customer) zu.';
public function handle(UserRolePermissionSyncService $roleSync): int
{
$role = (string) $this->option('role');
$dryRun = (bool) $this->option('dry-run');
$ids = User::query()
->where('is_active', true)
->whereDoesntHave('roles')
->pluck('id');
if ($ids->isEmpty()) {
$this->info('Keine aktiven rollenlosen Nutzer gefunden – nichts zu tun.');
return self::SUCCESS;
}
if ($dryRun) {
$this->warn("[DRY-RUN] {$ids->count()} aktive rollenlose Nutzer würden die Rolle '{$role}' erhalten.");
return self::SUCCESS;
}
$assigned = 0;
foreach ($ids->chunk(500) as $chunk) {
User::query()->whereIn('id', $chunk)->get()->each(function (User $user) use ($roleSync, $role, &$assigned): void {
$roleSync->assignRoleAndSyncPermissions($user, $role);
$assigned++;
});
}
$this->info("{$assigned} aktiven rollenlosen Nutzern die Rolle '{$role}' zugewiesen.");
return self::SUCCESS;
}
}