Skip to content

Commit afb2b0b

Browse files
Make metadata expiration time configurable (#1860)
* Make metadata expiration time configurable * Add sanity checks & test coverage on parameter & cleanup & docs --------- Co-authored-by: Johan Kromhout <johan.kromhout@dawn.tech>
1 parent 025f511 commit afb2b0b

6 files changed

Lines changed: 67 additions & 7 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ Maintenance:
2222
* `symfony/monolog-bundle` upgraded to ^4.0; review your monolog configuration if you have customised it outside of the defaults.
2323

2424
Changes:
25+
* The metadata expiration time (`validUntil` attribute) is now configurable via the `metadata_expiration_time` parameter in `parameters.yml`.
26+
* Action required: Add `metadata_expiration_time` to `parameters.yaml`, suggested value: `86400`. This is the old behaviour in which metadata is cached for 24 hours.
2527
* The `consent.deleted_at` should be not nullable, and have a default value of `0000-00-00 00:00:00`.
2628
* Because `deleted_at` is part of the PK, no migration is provided. The database engine should not allow this to be null in the first place, so it is probably not nullable already on your db.
2729
* The `0000-00-00 00:00:00` is added for clarity/consistency, as this is probably the default behaviour of your database already.

config/packages/parameters.yml.dist

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ parameters:
5555
## Add RequestedAttributes to the AttributeConsumingService of the SP Proxy metadata of Engineblock, default is all
5656
## Options are 'all' (optional and required attributes), 'required' (only required attributes) or 'none'
5757
metadata_add_requested_attributes: all
58+
## The number of seconds a Metadata document is deemed valid (default 24h). Must be a positive integer.
59+
metadata_expiration_time: 86400
5860

5961
##########################################################################################
6062
## PHP SETTINGS

config/services/services.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ services:
157157
- '@OpenConext\EngineBlock\Xml\DocumentSigner'
158158
- '@OpenConext\EngineBlock\Service\TimeProvider\TimeProvider'
159159
- '%metadata_add_requested_attributes%'
160+
- "%metadata_expiration_time%"
160161

161162
OpenConext\EngineBlock\Xml\MetadataProvider:
162163
arguments:

docs/metadata_generation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ the built-in metadata much more flexible than it is now.
5858
* Every document starts with a terms of use comment. This value can be configured in the `openconext.termsOfUse` ini
5959
setting.
6060
* The Metadata documents are signed.
61-
* The Metadata documents are deemed valid for a period of 86400 seconds (1 day).
61+
* The Metadata documents are deemed valid for a configurable period (default: 86400 seconds / 1 day), controlled via the `metadata_expiration_time` parameter in `parameters.yml`.
6262
* The EngineBlock UIInfo elements are generated from the `parameters.yml` config and are translated to English and
6363
Dutch when possible. Mainly English UI Info will be published.
6464
* The logo can be specified using the following `parameters.yml` settings

src/OpenConext/EngineBlock/Xml/MetadataRenderer.php

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
namespace OpenConext\EngineBlock\Xml;
2020

2121
use EngineBlock_Saml2_IdGenerator;
22+
use InvalidArgumentException;
2223
use OpenConext\EngineBlock\Metadata\Factory\Collection\IdentityProviderEntityCollection;
2324
use OpenConext\EngineBlock\Metadata\Factory\Helper\IdentityProviderMetadataHelper;
2425
use OpenConext\EngineBlock\Metadata\Factory\Helper\ServiceProviderMetadataHelper;
@@ -30,14 +31,17 @@
3031
use OpenConext\EngineBlockBundle\Localization\LanguageSupportProvider;
3132
use Twig\Environment;
3233

34+
/**
35+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
36+
*/
3337
class MetadataRenderer
3438
{
3539
const ID_PREFIX = 'EB';
3640

3741
/**
3842
* The number of seconds a Metadata document is deemed valid
3943
*/
40-
const METADATA_EXPIRATION_TIME = 86400;
44+
private int $metadataExpirationTime;
4145

4246
/**
4347
* @var Environment
@@ -83,15 +87,24 @@ public function __construct(
8387
KeyPairFactory $keyPairFactory,
8488
DocumentSigner $documentSigner,
8589
TimeProvider $timeProvider,
86-
string $addRequestedAttributes
90+
string $addRequestedAttributes,
91+
int $metadataExpirationTime
8792
) {
93+
if ($metadataExpirationTime <= 0) {
94+
throw new InvalidArgumentException(sprintf(
95+
'metadataExpirationTime must be a positive integer, %d given',
96+
$metadataExpirationTime
97+
));
98+
}
99+
88100
$this->languageSupportProvider = $languageSupportProvider;
89101
$this->twig = $twig;
90102
$this->samlIdGenerator = $samlIdGenerator;
91103
$this->keyPairFactory = $keyPairFactory;
92104
$this->documentSigner = $documentSigner;
93105
$this->timeProvider = $timeProvider;
94106
$this->addRequestedAttributes = $addRequestedAttributes;
107+
$this->metadataExpirationTime = $metadataExpirationTime;
95108
}
96109

97110
public function fromServiceProviderEntity(ServiceProviderEntityInterface $sp, string $keyId) : string
@@ -190,6 +203,6 @@ private function renderMetadataXmlIdentityProviderCollection(IdentityProviderEnt
190203

191204
private function getValidUntil(): string
192205
{
193-
return $this->timeProvider->timestamp(self::METADATA_EXPIRATION_TIME);
206+
return $this->timeProvider->timestamp($this->metadataExpirationTime);
194207
}
195208
}

tests/unit/OpenConext/EngineBlock/Xml/MetadataRendererTest.php

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use DOMDocument;
2121
use EngineBlock_Saml2_IdGenerator;
2222
use Exception;
23+
use InvalidArgumentException;
2324
use Mockery as m;
2425
use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration;
2526
use OpenConext\EngineBlock\Metadata\ContactPerson;
@@ -295,8 +296,48 @@ public function metadata_add_no_requested_attributes()
295296
$this->assertStringNotContainsString($this->getRequestedAttributeXml('attribute3', false), $xml);
296297
}
297298

298-
private function buildMetadataRenderer(string $addRequestedAttributes)
299+
#[Group('Metadata')]
300+
#[Test]
301+
public function a_negative_metadata_expiration_time_throws_an_invalid_argument_exception()
302+
{
303+
$this->expectException(InvalidArgumentException::class);
304+
$this->buildMetadataRenderer('all', -1);
305+
}
306+
307+
#[Group('Metadata')]
308+
#[Test]
309+
public function a_zero_metadata_expiration_time_throws_an_invalid_argument_exception()
299310
{
311+
$this->expectException(InvalidArgumentException::class);
312+
$this->buildMetadataRenderer('all', 0);
313+
}
314+
315+
#[Group('Metadata')]
316+
#[Test]
317+
public function the_configured_metadata_expiration_time_is_reflected_in_the_valid_until_attribute()
318+
{
319+
$fixedTime = mktime(0, 0, 0, 1, 1, 2026);
320+
$expirationTime = 3600;
321+
322+
$timeProvider = m::mock(TimeProvider::class);
323+
$timeProvider->shouldReceive('timestamp')
324+
->andReturnUsing(function ($deltaSeconds) use ($fixedTime) {
325+
return gmdate(TimeProvider::TIMESTAMP_FORMAT, $fixedTime + $deltaSeconds);
326+
});
327+
328+
$renderer = $this->buildMetadataRenderer('all', $expirationTime, $timeProvider);
329+
330+
$expectedValidUntil = gmdate(TimeProvider::TIMESTAMP_FORMAT, $fixedTime + $expirationTime);
331+
332+
$spXml = $renderer->fromServiceProviderEntity($this->buildSp(), 'default');
333+
$this->assertStringContainsString('validUntil="' . $expectedValidUntil . '"', $spXml);
334+
}
335+
336+
private function buildMetadataRenderer(
337+
string $addRequestedAttributes,
338+
int $metadataExpirationTime = 86400,
339+
?TimeProvider $timeProvider = null
340+
) {
300341
$basePath = realpath(__DIR__ . '/../../../../../');
301342

302343
$privateKey = new X509PrivateKey($basePath . '/tests/resources/key/engineblock.pem');
@@ -339,8 +380,9 @@ private function buildMetadataRenderer(string $addRequestedAttributes)
339380
$samlIdGenerator,
340381
$keyPairFactory,
341382
$documentSigner,
342-
new TimeProvider(),
343-
$addRequestedAttributes
383+
$timeProvider ?? new TimeProvider(),
384+
$addRequestedAttributes,
385+
$metadataExpirationTime
344386
);
345387
}
346388

0 commit comments

Comments
 (0)