Skip to content

Commit

Permalink
Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
martinlagler committed Mar 12, 2024
1 parent 627346e commit 99783b3
Show file tree
Hide file tree
Showing 8 changed files with 576 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@
use Sulu\Bundle\SecurityBundle\Exception\RoleNameAlreadyExistsException;
use Sulu\Bundle\SecurityBundle\Security\Exception\EmailNotUniqueException;
use Sulu\Bundle\SecurityBundle\Security\Exception\UsernameNotUniqueException;
use Sulu\Bundle\SecurityBundle\SingleSignOn\Adapter\OpenId\OpenIdSingleSignOnAdapter;
use Sulu\Bundle\SecurityBundle\SingleSignOn\SingleSignOnAdapterFactory;
use Sulu\Bundle\SecurityBundle\SingleSignOn\SingleSignOnAdapterFactoryInterface;
use Sulu\Bundle\SecurityBundle\SingleSignOn\SingleSignOnAdapterInterface;
use Sulu\Component\HttpKernel\SuluKernel;
use Sulu\Component\Security\Authentication\RoleRepositoryInterface;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,7 @@
<argument type="service" id="sulu.repository.contact"/>
<argument type="service" id="sulu.repository.role"/>
<argument type="service" id="router"/>
<argument>%sulu_core.translations%</argument>

<tag name="sulu_security.single_sign_on_factory"/>
</service>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public function __construct(
#[\SensitiveParameter]
private string $clientSecret,
private string $userRole,
private array $translations,
) {
}

Expand Down Expand Up @@ -270,7 +271,8 @@ private function createOrUpdateAdminUser(string $email, array $attributes): void
$contact = $user->getContact();
$contact->setFirstName($attributes['given_name'] ?? '');
$contact->setLastName($attributes['family_name'] ?? '');
$user->setLocale((isset($attributes['locale']) && 'de' === $attributes['locale']) ? 'de' : 'en');
$locale = (isset($attributes['locale']) && \in_array($attributes['locale'], $this->translations, true)) ? $attributes['locale'] : 'en';
$user->setLocale($locale);

$this->entityManager->flush();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public function __construct(
private readonly ContactRepositoryInterface $contactRepository,
private readonly RoleRepositoryInterface $roleRepository,
private readonly UrlGeneratorInterface $urlGenerator,
private readonly array $translations,
) {
}

Expand All @@ -58,6 +59,7 @@ public function createAdapter(#[\SensitiveParameter] array $dsn, string $userRol
$clientId,
$clientSecret,
$userRole,
$this->translations,
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ public function onKernelRequest(RequestEvent $event): void

// Todo: Change this, userRepository should not return an error if there was no user found.
try {
/** @var User $user */
/** @var ?User $user */
$user = $this->userRepository->findUserByIdentifier($identifier);
$email = $user->getEmail() ?? $user->getUsername();
$email = $user ? ($user->getEmail() ?? $user->getUsername()) : $identifier;
} catch (NoResultException $e) {
$email = $identifier;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
<?php

declare(strict_types=1);

/*
* This file is part of Sulu.
*
* (c) Sulu GmbH
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace Sulu\Bundle\SecurityBundle\Tests\Unit\SingleSignOn\Adapter\OpenId;

use Doctrine\ORM\EntityManagerInterface;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Prophecy\PhpUnit\ProphecyTrait;
use Prophecy\Prophecy\ObjectProphecy;
use Sulu\Bundle\ContactBundle\Entity\Contact;
use Sulu\Bundle\ContactBundle\Entity\ContactRepositoryInterface;
use Sulu\Bundle\SecurityBundle\Entity\Role;
use Sulu\Bundle\SecurityBundle\SingleSignOn\Adapter\OpenId\OpenIdSingleSignOnAdapter;
use Sulu\Component\Security\Authentication\RoleRepositoryInterface;
use Sulu\Component\Security\Authentication\UserRepositoryInterface;
use Symfony\Component\HttpClient\MockHttpClient;
use Symfony\Component\HttpClient\Response\MockResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;

class OpenIdSingleSignOnAdapterTest extends TestCase
{
use ProphecyTrait;

private MockHttpClient $httpClient;

/**
* @var ObjectProphecy<UserRepositoryInterface>
*/
private $userRepository;

/**
* @var ObjectProphecy<EntityManagerInterface>
*/
private $entityManager;

/**
* @var ObjectProphecy<ContactRepositoryInterface>
*/
private $contactRepository;

/**
* @var ObjectProphecy<RoleRepositoryInterface>
*/
private $roleRepository;

/**
* @var ObjectProphecy<UrlGeneratorInterface>
*/
private $urlGenerator;

private OpenIdSingleSignOnAdapter $adapter;

protected function setUp(): void
{
$this->httpClient = new MockHttpClient();
$this->userRepository = $this->prophesize(UserRepositoryInterface::class);
$this->entityManager = $this->prophesize(EntityManagerInterface::class);
$this->contactRepository = $this->prophesize(ContactRepositoryInterface::class);
$this->roleRepository = $this->prophesize(RoleRepositoryInterface::class);
$this->urlGenerator = $this->prophesize(UrlGeneratorInterface::class);

$this->adapter = new OpenIdSingleSignOnAdapter(

Check failure on line 77 in src/Sulu/Bundle/SecurityBundle/Tests/Unit/SingleSignOn/Adapter/OpenId/OpenIdSingleSignOnAdapterTest.php

View workflow job for this annotation

GitHub Actions / PHP Lint

Class Sulu\Bundle\SecurityBundle\SingleSignOn\Adapter\OpenId\OpenIdSingleSignOnAdapter constructor invoked with 10 parameters, 11 required.
$this->httpClient,
$this->userRepository->reveal(),
$this->entityManager->reveal(),
$this->contactRepository->reveal(),
$this->roleRepository->reveal(),
$this->urlGenerator->reveal(),
'https://example.com/endpoint',
'clientId',
'clientSecret',
'userRole',
);
}

public function testGenerateLoginUrl(): void
{
$session = new Session(new MockArraySessionStorage());
/** @var string $responseContent */
$responseContent = \json_encode([
'authorization_endpoint' => 'https://example.com/authorize',
]);

$response = new MockResponse($responseContent, [
'http_code' => 200,
'response_headers' => ['Content-Type' => 'application/json'],
]);

$this->httpClient->setResponseFactory([$response]);
$request = new Request();
$request->setSession($session);
$redirectUrl = 'https://example.com/redirect';
$domain = 'example.com';

$loginUrl = $this->adapter->generateLoginUrl($request, $redirectUrl, $domain);

$this->assertStringStartsWith('https://example.com/authorize', $loginUrl);

/** @var array{
* domain: string,
* state: string,
* } $openIdAttributes
*/
$openIdAttributes = $session->get(OpenIdSingleSignOnAdapter::OPEN_ID_ATTRIBUTES);
$this->assertSame($domain, $openIdAttributes['domain']);
$this->assertIsString($openIdAttributes['state']);
}

public function testIsAuthorizationValid(): void
{
$isValid = $this->adapter->isAuthorizationValid(['state' => 'f20f9604-7577-4ac8-8890-9a6fbf359259'], ['state' => 'f20f9604-7577-4ac8-8890-9a6fbf359259']);
$isNotValid = $this->adapter->isAuthorizationValid(['state' => 'f20f9604-7577-4ac8-8890-9a6fbf359259'], ['state' => '123-7577-4ac8-8890-9a6fbf359259']);
$isNotSet = $this->adapter->isAuthorizationValid([], ['state' => '123-7577-4ac8-8890-9a6fbf359259']);

$this->assertTrue($isValid);
$this->assertFalse($isNotValid);
$this->assertFalse($isNotSet);
}

public function testCreateOrUpdateUser(): void
{
$token = 'mock_token';
$expectedRequests = [
function($method, $url, $options): MockResponse {
$this->assertSame('GET', $method);
$this->assertSame('https://example.com/endpoint', $url);

/** @var string $response */
$response = \json_encode([
'token_endpoint' => 'https://token_endpoint.com',
'userinfo_endpoint' => 'https://userinfo_endpoint.com',
]);

return new MockResponse($response);
},

function($method, $url, $options): MockResponse {
$this->assertSame('POST', $method);
$this->assertSame('https://token_endpoint.com/', $url);

/** @var string $response */
$response = \json_encode([
'access_token' => 'ya29.a0Ad52N38l9acjoNc975Apn4W4H8DK_TtX_S',
]);

return new MockResponse($response);
},

function($method, $url, $options): MockResponse {
$this->assertSame('GET', $method);
$this->assertSame('https://userinfo_endpoint.com/', $url);

/** @var string $response */
$response = \json_encode([
'email' => '[email protected]',
]);

return new MockResponse($response);
},
];

$this->httpClient->setResponseFactory($expectedRequests);

$this->urlGenerator->generate('sulu_admin', [], UrlGeneratorInterface::ABSOLUTE_URL)
->shouldBeCalled()
->willReturn('https://sulu.io/admin');

$this->userRepository->findOneBy(Argument::any())->willReturn(null);
$this->contactRepository->createNew()->willReturn($this->prophesize(Contact::class)->reveal());
$this->entityManager->persist(Argument::any())->shouldBeCalled();
$role = $this->prophesize(Role::class);
$role->getAnonymous()->shouldBeCalled()->willReturn(false);
$role->getIdentifier()->willReturn('[email protected]');
$this->roleRepository->findOneBy(Argument::any())
->shouldBeCalled()
->willReturn($role->reveal());
$this->entityManager->flush()->shouldBeCalled();

$expectedUserBadge = new UserBadge('[email protected]', null, ['email' => '[email protected]']);

$result = $this->adapter->createOrUpdateUser($token);

$this->assertEquals($expectedUserBadge, $result);
}
}
Loading

0 comments on commit 99783b3

Please sign in to comment.