PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.5.1
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.5.1
1.6.5 1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.5.4 1.5.5 1.5.3 1.5.2 1.5.1 1.5.0 1.4.2 1.4.1 1.4.0 1.3.28 1.3.27 1.3.26 1.3.25 1.3.23 1.3.22 1.3.21 1.3.20 1.3.19 trunk All 48 releases
fluent-cart / app / Services / FileSystem / Drivers / S3 / S3BucketList.php

S3BucketList.php in FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler 1.5.1, at app/Services/FileSystem/Drivers/S3/S3BucketList.php

187 lines 5.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentCart\App\Services\FileSystem\Drivers\S3;
4
5 use FluentCart\Framework\Support\Arr;
6
7 class S3BucketList
8 {
9 private string $accessKey;
10 private string $secretKey;
11 private string $region;
12 private string $hashAlgorithm = 'sha256';
13 private string $httpMethod;
14 private string $signature;
15 private $timeStamp;
16 private $date;
17 private string $requestUrl;
18 private ?string $sessionToken = null;
19
20
21 public static function get(string $secret, string $accessKey, string $region, ?string $sessionToken = null)
22 {
23 $validation = S3InputValidator::validateRegion($region);
24 if (is_wp_error($validation)) {
25 return $validation;
26 }
27
28 return (new static($secret, $accessKey, $region, $sessionToken))->getList();
29 }
30
31 public function __construct(string $secret, string $accessKey, string $region, ?string $sessionToken = null)
32 {
33 $this->secretKey = $secret;
34 $this->accessKey = $accessKey;
35 $this->region = $region;
36 $this->sessionToken = $sessionToken;
37
38 $this->httpMethod = "GET";
39 $this->timeStamp = gmdate('Ymd\THis\Z');
40 $this->date = substr($this->timeStamp, 0, 8);
41 if ($region !== 'us-east-1' && $region) {
42 $this->requestUrl = "https://s3.{$region}.amazonaws.com";
43 } else {
44 $this->requestUrl = "https://s3.amazonaws.com";
45 }
46
47 $this->generateSignature();
48 }
49
50 public function getList()
51 {
52 add_filter('http_request_timeout', function () {
53 return 30; // Set the timeout to 30 seconds (or adjust as needed)
54 });
55
56 $response = wp_remote_request($this->requestUrl, [
57 'method' => $this->httpMethod,
58 'headers' => $this->getHeaders()
59 ]);
60
61 if (is_wp_error($response)) {
62 return $response;
63 }
64
65 $responseCode = wp_remote_retrieve_response_code($response);
66
67 if ($responseCode == '200') {
68 return $this->parseResponseXml($response);
69 } else {
70 return new \WP_Error(
71 $responseCode,
72 __('Invalid Credential', 'fluent-cart')
73 );
74 }
75 }
76
77 private function parseResponseXml($response): array
78 {
79 $xml = simplexml_load_string(wp_remote_retrieve_body($response));
80 $array = json_decode(json_encode($xml), TRUE);
81
82 $responseBucket = Arr::get($array, 'Buckets.Bucket', []);
83
84 if(Arr::has($responseBucket,'Name')){
85 return [
86 Arr::get($responseBucket, 'Name')
87 ];
88 }
89
90 $buckets = [];
91 foreach ($responseBucket as $bucket) {
92 $buckets[] = Arr::get($bucket, 'Name');
93 }
94 return $buckets;
95 }
96
97 public function getSignature(): string
98 {
99 return $this->signature;
100 }
101
102 public function generateSignature()
103 {
104 $this->signature = $this->generateSignatureKey();
105 }
106
107 private function createScope(): string
108 {
109 return "{$this->date}/{$this->region}/s3/aws4_request";
110 }
111
112 private function getContentHash(): string
113 {
114 return hash($this->hashAlgorithm, "");
115 }
116
117 private function createCanonicalUrl(): string
118 {
119 $payload = "$this->httpMethod\n" .
120 "/\n\n" .
121 "host:{$this->getHost()}\n" .
122 "x-amz-content-sha256:{$this->getContentHash()}\n" .
123 "x-amz-date:{$this->timeStamp}\n";
124
125 if ($this->sessionToken) {
126 $payload .= "x-amz-security-token:{$this->sessionToken}\n";
127 }
128
129 $payload .= "\n";
130
131 $signedHeaders = "host;x-amz-content-sha256;x-amz-date";
132 if ($this->sessionToken) {
133 $signedHeaders .= ";x-amz-security-token";
134 }
135
136 $payload .= $signedHeaders . "\n" .
137 "{$this->getContentHash()}";
138
139 return $payload;
140 }
141
142 private function getHost(): string
143 {
144 return parse_url($this->requestUrl, PHP_URL_HOST) ?: "s3.amazonaws.com";
145 }
146
147 private function createStringToSign(): string
148 {
149 $hash = hash($this->hashAlgorithm, $this->createCanonicalUrl());
150 return "AWS4-HMAC-SHA256\n{$this->timeStamp}\n{$this->createScope()}\n{$hash}";
151 }
152
153 private function getSigningKey()
154 {
155 $dateKey = hash_hmac($this->hashAlgorithm, $this->date, "AWS4{$this->secretKey}", true);
156 $regionKey = hash_hmac($this->hashAlgorithm, $this->region, $dateKey, true);
157 $serviceKey = hash_hmac($this->hashAlgorithm, 's3', $regionKey, true);
158 return hash_hmac($this->hashAlgorithm, 'aws4_request', $serviceKey, true);
159 }
160
161 private function generateSignatureKey()
162 {
163 return hash_hmac($this->hashAlgorithm, $this->createStringToSign(), $this->getSigningKey());
164 }
165
166 public function getHeaders(): array
167 {
168 $headers = [
169 "x-amz-content-sha256" => $this->getContentHash(),
170 'x-amz-date' => $this->timeStamp,
171 ];
172
173 if ($this->sessionToken) {
174 $headers['x-amz-security-token'] = $this->sessionToken;
175 }
176
177 $signedHeaders = "host;x-amz-content-sha256;x-amz-date";
178 if ($this->sessionToken) {
179 $signedHeaders .= ";x-amz-security-token";
180 }
181
182 $headers['Authorization'] = "AWS4-HMAC-SHA256 Credential={$this->accessKey}/{$this->date}/{$this->region}/s3/aws4_request, SignedHeaders={$signedHeaders}, Signature={$this->getSignature()}";
183
184 return $headers;
185 }
186 }
187