vcard4reseller/backend/src/Security/TenantContext.php
Thomas Peterson bcc06e697b Rechte: User in Employee verschmolzen (eine Identität pro Person)
Beseitigt die Doppelung Admin-Login vs. Mitarbeiter — jeder ist ein Employee
mit optionalem Login/Rechtegruppe (Voraussetzung für Mitarbeiter-Zeiterfassung).

- Employee implementiert UserInterface/PasswordAuthenticated (loginEmail unique,
  password, roles); User-Entität entfernt; Security-Provider → Employee.loginEmail
- Plattform = Reseller mit isPlatform + Org-Firma; Reseller haben Org-Firma
  (Company.isResellerOrg) für ihr Personal → alles = Reseller→Firma→Mitarbeiter
- TenantContext leitet Reseller/Company aus dem Mitarbeiter ab (Reseller-/
  Plattform-Admin = reseller-weit)
- UserAdminController: Login pro Mitarbeiter vergeben/entziehen
  (POST/DELETE /api/employees/{id}/login), /api/users = Logins-Übersicht
- Provisioning/Seed auf das neue Modell; Migrationen zu einer Baseline gesquasht
- Frontend: EmployeesView Login-Block + UsersView (Logins-Übersicht)

Verifiziert: Login, /me, Mandantenscoping, delegierter Grant (Eskalation→403),
öffentliches Profil, SPA-Flow.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 17:27:38 +02:00

51 lines
1.3 KiB
PHP

<?php
namespace App\Security;
use App\Entity\Company;
use App\Entity\Employee;
use App\Entity\Reseller;
use Symfony\Bundle\SecurityBundle\Security;
/**
* Liefert den Mandantenkontext (Reseller/Company) des eingeloggten Mitarbeiters.
* Alles wird aus dem Employee abgeleitet (Employee = Login-Identität):
* - Reseller = company.reseller
* - Company = die eigene Firma NUR für Firmen-Admins/Mitarbeiter; Reseller-/
* Plattform-Admins arbeiten reseller-weit (company = null).
* Plattform-Admins sehen alles.
*/
final class TenantContext
{
public function __construct(private readonly Security $security)
{
}
public function getEmployee(): ?Employee
{
$user = $this->security->getUser();
return $user instanceof Employee ? $user : null;
}
public function isPlatformAdmin(): bool
{
return $this->security->isGranted(Employee::ROLE_PLATFORM_ADMIN);
}
public function getReseller(): ?Reseller
{
return $this->getEmployee()?->getCompany()->getReseller();
}
public function getCompany(): ?Company
{
// Reseller-/Plattform-Admins sind reseller-weit unterwegs → keine Company-Einschränkung
if ($this->security->isGranted(Employee::ROLE_RESELLER_ADMIN)) {
return null;
}
return $this->getEmployee()?->getCompany();
}
}