PluginProbe
Media Cloud Sync / 1.4.1
Media Cloud Sync v1.4.1
1.4.1 1.4.0 1.3.12 1.3.11 1.3.10 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.2.0 1.2.10 1.2.11 1.2.12 1.2.13 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 All 35 releases
media-cloud-sync / includes / sdk / s3 / Aws / EndpointV2 / Ruleset / RulesetStandardLibrary.php

RulesetStandardLibrary.php in Media Cloud Sync 1.4.1, at includes/sdk/s3/Aws/EndpointV2/Ruleset/RulesetStandardLibrary.php

343 lines 12.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Dudlewebs\WPMCS\s3\Aws\EndpointV2\Ruleset;
4
5 use Dudlewebs\WPMCS\s3\Aws\Exception\UnresolvedEndpointException;
6 /**
7 * Provides functions and actions to be performed for endpoint evaluation.
8 * This is an internal only class and is not subject to backwards-compatibility guarantees.
9 *
10 * @internal
11 */
12 class RulesetStandardLibrary
13 {
14 const IPV4_RE = '/^(?:[0-9]{1,3}\\.){3}[0-9]{1,3}$/';
15 const IPV6_RE = '/([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|
16 . ([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]
17 . {1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:)
18 . {1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|
19 . [0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:
20 . (:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|
21 . 1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]
22 . {1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]
23 . |1{0,1}[0-9]){0,1}[0-9])/';
24 const TEMPLATE_ESCAPE_RE = '/{\\{\\s*(.*?)\\s*\\}\\}/';
25 const TEMPLATE_SEARCH_RE = '/\\{[a-zA-Z#]+\\}/';
26 const TEMPLATE_PARSE_RE = '#\\{((?>[^\\{\\}]+)|(?R))*\\}#x';
27 const HOST_LABEL_RE = '/^(?!-)[a-zA-Z\\d-]{1,63}(?<!-)$/';
28 private $partitions;
29 public function __construct($partitions)
30 {
31 $this->partitions = $partitions;
32 }
33 /**
34 * Determines if a value is set.
35 *
36 * @return boolean
37 */
38 public function is_set($value)
39 {
40 return isset($value);
41 }
42 /**
43 * Function implementation of logical operator `not`
44 *
45 * @return boolean
46 */
47 public function not($value)
48 {
49 return !$value;
50 }
51 /**
52 * Find an attribute within a value given a path string.
53 *
54 * @return mixed
55 */
56 public function getAttr($from, $path)
57 {
58 // Handles the case where "[<int|string]" is provided as the top-level path
59 if (\preg_match('/^\\[(\\w+)\\]$/', $path, $matches)) {
60 $index = \is_numeric($matches[1]) ? (int) $matches[1] : $matches[1];
61 return $from[$index] ?? null;
62 }
63 $parts = \explode('.', $path);
64 foreach ($parts as $part) {
65 $sliceIdx = \strpos($part, '[');
66 if ($sliceIdx !== \false) {
67 if (\substr($part, -1) !== ']') {
68 return null;
69 }
70 $slice = (int) \substr($part, $sliceIdx + 1, \strlen($part) - 1);
71 $fromIndex = \substr($part, 0, $sliceIdx);
72 $from = $from[$fromIndex][$slice] ?? null;
73 } else {
74 $from = $from[$part];
75 }
76 }
77 return $from;
78 }
79 /**
80 * Computes a substring given the start index and end index. If `reverse` is
81 * true, slice the string from the end instead.
82 *
83 * @return mixed
84 */
85 public function substring($input, $start, $stop, $reverse)
86 {
87 if (!\is_string($input)) {
88 throw new UnresolvedEndpointException('Input passed to `substring` must be `string`.');
89 }
90 if (\preg_match('/[^\\x00-\\x7F]/', $input)) {
91 return null;
92 }
93 if ($start >= $stop or \strlen($input) < $stop) {
94 return null;
95 }
96 if (!$reverse) {
97 return \substr($input, $start, $stop - $start);
98 } else {
99 $offset = \strlen($input) - $stop;
100 $length = $stop - $start;
101 return \substr($input, $offset, $length);
102 }
103 }
104 /**
105 * Evaluates two strings for equality.
106 *
107 * @return boolean
108 */
109 public function stringEquals($string1, $string2)
110 {
111 if (!\is_string($string1) || !\is_string($string2)) {
112 throw new UnresolvedEndpointException('Values passed to StringEquals must be `string`.');
113 }
114 return $string1 === $string2;
115 }
116 /**
117 * Evaluates two booleans for equality.
118 *
119 * @return boolean
120 */
121 public function booleanEquals($boolean1, $boolean2)
122 {
123 return \filter_var($boolean1, \FILTER_VALIDATE_BOOLEAN) === \filter_var($boolean2, \FILTER_VALIDATE_BOOLEAN);
124 }
125 /**
126 * Percent-encodes an input string.
127 *
128 * @return mixed
129 */
130 public function uriEncode($input)
131 {
132 if (\is_null($input)) {
133 return null;
134 }
135 return \str_replace('%7E', '~', \rawurlencode($input));
136 }
137 /**
138 * Parses URL string into components.
139 *
140 * @return mixed
141 */
142 public function parseUrl($url)
143 {
144 if (\is_null($url)) {
145 return null;
146 }
147 $parsed = \parse_url($url);
148 if ($parsed === \false || !empty($parsed['query'])) {
149 return null;
150 } elseif (!isset($parsed['scheme'])) {
151 return null;
152 }
153 if ($parsed['scheme'] !== 'http' && $parsed['scheme'] !== 'https') {
154 return null;
155 }
156 $urlInfo = [];
157 $urlInfo['scheme'] = $parsed['scheme'];
158 $urlInfo['authority'] = isset($parsed['host']) ? $parsed['host'] : '';
159 if (isset($parsed['port'])) {
160 $urlInfo['authority'] = $urlInfo['authority'] . ":" . $parsed['port'];
161 }
162 $urlInfo['path'] = isset($parsed['path']) ? $parsed['path'] : '';
163 $urlInfo['normalizedPath'] = !empty($parsed['path']) ? \rtrim($urlInfo['path'] ?: '', '/' . "/") . '/' : '/';
164 $urlInfo['isIp'] = !isset($parsed['host']) ? 'false' : $this->isValidIp($parsed['host']);
165 return $urlInfo;
166 }
167 /**
168 * Evaluates whether a value is a valid host label per
169 * RFC 1123. If allow_subdomains is true, split on `.` and validate
170 * each subdomain separately.
171 *
172 * @return boolean
173 */
174 public function isValidHostLabel($hostLabel, $allowSubDomains)
175 {
176 if (!isset($hostLabel) || !$allowSubDomains && \strpos($hostLabel, '.') != \false) {
177 return \false;
178 }
179 if ($allowSubDomains) {
180 foreach (\explode('.', $hostLabel) as $subdomain) {
181 if (!$this->validateHostLabel($subdomain)) {
182 return \false;
183 }
184 }
185 return \true;
186 } else {
187 return $this->validateHostLabel($hostLabel);
188 }
189 }
190 /**
191 * Parse and validate string for ARN components.
192 *
193 * @return array|null
194 */
195 public function parseArn($arnString)
196 {
197 if (\is_null($arnString) || \substr($arnString, 0, 3) !== "arn") {
198 return null;
199 }
200 $arn = [];
201 $parts = \explode(':', $arnString, 6);
202 if (\sizeof($parts) < 6) {
203 return null;
204 }
205 $arn['partition'] = isset($parts[1]) ? $parts[1] : null;
206 $arn['service'] = isset($parts[2]) ? $parts[2] : null;
207 $arn['region'] = isset($parts[3]) ? $parts[3] : null;
208 $arn['accountId'] = isset($parts[4]) ? $parts[4] : null;
209 $arn['resourceId'] = isset($parts[5]) ? $parts[5] : null;
210 if (empty($arn['partition']) || empty($arn['service']) || empty($arn['resourceId'])) {
211 return null;
212 }
213 $resource = $arn['resourceId'];
214 $arn['resourceId'] = \preg_split("/[:\\/]/", $resource);
215 return $arn;
216 }
217 /**
218 * Matches a region string to an AWS partition.
219 *
220 * @return mixed
221 */
222 public function partition($region)
223 {
224 if (!\is_string($region)) {
225 throw new UnresolvedEndpointException('Value passed to `partition` must be `string`.');
226 }
227 $partitions = $this->partitions;
228 foreach ($partitions['partitions'] as $partition) {
229 if (\array_key_exists($region, $partition['regions']) || \preg_match("/{$partition['regionRegex']}/", $region)) {
230 return $partition['outputs'];
231 }
232 }
233 //return `aws` partition if no match is found.
234 return $partitions['partitions'][0]['outputs'];
235 }
236 /**
237 * Evaluates whether a value is a valid bucket name for virtual host
238 * style bucket URLs.
239 *
240 * @return boolean
241 */
242 public function isVirtualHostableS3Bucket($bucketName, $allowSubdomains)
243 {
244 if (\is_null($bucketName) || (\strlen($bucketName) < 3 || \strlen($bucketName) > 63) || \preg_match(self::IPV4_RE, $bucketName) || \strtolower($bucketName) !== $bucketName) {
245 return \false;
246 }
247 if ($allowSubdomains) {
248 $labels = \explode('.', $bucketName);
249 $results = [];
250 foreach ($labels as $label) {
251 $results[] = $this->isVirtualHostableS3Bucket($label, \false);
252 }
253 return !\in_array(\false, $results);
254 }
255 return $this->isValidHostLabel($bucketName, \false);
256 }
257 public function callFunction($funcCondition, &$inputParameters)
258 {
259 $funcArgs = [];
260 foreach ($funcCondition['argv'] as $arg) {
261 $funcArgs[] = $this->resolveValue($arg, $inputParameters);
262 }
263 $funcName = \str_replace('aws.', '', $funcCondition['fn']);
264 if ($funcName === 'isSet') {
265 $funcName = 'is_set';
266 }
267 $result = \call_user_func_array([RulesetStandardLibrary::class, $funcName], $funcArgs);
268 if (isset($funcCondition['assign'])) {
269 $assign = $funcCondition['assign'];
270 if (isset($inputParameters[$assign])) {
271 throw new UnresolvedEndpointException("Assignment `{$assign}` already exists in input parameters" . " or has already been assigned by an endpoint rule and cannot be overwritten.");
272 }
273 $inputParameters[$assign] = $result;
274 }
275 return $result;
276 }
277 public function resolveValue($value, $inputParameters)
278 {
279 //Given a value, check if it's a function, reference or template.
280 //returns resolved value
281 if ($this->isFunc($value)) {
282 return $this->callFunction($value, $inputParameters);
283 } elseif ($this->isRef($value)) {
284 return isset($inputParameters[$value['ref']]) ? $inputParameters[$value['ref']] : null;
285 } elseif ($this->isTemplate($value)) {
286 return $this->resolveTemplateString($value, $inputParameters);
287 }
288 return $value;
289 }
290 public function isFunc($arg)
291 {
292 return \is_array($arg) && isset($arg['fn']);
293 }
294 public function isRef($arg)
295 {
296 return \is_array($arg) && isset($arg['ref']);
297 }
298 public function isTemplate($arg)
299 {
300 return \is_string($arg) && !empty(\preg_match(self::TEMPLATE_SEARCH_RE, $arg));
301 }
302 public function resolveTemplateString($value, $inputParameters)
303 {
304 return \preg_replace_callback(self::TEMPLATE_PARSE_RE, function ($match) use($inputParameters) {
305 if (\preg_match(self::TEMPLATE_ESCAPE_RE, $match[0])) {
306 return $match[1];
307 }
308 $notFoundMessage = 'Resolved value was null. Please check rules and ' . 'input parameters and try again.';
309 $parts = \explode("#", $match[1]);
310 if (\count($parts) > 1) {
311 $resolvedValue = $inputParameters;
312 foreach ($parts as $part) {
313 if (!isset($resolvedValue[$part])) {
314 throw new UnresolvedEndpointException($notFoundMessage);
315 }
316 $resolvedValue = $resolvedValue[$part];
317 }
318 return $resolvedValue;
319 } else {
320 if (!isset($inputParameters[$parts[0]])) {
321 throw new UnresolvedEndpointException($notFoundMessage);
322 }
323 return $inputParameters[$parts[0]];
324 }
325 }, $value);
326 }
327 private function validateHostLabel($hostLabel)
328 {
329 if (empty($hostLabel) || \strlen($hostLabel) > 63) {
330 return \false;
331 }
332 if (\preg_match(self::HOST_LABEL_RE, $hostLabel)) {
333 return \true;
334 }
335 return \false;
336 }
337 private function isValidIp($hostName)
338 {
339 $isWrapped = \strpos($hostName, '[') === 0 && \strrpos($hostName, ']') === \strlen($hostName) - 1;
340 return \preg_match(self::IPV4_RE, $hostName) || $isWrapped && \preg_match(self::IPV6_RE, $hostName) ? 'true' : 'false';
341 }
342 }
343