Skip to content

Commit a5c1e39

Browse files
committed
Add unit tests
1 parent 72d9054 commit a5c1e39

6 files changed

Lines changed: 677 additions & 3 deletions

File tree

src/Bridges/OAuth2Bridge.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public function encrypt(
3636
Crypto::encrypt($unencryptedData, $encryptionKey) :
3737
Crypto::encryptWithPassword($unencryptedData, $encryptionKey);
3838
} catch (\Exception $e) {
39-
throw new OidcException('Error enrypting data: ' . $e->getMessage(), (int)$e->getCode(), $e);
39+
throw new OidcException('Error encrypting data: ' . $e->getMessage(), (int)$e->getCode(), $e);
4040
}
4141
}
4242

src/Controllers/OAuth2/TokenIntrospectionController.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,6 @@ public function __construct(
5252

5353
public function __invoke(Request $request): Response
5454
{
55-
// TODO mivanci Add endpoint to OAuth2 discovery document.
56-
5755
try {
5856
$this->ensureAuthenticatedClient($request);
5957
} catch (AuthorizationException $e) {
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SimpleSAML\Test\Module\oidc\unit\Bridges;
6+
7+
use Defuse\Crypto\Key;
8+
use PHPUnit\Framework\Attributes\CoversClass;
9+
use PHPUnit\Framework\Attributes\UsesClass;
10+
use PHPUnit\Framework\MockObject\MockObject;
11+
use PHPUnit\Framework\TestCase;
12+
use SimpleSAML\Module\oidc\Bridges\OAuth2Bridge;
13+
use SimpleSAML\Module\oidc\Exceptions\OidcException;
14+
use SimpleSAML\Module\oidc\ModuleConfig;
15+
16+
#[CoversClass(OAuth2Bridge::class)]
17+
#[UsesClass(OidcException::class)]
18+
class OAuth2BridgeTest extends TestCase
19+
{
20+
private ModuleConfig&MockObject $moduleConfig;
21+
private OAuth2Bridge $bridge;
22+
23+
24+
protected function setUp(): void
25+
{
26+
$this->moduleConfig = $this->createMock(ModuleConfig::class);
27+
$this->bridge = new OAuth2Bridge($this->moduleConfig);
28+
}
29+
30+
31+
public function testEncryptDecryptWithPasswordFromConfig(): void
32+
{
33+
$password = 'secret-password';
34+
$this->moduleConfig->method('getEncryptionKey')->willReturn($password);
35+
36+
$unencrypted = 'secret-data-2';
37+
$encrypted = $this->bridge->encrypt($unencrypted);
38+
39+
$this->assertNotEquals($unencrypted, $encrypted);
40+
41+
$decrypted = $this->bridge->decrypt($encrypted);
42+
$this->assertEquals($unencrypted, $decrypted);
43+
}
44+
45+
public function testEncryptDecryptWithExplicitKey(): void
46+
{
47+
$key = Key::createNewRandomKey();
48+
49+
$unencrypted = 'secret-data-3';
50+
$encrypted = $this->bridge->encrypt($unencrypted, $key);
51+
52+
$this->assertNotEquals($unencrypted, $encrypted);
53+
54+
$decrypted = $this->bridge->decrypt($encrypted, $key);
55+
$this->assertEquals($unencrypted, $decrypted);
56+
}
57+
58+
public function testEncryptDecryptWithExplicitPassword(): void
59+
{
60+
$password = 'secret-password-explicit';
61+
62+
$unencrypted = 'secret-data-4';
63+
$encrypted = $this->bridge->encrypt($unencrypted, $password);
64+
65+
$this->assertNotEquals($unencrypted, $encrypted);
66+
67+
$decrypted = $this->bridge->decrypt($encrypted, $password);
68+
$this->assertEquals($unencrypted, $decrypted);
69+
}
70+
71+
72+
public function testDecryptThrowsOidcExceptionOnInvalidData(): void
73+
{
74+
$this->moduleConfig->method('getEncryptionKey')->willReturn('secret-password');
75+
76+
$this->expectException(OidcException::class);
77+
$this->expectExceptionMessage('Error decrypting data:');
78+
79+
$this->bridge->decrypt('invalid-encrypted-data');
80+
}
81+
}
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SimpleSAML\Test\Module\oidc\unit\Controllers\OAuth2;
6+
7+
use PHPUnit\Framework\MockObject\MockObject;
8+
use PHPUnit\Framework\TestCase;
9+
use SimpleSAML\Module\oidc\Controllers\OAuth2\OAuth2ServerConfigurationController;
10+
use SimpleSAML\Module\oidc\ModuleConfig;
11+
use SimpleSAML\Module\oidc\Services\OpMetadataService;
12+
use SimpleSAML\Module\oidc\Utils\Routes;
13+
use SimpleSAML\OpenID\Algorithms\SignatureAlgorithmBag;
14+
use SimpleSAML\OpenID\Codebooks\AccessTokenTypesEnum;
15+
use SimpleSAML\OpenID\Codebooks\ClaimsEnum;
16+
use SimpleSAML\OpenID\Codebooks\ClientAuthenticationMethodsEnum;
17+
use SimpleSAML\OpenID\SupportedAlgorithms;
18+
use Symfony\Component\HttpFoundation\JsonResponse;
19+
20+
/**
21+
* @covers \SimpleSAML\Module\oidc\Controllers\OAuth2\OAuth2ServerConfigurationController
22+
*/
23+
class OAuth2ServerConfigurationControllerTest extends TestCase
24+
{
25+
final public const OIDC_OP_METADATA = [
26+
'issuer' => 'http://localhost',
27+
'authorization_endpoint' => 'http://localhost/authorization',
28+
'token_endpoint' => 'http://localhost/token',
29+
];
30+
31+
protected MockObject $opMetadataServiceMock;
32+
protected MockObject $routesMock;
33+
protected MockObject $moduleConfigMock;
34+
35+
protected function setUp(): void
36+
{
37+
$this->opMetadataServiceMock = $this->createMock(OpMetadataService::class);
38+
$this->routesMock = $this->createMock(Routes::class);
39+
$this->moduleConfigMock = $this->createMock(ModuleConfig::class);
40+
41+
$this->opMetadataServiceMock->method('getMetadata')->willReturn(self::OIDC_OP_METADATA);
42+
}
43+
44+
protected function mock(
45+
?OpMetadataService $opMetadataService = null,
46+
?Routes $routes = null,
47+
?ModuleConfig $moduleConfig = null,
48+
): OAuth2ServerConfigurationController {
49+
return new OAuth2ServerConfigurationController(
50+
$opMetadataService ?? $this->opMetadataServiceMock,
51+
$routes ?? $this->routesMock,
52+
$moduleConfig ?? $this->moduleConfigMock,
53+
);
54+
}
55+
56+
public function testItIsInitializable(): void
57+
{
58+
$this->assertInstanceOf(
59+
OAuth2ServerConfigurationController::class,
60+
$this->mock(),
61+
);
62+
}
63+
64+
public function testItReturnsConfigurationWithoutIntrospectionIfApiDisabled(): void
65+
{
66+
$this->moduleConfigMock->method('getApiEnabled')->willReturn(false);
67+
$this->moduleConfigMock->method('getApiOAuth2TokenIntrospectionEndpointEnabled')->willReturn(true);
68+
69+
$jsonResponseMock = $this->createMock(JsonResponse::class);
70+
$this->routesMock->expects($this->once())
71+
->method('newJsonResponse')
72+
->with(self::OIDC_OP_METADATA)
73+
->willReturn($jsonResponseMock);
74+
75+
$this->assertSame($jsonResponseMock, $this->mock()->__invoke());
76+
}
77+
78+
public function testItReturnsConfigurationWithoutIntrospectionIfIntrospectionDisabled(): void
79+
{
80+
$this->moduleConfigMock->method('getApiEnabled')->willReturn(true);
81+
$this->moduleConfigMock->method('getApiOAuth2TokenIntrospectionEndpointEnabled')->willReturn(false);
82+
83+
$jsonResponseMock = $this->createMock(JsonResponse::class);
84+
$this->routesMock->expects($this->once())
85+
->method('newJsonResponse')
86+
->with(self::OIDC_OP_METADATA)
87+
->willReturn($jsonResponseMock);
88+
89+
$this->assertSame($jsonResponseMock, $this->mock()->__invoke());
90+
}
91+
92+
public function testItReturnsConfigurationWithIntrospectionEndpointEnabled(): void
93+
{
94+
$this->moduleConfigMock->method('getApiEnabled')->willReturn(true);
95+
$this->moduleConfigMock->method('getApiOAuth2TokenIntrospectionEndpointEnabled')->willReturn(true);
96+
97+
$signatureAlgorithmBagMock = $this->createMock(SignatureAlgorithmBag::class);
98+
$signatureAlgorithmBagMock->method('getAllNamesUnique')->willReturn(['RS256', 'ES256']);
99+
100+
$supportedAlgorithmsMock = $this->createMock(SupportedAlgorithms::class);
101+
$supportedAlgorithmsMock->method('getSignatureAlgorithmBag')->willReturn($signatureAlgorithmBagMock);
102+
103+
$this->moduleConfigMock->method('getSupportedAlgorithms')->willReturn($supportedAlgorithmsMock);
104+
105+
$introspectionEndpoint = 'http://localhost/introspect';
106+
$this->routesMock->method('urlApiOAuth2TokenIntrospection')->willReturn($introspectionEndpoint);
107+
108+
$expectedConfiguration = self::OIDC_OP_METADATA;
109+
$expectedConfiguration[ClaimsEnum::IntrospectionEndpoint->value] = $introspectionEndpoint;
110+
$expectedConfiguration[ClaimsEnum::IntrospectionEndpointAuthMethodsSupported->value] = [
111+
ClientAuthenticationMethodsEnum::ClientSecretBasic->value,
112+
ClientAuthenticationMethodsEnum::ClientSecretPost->value,
113+
ClientAuthenticationMethodsEnum::PrivateKeyJwt->value,
114+
AccessTokenTypesEnum::Bearer->value,
115+
];
116+
$expectedConfiguration[ClaimsEnum::IntrospectionEndpointAuthSigningAlgValuesSupported->value] = [
117+
'RS256',
118+
'ES256',
119+
];
120+
121+
$jsonResponseMock = $this->createMock(JsonResponse::class);
122+
$this->routesMock->expects($this->once())
123+
->method('newJsonResponse')
124+
->with($expectedConfiguration)
125+
->willReturn($jsonResponseMock);
126+
127+
$this->assertSame($jsonResponseMock, $this->mock()->__invoke());
128+
}
129+
}

0 commit comments

Comments
 (0)