CHANGELOG.md000064400000000531146412134410006354 0ustar00# CHANGELOG ## 1.1.3 - 2020-12-24 - Require guzzle ^6.3|^7.0 ## 1.0.2 - 2020-02-14 - Update Tea. ## 1.0.1 - 2019-12-30 - Supported get `Role Name` automatically. ## 1.0.0 - 2019-09-01 - Initial release of the Alibaba Cloud Credentials for PHP Version 1.0.0 on Packagist See for more information. CONTRIBUTING.md000064400000003232146412134410006775 0ustar00# CONTRIBUTING We work hard to provide a high-quality and useful SDK for Alibaba Cloud, and we greatly value feedback and contributions from our community. Please submit your [issues][issues] or [pull requests][pull-requests] through GitHub. ## Tips - The SDK is released under the [Apache license][license]. Any code you submit will be released under that license. For substantial contributions, we may ask you to sign a [Alibaba Documentation Corporate Contributor License Agreement (CLA)][cla]. - We follow all of the relevant PSR recommendations from the [PHP Framework Interop Group][php-fig]. Please submit code that follows these standards. The [PHP CS Fixer][cs-fixer] tool can be helpful for formatting your code. Your can use `composer fixer` to fix code. - We maintain a high percentage of code coverage in our unit tests. If you make changes to the code, please add, update, and/or remove tests as appropriate. - If your code does not conform to the PSR standards, does not include adequate tests, or does not contain a changelog document, we may ask you to update your pull requests before we accept them. We also reserve the right to deny any pull requests that do not align with our standards or goals. [issues]: https://github.com/aliyun/credentials-php/issues [pull-requests]: https://github.com/aliyun/credentials-php/pulls [license]: http://www.apache.org/licenses/LICENSE-2.0 [cla]: https://alibaba-cla-2018.oss-cn-beijing.aliyuncs.com/Alibaba_Documentation_Open_Source_Corporate_CLA.pdf [php-fig]: http://php-fig.org [cs-fixer]: http://cs.sensiolabs.org/ [docs-readme]: https://github.com/aliyun/credentials-php/blob/master/README.md LICENSE.md000064400000001115146412134410006146 0ustar00Copyright (c) 2009-present, Alibaba Cloud All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. NOTICE.md000064400000007662146412134410006062 0ustar00# NOTICE Copyright (c) 2009-present, Alibaba Cloud All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. # Guzzle Copyright (c) 2011-2018 Michael Dowling, https://github.com/mtdowling Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # jmespath.php Copyright (c) 2014 Michael Dowling, https://github.com/mtdowling Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # Dot Copyright (c) 2016-2019 Riku Särkinen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. README-zh-CN.md000064400000021241146412134410006740 0ustar00[English](/README.md) | 简体中文 # Alibaba Cloud Credentials for PHP [![Latest Stable Version](https://poser.pugx.org/alibabacloud/credentials/v/stable)](https://packagist.org/packages/alibabacloud/credentials) [![composer.lock](https://poser.pugx.org/alibabacloud/credentials/composerlock)](https://packagist.org/packages/alibabacloud/credentials) [![Total Downloads](https://poser.pugx.org/alibabacloud/credentials/downloads)](https://packagist.org/packages/alibabacloud/credentials) [![License](https://poser.pugx.org/alibabacloud/credentials/license)](https://packagist.org/packages/alibabacloud/credentials) [![codecov](https://codecov.io/gh/aliyun/credentials-php/branch/master/graph/badge.svg)](https://codecov.io/gh/aliyun/credentials-php) [![Travis Build Status](https://travis-ci.org/aliyun/credentials-php.svg?branch=master)](https://travis-ci.org/aliyun/credentials-php) [![Appveyor Build Status](https://ci.appveyor.com/api/projects/status/6jxpwmhyfipagtge/branch/master?svg=true)](https://ci.appveyor.com/project/aliyun/credentials-php) ![](https://aliyunsdk-pages.alicdn.com/icons/AlibabaCloud.svg) Alibaba Cloud Credentials for PHP 是帮助 PHP 开发者管理凭据的工具。 ## 先决条件 您的系统需要满足[先决条件](/docs/zh-CN/0-Prerequisites.md),包括 PHP> = 5.6。 我们强烈建议使用cURL扩展,并使用TLS后端编译cURL 7.16.2+。 ## 安装依赖 如果已在系统上[全局安装 Composer](https://getcomposer.org/doc/00-intro.md#globally),请直接在项目目录中运行以下内容来安装 Alibaba Cloud Credentials for PHP 作为依赖项: ``` composer require alibabacloud/credentials ``` > 一些用户可能由于网络问题无法安装,可以使用[阿里云 Composer 全量镜像](https://developer.aliyun.com/composer)。 请看[安装](/docs/zh-CN/1-Installation.md)有关通过 Composer 和其他方式安装的详细信息。 ## 快速使用 在您开始之前,您需要注册阿里云帐户并获取您的[凭证](https://usercenter.console.aliyun.com/#/manage/ak)。 ### 凭证类型 #### AccessKey 通过[用户信息管理][ak]设置 access_key,它们具有该账户完全的权限,请妥善保管。有时出于安全考虑,您不能把具有完全访问权限的主账户 AccessKey 交于一个项目的开发者使用,您可以[创建RAM子账户][ram]并为子账户[授权][permissions],使用RAM子用户的 AccessKey 来进行API调用。 ```php getAccessKeyId(); $credential->getAccessKeySecret(); // Access Key $ak = new Credential([ 'type' => 'access_key', 'access_key_id' => '', 'access_key_secret' => '', ]); $ak->getAccessKeyId(); $ak->getAccessKeySecret(); ``` #### STS 通过安全令牌服务(Security Token Service,简称 STS),申请临时安全凭证(Temporary Security Credentials,简称 TSC),创建临时安全凭证。 ```php 'sts', 'access_key_id' => '', 'accessKey_secret' => '', 'security_token' => '', ]); $sts->getAccessKeyId(); $sts->getAccessKeySecret(); $sts->getSecurityToken(); ``` #### RamRoleArn 通过指定[RAM角色][RAM Role],让凭证自动申请维护 STS Token。你可以通过为 `Policy` 赋值来限制获取到的 STS Token 的权限。 ```php 'ram_role_arn', 'access_key_id' => '', 'access_key_secret' => '', 'role_arn' => '', 'role_session_name' => '', 'policy' => '', ]); $ramRoleArn->getAccessKeyId(); $ramRoleArn->getAccessKeySecret(); $ramRoleArn->getRoleArn(); $ramRoleArn->getRoleSessionName(); $ramRoleArn->getPolicy(); ``` #### EcsRamRole 通过指定角色名称,让凭证自动申请维护 STS Token ```php 'ecs_ram_role', 'role_name' => '', ]); $ecsRamRole->getRoleName(); // Note: `role_name` is optional. It will be retrieved automatically if not set. It is highly recommended to set it up to reduce requests. ``` #### RsaKeyPair 通过指定公钥Id和私钥文件,让凭证自动申请维护 AccessKey。仅支持日本站。 ```php 'rsa_key_pair', 'public_key_id' => '', 'private_key_file' => '', ]); $rsaKeyPair->getPublicKeyId(); $rsaKeyPair->getPrivateKey(); ``` #### Bearer Token 如呼叫中心(CCC)需用此凭证,请自行申请维护 Bearer Token。 ```php 'bearer', 'bearer_token' => '', ]); $bearerToken->getBearerToken(); $bearerToken->getSignature(); ``` ## 默认凭证提供程序链 默认凭证提供程序链查找可用的凭证,寻找顺序如下: ### 1. 环境凭证 程序首先会在环境变量里寻找环境凭证,如果定义了 `ALIBABA_CLOUD_ACCESS_KEY_ID` 和 `ALIBABA_CLOUD_ACCESS_KEY_SECRET` 环境变量且不为空,程序将使用他们创建默认凭证。 ### 2. 配置文件 > 如果用户主目录存在默认文件 `~/.alibabacloud/credentials` (Windows 为 `C:\Users\USER_NAME\.alibabacloud\credentials`),程序会自动创建指定类型和名称的凭证。默认文件可以不存在,但解析错误会抛出异常。 凭证名称不分大小写,若凭证同名,后者会覆盖前者。不同的项目、工具之间可以共用这个配置文件,因为超出项目之外,也不会被意外提交到版本控制。Windows 上可以使用环境变量引用到主目录 %UserProfile%。类 Unix 的系统可以使用环境变量 $HOME 或 ~ (tilde)。 可以通过定义 `ALIBABA_CLOUD_CREDENTIALS_FILE` 环境变量修改默认文件的路径。 ```ini [default] type = access_key # 认证方式为 access_key access_key_id = foo # Key access_key_secret = bar # Secret [project1] type = ecs_ram_role # 认证方式为 ecs_ram_role role_name = EcsRamRoleTest # Role Name,非必填,不填则自动获取,建议设置,可以减少网络请求。 [project2] type = ram_role_arn # 认证方式为 ram_role_arn access_key_id = foo access_key_secret = bar role_arn = role_arn role_session_name = session_name [project3] type = rsa_key_pair # 认证方式为 rsa_key_pair public_key_id = publicKeyId # Public Key ID private_key_file = /your/pk.pem # Private Key 文件 ``` ### 3. 实例 RAM 角色 如果定义了环境变量 `ALIBABA_CLOUD_ECS_METADATA` 且不为空,程序会将该环境变量的值作为角色名称,请求 `http://100.100.100.200/latest/meta-data/ram/security-credentials/` 获取临时安全凭证作为默认凭证。 ### 自定义凭证提供程序链 可通过自定义程序链代替默认程序链的寻找顺序,也可以自行编写闭包传入提供者。 ```php = 5.6. We strongly recommend using the cURL extension and compiling cURL 7.16.2+ using the TLS backend. ## Installation If you have [Globally Install Composer](https://getcomposer.org/doc/00-intro.md#globally) on your system, install Alibaba Cloud Credentials for PHP as a dependency by running the following directly in the project directory: ``` composer require alibabacloud/credentials ``` > Some users may not be able to install due to network problems, you can switch to the [Alibaba Cloud Composer Mirror](https://developer.aliyun.com/composer). See [Installation](/docs/zh-CN/1-Installation.md) for details on installing through Composer and other means. ## Quick Examples Before you begin, you need to sign up for an Alibaba Cloud account and retrieve your [Credentials](https://usercenter.console.aliyun.com/#/manage/ak). ### Credential Type #### AccessKey Setup access_key credential through [User Information Management][ak], it have full authority over the account, please keep it safe. Sometimes for security reasons, you cannot hand over a primary account AccessKey with full access to the developer of a project. You may create a sub-account [RAM Sub-account][ram] , grant its [authorization][permissions],and use the AccessKey of RAM Sub-account. ```php getAccessKeyId(); $credential->getAccessKeySecret(); // Access Key $ak = new Credential([ 'type' => 'access_key', 'access_key_id' => '', 'access_key_secret' => '', ]); $ak->getAccessKeyId(); $ak->getAccessKeySecret(); ``` #### STS Create a temporary security credential by applying Temporary Security Credentials (TSC) through the Security Token Service (STS). ```php 'sts', 'access_key_id' => '', 'accessKey_secret' => '', 'security_token' => '', ]); $sts->getAccessKeyId(); $sts->getAccessKeySecret(); $sts->getSecurityToken(); ``` #### RamRoleArn By specifying [RAM Role][RAM Role], the credential will be able to automatically request maintenance of STS Token. If you want to limit the permissions([How to make a policy][policy]) of STS Token, you can assign value for `Policy`. ```php 'ram_role_arn', 'access_key_id' => '', 'access_key_secret' => '', 'role_arn' => '', 'role_session_name' => '', 'policy' => '', ]); $ramRoleArn->getAccessKeyId(); $ramRoleArn->getAccessKeySecret(); $ramRoleArn->getRoleArn(); $ramRoleArn->getRoleSessionName(); $ramRoleArn->getPolicy(); ``` #### EcsRamRole By specifying the role name, the credential will be able to automatically request maintenance of STS Token. ```php 'ecs_ram_role', 'role_name' => '', ]); $ecsRamRole->getRoleName(); // Note: `role_name` is optional. It will be retrieved automatically if not set. It is highly recommended to set it up to reduce requests. ``` #### RsaKeyPair By specifying the public key Id and the private key file, the credential will be able to automatically request maintenance of the AccessKey before sending the request. Only Japan station is supported. ```php 'rsa_key_pair', 'public_key_id' => '', 'private_key_file' => '', ]); $rsaKeyPair->getPublicKeyId(); $rsaKeyPair->getPrivateKey(); ``` #### Bearer Token If credential is required by the Cloud Call Centre (CCC), please apply for Bearer Token maintenance by yourself. ```php 'bearer', 'bearer_token' => '', ]); $bearerToken->getBearerToken(); $bearerToken->getSignature(); ``` ## Default credential provider chain The default credential provider chain looks for available credentials, looking in the following order: ### 1. Environmental certificate The program first looks for environment credentials in the environment variable. If the `ALIBABA_CLOUD_ACCESS_KEY_ID` and `ALIBABA_CLOUD_ACCESS_KEY_SECRET` environment variables are defined and not empty, the program will use them to create default credentials. ### 2. Configuration file > If the user's home directory has the default file `~/.alibabacloud/credentials` (Windows is `C:\Users\USER_NAME\.alibabacloud\credentials`), the program will automatically create credentials with the specified type and name. The default file may not exist, but parsing errors will throw an exception. The voucher name is not case sensitive. If the voucher has the same name, the latter will overwrite the former. This configuration file can be shared between different projects and tools, and it will not be accidentally submitted to version control because it is outside the project. Environment variables can be referenced to the home directory %UserProfile% on Windows. Unix-like systems can use the environment variable $HOME or ~ (tilde). The path to the default file can be modified by defining the `ALIBABA_CLOUD_CREDENTIALS_FILE` environment variable. ```ini [default] type = access_key # Authentication method is access_key access_key_id = foo # Key access_key_secret = bar # Secret [project1] type = ecs_ram_role # Authentication method is ecs_ram_role role_name = EcsRamRoleTest # Role name, optional. It will be retrieved automatically if not set. It is highly recommended to set it up to reduce requests. [project2] type = ram_role_arn # Authentication method is ram_role_arn access_key_id = foo access_key_secret = bar role_arn = role_arn role_session_name = session_name [project3] type = rsa_key_pair # Authentication method is rsa_key_pair public_key_id = publicKeyId # Public Key ID private_key_file = /your/pk.pem # Private Key File ``` ### 3. Instance RAM role If the environment variable `ALIBABA_CLOUD_ECS_METADATA` is defined and not empty, the program will take the value of the environment variable as the role name and request `http://100.100.100.200/latest/meta-data/ram/security-credentials/` to get the temporary Security credentials are used as default credentials. ### Custom credential provider chain You can replace the default order of the program chain by customizing the program chain, or you can write the closure to the provider. ```php for more information. composer.json000064400000006105146412134410007270 0ustar00{ "name": "alibabacloud/credentials", "homepage": "https://www.alibabacloud.com/", "description": "Alibaba Cloud Credentials for PHP", "keywords": [ "sdk", "tool", "cloud", "client", "aliyun", "library", "alibaba", "Credentials", "alibabacloud" ], "type": "library", "license": "Apache-2.0", "support": { "source": "https://github.com/aliyun/credentials-php", "issues": "https://github.com/aliyun/credentials-php/issues" }, "authors": [ { "name": "Alibaba Cloud SDK", "email": "sdk-team@alibabacloud.com", "homepage": "http://www.alibabacloud.com" } ], "require": { "php": ">=5.6", "ext-curl": "*", "ext-json": "*", "ext-libxml": "*", "ext-openssl": "*", "ext-mbstring": "*", "ext-simplexml": "*", "ext-xmlwriter": "*", "guzzlehttp/guzzle": "^6.3|^7.0", "adbario/php-dot-notation": "^2.2", "alibabacloud/tea": "^3.0" }, "require-dev": { "ext-spl": "*", "ext-dom": "*", "ext-pcre": "*", "psr/cache": "^1.0", "ext-sockets": "*", "drupal/coder": "^8.3", "symfony/dotenv": "^3.4", "phpunit/phpunit": "^5.7|^6.6|^7.5", "monolog/monolog": "^1.24", "composer/composer": "^1.8", "mikey179/vfsstream": "^1.6", "symfony/var-dumper": "^3.4" }, "suggest": { "ext-sockets": "To use client-side monitoring" }, "autoload": { "psr-4": { "AlibabaCloud\\Credentials\\": "src" } }, "autoload-dev": { "psr-4": { "AlibabaCloud\\Credentials\\Tests\\": "tests/" } }, "config": { "preferred-install": "dist", "optimize-autoloader": true, "allow-plugins": { "dealerdirect/phpcodesniffer-composer-installer": true } }, "minimum-stability": "dev", "prefer-stable": true, "scripts-descriptions": { "cs": "Tokenizes PHP, JavaScript and CSS files to detect violations of a defined coding standard.", "cbf": "Automatically correct coding standard violations.", "fixer": "Fixes code to follow standards.", "test": "Run all tests.", "unit": "Run Unit tests.", "feature": "Run Feature tests.", "clearCache": "Clear cache like coverage.", "coverage": "Show Coverage html.", "endpoints": "Update endpoints from OSS." }, "scripts": { "cs": "phpcs --standard=PSR2 -n ./", "cbf": "phpcbf --standard=PSR2 -n ./", "fixer": "php-cs-fixer fix ./", "test": [ "phpunit --colors=always" ], "unit": [ "@clearCache", "phpunit --testsuite=Unit --colors=always" ], "feature": [ "@clearCache", "phpunit --testsuite=Feature --colors=always" ], "coverage": "open cache/coverage/index.html", "clearCache": "rm -rf cache/*" } } src/AccessKeyCredential.php000064400000002545146412134410011717 0ustar00accessKeyId = $access_key_id; $this->accessKeySecret = $access_key_secret; } /** * @return string */ public function getAccessKeyId() { return $this->accessKeyId; } /** * @return string */ public function getAccessKeySecret() { return $this->accessKeySecret; } /** * @return string */ public function __toString() { return "$this->accessKeyId#$this->accessKeySecret"; } /** * @return ShaHmac1Signature */ public function getSignature() { return new ShaHmac1Signature(); } public function getSecurityToken() { return ''; } } src/BearerTokenCredential.php000064400000001620146412134410012237 0ustar00bearerToken = $bearer_token; } /** * @return string */ public function getBearerToken() { return $this->bearerToken; } /** * @return string */ public function __toString() { return "bearerToken#$this->bearerToken"; } /** * @return BearerTokenSignature */ public function getSignature() { return new BearerTokenSignature(); } } src/Credential.php000064400000010556146412134410010125 0ustar00 AccessKeyCredential::class, 'sts' => StsCredential::class, 'ecs_ram_role' => EcsRamRoleCredential::class, 'ram_role_arn' => RamRoleArnCredential::class, 'rsa_key_pair' => RsaKeyPairCredential::class, 'bearer' => BearerTokenCredential::class, ]; /** * @var AccessKeyCredential|BearerTokenCredential|EcsRamRoleCredential|RamRoleArnCredential|RsaKeyPairCredential */ protected $credential; /** * @var string */ protected $type; /** * Credential constructor. * * @param array|Config $config * * @throws ReflectionException */ public function __construct($config = []) { if ($config instanceof Config) { $config = $this->parse($config); } if ($config !== []) { $this->config = array_change_key_case($config); $this->parseConfig(); } else { $this->credential = Credentials::get()->getCredential(); } } /** * @param Config $config * * @return array */ private function parse($config) { $config = get_object_vars($config); $res = []; foreach ($config as $key => $value) { $res[$this->toUnderScore($key)] = $value; } return $res; } private function toUnderScore($str) { $dstr = preg_replace_callback('/([A-Z]+)/', function ($matchs) { return '_' . strtolower($matchs[0]); }, $str); return trim(preg_replace('/_{2,}/', '_', $dstr), '_'); } /** * @throws ReflectionException */ private function parseConfig() { if (!isset($this->config['type'])) { throw new InvalidArgumentException('Missing required type option'); } $this->type = $this->config['type']; if (!isset($this->types[$this->type])) { throw new InvalidArgumentException( 'Invalid type option, support: ' . implode(', ', array_keys($this->types)) ); } $class = new ReflectionClass($this->types[$this->type]); $parameters = []; /** * @var $parameter ReflectionParameter */ foreach ($class->getConstructor()->getParameters() as $parameter) { $parameters[] = $this->getValue($parameter); } $this->credential = $class->newInstance(...$parameters); } /** * @param ReflectionParameter $parameter * * @return string|array * @throws ReflectionException */ protected function getValue(ReflectionParameter $parameter) { if ($parameter->name === 'config' || $parameter->name === 'credential') { return $this->config; } foreach ($this->config as $key => $value) { if (strtolower($parameter->name) === $key) { return $value; } } if ($parameter->isDefaultValueAvailable()) { return $parameter->getDefaultValue(); } throw new InvalidArgumentException("Missing required {$parameter->name} option in config for {$this->type}"); } /** * @return AccessKeyCredential|BearerTokenCredential|EcsRamRoleCredential|RamRoleArnCredential|RsaKeyPairCredential */ public function getCredential() { return $this->credential; } /** * @return array */ public function getConfig() { return $this->config; } /** * @return string */ public function getType() { return $this->type; } /** * @param string $name * @param array $arguments * * @return mixed */ public function __call($name, $arguments) { return $this->credential->$name($arguments); } } src/Credential/Config.php000064400000001365146412134410011330 0ustar00 $v) { $this->{$k} = $v; } } } src/Credentials.php000064400000004076146412134410010310 0ustar00roleName = $role_name; } /** * @return string * @throws GuzzleException * @throws Exception */ public function getRoleName() { if ($this->roleName !== null) { return $this->roleName; } $this->roleName = $this->getRoleNameFromMeta(); return $this->roleName; } /** * @return string * @throws Exception */ public function getRoleNameFromMeta() { $options = [ 'http_errors' => false, 'timeout' => 1, 'connect_timeout' => 1, ]; $result = Request::createClient()->request( 'GET', 'http://100.100.100.200/latest/meta-data/ram/security-credentials/', $options ); if ($result->getStatusCode() === 404) { throw new InvalidArgumentException('The role name was not found in the instance'); } if ($result->getStatusCode() !== 200) { throw new RuntimeException('Error retrieving credentials from result: ' . $result->getBody()); } $role_name = (string)$result; if (!$role_name) { throw new RuntimeException('Error retrieving credentials from result is empty'); } return $role_name; } /** * @return string */ public function __toString() { return "roleName#$this->roleName"; } /** * @return ShaHmac1Signature */ public function getSignature() { return new ShaHmac1Signature(); } /** * @return string * @throws Exception * @throws GuzzleException */ public function getAccessKeyId() { return $this->getSessionCredential()->getAccessKeyId(); } /** * @return StsCredential * @throws Exception * @throws GuzzleException */ protected function getSessionCredential() { return (new EcsRamRoleProvider($this))->get(); } /** * @return string * @throws Exception * @throws GuzzleException */ public function getAccessKeySecret() { return $this->getSessionCredential()->getAccessKeySecret(); } /** * @return string * @throws Exception * @throws GuzzleException */ public function getSecurityToken() { return $this->getSessionCredential()->getSecurityToken(); } /** * @return int * @throws Exception * @throws GuzzleException */ public function getExpiration() { return $this->getSessionCredential()->getExpiration(); } } src/Filter.php000064400000006200146412134410007267 0ustar00 $value) { if (is_int($key)) { $result[] = $value; continue; } if (isset($result[$key]) && is_array($result[$key])) { $result[$key] = self::merge( [$result[$key], $value] ); continue; } $result[$key] = $value; } } return $result; } /** * @param $filename * * @return bool */ public static function inOpenBasedir($filename) { $open_basedir = ini_get('open_basedir'); if (!$open_basedir) { return true; } $dirs = explode(PATH_SEPARATOR, $open_basedir); return empty($dirs) || self::inDir($filename, $dirs); } /** * @param string $filename * @param array $dirs * * @return bool */ public static function inDir($filename, array $dirs) { foreach ($dirs as $dir) { if ($dir[strlen($dir) - 1] !== DIRECTORY_SEPARATOR) { $dir .= DIRECTORY_SEPARATOR; } if (0 === strpos($filename, $dir)) { return true; } } return false; } /** * @return bool */ public static function isWindows() { return PATH_SEPARATOR === ';'; } /** * @param $key * * @return bool|mixed */ public static function envNotEmpty($key) { $value = self::env($key, false); if ($value) { return $value; } return false; } /** * Gets the value of an environment variable. * * @param string $key * @param mixed $default * * @return mixed */ public static function env($key, $default = null) { $value = getenv($key); if ($value === false) { return self::value($default); } if (self::envSubstr($value)) { return substr($value, 1, -1); } return self::envConversion($value); } /** * Return the default value of the given value. * * @param mixed $value * * @return mixed */ public static function value($value) { return $value instanceof Closure ? $value() : $value; } /** * @param $value * * @return bool */ public static function envSubstr($value) { return ($valueLength = strlen($value)) > 1 && strpos($value, '"') === 0 && $value[$valueLength - 1] === '"'; } /** * @param $value * * @return bool|string|null */ public static function envConversion($value) { $key = strtolower($value); if ($key === 'null' || $key === '(null)') { return null; } $list = [ 'true' => true, '(true)' => true, 'false' => false, '(false)' => false, 'empty' => '', '(empty)' => '', ]; return isset($list[$key]) ? $list[$key] : $value; } /** * Gets the environment's HOME directory. * * @return null|string */ public static function getHomeDirectory() { if (getenv('HOME')) { return getenv('HOME'); } return (getenv('HOMEDRIVE') && getenv('HOMEPATH')) ? getenv('HOMEDRIVE') . getenv('HOMEPATH') : null; } /** * @param mixed ...$parameters * * @codeCoverageIgnore */ public static function dd(...$parameters) { dump(...$parameters); exit; } } src/MockTrait.php000064400000004141146412134410007741 0ustar00 'access_key', 'access_key_id' => $accessKeyId, 'access_key_secret' => $accessKeySecret, ] ); } }; } /** * @return string */ public static function getDefaultName() { $name = Helper::envNotEmpty('ALIBABA_CLOUD_PROFILE'); if ($name) { return $name; } return 'default'; } /** * @return Closure */ public static function ini() { return static function () { $filename = Helper::envNotEmpty('ALIBABA_CLOUD_CREDENTIALS_FILE'); if (!$filename) { $filename = self::getDefaultFile(); } if (!Helper::inOpenBasedir($filename)) { return; } if ($filename !== self::getDefaultFile() && (!\is_readable($filename) || !\is_file($filename))) { throw new RuntimeException( 'Credentials file is not readable: ' . $filename ); } $file_array = \parse_ini_file($filename, true); if (\is_array($file_array) && !empty($file_array)) { foreach (\array_change_key_case($file_array) as $name => $configures) { Credentials::set($name, $configures); } } }; } /** * Get the default credential file. * * @return string */ public static function getDefaultFile() { return Helper::getHomeDirectory() . DIRECTORY_SEPARATOR . '.alibabacloud' . DIRECTORY_SEPARATOR . 'credentials'; } /** * @return Closure */ public static function instance() { return static function () { $instance = Helper::envNotEmpty('ALIBABA_CLOUD_ECS_METADATA'); if ($instance) { Credentials::set( self::getDefaultName(), [ 'type' => 'ecs_ram_role', 'role_name' => $instance, ] ); } }; } } src/Providers/EcsRamRoleProvider.php000064400000004444146412134410013536 0ustar00getCredentialsInCache(); if ($result === null) { $result = $this->request(); if (!isset($result['AccessKeyId'], $result['AccessKeySecret'], $result['SecurityToken'])) { throw new RuntimeException($this->error); } $this->cache($result->toArray()); } return new StsCredential( $result['AccessKeyId'], $result['AccessKeySecret'], strtotime($result['Expiration']), $result['SecurityToken'] ); } /** * Get credentials by request. * * @return ResponseInterface * @throws Exception * @throws GuzzleException */ public function request() { $credential = $this->credential; $url = $this->uri . $credential->getRoleName(); $options = [ 'http_errors' => false, 'timeout' => 1, 'connect_timeout' => 1, ]; $result = Request::createClient()->request('GET', $url, $options); if ($result->getStatusCode() === 404) { $message = 'The role was not found in the instance'; throw new InvalidArgumentException($message); } if ($result->getStatusCode() !== 200) { throw new RuntimeException('Error retrieving credentials from result: ' . $result->toJson()); } return $result; } } src/Providers/Provider.php000064400000003537146412134410011623 0ustar00credential = $credential; $this->config = $config; } /** * Get the credentials from the cache in the validity period. * * @return array|null */ public function getCredentialsInCache() { if (isset(self::$credentialsCache[(string)$this->credential])) { $result = self::$credentialsCache[(string)$this->credential]; if (\strtotime($result['Expiration']) - \time() >= $this->expirationSlot) { return $result; } } return null; } /** * Cache credentials. * * @param array $credential */ protected function cache(array $credential) { self::$credentialsCache[(string)$this->credential] = $credential; } } src/Providers/RamRoleArnProvider.php000064400000002527146412134410013544 0ustar00getCredentialsInCache(); if (null === $credential) { $result = (new AssumeRole($this->credential))->request(); if ($result->getStatusCode() !== 200) { throw new RuntimeException(isset($result['Message']) ? $result['Message'] : (string)$result->getBody()); } if (!isset($result['Credentials']['AccessKeyId'], $result['Credentials']['AccessKeySecret'], $result['Credentials']['SecurityToken'])) { throw new RuntimeException($this->error); } $credential = $result['Credentials']; $this->cache($credential); } return new StsCredential( $credential['AccessKeyId'], $credential['AccessKeySecret'], strtotime($credential['Expiration']), $credential['SecurityToken'] ); } } src/Providers/RsaKeyPairProvider.php000064400000002630146412134410013547 0ustar00getCredentialsInCache(); if ($credential === null) { $result = (new GenerateSessionAccessKey($this->credential))->request(); if ($result->getStatusCode() !== 200) { throw new RuntimeException(isset($result['Message']) ? $result['Message'] : (string)$result->getBody()); } if (!isset($result['SessionAccessKey']['SessionAccessKeyId'], $result['SessionAccessKey']['SessionAccessKeySecret'])) { throw new RuntimeException($this->error); } $credential = $result['SessionAccessKey']; $this->cache($credential); } return new StsCredential( $credential['SessionAccessKeyId'], $credential['SessionAccessKeySecret'], strtotime($credential['Expiration']) ); } } src/RamRoleArnCredential.php000064400000011335146412134410012044 0ustar00filterParameters($credential); $this->filterPolicy($credential); Filter::accessKey($credential['access_key_id'], $credential['access_key_secret']); $this->config = $config; $this->accessKeyId = $credential['access_key_id']; $this->accessKeySecret = $credential['access_key_secret']; $this->roleArn = $credential['role_arn']; $this->roleSessionName = $credential['role_session_name']; } /** * @param array $credential */ private function filterParameters(array $credential) { if (!isset($credential['access_key_id'])) { throw new InvalidArgumentException('Missing required access_key_id option in config for ram_role_arn'); } if (!isset($credential['access_key_secret'])) { throw new InvalidArgumentException('Missing required access_key_secret option in config for ram_role_arn'); } if (!isset($credential['role_arn'])) { throw new InvalidArgumentException('Missing required role_arn option in config for ram_role_arn'); } if (!isset($credential['role_session_name'])) { throw new InvalidArgumentException('Missing required role_session_name option in config for ram_role_arn'); } } /** * @param array $credential */ private function filterPolicy(array $credential) { if (isset($credential['policy'])) { if (is_string($credential['policy'])) { $this->policy = $credential['policy']; } if (is_array($credential['policy'])) { $this->policy = json_encode($credential['policy']); } } } /** * @return array */ public function getConfig() { return $this->config; } /** * @return string */ public function getRoleArn() { return $this->roleArn; } /** * @return string */ public function getRoleSessionName() { return $this->roleSessionName; } /** * @return string */ public function getPolicy() { return $this->policy; } /** * @return string */ public function __toString() { return "$this->accessKeyId#$this->accessKeySecret#$this->roleArn#$this->roleSessionName"; } /** * @return ShaHmac1Signature */ public function getSignature() { return new ShaHmac1Signature(); } /** * @return string */ public function getOriginalAccessKeyId() { return $this->accessKeyId; } /** * @return string */ public function getOriginalAccessKeySecret() { return $this->accessKeySecret; } /** * @return string * @throws Exception * @throws GuzzleException */ public function getAccessKeyId() { return $this->getSessionCredential()->getAccessKeyId(); } /** * @return StsCredential * @throws Exception * @throws GuzzleException */ protected function getSessionCredential() { return (new RamRoleArnProvider($this))->get(); } /** * @return string * @throws Exception * @throws GuzzleException */ public function getAccessKeySecret() { return $this->getSessionCredential()->getAccessKeySecret(); } /** * @return string * @throws Exception * @throws GuzzleException */ public function getSecurityToken() { return $this->getSessionCredential()->getSecurityToken(); } /** * @return string * @throws Exception * @throws GuzzleException */ public function getExpiration() { return $this->getSessionCredential()->getExpiration(); } } src/Request/AssumeRole.php000064400000002732146412134410011557 0ustar00signature = new ShaHmac1Signature(); $this->credential = $arnCredential; $this->uri = $this->uri->withHost('sts.aliyuncs.com'); $this->options['verify'] = false; $this->options['query']['RoleArn'] = $arnCredential->getRoleArn(); $this->options['query']['RoleSessionName'] = $arnCredential->getRoleSessionName(); $this->options['query']['DurationSeconds'] = Provider::DURATION_SECONDS; $this->options['query']['AccessKeyId'] = $this->credential->getOriginalAccessKeyId(); $this->options['query']['Version'] = '2015-04-01'; $this->options['query']['Action'] = 'AssumeRole'; $this->options['query']['RegionId'] = 'cn-hangzhou'; if ($arnCredential->getPolicy()) { $this->options['query']['Policy'] = $arnCredential->getPolicy(); } } } src/Request/GenerateSessionAccessKey.php000064400000002544146412134410014372 0ustar00signature = new ShaHmac256WithRsaSignature(); $this->credential = $credential; $this->uri = $this->uri->withHost('sts.ap-northeast-1.aliyuncs.com'); $this->options['verify'] = false; $this->options['query']['Version'] = '2015-04-01'; $this->options['query']['Action'] = 'GenerateSessionAccessKey'; $this->options['query']['RegionId'] = 'cn-hangzhou'; $this->options['query']['AccessKeyId'] = $credential->getPublicKeyId(); $this->options['query']['PublicKeyId'] = $credential->getPublicKeyId(); $this->options['query']['DurationSeconds'] = Provider::DURATION_SECONDS; } } src/Request/Request.php000064400000007673146412134410011141 0ustar00uri = (new Uri())->withScheme('https'); $this->options['http_errors'] = false; $this->options['connect_timeout'] = self::CONNECT_TIMEOUT; $this->options['timeout'] = self::TIMEOUT; // Turn on debug mode based on environment variable. if (strtolower(Helper::env('DEBUG')) === 'sdk') { $this->options['debug'] = true; } } /** * @return ResponseInterface * @throws Exception */ public function request() { $this->options['query']['Format'] = 'JSON'; $this->options['query']['SignatureMethod'] = $this->signature->getMethod(); $this->options['query']['SignatureVersion'] = $this->signature->getVersion(); $this->options['query']['SignatureNonce'] = self::uuid(json_encode($this->options['query'])); $this->options['query']['Timestamp'] = gmdate('Y-m-d\TH:i:s\Z'); $this->options['query']['Signature'] = $this->signature->sign( self::signString('GET', $this->options['query']), $this->credential->getOriginalAccessKeySecret() . '&' ); return self::createClient()->request('GET', (string)$this->uri, $this->options); } /** * @param string $salt * * @return string */ public static function uuid($salt) { return md5($salt . uniqid(md5(microtime(true)), true)); } /** * @param string $method * @param array $parameters * * @return string */ public static function signString($method, array $parameters) { ksort($parameters); $canonicalized = ''; foreach ($parameters as $key => $value) { $canonicalized .= '&' . self::percentEncode($key) . '=' . self::percentEncode($value); } return $method . '&%2F&' . self::percentEncode(substr($canonicalized, 1)); } /** * @param string $string * * @return null|string|string[] */ private static function percentEncode($string) { $result = rawurlencode($string); $result = str_replace(['+', '*'], ['%20', '%2A'], $result); $result = preg_replace('/%7E/', '~', $result); return $result; } /** * @return Client * @throws Exception */ public static function createClient() { if (Credentials::hasMock()) { $stack = HandlerStack::create(Credentials::getMock()); } else { $stack = HandlerStack::create(); } $stack->push(Middleware::mapResponse(static function (ResponseInterface $response) { return new Response($response); })); self::$config['handler'] = $stack; return new Client(self::$config); } } src/RsaKeyPairCredential.php000064400000006177146412134410012064 0ustar00publicKeyId = $public_key_id; $this->config = $config; try { $this->privateKey = file_get_contents($private_key_file); } catch (Exception $exception) { throw new InvalidArgumentException($exception->getMessage()); } } /** * @return array */ public function getConfig() { return $this->config; } /** * @return string */ public function getOriginalAccessKeyId() { return $this->getPublicKeyId(); } /** * @return string */ public function getPublicKeyId() { return $this->publicKeyId; } /** * @return string */ public function getOriginalAccessKeySecret() { return $this->getPrivateKey(); } /** * @return mixed */ public function getPrivateKey() { return $this->privateKey; } /** * @return string */ public function __toString() { return "publicKeyId#$this->publicKeyId"; } /** * @return ShaHmac1Signature */ public function getSignature() { return new ShaHmac1Signature(); } /** * @return string * @throws Exception * @throws GuzzleException */ public function getAccessKeyId() { return $this->getSessionCredential()->getAccessKeyId(); } /** * @return StsCredential * @throws Exception * @throws GuzzleException */ protected function getSessionCredential() { return (new RsaKeyPairProvider($this))->get(); } /** * @return string * @throws Exception * @throws GuzzleException */ public function getAccessKeySecret() { return $this->getSessionCredential()->getAccessKeySecret(); } /** * @return string * @throws Exception * @throws GuzzleException */ public function getSecurityToken() { return $this->getSessionCredential()->getSecurityToken(); } /** * @return int * @throws Exception * @throws GuzzleException */ public function getExpiration() { return $this->getSessionCredential()->getExpiration(); } } src/Signature/BearerTokenSignature.php000064400000001316146412134410014071 0ustar00getMessage() ); } return base64_encode($binarySignature); } } src/Signature/SignatureInterface.php000064400000001055146412134410013570 0ustar00accessKeyId = $access_key_id; $this->accessKeySecret = $access_key_secret; $this->expiration = $expiration; $this->securityToken = $security_token; } /** * @return int */ public function getExpiration() { return $this->expiration; } /** * @return string */ public function getAccessKeyId() { return $this->accessKeyId; } /** * @return string */ public function getAccessKeySecret() { return $this->accessKeySecret; } /** * @return string */ public function getSecurityToken() { return $this->securityToken; } /** * @return string */ public function __toString() { return "$this->accessKeyId#$this->accessKeySecret#$this->securityToken"; } /** * @return ShaHmac1Signature */ public function getSignature() { return new ShaHmac1Signature(); } }