feat(auth): harden login flows and finalize quality-check coverage
This commit is contained in:
@@ -397,6 +397,83 @@ class MicrosoftOidcServiceTest extends TestCase
|
||||
$this->assertSame('tenant-id-123', (string) (($result['claims'] ?? [])['tid'] ?? ''));
|
||||
}
|
||||
|
||||
public function testHandleCallbackReturnsEmailDomainNotAllowedWhenTenantDomainPolicyRejectsUser(): void
|
||||
{
|
||||
[$idToken, $jwk] = $this->buildValidIdToken('client-id', 'tenant-id-123', 'nonce-123');
|
||||
|
||||
$stateStore = $this->createMock(MicrosoftOidcStateStoreService::class);
|
||||
$stateStore->method('consume')->willReturn([
|
||||
'ok' => true,
|
||||
'entry' => [
|
||||
'tenant_id' => 12,
|
||||
'nonce' => 'nonce-123',
|
||||
'code_verifier' => 'verifier-123',
|
||||
'redirect_uri' => 'https://app.example/auth/microsoft/callback',
|
||||
'locale' => 'de',
|
||||
],
|
||||
]);
|
||||
|
||||
$tenantGateway = $this->createMock(AuthTenantGateway::class);
|
||||
$tenantGateway->expects($this->once())
|
||||
->method('findById')
|
||||
->with(12)
|
||||
->willReturn([
|
||||
'id' => 12,
|
||||
'status' => 'active',
|
||||
'uuid' => 'tenant-uuid',
|
||||
]);
|
||||
|
||||
$tenantSsoService = $this->createMock(TenantSsoService::class);
|
||||
$tenantSsoService->method('getEffectiveMicrosoftProviderConfig')->willReturn([
|
||||
'ok' => true,
|
||||
'config' => [
|
||||
'authority' => 'https://login.microsoftonline.com/tenant-id-123/v2.0',
|
||||
'client_id' => 'client-id',
|
||||
'client_secret' => 'client-secret',
|
||||
'tenant_id' => 'tenant-id-123',
|
||||
'allowed_domains' => 'allowed.example.com',
|
||||
'sync_profile_on_login' => 0,
|
||||
'sync_profile_fields' => [],
|
||||
],
|
||||
]);
|
||||
$tenantSsoService->method('normalizeProfileSyncFields')->willReturn([]);
|
||||
$tenantSsoService->expects($this->once())
|
||||
->method('isEmailDomainAllowed')
|
||||
->with('user@example.com', ['allowed.example.com'])
|
||||
->willReturn(false);
|
||||
|
||||
$oidcGateway = $this->createMock(OidcHttpGateway::class);
|
||||
$oidcGateway->expects($this->exactly(3))
|
||||
->method('call')
|
||||
->willReturnOnConsecutiveCalls(
|
||||
[
|
||||
'status' => 200,
|
||||
'data' => json_encode([
|
||||
'token_endpoint' => 'https://login.microsoftonline.com/tenant-id-123/oauth2/v2.0/token',
|
||||
'issuer' => 'https://login.microsoftonline.com/{tenantid}/v2.0',
|
||||
'jwks_uri' => 'https://login.microsoftonline.com/tenant-id-123/discovery/v2.0/keys',
|
||||
]) ?: '{}',
|
||||
],
|
||||
[
|
||||
'status' => 200,
|
||||
'data' => json_encode([
|
||||
'id_token' => $idToken,
|
||||
'access_token' => '',
|
||||
]) ?: '{}',
|
||||
],
|
||||
[
|
||||
'status' => 200,
|
||||
'data' => json_encode(['keys' => [$jwk]]) ?: '{}',
|
||||
],
|
||||
);
|
||||
|
||||
$service = $this->newService($tenantSsoService, $tenantGateway, $oidcGateway, $stateStore);
|
||||
$result = $service->handleCallback('state-ok', 'code-ok');
|
||||
|
||||
$this->assertFalse($result['ok']);
|
||||
$this->assertSame('email_domain_not_allowed', $result['error']);
|
||||
}
|
||||
|
||||
private function newServiceForTokenFlow(array $discoveryResponse, ?array $tokenResponse = null): MicrosoftOidcService
|
||||
{
|
||||
$stateStore = $this->createMock(MicrosoftOidcStateStoreService::class);
|
||||
|
||||
Reference in New Issue
Block a user