From f1239150ca8ba7c34b98718901fa5aa4b8bd6cdf Mon Sep 17 00:00:00 2001 From: Paul-joseph Krogulec Date: Tue, 11 Apr 2023 09:58:56 +0200 Subject: [PATCH] feat: use DateTimeInterface in sign constructor --- CHANGELOG.md | 4 ++ DependencyInjection/Compiler/SignerPass.php | 2 +- README.md | 12 ++++- UrlSigner/AbstractUrlSigner.php | 8 +-- UrlSigner/UrlSignerInterface.php | 2 +- features/app/config/packages/url_signer.yaml | 1 + .../Compiler/SignerPassTest.php | 2 +- tests/UrlSigner/AbstractUrlSignerTest.php | 51 +++++++++++++------ 8 files changed, 58 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2170b76..87d9dee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## 2.2.0 + +* Allow to use a date/time string in default expiration time configuration + ## 2.1.0 * Minor **BC break**: use the new classes from `spatie/url-signer` 2.1.0 (`DateTimeInterface` instead of `DateTime` in `sign`) diff --git a/DependencyInjection/Compiler/SignerPass.php b/DependencyInjection/Compiler/SignerPass.php index 8c599cf..ddee161 100644 --- a/DependencyInjection/Compiler/SignerPass.php +++ b/DependencyInjection/Compiler/SignerPass.php @@ -54,7 +54,7 @@ private function getSigners(ContainerBuilder $container): array $signerServiceDefinition = $container->getDefinition($signerServiceId); $signerServiceDefinition->setBindings([ 'string $signatureKey' => '%url_signer.signature_key%', - 'int $defaultExpiration' => '%url_signer.default_expiration%', + '$defaultExpiration' => '%url_signer.default_expiration%', 'string $expiresParameter' => '%url_signer.expires_parameter%', 'string $signatureParameter' => '%url_signer.signature_parameter%', ]); diff --git a/README.md b/README.md index 8731b3e..5ef6033 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,9 @@ coop_tilleuls_url_signer: signer: 'md5' # 'sha256' by default ``` -The default expiration time (in seconds) can be changed too: +The default expiration time can be changed too. + +In seconds: ```yml # config/packages/url_signer.yaml @@ -70,6 +72,14 @@ coop_tilleuls_url_signer: default_expiration: 3600 # 86400 by default ``` +With a date/time string: + +```yml +# config/packages/url_signer.yaml +coop_tilleuls_url_signer: + default_expiration: '1 day' +``` + You can also customize the URL parameter names: ```yml diff --git a/UrlSigner/AbstractUrlSigner.php b/UrlSigner/AbstractUrlSigner.php index 11281a3..c6cfc23 100644 --- a/UrlSigner/AbstractUrlSigner.php +++ b/UrlSigner/AbstractUrlSigner.php @@ -17,16 +17,16 @@ abstract class AbstractUrlSigner extends SpatieAbstractUrlSigner implements UrlSignerInterface { - private int $defaultExpiration; + private \DateTimeInterface|int $defaultExpiration; - public function __construct(string $signatureKey, int $defaultExpiration, string $expiresParameter, string $signatureParameter) + public function __construct(string $signatureKey, int|string $defaultExpiration, string $expiresParameter, string $signatureParameter) { parent::__construct($signatureKey, $expiresParameter, $signatureParameter); - $this->defaultExpiration = $defaultExpiration; + $this->defaultExpiration = \is_string($defaultExpiration) ? new \DateTimeImmutable($defaultExpiration) : $defaultExpiration; } - public function sign(string $url, int|\DateTimeInterface $expiration = null, string $signatureKey = null): string + public function sign(string $url, \DateTimeInterface|int $expiration = null, string $signatureKey = null): string { return parent::sign($url, $expiration ?? $this->defaultExpiration, $signatureKey); } diff --git a/UrlSigner/UrlSignerInterface.php b/UrlSigner/UrlSignerInterface.php index 0e82177..84065ef 100644 --- a/UrlSigner/UrlSignerInterface.php +++ b/UrlSigner/UrlSignerInterface.php @@ -17,7 +17,7 @@ interface UrlSignerInterface extends UrlSigner { - public function sign(string $url, int|\DateTimeInterface $expiration, string $signatureKey = null): string; + public function sign(string $url, \DateTimeInterface|int $expiration, string $signatureKey = null): string; public static function getName(): string; } diff --git a/features/app/config/packages/url_signer.yaml b/features/app/config/packages/url_signer.yaml index 8282935..8b61f10 100644 --- a/features/app/config/packages/url_signer.yaml +++ b/features/app/config/packages/url_signer.yaml @@ -1,2 +1,3 @@ coop_tilleuls_url_signer: signature_key: '%env(string:SIGNATURE_KEY)%' + default_expiration: '2 days' diff --git a/tests/DependencyInjection/Compiler/SignerPassTest.php b/tests/DependencyInjection/Compiler/SignerPassTest.php index 929da33..db6436c 100644 --- a/tests/DependencyInjection/Compiler/SignerPassTest.php +++ b/tests/DependencyInjection/Compiler/SignerPassTest.php @@ -53,7 +53,7 @@ public function testProcess(): void ]); $bindings = [ 'string $signatureKey' => '%url_signer.signature_key%', - 'int $defaultExpiration' => '%url_signer.default_expiration%', + '$defaultExpiration' => '%url_signer.default_expiration%', 'string $expiresParameter' => '%url_signer.expires_parameter%', 'string $signatureParameter' => '%url_signer.signature_parameter%', ]; diff --git a/tests/UrlSigner/AbstractUrlSignerTest.php b/tests/UrlSigner/AbstractUrlSignerTest.php index bb09d99..aff3d06 100644 --- a/tests/UrlSigner/AbstractUrlSignerTest.php +++ b/tests/UrlSigner/AbstractUrlSignerTest.php @@ -24,25 +24,12 @@ final class AbstractUrlSignerTest extends TestCase { private AbstractUrlSigner $signer; + private AbstractUrlSigner $signerDateTime; protected function setUp(): void { - $this->signer = new class('secret', 5, 'exp', 'sign') extends AbstractUrlSigner { - public static function getName(): string - { - return 'abstract'; - } - - protected function createSignature(string $url, string $expiration, string $signatureKey): string - { - return "{$url}::{$expiration}::{$signatureKey}"; - } - - protected function getExpirationTimestamp(int|\DateTimeInterface $expirationInSeconds): string - { - return $expirationInSeconds instanceof \DateTimeInterface ? 'datetime' : (string) $expirationInSeconds; - } - }; + $this->signer = new Signer('secret', 5, 'exp', 'sign'); + $this->signerDateTime = new Signer('secret', '2023-09-14', 'exp', 'sign'); } public function testSignDefaultExpiration(): void @@ -58,4 +45,36 @@ public function testSignWithExpiration(): void self::assertSame('http://test.org/valid-signature?exp=7&sign=http%3A%2F%2Ftest.org%2Fvalid-signature%3A%3A7%3A%3Asecret', $signedUrl); } + + public function testSignDefaultExpirationWithDateTime(): void + { + $signedUrl = $this->signerDateTime->sign('http://test.org/valid-signature'); + + self::assertSame('http://test.org/valid-signature?exp=1694649600&sign=http%3A%2F%2Ftest.org%2Fvalid-signature%3A%3A1694649600%3A%3Asecret', $signedUrl); + } + + public function testSignWithExpirationWithDateTime(): void + { + $signedUrl = $this->signerDateTime->sign('http://test.org/valid-signature', 7); + + self::assertSame('http://test.org/valid-signature?exp=7&sign=http%3A%2F%2Ftest.org%2Fvalid-signature%3A%3A7%3A%3Asecret', $signedUrl); + } +} + +final class Signer extends AbstractUrlSigner +{ + public static function getName(): string + { + return 'abstract'; + } + + protected function createSignature(string $url, string $expiration, string $signatureKey): string + { + return "{$url}::{$expiration}::{$signatureKey}"; + } + + protected function getExpirationTimestamp(\DateTimeInterface|int $expirationInSeconds): string + { + return (string) ($expirationInSeconds instanceof \DateTimeInterface ? $expirationInSeconds->getTimestamp() : $expirationInSeconds); + } }