Skip to content

Commit a15b1ab

Browse files
committed
feat(symfony): prevent using temporary/expiring routes if not supported
1 parent 4d9b951 commit a15b1ab

File tree

4 files changed

+43
-7
lines changed

4 files changed

+43
-7
lines changed

src/Filesystem/Symfony/DependencyInjection/ZenstruckFilesystemExtension.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
use Symfony\Component\DependencyInjection\ServiceLocator;
2828
use Symfony\Component\HttpFoundation\UriSigner;
2929
use Symfony\Component\HttpKernel\DependencyInjection\ConfigurableExtension;
30+
use Symfony\Component\HttpKernel\Kernel;
3031
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
3132
use Symfony\Component\String\Slugger\SluggerInterface;
3233
use Symfony\Component\Validator\Validator\ValidatorInterface;
@@ -359,6 +360,10 @@ private function registerFilesystem(string $name, array $config, ContainerBuilde
359360
break;
360361

361362
case isset($config['temporary_url']['route']):
363+
if (Kernel::VERSION_ID < 70100) { // @phpstan-ignore smaller.alwaysFalse
364+
throw new LogicException('"temporary_url" requires Symfony 7.1 or higher.');
365+
}
366+
362367
$container->register($id = '.zenstruck_filesystem.filesystem_temporary_url.'.$name, RouteTemporaryUrlGenerator::class)
363368
->setArguments([
364369
new Reference('.zenstruck_filesystem.route_url_generator.locator'),

src/Filesystem/Symfony/Routing/RouteUrlGenerator.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Psr\Container\ContainerInterface;
1515
use Symfony\Component\HttpFoundation\UriSigner;
16+
use Symfony\Component\HttpKernel\Kernel;
1617
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
1718

1819
/**
@@ -63,6 +64,10 @@ final protected function generate(string $path, array $routeParameters, string|\
6364
$expires = new \DateTimeImmutable($expires);
6465
}
6566

67+
if ($expires && Kernel::VERSION_ID < 70100) { // @phpstan-ignore smaller.alwaysFalse, booleanAnd.alwaysFalse
68+
throw new \LogicException('Expiring URLs requires Symfony 7.1 or higher.');
69+
}
70+
6671
return $this->container->get(UriSigner::class)->sign($url, $expires);
6772
}
6873
}

tests/Filesystem/Symfony/ZenstruckFilesystemBundleTest.php

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Zenstruck\Tests\Filesystem\Symfony;
1313

1414
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
15+
use Symfony\Component\HttpKernel\Kernel;
1516
use Zenstruck\Filesystem\Node\Path\Expression;
1617
use Zenstruck\Filesystem\Test\InteractsWithFilesystem;
1718
use Zenstruck\Filesystem\Test\ResetFilesystem;
@@ -101,15 +102,29 @@ public function can_generate_urls(): void
101102
$privateFile = $this->filesystem()->write('private://bar/file.png', 'content')->ensureImage();
102103

103104
$this->assertStringContainsString('http://localhost/private/bar/file.png', $privateFile->publicUrl());
104-
$this->assertStringContainsString('http://localhost/private/bar/file.png', $privateFile->publicUrl(['expires' => 'tomorrow']));
105105
$this->assertSame('/glide/bar/file.png?w=100&h=200', $privateFile->transformUrl(['w' => 100, 'h' => 200]));
106106
}
107107

108108
/**
109109
* @test
110110
*/
111-
public function can_generate_signed_and_temporary_urls(): void
111+
public function can_generate_signed_urls(): void
112112
{
113+
$privateFile = $this->filesystem()->write('private://bar/file.png', 'content')->ensureImage();
114+
115+
$this->assertStringContainsString('_hash=', $privateFile->publicUrl());
116+
$this->assertStringNotContainsString('_expiration=', $privateFile->publicUrl());
117+
}
118+
119+
/**
120+
* @test
121+
*/
122+
public function can_generate_temporary_urls(): void
123+
{
124+
if (Kernel::VERSION_ID < 70100) {
125+
$this->markTestSkipped('Temporary URLs are not supported in Symfony < 7.1.');
126+
}
127+
113128
$publicFile = $this->filesystem()->write('public://foo/file.png', 'content')->ensureImage();
114129

115130
$this->assertStringContainsString('/temp/foo/file.png', $publicFile->temporaryUrl('tomorrow'));
@@ -118,15 +133,26 @@ public function can_generate_signed_and_temporary_urls(): void
118133

119134
$privateFile = $this->filesystem()->write('private://bar/file.png', 'content')->ensureImage();
120135

121-
$this->assertStringContainsString('_hash=', $privateFile->publicUrl());
122-
$this->assertStringNotContainsString('_expiration=', $privateFile->publicUrl());
123-
$this->assertStringContainsString('_hash=', $privateFile->publicUrl(['expires' => 'tomorrow']));
124-
$this->assertStringContainsString('_expiration=', $privateFile->publicUrl(['expires' => 'tomorrow']));
125136
$this->assertStringContainsString('/private/bar/file.png', $privateFile->temporaryUrl('tomorrow'));
126137
$this->assertStringContainsString('_hash=', $privateFile->temporaryUrl('tomorrow'));
127138
$this->assertStringContainsString('_expiration=', $privateFile->temporaryUrl('tomorrow'));
128139
}
129140

141+
/**
142+
* @test
143+
*/
144+
public function can_generate_expiring_public_urls(): void
145+
{
146+
if (Kernel::VERSION_ID < 70100) {
147+
$this->markTestSkipped('Expiring URLs are not supported in Symfony < 7.1.');
148+
}
149+
150+
$privateFile = $this->filesystem()->write('private://bar/file.png', 'content')->ensureImage();
151+
152+
$this->assertStringContainsString('_hash=', $privateFile->publicUrl(['expires' => 'tomorrow']));
153+
$this->assertStringContainsString('_expiration=', $privateFile->publicUrl(['expires' => 'tomorrow']));
154+
}
155+
130156
/**
131157
* @test
132158
*/

tests/Fixtures/TestKernel.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ protected function configureContainer(ContainerBuilder $c, LoaderInterface $load
122122
'prefix' => '/prefix',
123123
'version' => 'size',
124124
],
125-
'temporary_url' => 'route:public_temp',
125+
'temporary_url' => self::VERSION_ID < 70100 ? null : 'route:public_temp',
126126
'image_url' => 'route:public_transform',
127127
'reset_before_tests' => true,
128128
'events' => true,

0 commit comments

Comments
 (0)