- TenantAccessPolicy: Plattform-Host nur Plattform-/Reseller-Admins, Reseller-Host nur dessen Nutzer, Firmen-Host nur Firmen-Nutzer (+ zugehöriger Reseller-Admin); Plattform-Admin überall. - LoginSuccessHandler prüft vor JWT-Ausstellung → 403 bei falschem Host. - Login zeigt die 403-Hinweismeldung. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
57 lines
2.0 KiB
PHP
57 lines
2.0 KiB
PHP
<?php
|
|
|
|
namespace App\Security;
|
|
|
|
use App\Entity\Employee;
|
|
use App\Service\ResolvedTenant;
|
|
|
|
/**
|
|
* Entscheidet, ob ein Mitarbeiter sich auf dem Host eines bestimmten Tenants
|
|
* anmelden darf (White-Label-Scoping, KONZEPT §11):
|
|
* - Plattform-Host: nur Plattform- und Reseller-Admins (Firmen nutzen ihre Subdomain).
|
|
* - Reseller-Host: alle Nutzer dieses Resellers (inkl. seiner Firmen).
|
|
* - Firmen-Host: nur Nutzer dieser Firma (plus deren Reseller-Admin).
|
|
* Plattform-Admins dürfen überall (Support/Verwaltung).
|
|
*/
|
|
final class TenantAccessPolicy
|
|
{
|
|
public function canLogin(Employee $user, ResolvedTenant $tenant): bool
|
|
{
|
|
$roles = $user->getRoles();
|
|
$isPlatform = \in_array(Employee::ROLE_PLATFORM_ADMIN, $roles, true);
|
|
$isReseller = \in_array(Employee::ROLE_RESELLER_ADMIN, $roles, true);
|
|
|
|
if ($isPlatform) {
|
|
return true;
|
|
}
|
|
|
|
$userReseller = $user->getReseller();
|
|
$userCompany = $user->getCompany();
|
|
|
|
return match ($tenant->kind) {
|
|
ResolvedTenant::KIND_PLATFORM => $isReseller,
|
|
ResolvedTenant::KIND_RESELLER => null !== $userReseller
|
|
&& null !== $tenant->reseller
|
|
&& $userReseller->getId()->equals($tenant->reseller->getId()),
|
|
ResolvedTenant::KIND_COMPANY => $this->canLoginCompany($userCompany, $userReseller, $isReseller, $tenant),
|
|
default => false,
|
|
};
|
|
}
|
|
|
|
private function canLoginCompany(
|
|
?\App\Entity\Company $userCompany,
|
|
?\App\Entity\Reseller $userReseller,
|
|
bool $isReseller,
|
|
ResolvedTenant $tenant,
|
|
): bool {
|
|
if (null !== $userCompany && null !== $tenant->company
|
|
&& $userCompany->getId()->equals($tenant->company->getId())) {
|
|
return true;
|
|
}
|
|
|
|
// Reseller-Admin des zugehörigen Resellers darf den Firmen-Host ebenfalls nutzen
|
|
return $isReseller && null !== $userReseller && null !== $tenant->reseller
|
|
&& $userReseller->getId()->equals($tenant->reseller->getId());
|
|
}
|
|
}
|