-
-
Notifications
You must be signed in to change notification settings - Fork 366
Expand file tree
/
Copy pathHasUrlGenerator.php
More file actions
105 lines (90 loc) · 3.49 KB
/
HasUrlGenerator.php
File metadata and controls
105 lines (90 loc) · 3.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
<?php
/**
* SPDX-License-Identifier: MIT
* Copyright (c) 2017-2018 Tobias Reich
* Copyright (c) 2018-2025 LycheeOrg.
*/
namespace App\Models\Extensions;
use App\Enum\SizeVariantType;
use App\Exceptions\ConfigurationKeyMissingException;
use App\Models\Configs;
use Illuminate\Contracts\Encryption\EncryptException;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\URL;
use League\Flysystem\AwsS3V3\AwsS3V3Adapter;
trait HasUrlGenerator
{
/**
* Given a short, path, storage disk and size variant type, we return the URL formatted data.
*
* @throws \InvalidArgumentException
* @throws ConfigurationKeyMissingException
* @throws \RuntimeException
* @throws EncryptException
*/
public static function pathToUrl(string $short_path, string $storage_disk, SizeVariantType $type): string
{
if ($type === SizeVariantType::PLACEHOLDER) {
return 'data:image/webp;base64,' . $short_path;
}
$image_disk = Storage::disk($storage_disk);
/** @disregard P1013 */
$storage_adapter = $image_disk->getAdapter();
if ($storage_adapter instanceof AwsS3V3Adapter) {
// @codeCoverageIgnoreStart
return self::getAwsUrl($short_path, $storage_disk);
// @codeCoverageIgnoreEnd
}
// If we do not sign the URL or we do not use secure image links, we return the URL directly.
if (self::shouldNotUseSignedUrl() && !Configs::getValueAsBool('secure_image_link_enabled')) {
return $image_disk->url($short_path);
}
// We we use the secure image link, we encrypt the path.
if (Configs::getValueAsBool('secure_image_link_enabled')) {
$short_path = Crypt::encryptString($short_path);
}
// Return the url directly if we do not use signed URLs.
if (self::shouldNotUseSignedUrl()) {
return Url::route('image', ['path' => $short_path]);
}
$temporary_image_link_life_in_seconds = Configs::getValueAsInt('temporary_image_link_life_in_seconds');
/** @disregard P1013 */
return URL::temporarySignedRoute('image', now()->addSeconds($temporary_image_link_life_in_seconds), ['path' => $short_path], true);
}
/**
* Return true if :
* - image link protection is disabled
* - image link protection is enabled but the user is logged in (and protection is disabled for logged in users)
* - image link protection is enabled but the user is an admin
*
* @return bool
*/
protected static function shouldNotUseSignedUrl(): bool
{
return
!Configs::getValueAsBool('temporary_image_link_enabled') ||
(!Configs::getValueAsBool('temporary_image_link_when_logged_in') && Auth::user() !== null) ||
(!Configs::getValueAsBool('temporary_image_link_when_admin') && Auth::user()?->may_administrate === true);
}
/**
* Retrieve the tempary url from AWS if possible.
*
* @codeCoverageIgnore
*/
private static function getAwsUrl(string $short_path, string $storage_disk): string
{
// In order to allow a grace period, we create a new symbolic link,
$temporary_image_link_life_in_seconds = Configs::getValueAsInt('temporary_image_link_life_in_seconds');
$image_disk = Storage::disk($storage_disk);
// Return the public URL in case the S3 bucket is set to public, otherwise generate a temporary URL
$visibility = config('filesystems.disks.s3.visibility', 'private');
if ($visibility === 'public') {
/** @disregard P1013 */
return $image_disk->url($short_path);
}
/** @disregard P1013 */
return $image_disk->temporaryUrl($short_path, now()->addSeconds($temporary_image_link_life_in_seconds));
}
}