Skip to content

Commit

Permalink
Add oidcUser test with mock OpenIDConnectClient
Browse files Browse the repository at this point in the history
Test oidcUser::authenticate() method with mock OpenIDConnectClient.
  • Loading branch information
sbreker committed Oct 2, 2024
1 parent 70dbd16 commit 82faa97
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 3 deletions.
2 changes: 1 addition & 1 deletion phpunit.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<phpunit bootstrap="test/bootstrap/phpunit.php">
<phpunit bootstrap="test/bootstrap/phpunit.php" stderr="true">
<testsuites>
<testsuite name="unit">
<directory>test/phpunit</directory>
Expand Down
17 changes: 15 additions & 2 deletions plugins/arOidcPlugin/lib/oidcUser.class.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

use Jumbojett\OpenIDConnectClient;

/*
* This file is part of the Access to Memory (AtoM) software.
*
Expand All @@ -19,7 +21,7 @@

class oidcUser extends myUser implements Zend_Acl_Role_Interface
{
private $oidcClient;
private ?OpenIDConnectClient $oidcClient = null;

/**
* Initialize.
Expand All @@ -31,13 +33,24 @@ class oidcUser extends myUser implements Zend_Acl_Role_Interface
public function initialize(sfEventDispatcher $dispatcher, sfStorage $storage, $options = [])
{
$this->logger = sfContext::getInstance()->getLogger();

if (null === $this->oidcClient) {
$this->oidcClient = arOidc::getOidcInstance();
$this->setOidcClient(arOidc::getOidcInstance());
}

parent::initialize($dispatcher, $storage, $options);
}

/**
* Setter for the OIDC client.
*/
public function setOidcClient(OpenIDConnectClient $oidcClient)
{
if (null !== $oidcClient) {
$this->oidcClient = $oidcClient;
}
}

/**
* Try to authenticate with IAM system using OIDC.
*
Expand Down
144 changes: 144 additions & 0 deletions test/phpunit/arOidcPlugin/lib/oidcUserTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
<?php

use Jumbojett\OpenIDConnectClient;
use PHPUnit\Framework\TestCase;

require_once 'plugins/arOidcPlugin/config/arOidcPluginConfiguration.class.php';

/**
* @internal
*
* @covers \oidcUser
*/
class OidcUserTest extends TestCase
{
public function setUp(): void
{
@session_start();

// Setup for instantiating new user.
$this->dispatcher = new sfEventDispatcher();
$sessionPath = sys_get_temp_dir().'/sessions_'.rand(11111, 99999);
$this->storage = new MySessionStorage(['session_path' => $sessionPath]);
}

public function authenticateSuccessProvider()
{
return [
'OIDC authenticate()' => [
'redirectUrl' => 'http://127.0.0.1:63001/index.php/oidc/login',
'providerId' => 'primary',
'providers' => [
'primary' => [
'url' => 'https://keycloak:8443/realms/primary',
'client_id' => 'primary_client_id',
'client_secret' => 'client_secret',
'send_oidc_logout' => true,
'enable_refresh_token_use' => true,
'server_cert' => false,
'set_groups_from_attributes' => true,
'user_groups' => [
'administrator' => [
'attribute_value' => 'atom-admin',
'group_id' => 100,
],
'editor' => [
'attribute_value' => 'atom-editor',
'group_id' => 101,
],
],
'scopes' => [
'openid',
'profile',
'email',
],
'roles_source' => 'access_token',
'roles_path' => [
'realm_access',
'roles',
],
'user_matching_source' => 'oidc-email',
'auto_create_atom_user' => true,
],
],
'expected' => true,
],
];
}

/**
* @dataProvider authenticateSuccessProvider
*
* @param mixed $expected
* @param mixed $redirectUrl
* @param mixed $providerId
* @param mixed $providers
*/
public function testAuthenticateSuccess($redirectUrl, $providerId, $providers, $expected)
{
// $client = $this->getMockBuilder(OpenIDConnectClient::class)->setMethods(['authenticate', 'requestUserInfo', 'getIdToken', 'getVerifiedClaims'])->getMock();
$oidcClientMock = $this->getMockBuilder(OpenIDConnectClient::class)
->disableOriginalConstructor()
->getMock()
;

$oidcClientMock->method('authenticate')
->willReturn(true)
;

// Mock the requestUserInfo method to return different values based on input params.
$oidcClientMock->expects($this->atMost(2)) // Expect the method to be called twice
->method('requestUserInfo')
->withConsecutive(
[$this->equalTo('preferred_username')],
[$this->equalTo('email')],
)
->willReturnOnConsecutiveCalls(
'demo',
'[email protected]',
)
;

// Mock the getIdToken method to return a fake ID token.
$oidcClientMock->expects($this->atMost(1))
->method('getIdToken')
->willReturn('fake-id-token-123')
;

// Mock the getVerifiedClaims method to return a fake expiry time for 'exp'.
$oidcClientMock->expects($this->atMost(1))
->method('getVerifiedClaims')
->with($this->equalTo('exp'))
->willReturn(1694000000)
;

// Mock the getRefreshToken method to be called zero or one time.
$oidcClientMock->expects($this->atMost(1))
->method('getRefreshToken')
->willReturn('fake-refresh-token-456')
;

sfConfig::set('app_oidc_redirect_url', $redirectUrl);
sfConfig::set('app_oidc_primary_provider_name', $providerId);
sfConfig::set('app_oidc_providers', $providers);

$user = new oidcUser($this->dispatcher, $this->storage);
$user->initialize($this->dispatcher, $this->storage);
$user->setSessionProviderId('primary');
$user->setOidcClient($oidcClientMock);

$result = $user->authenticate();

$this->assertEquals($expected, $result, 'OIDC user authenticate failed.');
}
}

class MySessionStorage extends sfSessionTestStorage
{
public function regenerate($destroy = false)
{
$this->sessionId = rand(1, 9999);

return true;
}
}

0 comments on commit 82faa97

Please sign in to comment.