$linksOutput = [];
preg_match_all("/\<a.*href\=(\'|\")(.*?)(\'|\").*?\>/i", $htmlContent, $linksOutput);
- // Replace image src with base64 encoded image strings
+ // Update relative links to be absolute, with instance url
if (isset($linksOutput[0]) && count($linksOutput[0]) > 0) {
foreach ($linksOutput[0] as $index => $linkMatch) {
$oldLinkString = $linkMatch;
}
}
- // Replace any relative links with system domain
return $htmlContent;
}
}
$storagePath = $this->adjustPathForStorageDisk($storagePath);
+
+ // Apply access control when local_secure_restricted images are active
+ if ($this->usingSecureRestrictedImages()) {
+ if (!$this->checkUserHasAccessToRelationOfImageAtPath($storagePath)) {
+ return null;
+ }
+ }
+
$storage = $this->getStorageDisk();
$imageData = null;
if ($storage->exists($storagePath)) {
*/
protected function checkUserHasAccessToRelationOfImageAtPath(string $path): bool
{
+ if (strpos($path, '/uploads/images/') === 0) {
+ $path = substr($path, 15);
+ }
+
// Strip thumbnail element from path if existing
$originalPathSplit = array_filter(explode('/', $path), function(string $part) {
$resizedDir = (strpos($part, 'thumbs-') === 0 || strpos($part, 'scaled-') === 0);
}
}
+ public function test_secure_restricted_image_access_controlled_in_exports()
+ {
+ config()->set('filesystems.images', 'local_secure_restricted');
+ $this->asEditor();
+ $galleryFile = $this->getTestImage('my-secure-restricted-export-test.png');
+
+ /** @var Page $pageA */
+ /** @var Page $pageB */
+ $pageA = Page::query()->first();
+ $pageB = Page::query()->where('id', '!=', $pageA->id)->first();
+ $expectedPath = storage_path('uploads/images/gallery/' . date('Y-m') . '/my-secure-restricted-export-test.png');
+
+ $upload = $this->asEditor()->call('POST', '/images/gallery', ['uploaded_to' => $pageA->id], [], ['file' => $galleryFile], []);
+ $upload->assertOk();
+
+ $imageUrl = json_decode($upload->getContent(), true)['url'];
+ $pageB->html .= "<img src=\"{$imageUrl}\">";
+ $pageB->save();
+
+ $encodedImageContent = base64_encode(file_get_contents($expectedPath));
+ $export = $this->get($pageB->getUrl('/export/html'));
+ $this->assertStringContainsString($encodedImageContent, $export->getContent());
+
+ $this->setEntityRestrictions($pageA, [], []);
+
+ $export = $this->get($pageB->getUrl('/export/html'));
+ $this->assertStringNotContainsString($encodedImageContent, $export->getContent());
+
+ if (file_exists($expectedPath)) {
+ unlink($expectedPath);
+ }
+ }
+
public function test_image_delete()
{
$page = Page::query()->first();