Le super admin (table super_admins, master DB) ne pouvait pas se connecter via /api/login car ce firewall n'utilisait que le provider tenant. De même, le JWT n'était pas enrichi pour les super admins, l'endpoint /api/me/roles les rejetait, et le frontend redirigeait systématiquement vers /dashboard. Un chain provider (super_admin + tenant) résout l'authentification, le JwtPayloadEnricher et MyRolesProvider gèrent désormais les deux types d'utilisateurs, et le frontend redirige selon le rôle après login.
130 lines
4.2 KiB
PHP
130 lines
4.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Tests\Unit\Administration\Infrastructure\Api\Provider;
|
|
|
|
use ApiPlatform\Metadata\Get;
|
|
use App\Administration\Application\Port\ActiveRoleStore;
|
|
use App\Administration\Application\Service\RoleContext;
|
|
use App\Administration\Domain\Model\User\Email;
|
|
use App\Administration\Domain\Model\User\Role;
|
|
use App\Administration\Domain\Model\User\StatutCompte;
|
|
use App\Administration\Domain\Model\User\User;
|
|
use App\Administration\Domain\Model\User\UserId;
|
|
use App\Administration\Domain\Repository\UserRepository;
|
|
use App\Administration\Infrastructure\Api\Provider\MyRolesProvider;
|
|
use App\Administration\Infrastructure\Security\SecurityUser;
|
|
use App\Shared\Domain\Tenant\TenantId;
|
|
use App\SuperAdmin\Domain\Model\SuperAdmin\SuperAdminId;
|
|
use App\SuperAdmin\Infrastructure\Security\SecuritySuperAdmin;
|
|
use DateTimeImmutable;
|
|
use PHPUnit\Framework\Attributes\Test;
|
|
use PHPUnit\Framework\TestCase;
|
|
use Symfony\Bundle\SecurityBundle\Security;
|
|
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
|
|
|
|
final class MyRolesProviderTest extends TestCase
|
|
{
|
|
#[Test]
|
|
public function provideReturnsSuperAdminRoleForSecuritySuperAdmin(): void
|
|
{
|
|
$security = $this->createMock(Security::class);
|
|
$security->method('getUser')->willReturn(
|
|
new SecuritySuperAdmin(
|
|
superAdminId: SuperAdminId::generate(),
|
|
email: 'sadmin@test.com',
|
|
hashedPassword: 'hashed',
|
|
)
|
|
);
|
|
|
|
$userRepository = $this->createMock(UserRepository::class);
|
|
$roleContext = new RoleContext(new NullActiveRoleStore());
|
|
|
|
$provider = new MyRolesProvider($security, $userRepository, $roleContext);
|
|
$output = $provider->provide(new Get());
|
|
|
|
self::assertSame('ROLE_SUPER_ADMIN', $output->activeRole);
|
|
self::assertSame('Super Admin', $output->activeRoleLabel);
|
|
self::assertCount(1, $output->roles);
|
|
self::assertSame('ROLE_SUPER_ADMIN', $output->roles[0]['value']);
|
|
self::assertSame('Super Admin', $output->roles[0]['label']);
|
|
}
|
|
|
|
#[Test]
|
|
public function provideReturnsUserRolesForSecurityUser(): void
|
|
{
|
|
$userId = UserId::generate();
|
|
$tenantId = TenantId::fromString('550e8400-e29b-41d4-a716-446655440002');
|
|
|
|
$securityUser = new SecurityUser(
|
|
userId: $userId,
|
|
email: 'user@example.com',
|
|
hashedPassword: 'hashed',
|
|
tenantId: $tenantId,
|
|
roles: ['ROLE_PARENT'],
|
|
);
|
|
|
|
$security = $this->createMock(Security::class);
|
|
$security->method('getUser')->willReturn($securityUser);
|
|
|
|
$user = User::reconstitute(
|
|
id: $userId,
|
|
email: new Email('user@example.com'),
|
|
roles: [Role::PARENT],
|
|
tenantId: $tenantId,
|
|
schoolName: 'Test',
|
|
statut: StatutCompte::ACTIF,
|
|
dateNaissance: null,
|
|
createdAt: new DateTimeImmutable(),
|
|
hashedPassword: 'hashed',
|
|
activatedAt: new DateTimeImmutable(),
|
|
consentementParental: null,
|
|
);
|
|
|
|
$userRepository = $this->createMock(UserRepository::class);
|
|
$userRepository->method('get')->willReturn($user);
|
|
|
|
$roleContext = new RoleContext(new NullActiveRoleStore());
|
|
|
|
$provider = new MyRolesProvider($security, $userRepository, $roleContext);
|
|
$output = $provider->provide(new Get());
|
|
|
|
self::assertSame('ROLE_PARENT', $output->activeRole);
|
|
}
|
|
|
|
#[Test]
|
|
public function provideThrowsUnauthorizedForUnknownUserType(): void
|
|
{
|
|
$security = $this->createMock(Security::class);
|
|
$security->method('getUser')->willReturn(null);
|
|
|
|
$userRepository = $this->createMock(UserRepository::class);
|
|
$roleContext = new RoleContext(new NullActiveRoleStore());
|
|
|
|
$provider = new MyRolesProvider($security, $userRepository, $roleContext);
|
|
|
|
$this->expectException(UnauthorizedHttpException::class);
|
|
$provider->provide(new Get());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @internal
|
|
*/
|
|
final class NullActiveRoleStore implements ActiveRoleStore
|
|
{
|
|
public function store(User $user, Role $role): void
|
|
{
|
|
}
|
|
|
|
public function get(User $user): ?Role
|
|
{
|
|
return null;
|
|
}
|
|
|
|
public function clear(User $user): void
|
|
{
|
|
}
|
|
}
|