ÿØÿà JFIF    ÿÛ „  ( %!1"%)+...383-7(-.+  -%%--------+------------/----------------------------ÿÀ  ¶" ÿÄ     ÿÄ @    !1AQaq‘¡"±ÁÑð2’BRráS‚ñ3b¢CT²Ò #cÿÄ    ÿÄ '   1!AQ2a"‘±#ÿÚ   ? ò(/p‘—–¢·,M|¯G»R£üešT. ôŸEoCFñ‡ 4ÔkåóxR|µÁ¨ÓDà!Ç´µ˜‡p ÍQ‹§!þž^õWsŒy  åÁ§$á«%ºq˜™JyyË0y«^Ϗ -3ÃÏËÈ£Æ\P’ä„s&•‹Üs üô'àWt¹pñCp$bÚF`·7.^)¾!)ÒÙ˜–ÅÏš^h¾ø³·ìe±ŒaeÖ—Í,e=B}Jéߦ$$½—šÙÜCC¯¶è8β–Åkèwx LÉngT±æ¹£Ócœ¿Í/©Éÿ ‰ÚCÒ­mq;Tt¶–}0"zÖPcd1š­¤tˆ„ÐÓâqú[™öUCŠ2޿د­É(¸ßúçšmW,Ò ºf‹Ån™ÄLêÁ8üÁkÁ€L¥ÍuJ1œôrÂSŒÓöt!7EUíïb)AËi¬â-ÙHk8òÁiXYwÅ)O^"ÇØriÛô{»wRUKÙÏÚlÓ¬€‚’שT ] ªb—ÊîKC^×M“xùäñz¬zJ× {4[¹M'IÆeH1LCWÕ]œûº WDæà°OÅ‚¹c²ÞuA–rL`HšpCez‡V’— Ž‚Ë„–ñ­'µR0ÕÖ=À:±G»C\nÆÉ5*¢ †3šhQ4ýÒi$Õ1"Ü]¢p-q3zcQ$ªö¨¥æf›‘»´ÝÚHá„e²JÇ–iÊ:·à¬Øc5Åk»Laª*wi [0Ówk ¦a¦0Õ²ÅÅ‚T¸’³q:Æ<¹ú Ò˜Æ}2VE•Ѐp¡Ô3Úº …h³^LJºçì¥Ánó|˜ÖˆÎˆ+« ¦dø‘Mº–d\ªDðÛ„Ì×LÝ——Ð9Ç|•FèçVm™¨€™3õS–9Äå¢<̉Ìm¢±`·º˜&Z²ž Ë®D«¶»6™‰©­HÈ Àá«h­i³04æ’hxœi3ï¨(ÓL·†‹¶ËpŒ ƒÜÒ? :õdsÀ –3æÓ·Üjâ¬9—]8n¼&]I F£¼…ì–—Œ0v°LǐÅfÛ2TÖ’aµ˜N@ÖBSÏ^à´4-±°b×nÈÈœÆD=KdŒø…ÄÈK,›ÖR§fjü$^ÔÎ!„6^ s:Üun\ôkCÞò÷<—Lúl Í›G¹ÀPá¼Nc¡šÒ…ÙWͳœ±vÊáЄ×9‹P‰cEØ‘™›µŸP<×g1 º©Ø¬wiÁ^l5× I/';Ë+´Z‡ÓÄFÕp[Èð’ HÄ ó 9¬Dl4“é±Ï”V=^Hð;žLädÉa‚°Ë,#/Ž~²BÔÛ QãñQtIeórVB,ÏÂf‹4#Μc‹É3ZIÖ Œ¢¥·üxa‡Ãçè„jŠ[5 Ä!U?,3žÎ×…ðdÓ÷háŠA‰ìÄ4÷ÃÜZÃE{‰®+W\ZÍE[‰»µk»MÝ­`¢©†˜ÃV‹-f¢¡†¢a«eŠ%«Y¨©q%jâd,Ôq`) ¤¦…šˆ ¦E>0Ùb²t–Ÿ  ÷jsςҒKÈcø(é›;k(’#ôŒQ ™C> õ³M9óºÆµ¤çâ;uÀ)5>RÔ¸fÓ~Ȧ—’-$fe«"FâUˆÊwµPÏu w+"åÉó¨6s™Û9(À¨ù©hE°½†n`m~“@©›p!Vkhµ Á1šbEqqÊ@ºèl›2 –Yã%‘‚hÛ{a¶‡ÅÞM²¬çL34®Çl]®‹ŽØŒm'RÜe35æöˆ­Á­ cP9šeÁköo´L³Ì=p8]”‡B¶,šº|ɏdzXˆØk*ÇÚ{#ñ‰pã(€¶‡9ý'šÜ³½¯kƒ†Â’ëSOƒ•Å®H6+a¢µˆ‹Y¨b˜b+XˆÖ!°u!¢"µˆˆn2ˆ Å0Ä`Å Ô®c(ÓÜGº•Ä»Œ âWî%q.áÐÄ÷î%umÍ£+ÜQ,Vn¦-GphU¸¢X­&,Gt ·K¢ÅÅ·¥RÄÊÉbKn N­R2g$VµÕó Qr#–ÓZUÏð0ÎtÙÀœz ëöo“Îk¯n„T°"SÞ+³/…€½"ižãO%Í%&Δâ‘ËØ´IˆÓ°Ë‰ÞM3.™yçÁzit›`4C`k¢¼á!álÄï sÂ[×!¤l¾æo"ƒIÔ'@ªu)3›ô®“@Z à¾] üœ'‡4¸PÞkÁ-qÄH‰ÓÍBd´ÿ —¹°ÄA&ÊUC„öz‚‚RæŠtf¬>˜ÑidšEçÑL÷áý¡V±h§­c¿¥¨ƒ@g¼…Ýö^ÞËc.ž„æ“I[ ª+·zÐÒÚ,½Ð»¶€C›7jk$๖€Ž¾ÅÙpp¶ÍþéΤ ½ØÎŒq ñpæžÅ¥#Øâ49ÃÂK^MYV“,¶Éz_òæ:…;Õ«¦I3âJ£¤û5$7Èxün\â]Êe¯(Ÿ&Ž‹¶2<6Ćf× æ¢ƱqWı[(ÙÂŽç‚T7¨@ÈÉÍß‚ïÙ"&3TYlGށ†)†#5ŠA©^T2ÆÁ†)©†©†¤yGXÁ†©"†)©¼ÅV WS†#©]R–r‹q5ÕbâWþBh¯u+ªÅÄ×ü„nÑ^êkªÁj‰jeœWˆÕÕ`µDµ2Ì+Ä µDµµ5Ô{¤Þ0RF’H÷AÛ<ÊÁ§ ƈæ0Ñ£ê4 öÚµ[¬/1²€â<-¬šö²r×0o×w ´xÐÒË„ g01¬„åEM蛇Ã\6µE›‘fÙO k÷CºnÓ1`iîÒ² áÂ!ÑLÄÿ ³¬\õ*:M=Ç»c‹2[‰ØsÕLò\ŒK L^™üÄN\¶#» Ç\……ßïIœÉ$¸ÎñÍ®ÔHÇ Ûí/´>Li”„†g^$ 7NÍÑÑ2M2ªNg=k½Ð}Ÿl6‡ —JWˆ”ÞéT·+µ¦üÂFè¢Vs6ýÆ4»2+2IÝ9ô9®ÇGÙÇ1+Ä8;*Õ§ž½D*îÑWÚçá3Ma¤·ˆ¥t}š²Ü…Q+Æüµ8HíS”üxGéÁˆ¦Ël„éÈ 5 µÄƒ6äÜ(kIš¯S†fÖ&¸®×v|Äyˆ*禌Éù@7-®Ä[]ÎÖ¿ê`º…=:…žJVnݳvðÖKE¼‚ »mà ÷f®:Ë ™–4rð¡4` ܹçž~‹C=œ…¾Ïj|VDtK.ƒ"9 Ï ­–éXá³6WÒïIL-Ї Ç Ruleset.php000064400000005466152267630250006723 0ustar00version = $ruleset['version']; $this->parameters = $this->createParameters($ruleset['parameters']); $this->rules = $this->createRules($ruleset['rules']); $this->standardLibrary = new RulesetStandardLibrary($partitions); } /** * @return mixed */ public function getVersion() { return $this->version; } /** * @return array */ public function getParameters() { return $this->parameters; } /** * @return array */ public function getRules() { return $this->rules; } /** * Evaluate the ruleset against the input parameters. * Return the first rule the parameters match against. * * @return mixed */ public function evaluate(array $inputParameters) { $this->validateInputParameters($inputParameters); foreach($this->rules as $rule) { $evaluation = $rule->evaluate($inputParameters, $this->standardLibrary); if ($evaluation !== false) { return $evaluation; } } return false; } /** * Ensures all corresponding client-provided parameters match * the Ruleset parameter's specified type. * * @return void */ private function validateInputParameters(array &$inputParameters) { foreach($this->parameters as $paramName => $param) { $inputParam = isset($inputParameters[$paramName]) ? $inputParameters[$paramName] : null; if (is_null($inputParam) && !is_null($param->getDefault())) { $inputParameters[$paramName] = $param->getDefault(); } elseif (!is_null($inputParam)) { $param->validateInputParam($inputParam); } } } private function createParameters(array $parameters) { $parameterList = []; foreach($parameters as $name => $definition) { $parameterList[$name] = new RulesetParameter($name, $definition); } return $parameterList; } private function createRules(array $rules) { $rulesList = []; forEach($rules as $rule) { $ruleObj = RuleCreator::create($rule['type'], $rule); $rulesList[] = $ruleObj; } return $rulesList; } } RulesetParameter.php000064400000007640152267630250010560 0ustar00 */ private static $typeMap = [ 'String' => 'is_string', 'Boolean' => 'is_bool', 'StringArray' => 'isStringArray' ]; public function __construct($name, array $definition) { $type = ucfirst($definition['type']); if ($this->isValidType($type)) { $this->type = $type; } else { throw new UnresolvedEndpointException( 'Unknown parameter type ' . "`{$type}`" . '. Parameters must be of type `String`, `Boolean` or `StringArray.' ); } $this->name = $name; $this->builtIn = $definition['builtIn'] ?? null; $this->default = $definition['default'] ?? null; $this->required = $definition['required'] ?? false; $this->documentation = $definition['documentation'] ?? null; $this->deprecated = $definition['deprecated'] ?? false; } /** * @return mixed */ public function getName() { return $this->name; } /** * @return mixed */ public function getType() { return $this->type; } /** * @return mixed */ public function getBuiltIn() { return $this->builtIn; } /** * @return mixed */ public function getDefault() { return $this->default; } /** * @return boolean */ public function getRequired() { return $this->required; } /** * @return string */ public function getDocumentation() { return $this->documentation; } /** * @return boolean */ public function getDeprecated() { return $this->deprecated; } /** * Validates that an input parameter matches the type provided in its definition. * * @return void * @throws InvalidArgumentException */ public function validateInputParam($inputParam) { if (!$this->isValidInput($inputParam)) { throw new UnresolvedEndpointException( "Input parameter `{$this->name}` is the wrong type. Must be a {$this->type}." ); } if ($this->deprecated) { $deprecated = $this->deprecated; $deprecationString = "{$this->name} has been deprecated "; $msg = $deprecated['message'] ?? null; $since = $deprecated['since'] ?? null; if (!is_null($since)){ $deprecationString .= 'since ' . $since . '. '; } if (!is_null($msg)) { $deprecationString .= $msg; } trigger_error($deprecationString, E_USER_WARNING); } } private function isValidType($type) { return isset(self::$typeMap[$type]); } private function isValidInput($inputParam): bool { $method = self::$typeMap[$this->type]; if (is_callable($method)) { return $method($inputParam); } elseif (method_exists($this, $method)) { return $this->$method($inputParam); } return false; } private function isStringArray(array $array): bool { if (is_associative($array)) { return false; } foreach($array as $value) { if (!is_string($value)) { return false; } } return true; } } RulesetStandardLibrary.php000064400000031672152267630250011727 0ustar00[^\{\}]+)|(?R))*\}#x'; const HOST_LABEL_RE = '/^(?!-)[a-zA-Z\d-]{1,63}(?partitions = $partitions; } /** * Determines if a value is set. * * @return boolean */ public function is_set($value) { return isset($value); } /** * Function implementation of logical operator `not` * * @return boolean */ public function not($value) { return !$value; } /** * Find an attribute within a value given a path string. * * @return mixed */ public function getAttr($from, $path) { // Handles the case where "[= $stop or strlen($input) < $stop) { return null; } if (!$reverse) { return substr($input, $start, $stop - $start); } else { $offset = strlen($input) - $stop; $length = $stop - $start; return substr($input, $offset, $length); } } /** * Evaluates two strings for equality. * * @return boolean */ public function stringEquals($string1, $string2) { if (!is_string($string1) || !is_string($string2)) { throw new UnresolvedEndpointException( 'Values passed to StringEquals must be `string`.' ); } return $string1 === $string2; } /** * Evaluates two booleans for equality. * * @return boolean */ public function booleanEquals($boolean1, $boolean2) { return filter_var($boolean1, FILTER_VALIDATE_BOOLEAN) === filter_var($boolean2, FILTER_VALIDATE_BOOLEAN); } /** * Percent-encodes an input string. * * @return mixed */ public function uriEncode($input) { if (is_null($input)) { return null; } return str_replace('%7E', '~', rawurlencode($input)); } /** * Parses URL string into components. * * @return mixed */ public function parseUrl($url) { if (is_null($url)) { return null; } $parsed = parse_url($url); if ($parsed === false || !empty($parsed['query'])) { return null; } elseif (!isset($parsed['scheme'])) { return null; } if ($parsed['scheme'] !== 'http' && $parsed['scheme'] !== 'https' ) { return null; } $urlInfo = []; $urlInfo['scheme'] = $parsed['scheme']; $urlInfo['authority'] = isset($parsed['host']) ? $parsed['host'] : ''; if (isset($parsed['port'])) { $urlInfo['authority'] = $urlInfo['authority'] . ":" . $parsed['port']; } $urlInfo['path'] = isset($parsed['path']) ? $parsed['path'] : ''; $urlInfo['normalizedPath'] = !empty($parsed['path']) ? rtrim($urlInfo['path'] ?: '', '/' . "/") . '/' : '/'; $urlInfo['isIp'] = !isset($parsed['host']) ? 'false' : $this->isValidIp($parsed['host']); return $urlInfo; } /** * Evaluates whether a value is a valid host label per * RFC 1123. If allow_subdomains is true, split on `.` and validate * each subdomain separately. * * @return boolean */ public function isValidHostLabel($hostLabel, $allowSubDomains) { if (!isset($hostLabel) || (!$allowSubDomains && strpos($hostLabel, '.') != false) ) { return false; } if ($allowSubDomains) { foreach (explode('.', $hostLabel) as $subdomain) { if (!$this->validateHostLabel($subdomain)) { return false; } } return true; } else { return $this->validateHostLabel($hostLabel); } } /** * Parse and validate string for ARN components. * * @return array|null */ public function parseArn($arnString) { if (is_null($arnString) || substr( $arnString, 0, 3 ) !== "arn" ) { return null; } $arn = []; $parts = explode(':', $arnString, 6); if (sizeof($parts) < 6) { return null; } $arn['partition'] = isset($parts[1]) ? $parts[1] : null; $arn['service'] = isset($parts[2]) ? $parts[2] : null; $arn['region'] = isset($parts[3]) ? $parts[3] : null; $arn['accountId'] = isset($parts[4]) ? $parts[4] : null; $arn['resourceId'] = isset($parts[5]) ? $parts[5] : null; if (empty($arn['partition']) || empty($arn['service']) || empty($arn['resourceId']) ) { return null; } $resource = $arn['resourceId']; $arn['resourceId'] = preg_split("/[:\/]/", $resource); return $arn; } /** * Matches a region string to an AWS partition. * * @return mixed */ public function partition($region) { if (!is_string($region)) { throw new UnresolvedEndpointException( 'Value passed to `partition` must be `string`.' ); } $partitions = $this->partitions; foreach ($partitions['partitions'] as $partition) { if (array_key_exists($region, $partition['regions']) || preg_match("/{$partition['regionRegex']}/", $region) ) { return $partition['outputs']; } } //return `aws` partition if no match is found. return $partitions['partitions'][0]['outputs']; } /** * Evaluates whether a value is a valid bucket name for virtual host * style bucket URLs. * * @return boolean */ public function isVirtualHostableS3Bucket($bucketName, $allowSubdomains) { if ((is_null($bucketName) || (strlen($bucketName) < 3 || strlen($bucketName) > 63)) || preg_match(self::IPV4_RE, $bucketName) || strtolower($bucketName) !== $bucketName ) { return false; } if ($allowSubdomains) { $labels = explode('.', $bucketName); $results = []; forEach($labels as $label) { $results[] = $this->isVirtualHostableS3Bucket($label, false); } return !in_array(false, $results); } return $this->isValidHostLabel($bucketName, false); } public function callFunction($funcCondition, &$inputParameters) { $funcArgs = []; forEach($funcCondition['argv'] as $arg) { $funcArgs[] = $this->resolveValue($arg, $inputParameters); } $funcName = str_replace('aws.', '', $funcCondition['fn']); if ($funcName === 'isSet') { $funcName = 'is_set'; } $result = call_user_func_array( [RulesetStandardLibrary::class, $funcName], $funcArgs ); if (isset($funcCondition['assign'])) { $assign = $funcCondition['assign']; if (isset($inputParameters[$assign])){ throw new UnresolvedEndpointException( "Assignment `{$assign}` already exists in input parameters" . " or has already been assigned by an endpoint rule and cannot be overwritten." ); } $inputParameters[$assign] = $result; } return $result; } public function resolveValue($value, $inputParameters) { //Given a value, check if it's a function, reference or template. //returns resolved value if ($this->isFunc($value)) { return $this->callFunction($value, $inputParameters); } elseif ($this->isRef($value)) { return isset($inputParameters[$value['ref']]) ? $inputParameters[$value['ref']] : null; } elseif ($this->isTemplate($value)) { return $this->resolveTemplateString($value, $inputParameters); } return $value; } public function isFunc($arg) { return is_array($arg) && isset($arg['fn']); } public function isRef($arg) { return is_array($arg) && isset($arg['ref']); } public function isTemplate($arg) { return is_string($arg) && !empty(preg_match(self::TEMPLATE_SEARCH_RE, $arg)); } public function resolveTemplateString($value, $inputParameters) { return preg_replace_callback( self::TEMPLATE_PARSE_RE, function ($match) use ($inputParameters) { if (preg_match(self::TEMPLATE_ESCAPE_RE, $match[0])) { return $match[1]; } $notFoundMessage = 'Resolved value was null. Please check rules and ' . 'input parameters and try again.'; $parts = explode("#", $match[1]); if (count($parts) > 1) { $resolvedValue = $inputParameters; foreach($parts as $part) { if (!isset($resolvedValue[$part])) { throw new UnresolvedEndpointException($notFoundMessage); } $resolvedValue = $resolvedValue[$part]; } return $resolvedValue; } else { if (!isset($inputParameters[$parts[0]])) { throw new UnresolvedEndpointException($notFoundMessage); } return $inputParameters[$parts[0]]; } }, $value ); } private function validateHostLabel ($hostLabel) { if (empty($hostLabel) || strlen($hostLabel) > 63) { return false; } if (preg_match(self::HOST_LABEL_RE, $hostLabel)) { return true; } return false; } private function isValidIp($hostName) { $isWrapped = strpos($hostName, '[') === 0 && strrpos($hostName, ']') === strlen($hostName) - 1; return preg_match( self::IPV4_RE, $hostName ) //IPV6 enclosed in brackets || ($isWrapped && preg_match( self::IPV6_RE, $hostName )) ? 'true' : 'false'; } } RulesetEndpoint.php000064400000002110152267630250010403 0ustar00url = $url; $this->properties = $properties; $this->headers = $headers; } /** * @return mixed */ public function getUrl() { return $this->url; } /** * @param $property * @return mixed */ public function getProperty($property) { if (isset($this->properties[$property])) { return $this->properties[$property]; } return null; } /** * @return mixed */ public function getProperties() { return $this->properties; } /** * @return mixed */ public function getHeaders() { return $this->headers; } }