-
Notifications
You must be signed in to change notification settings - Fork 243
Expand file tree
/
Copy pathLicensedPackageManifest.php
More file actions
130 lines (107 loc) · 3.87 KB
/
LicensedPackageManifest.php
File metadata and controls
130 lines (107 loc) · 3.87 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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
<?php
namespace ProcessMaker;
use Illuminate\Foundation\PackageManifest;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use ProcessMaker\Providers\ProcessMakerServiceProvider;
use Spatie\Multitenancy\MultitenancyServiceProvider;
use Throwable;
class LicensedPackageManifest extends PackageManifest
{
const EXPIRE_CACHE_KEY = 'license_expires_at';
const DISCOVER_PACKAGES_LOCK_KEY = 'discover_package_lock_key';
const DISCOVER_PACKAGES = 'package:discover';
const LAST_PACKAGE_DISCOVERY = 0;
protected function packagesToIgnore()
{
$packagesToIgnore = $this->loadPackagesToIgnore()->all();
return [...parent::packagesToIgnore(), ...$packagesToIgnore];
}
public function loadPackagesToIgnore()
{
if (!$this->hasLicenseFile()) {
return collect([]); // Allow all packages
}
$this->setExpireCache();
$licensedPackages = $this->licensedPackages();
return $this->allPackages()
->reject(fn ($package) => $licensedPackages->contains($package))
->values();
}
public function list()
{
return array_keys($this->getManifest());
}
private function parseLicense()
{
if (!$this->hasLicenseFile()) {
return null;
}
$license = Storage::disk('local')->get('license.json');
return json_decode($license, true);
}
private function licensedPackages()
{
$default = collect(['packages', 'package-api-testing']);
$data = $this->parseLicense();
$expires = Carbon::parse($data['expires_at']);
if ($expires->isPast()) {
$packages = $default;
} else {
$packages = $default->concat($data['packages']);
}
return $packages->map(fn ($k) => "processmaker/{$k}");
}
private function hasLicenseFile()
{
return Storage::disk('local')->exists('license.json');
}
private function setExpireCache()
{
if ($data = $this->parseLicense()) {
$expires = Carbon::parse($data['expires_at']);
if ($expires->isPast()) {
Cache::forget(self::EXPIRE_CACHE_KEY);
} else {
Cache::forever(self::EXPIRE_CACHE_KEY, $expires->timestamp);
}
} else {
Cache::forget(self::EXPIRE_CACHE_KEY);
}
}
private function allPackages()
{
$composer = json_decode(file_get_contents(base_path('composer.json')), true);
// Add enterprise packages
$packages = $composer['extra']['processmaker']['enterprise'];
// Add custom packages
$packages = array_merge($packages, $composer['extra']['processmaker']['custom']);
// Add docker-executors packages
$packages = array_merge($packages, $composer['extra']['processmaker']['docker-executors']);
return collect($packages)
->map(fn ($k, $v) => "processmaker/{$v}")
->values();
}
/**
* Discovers packages ensuring there's no overlapping or concurrent executions of package:discover.
*
* @param int $lockDurationSeconds The duration in minutes to consider the lock file as valid.
* @return void
*/
public static function discoverPackagesOnce(int $lockDurationSeconds = 60): void
{
$lock = Cache::lock(self::DISCOVER_PACKAGES_LOCK_KEY, $lockDurationSeconds);
if ($lock->get()) {
try {
Artisan::call(self::DISCOVER_PACKAGES);
Cache::put(self::LAST_PACKAGE_DISCOVERY, Carbon::now()->timestamp);
} catch (Throwable $e) {
Log::error('LicenseService - Error during package discovery: ' . $e->getMessage());
}
$lock->release();
}
}
}