Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion config/services/compat.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ services:

engineblock.compat.saml2_id_generator:
public: true
class: EngineBlock_Saml2_IdGenerator_Default
alias: OpenConext\EngineBlock\Saml2\IdGenerator

engineblock.compat.attribute_release_policy_enforcer:
public: false
Expand Down
8 changes: 7 additions & 1 deletion config/services/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -167,11 +167,17 @@ services:
- '@OpenConext\EngineBlock\Metadata\Factory\ValueObject\EngineBlockConfiguration'
- '@OpenConext\EngineBlockBundle\Url\UrlProvider'

OpenConext\EngineBlock\Saml2\DefaultIdGenerator: ~

OpenConext\EngineBlock\Saml2\IdGenerator:
alias: OpenConext\EngineBlock\Saml2\DefaultIdGenerator
public: true

OpenConext\EngineBlock\Xml\MetadataRenderer:
arguments:
- '@OpenConext\EngineBlockBundle\Localization\LanguageSupportProvider'
- '@twig'
- '@engineblock.compat.saml2_id_generator'
- '@OpenConext\EngineBlock\Saml2\IdGenerator'
- '@OpenConext\EngineBlock\Metadata\X509\KeyPairFactory'
- '@OpenConext\EngineBlock\Xml\DocumentSigner'
- '@OpenConext\EngineBlock\Service\TimeProvider\TimeProvider'
Expand Down
2 changes: 1 addition & 1 deletion library/EngineBlock/Application/DiContainer.php
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ public function getTimeProvider()
}

/**
* @return EngineBlock_Saml2_IdGenerator
* @return \OpenConext\EngineBlock\Saml2\IdGenerator
*/
public function getSaml2IdGenerator()
{
Expand Down
4 changes: 2 additions & 2 deletions library/EngineBlock/Corto/Module/Service/SingleSignOn.php
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ protected function _createUnsolicitedRequest()
$relayState = !empty($_GET['RelayState']) ? $_GET['RelayState'] : null;

$sspRequest = new AuthnRequest();
$sspRequest->setId($this->_server->getNewId(EngineBlock_Saml2_IdGenerator::ID_USAGE_SAML2_REQUEST));
$sspRequest->setId($this->_server->getNewId(\OpenConext\EngineBlock\Saml2\IdGenerator::ID_USAGE_SAML2_REQUEST));
$issuer = new Issuer();
$issuer->setValue($entityId);
$sspRequest->setIssuer($issuer);
Expand Down Expand Up @@ -389,7 +389,7 @@ protected function _createUnsolicitedRequest()
protected function _createDebugRequest()
{
$sspRequest = new AuthnRequest();
$sspRequest->setId($this->_server->getNewId(EngineBlock_Saml2_IdGenerator::ID_USAGE_SAML2_REQUEST));
$sspRequest->setId($this->_server->getNewId(\OpenConext\EngineBlock\Saml2\IdGenerator::ID_USAGE_SAML2_REQUEST));
$issuer = new Issuer();
$issuer->setValue($this->_server->getUrl('spMetadataService'));
$sspRequest->setIssuer($issuer);
Expand Down
6 changes: 3 additions & 3 deletions library/EngineBlock/Corto/ProxyServer.php
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,7 @@ public function createEnhancedResponse(
// Create a new assertion by us.
$newAssertion = new Assertion();
$newResponse->setAssertions(array($newAssertion));
$newAssertion->setId($this->getNewId(EngineBlock_Saml2_IdGenerator::ID_USAGE_SAML2_ASSERTION));
$newAssertion->setId($this->getNewId(\OpenConext\EngineBlock\Saml2\IdGenerator::ID_USAGE_SAML2_ASSERTION));
$newAssertion->setIssueInstant(time());
$newAssertion->setIssuer($newResponse->getIssuer());

Expand Down Expand Up @@ -892,7 +892,7 @@ protected function _createBaseResponse(EngineBlock_Saml2_AuthnRequestAnnotationD
$response = new Response();
/** @var AuthnRequest $request */
$response->setRelayState($request->getRelayState());
$response->setId($this->getNewId(EngineBlock_Saml2_IdGenerator::ID_USAGE_SAML2_RESPONSE));
$response->setId($this->getNewId(\OpenConext\EngineBlock\Saml2\IdGenerator::ID_USAGE_SAML2_RESPONSE));
$response->setIssueInstant(time());
if (!$requestWasUnsolicited) {
$response->setInResponseTo($request->getId());
Expand Down Expand Up @@ -1399,7 +1399,7 @@ public function timeStamp($deltaSeconds = 0)
return $provider->timestamp($deltaSeconds);
}

public function getNewId($usage = EngineBlock_Saml2_IdGenerator::ID_USAGE_OTHER)
public function getNewId($usage = \OpenConext\EngineBlock\Saml2\IdGenerator::ID_USAGE_OTHER)
{
$generator = EngineBlock_ApplicationSingleton::getInstance()->getDiContainer()->getSaml2IdGenerator();
return $generator->generate(self::ID_PREFIX, $usage);
Expand Down
2 changes: 1 addition & 1 deletion library/EngineBlock/Saml2/AuthnRequestFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public static function createFromRequest(
/** @var AuthnRequest $originalRequest */

$sspRequest = new AuthnRequest();
$sspRequest->setId($server->getNewId(EngineBlock_Saml2_IdGenerator::ID_USAGE_SAML2_REQUEST));
$sspRequest->setId($server->getNewId(\OpenConext\EngineBlock\Saml2\IdGenerator::ID_USAGE_SAML2_REQUEST));
$sspRequest->setIssueInstant(time());
$sspRequest->setDestination(isset($idpMetadata->singleSignOnServices[0]) ? $idpMetadata->singleSignOnServices[0]->location : null);
$sspRequest->setForceAuthn($originalRequest->getForceAuthn());
Expand Down
30 changes: 30 additions & 0 deletions src/OpenConext/EngineBlock/Saml2/DefaultIdGenerator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php declare(strict_types=1);

/**
* Copyright 2026 SURFnet B.V.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

namespace OpenConext\EngineBlock\Saml2;

use function bin2hex;
use function random_bytes;

final class DefaultIdGenerator implements IdGenerator
{
public function generate(string $prefix = 'EB', string $usage = self::ID_USAGE_OTHER): string
{
return $prefix . bin2hex(random_bytes(20));
}
}
30 changes: 30 additions & 0 deletions src/OpenConext/EngineBlock/Saml2/IdGenerator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php declare(strict_types=1);

/**
* Copyright 2026 SURFnet B.V.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

namespace OpenConext\EngineBlock\Saml2;

interface IdGenerator
{
const ID_USAGE_SAML2_METADATA = 'saml2-metadata';
const ID_USAGE_OTHER = 'other';
const ID_USAGE_SAML2_RESPONSE = 'saml2-response';
const ID_USAGE_SAML2_REQUEST = 'saml2-request';
const ID_USAGE_SAML2_ASSERTION = 'saml2-assertion';

public function generate(string $prefix = 'EB', string $usage = self::ID_USAGE_OTHER): string;
}
12 changes: 6 additions & 6 deletions src/OpenConext/EngineBlock/Xml/MetadataRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

namespace OpenConext\EngineBlock\Xml;

use EngineBlock_Saml2_IdGenerator;
use InvalidArgumentException;
use OpenConext\EngineBlock\Metadata\Factory\Collection\IdentityProviderEntityCollection;
use OpenConext\EngineBlock\Metadata\Factory\Helper\IdentityProviderMetadataHelper;
Expand All @@ -27,6 +26,7 @@
use OpenConext\EngineBlock\Metadata\Factory\ServiceProviderEntityInterface;
use OpenConext\EngineBlock\Metadata\X509\KeyPairFactory;
use OpenConext\EngineBlock\Metadata\X509\X509KeyPair;
use OpenConext\EngineBlock\Saml2\IdGenerator as SamlIdGenerator;
use OpenConext\EngineBlock\Service\TimeProvider\TimeProvider;
use OpenConext\EngineBlockBundle\Localization\LanguageSupportProvider;
use Twig\Environment;
Expand All @@ -49,7 +49,7 @@ class MetadataRenderer
private $twig;

/**
* @var EngineBlock_Saml2_IdGenerator
* @var SamlIdGenerator
*/
private $samlIdGenerator;

Expand Down Expand Up @@ -83,7 +83,7 @@ class MetadataRenderer
public function __construct(
LanguageSupportProvider $languageSupportProvider,
Environment $twig,
EngineBlock_Saml2_IdGenerator $samlIdGenerator,
SamlIdGenerator $samlIdGenerator,
KeyPairFactory $keyPairFactory,
DocumentSigner $documentSigner,
TimeProvider $timeProvider,
Expand Down Expand Up @@ -160,7 +160,7 @@ private function renderMetadataXmlServiceProvider(ServiceProviderEntityInterface
}

$params = [
'id' => $this->samlIdGenerator->generate(self::ID_PREFIX, EngineBlock_Saml2_IdGenerator::ID_USAGE_SAML2_METADATA),
'id' => $this->samlIdGenerator->generate(self::ID_PREFIX, SamlIdGenerator::ID_USAGE_SAML2_METADATA),
'validUntil' => $this->getValidUntil(),
'metadata' => $metadata,
'locales' => $this->languageSupportProvider->getSupportedLanguages(),
Expand All @@ -175,7 +175,7 @@ private function renderMetadataXmlIdentityProvider(IdentityProviderEntityInterfa
$metadata = new IdentityProviderMetadataHelper($idp, $this->languageSupportProvider);

$params = [
'id' => $this->samlIdGenerator->generate(self::ID_PREFIX, EngineBlock_Saml2_IdGenerator::ID_USAGE_SAML2_METADATA),
'id' => $this->samlIdGenerator->generate(self::ID_PREFIX, SamlIdGenerator::ID_USAGE_SAML2_METADATA),
'validUntil' => $this->getValidUntil(),
'metadata' => $metadata,
'locales' => $this->languageSupportProvider->getSupportedLanguages(),
Expand All @@ -192,7 +192,7 @@ private function renderMetadataXmlIdentityProviderCollection(IdentityProviderEnt
}

$params = [
'id' => $this->samlIdGenerator->generate(self::ID_PREFIX, EngineBlock_Saml2_IdGenerator::ID_USAGE_SAML2_METADATA),
'id' => $this->samlIdGenerator->generate(self::ID_PREFIX, SamlIdGenerator::ID_USAGE_SAML2_METADATA),
'validUntil' => $this->getValidUntil(),
'metadataCollection' => $metadataCollection,
'locales' => $this->languageSupportProvider->getSupportedLanguages(),
Expand Down
65 changes: 65 additions & 0 deletions tests/unit/OpenConext/EngineBlock/Saml2/DefaultIdGeneratorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php declare(strict_types=1);

/**
* Copyright 2026 SURFnet B.V.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

namespace OpenConext\EngineBlock\Saml2;

use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;

class DefaultIdGeneratorTest extends TestCase
{
private DefaultIdGenerator $generator;

protected function setUp(): void
{
$this->generator = new DefaultIdGenerator();
}

#[Test]
public function generateReturnsStringWithGivenPrefix(): void
{
$id = $this->generator->generate('EB', IdGenerator::ID_USAGE_OTHER);

self::assertStringStartsWith('EB', $id);
}

#[Test]
public function generateReturnsUniqueIds(): void
{
$id1 = $this->generator->generate();
$id2 = $this->generator->generate();

self::assertNotSame($id1, $id2);
}

#[Test]
public function generateDefaultsToEbPrefix(): void
{
$id = $this->generator->generate();

self::assertStringStartsWith('EB', $id);
}

#[Test]
public function generateReturnsFortyHexCharsAfterPrefix(): void
{
$id = $this->generator->generate('EB', IdGenerator::ID_USAGE_OTHER);

self::assertMatchesRegularExpression('/^EB[0-9a-f]{40}$/', $id);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
namespace OpenConext\EngineBlock\Xml;

use DOMDocument;
use EngineBlock_Saml2_IdGenerator;
use OpenConext\EngineBlock\Saml2\IdGenerator as SamlIdGenerator;
use Exception;
use InvalidArgumentException;
use Mockery as m;
Expand Down Expand Up @@ -344,7 +344,7 @@ private function buildMetadataRenderer(
$publicKey = new X509Certificate(openssl_x509_read(file_get_contents($basePath . '/tests/resources/key/engineblock.crt')));
$keyPair = new X509KeyPair($publicKey, $privateKey);

$samlIdGenerator = $this->createMock(EngineBlock_Saml2_IdGenerator::class);
$samlIdGenerator = $this->createMock(SamlIdGenerator::class);
$samlIdGenerator->method('generate')
->willReturn('EB_metadata');

Expand Down