init commit

This commit is contained in:
2026-03-17 09:56:00 +08:00
commit e2c8ae752d
6827 changed files with 1211784 additions and 0 deletions

View File

@@ -0,0 +1,18 @@
# CHANGELOG
## 1.2.0 - 2024-10-17
- Refactor all credentials providers.
## 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 <https://github.com/aliyun/credentials-php> for more information.

View File

@@ -0,0 +1,30 @@
# 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

View File

@@ -0,0 +1,13 @@
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.
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.

View File

@@ -0,0 +1,88 @@
# NOTICE
<https://www.alibabacloud.com/>
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
<http://www.apache.org/licenses/LICENSE-2.0>
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
<https://github.com/guzzle/guzzle>
Copyright (c) 2011-2018 Michael Dowling, https://github.com/mtdowling <mtdowling@gmail.com>
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
<https://github.com/mtdowling/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
<https://github.com/adbario/php-dot-notation>
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.

View File

@@ -0,0 +1,21 @@
# Security Policy
## Supported Versions
Use this section to tell people about which versions of your project are
currently being supported with security updates.
| Version | Supported |
| ------- | ------------------ |
| 5.1.x | :white_check_mark: |
| 5.0.x | :x: |
| 4.0.x | :white_check_mark: |
| < 4.0 | :x: |
## Reporting a Vulnerability
Use this section to tell people how to report a vulnerability.
Tell them where to go, how often they can expect to get an update on a
reported vulnerability, what to expect if the vulnerability is accepted or
declined, etc.

View File

@@ -0,0 +1,6 @@
Upgrading Guide
===============
1.x
-----------------------
- This is the first version. See <https://github.com/aliyun/credentials-php> for more information.

View File

@@ -0,0 +1,107 @@
{
"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|^9.3",
"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/*"
}
}

View File

@@ -0,0 +1,86 @@
<?php
namespace AlibabaCloud\Credentials;
use AlibabaCloud\Credentials\Utils\Filter;
use AlibabaCloud\Credentials\Credential\CredentialModel;
use AlibabaCloud\Credentials\Signature\ShaHmac1Signature;
/**
* @deprecated
* Use the AccessKey to complete the authentication.
*/
class AccessKeyCredential implements CredentialsInterface
{
/**
* @var string
*/
private $accessKeyId;
/**
* @var string
*/
private $accessKeySecret;
/**
* AccessKeyCredential constructor.
*
* @param string $access_key_id Access key ID
* @param string $access_key_secret Access Key Secret
*/
public function __construct($access_key_id, $access_key_secret)
{
Filter::accessKey($access_key_id, $access_key_secret);
$this->accessKeyId = $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 '';
}
/**
* @inheritDoc
*/
public function getCredential()
{
return new CredentialModel([
'accessKeyId' => $this->accessKeyId,
'accessKeySecret' => $this->accessKeySecret,
'type' => 'access_key',
]);
}
}

View File

@@ -0,0 +1,67 @@
<?php
namespace AlibabaCloud\Credentials;
use AlibabaCloud\Credentials\Utils\Filter;
use AlibabaCloud\Credentials\Credential\CredentialModel;
use AlibabaCloud\Credentials\Signature\BearerTokenSignature;
/**
* Class BearerTokenCredential
*/
class BearerTokenCredential implements CredentialsInterface
{
/**
* @var string
*/
private $bearerToken;
/**
* BearerTokenCredential constructor.
*
* @param $bearer_token
*/
public function __construct($bearer_token)
{
Filter::bearerToken($bearer_token);
$this->bearerToken = $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();
}
/**
* @inheritDoc
*/
public function getCredential()
{
return new CredentialModel([
'bearerToken' => $this->bearerToken,
'type' => 'bearer',
]);
}
}

View File

@@ -0,0 +1,268 @@
<?php
namespace AlibabaCloud\Credentials;
use AlibabaCloud\Credentials\Credential\Config;
use AlibabaCloud\Credentials\Credential\CredentialModel;
use AlibabaCloud\Credentials\Providers\DefaultCredentialsProvider;
use AlibabaCloud\Credentials\Providers\EcsRamRoleCredentialsProvider;
use AlibabaCloud\Credentials\Providers\OIDCRoleArnCredentialsProvider;
use AlibabaCloud\Credentials\Providers\RamRoleArnCredentialsProvider;
use AlibabaCloud\Credentials\Providers\RsaKeyPairCredentialsProvider;
use AlibabaCloud\Credentials\Providers\StaticAKCredentialsProvider;
use AlibabaCloud\Credentials\Providers\StaticSTSCredentialsProvider;
use AlibabaCloud\Credentials\Providers\URLCredentialsProvider;
use AlibabaCloud\Credentials\Utils\Helper;
use GuzzleHttp\Exception\GuzzleException;
use InvalidArgumentException;
use RuntimeException;
/**
* Class Credential
*
* @package AlibabaCloud\Credentials
*
*/
class Credential
{
/**
* Version of the Client
*/
const VERSION = '1.1.5';
/**
* @var Config
*/
protected $config;
/**
* @var CredentialsInterface
*/
protected $credential;
/**
* Credential constructor.
*
* @param array|Config $config
*/
public function __construct($config = [])
{
if (\is_array($config)) {
if (empty($config)) {
$this->config = null;
} else {
$this->config = new Config($this->parseConfig($config));
}
} else {
$this->config = $config;
}
$this->credential = $this->getCredentials($this->config);
}
/**
* @param array $config
*
* @return array
*/
private function parseConfig($config)
{
$res = [];
foreach (\array_change_key_case($config) as $key => $value) {
$res[Helper::snakeToCamelCase($key)] = $value;
}
return $res;
}
/**
* Credentials getter.
*
* @param Config $config
* @return CredentialsInterface
*
*/
private function getCredentials($config)
{
if (is_null($config)) {
return new CredentialsProviderWrap('default', new DefaultCredentialsProvider());
}
switch ($config->type) {
case 'access_key':
$provider = new StaticAKCredentialsProvider([
'accessKeyId' => $config->accessKeyId,
'accessKeySecret' => $config->accessKeySecret,
]);
return new CredentialsProviderWrap('access_key', $provider);
case 'sts':
$provider = new StaticSTSCredentialsProvider([
'accessKeyId' => $config->accessKeyId,
'accessKeySecret' => $config->accessKeySecret,
'securityToken' => $config->securityToken,
]);
return new CredentialsProviderWrap('sts', $provider);
case 'bearer':
return new BearerTokenCredential($config->bearerToken);
case 'ram_role_arn':
if (!is_null($config->securityToken) && $config->securityToken !== '') {
$innerProvider = new StaticSTSCredentialsProvider([
'accessKeyId' => $config->accessKeyId,
'accessKeySecret' => $config->accessKeySecret,
'securityToken' => $config->securityToken,
]);
} else {
$innerProvider = new StaticAKCredentialsProvider([
'accessKeyId' => $config->accessKeyId,
'accessKeySecret' => $config->accessKeySecret,
]);
}
$provider = new RamRoleArnCredentialsProvider([
'credentialsProvider' => $innerProvider,
'roleArn' => $config->roleArn,
'roleSessionName' => $config->roleSessionName,
'policy' => $config->policy,
'durationSeconds' => $config->roleSessionExpiration,
'externalId' => $config->externalId,
'stsEndpoint' => $config->STSEndpoint,
], [
'connectTimeout' => $config->connectTimeout,
'readTimeout' => $config->readTimeout,
]);
return new CredentialsProviderWrap('ram_role_arn', $provider);
case 'rsa_key_pair':
$provider = new RsaKeyPairCredentialsProvider([
'publicKeyId' => $config->publicKeyId,
'privateKeyFile' => $config->privateKeyFile,
'durationSeconds' => $config->roleSessionExpiration,
'stsEndpoint' => $config->STSEndpoint,
], [
'connectTimeout' => $config->connectTimeout,
'readTimeout' => $config->readTimeout,
]);
return new CredentialsProviderWrap('rsa_key_pair', $provider);
case 'ecs_ram_role':
$provider = new EcsRamRoleCredentialsProvider([
'roleName' => $config->roleName,
'disableIMDSv1' => $config->disableIMDSv1,
], [
'connectTimeout' => $config->connectTimeout,
'readTimeout' => $config->readTimeout,
]);
return new CredentialsProviderWrap('ecs_ram_role', $provider);
case 'oidc_role_arn':
$provider = new OIDCRoleArnCredentialsProvider([
'roleArn' => $config->roleArn,
'oidcProviderArn' => $config->oidcProviderArn,
'oidcTokenFilePath' => $config->oidcTokenFilePath,
'roleSessionName' => $config->roleSessionName,
'policy' => $config->policy,
'durationSeconds' => $config->roleSessionExpiration,
'stsEndpoint' => $config->STSEndpoint,
], [
'connectTimeout' => $config->connectTimeout,
'readTimeout' => $config->readTimeout,
]);
return new CredentialsProviderWrap('oidc_role_arn', $provider);
case "credentials_uri":
$provider = new URLCredentialsProvider([
'credentialsURI' => $config->credentialsURI,
], [
'connectTimeout' => $config->connectTimeout,
'readTimeout' => $config->readTimeout,
]);
return new CredentialsProviderWrap('credentials_uri', $provider);
default:
throw new InvalidArgumentException('Unsupported credential type option: ' . $config->type . ', support: access_key, sts, bearer, ecs_ram_role, ram_role_arn, rsa_key_pair, oidc_role_arn, credentials_uri');
}
}
/**
* @return CredentialModel
* @throws RuntimeException
* @throws GuzzleException
*/
public function getCredential()
{
return $this->credential->getCredential();
}
/**
* @return array
*/
public function getConfig()
{
return $this->config->toMap();
}
/**
* @deprecated use getCredential() instead
*
* @return string
* @throws RuntimeException
* @throws GuzzleException
*/
public function getType()
{
return $this->credential->getCredential()->getType();
}
/**
* @deprecated use getCredential() instead
*
* @return string
* @throws RuntimeException
* @throws GuzzleException
*/
public function getAccessKeyId()
{
return $this->credential->getCredential()->getAccessKeyId();
}
/**
* @deprecated use getCredential() instead
*
* @return string
* @throws RuntimeException
* @throws GuzzleException
*/
public function getAccessKeySecret()
{
return $this->credential->getCredential()->getAccessKeySecret();
}
/**
* @deprecated use getCredential() instead
*
* @return string
* @throws RuntimeException
* @throws GuzzleException
*/
public function getSecurityToken()
{
return $this->credential->getCredential()->getSecurityToken();
}
/**
* @deprecated use getCredential() instead
*
* @return string
* @throws RuntimeException
* @throws GuzzleException
*/
public function getBearerToken()
{
return $this->credential->getCredential()->getBearerToken();
}
/**
* @param string $name
* @param array $arguments
*
* @return mixed
*/
public function __call($name, $arguments)
{
return $this->credential->$name($arguments);
}
}

View File

@@ -0,0 +1,270 @@
<?php
namespace AlibabaCloud\Credentials\Credential;
use AlibabaCloud\Tea\Model;
class Config extends Model
{
public function validate()
{
}
public function toMap()
{
$res = [];
if (null !== $this->accessKeyId) {
$res['accessKeyId'] = $this->accessKeyId;
}
if (null !== $this->accessKeySecret) {
$res['accessKeySecret'] = $this->accessKeySecret;
}
if (null !== $this->securityToken) {
$res['securityToken'] = $this->securityToken;
}
if (null !== $this->bearerToken) {
$res['bearerToken'] = $this->bearerToken;
}
if (null !== $this->durationSeconds) {
$res['durationSeconds'] = $this->durationSeconds;
}
if (null !== $this->roleArn) {
$res['roleArn'] = $this->roleArn;
}
if (null !== $this->policy) {
$res['policy'] = $this->policy;
}
if (null !== $this->roleSessionExpiration) {
$res['roleSessionExpiration'] = $this->roleSessionExpiration;
}
if (null !== $this->roleSessionName) {
$res['roleSessionName'] = $this->roleSessionName;
}
if (null !== $this->publicKeyId) {
$res['publicKeyId'] = $this->publicKeyId;
}
if (null !== $this->privateKeyFile) {
$res['privateKeyFile'] = $this->privateKeyFile;
}
if (null !== $this->roleName) {
$res['roleName'] = $this->roleName;
}
if (null !== $this->credentialsURI) {
$res['credentialsURI'] = $this->credentialsURI;
}
if (null !== $this->type) {
$res['type'] = $this->type;
}
if (null !== $this->STSEndpoint) {
$res['STSEndpoint'] = $this->STSEndpoint;
}
if (null !== $this->externalId) {
$res['externalId'] = $this->externalId;
}
return $res;
}
/**
* @param array $map
* @return Config
*/
public static function fromMap($map = [])
{
$model = new self();
if (isset($map['accessKeyId'])) {
$model->accessKeyId = $map['accessKeyId'];
}
if (isset($map['accessKeySecret'])) {
$model->accessKeySecret = $map['accessKeySecret'];
}
if (isset($map['securityToken'])) {
$model->securityToken = $map['securityToken'];
}
if (isset($map['bearerToken'])) {
$model->bearerToken = $map['bearerToken'];
}
if (isset($map['durationSeconds'])) {
$model->durationSeconds = $map['durationSeconds'];
}
if (isset($map['roleArn'])) {
$model->roleArn = $map['roleArn'];
}
if (isset($map['policy'])) {
$model->policy = $map['policy'];
}
if (isset($map['roleSessionExpiration'])) {
$model->roleSessionExpiration = $map['roleSessionExpiration'];
}
if (isset($map['roleSessionName'])) {
$model->roleSessionName = $map['roleSessionName'];
}
if (isset($map['publicKeyId'])) {
$model->publicKeyId = $map['publicKeyId'];
}
if (isset($map['privateKeyFile'])) {
$model->privateKeyFile = $map['privateKeyFile'];
}
if (isset($map['roleName'])) {
$model->roleName = $map['roleName'];
}
if (isset($map['credentialsURI'])) {
$model->credentialsURI = $map['credentialsURI'];
}
if (isset($map['type'])) {
$model->type = $map['type'];
}
if (isset($map['STSEndpoint'])) {
$model->STSEndpoint = $map['STSEndpoint'];
}
if (isset($map['externalId'])) {
$model->externalId = $map['externalId'];
}
return $model;
}
/**
* @description credential type
* @example access_key
* @var string
*/
public $type = 'default';
/**
* @description accesskey id
* @var string
*/
public $accessKeyId;
/**
* @description accesskey secret
* @var string
*/
public $accessKeySecret;
/**
* @description security token
* @var string
*/
public $securityToken;
/**
* @description bearer token
* @var string
*/
public $bearerToken;
/**
* @description role name
* @var string
*/
public $roleName;
/**
* @description role arn
* @var string
*/
public $roleArn;
/**
* @description oidc provider arn
* @var string
*/
public $oidcProviderArn;
/**
* @description oidc token file path
* @var string
*/
public $oidcTokenFilePath;
/**
* @description role session expiration
* @example 3600
* @var int
*/
public $roleSessionExpiration;
/**
* @description role session name
* @var string
*/
public $roleSessionName;
/**
* @description role arn policy
* @var string
*/
public $policy;
/**
* @description external id for ram role arn
* @var string
*/
public $externalId;
/**
* @description sts endpoint
* @var string
*/
public $STSEndpoint;
public $publicKeyId;
public $privateKeyFile;
/**
* @description read timeout
* @var int
*/
public $readTimeout;
/**
* @description connection timeout
* @var int
*/
public $connectTimeout;
/**
* @description disable IMDS v1
* @var bool
*/
public $disableIMDSv1;
/**
* @description credentials URI
* @var string
*/
public $credentialsURI;
/**
* @deprecated
*/
public $metadataTokenDuration;
/**
* @deprecated
*/
public $durationSeconds;
/**
* @deprecated
*/
public $host;
/**
* @deprecated
*/
public $expiration;
/**
* @deprecated
*/
public $certFile = "";
/**
* @deprecated
*/
public $certPassword = "";
/**
* @internal
*/
public $proxy;
}

View File

@@ -0,0 +1,143 @@
<?php
// This file is auto-generated, don't edit it. Thanks.
namespace AlibabaCloud\Credentials\Credential;
use AlibabaCloud\Tea\Model;
class CredentialModel extends Model
{
public function validate()
{
}
public function toMap()
{
$res = [];
if (null !== $this->accessKeyId) {
$res['accessKeyId'] = $this->accessKeyId;
}
if (null !== $this->accessKeySecret) {
$res['accessKeySecret'] = $this->accessKeySecret;
}
if (null !== $this->securityToken) {
$res['securityToken'] = $this->securityToken;
}
if (null !== $this->bearerToken) {
$res['bearerToken'] = $this->bearerToken;
}
if (null !== $this->type) {
$res['type'] = $this->type;
}
if (null !== $this->providerName) {
$res['providerName'] = $this->providerName;
}
return $res;
}
/**
* @param array $map
* @return CredentialModel
*/
public static function fromMap($map = [])
{
$model = new self();
if (isset($map['accessKeyId'])) {
$model->accessKeyId = $map['accessKeyId'];
}
if (isset($map['accessKeySecret'])) {
$model->accessKeySecret = $map['accessKeySecret'];
}
if (isset($map['securityToken'])) {
$model->securityToken = $map['securityToken'];
}
if (isset($map['bearerToken'])) {
$model->bearerToken = $map['bearerToken'];
}
if (isset($map['type'])) {
$model->type = $map['type'];
}
if(isset($map['providerName'])){
$model->providerName = $map['providerName'];
}
return $model;
}
/**
* @description accesskey id
* @var string
*/
public $accessKeyId;
/**
* @description accesskey secret
* @var string
*/
public $accessKeySecret;
/**
* @description security token
* @var string
*/
public $securityToken;
/**
* @description bearer token
* @var string
*/
public $bearerToken;
/**
* @description type
* @example access_key
* @var string
*/
public $type;
/**
* @description provider name
* @example cli_profile/static_ak
* @var string
*/
public $providerName;
/**
* @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 getBearerToken()
{
return $this->bearerToken;
}
public function getType()
{
return $this->type;
}
public function getProviderName()
{
return $this->providerName;
}
}

View File

@@ -0,0 +1,97 @@
<?php
namespace AlibabaCloud\Credentials\Credential;
use AlibabaCloud\Credentials\Providers\Credentials;
class RefreshResult
{
/**
* RefreshResult constructor.
* @param Credentials $params
* @param int $staleTime
* @param int $prefetchTime
*/
public function __construct($credentials = null, $staleTime = PHP_INT_MAX, $prefetchTime = PHP_INT_MAX)
{
$this->credentials = $credentials;
$this->staleTime = $staleTime;
$this->prefetchTime = $prefetchTime;
}
public function validate() {}
public function toMap()
{
$res = [];
if (null !== $this->staleTime) {
$res['staleTime'] = $this->staleTime;
}
if (null !== $this->prefetchTime) {
$res['prefetchTime'] = $this->prefetchTime;
}
if (null !== $this->credentials) {
$res['credentials'] = $this->credentials;
}
return $res;
}
/**
* @param array $map
* @return RefreshResult
*/
public static function fromMap($map = [])
{
$model = new self();
if (isset($map['staleTime'])) {
$model->staleTime = $map['staleTime'];
}
if (isset($map['prefetchTime'])) {
$model->staleTime = $map['prefetchTime'];
}
if (isset($map['credentials'])) {
$model->staleTime = $map['credentials'];
}
return $model;
}
/**
* @description staleTime
* @var int
*/
public $staleTime;
/**
* @description prefetchTime
* @var int
*/
public $prefetchTime;
/**
* @description credentials
* @var Credentials
*/
public $credentials;
/**
* @return Credentials
*/
public function credentials()
{
return $this->credentials;
}
/**
* @var int
*/
public function staleTime()
{
return $this->staleTime;
}
/**
* @var int
*/
public function prefetchTime()
{
return $this->prefetchTime;
}
}

View File

@@ -0,0 +1,104 @@
<?php
namespace AlibabaCloud\Credentials;
use AlibabaCloud\Credentials\Providers\ChainProvider;
use AlibabaCloud\Credentials\Utils\Filter;
use AlibabaCloud\Credentials\Utils\MockTrait;
use ReflectionException;
use RuntimeException;
/**
* Class Credentials
*
* @package AlibabaCloud\Credentials
*/
class Credentials
{
use MockTrait;
/**
* @var array|CredentialsInterface[] containers of credentials
*/
protected static $credentials = [];
/**
* Get the credential instance by name.
*
* @param string $name
*
* @return Credential
* @throws ReflectionException
*/
public static function get($name = null)
{
if ($name !== null) {
Filter::credentialName($name);
} else {
$name = ChainProvider::getDefaultName();
}
self::load();
if (self::has($name)) {
return new Credential(self::$credentials[\strtolower($name)]);
}
throw new RuntimeException("Credential '$name' not found");
}
private static function load()
{
if (self::$credentials) {
return;
}
if (ChainProvider::hasCustomChain()) {
ChainProvider::customProvider(ChainProvider::getDefaultName());
} else {
ChainProvider::defaultProvider(ChainProvider::getDefaultName());
}
}
/**
* Determine whether there is a credential.
*
* @param string $name
*
* @return bool
*/
public static function has($name)
{
Filter::credentialName($name);
return isset(self::$credentials[\strtolower($name)]);
}
public static function flush()
{
self::$credentials = [];
}
/**
* Get all credentials.
*
* @return array
*/
public static function all()
{
self::load();
return self::$credentials;
}
/**
* @param string $name
* @param array $credential
*/
public static function set($name, array $credential)
{
Filter::credentialName($name);
self::$credentials[\strtolower($name)] = \array_change_key_case($credential);
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace AlibabaCloud\Credentials;
use AlibabaCloud\Credentials\Credential\CredentialModel;
use AlibabaCloud\Credentials\Signature\SignatureInterface;
/**
* @internal This class is intended for internal use within the package.
* Interface CredentialsInterface
*
* @codeCoverageIgnore
*/
interface CredentialsInterface
{
/**
* @deprecated
* @return string
*/
public function __toString();
/**
* @deprecated
* @return SignatureInterface
*/
public function getSignature();
/**
* @return CredentialModel
*/
public function getCredential();
}

View File

@@ -0,0 +1,76 @@
<?php
namespace AlibabaCloud\Credentials;
use AlibabaCloud\Credentials\Credential\CredentialModel;
use AlibabaCloud\Credentials\Providers\CredentialsProvider;
/**
* @internal This class is intended for internal use within the package.
* Class CredentialsProviderWrap
*
* @package AlibabaCloud\Credentials
*/
class CredentialsProviderWrap implements CredentialsInterface
{
/**
* @var string
*/
private $typeName;
/**
* @var CredentialsProvider
*/
private $credentialsProvider;
/**
* CLIProfileCredentialsProvider constructor.
*
* @param string $typeName
* @param CredentialsProvider $credentialsProvider
*/
public function __construct($typeName, $credentialsProvider)
{
$this->typeName = $typeName;
$this->credentialsProvider = $credentialsProvider;
}
/**
* @inheritDoc
*/
public function getCredential()
{
$credentials = $this->credentialsProvider->getCredentials();
return new CredentialModel([
'accessKeyId' => $credentials->getAccessKeyId(),
'accessKeySecret' => $credentials->getAccessKeySecret(),
'securityToken' => $credentials->getSecurityToken(),
'type' => $this->typeName,
'providerName' => $credentials->getProviderName(),
]);
}
/**
* @param string $name
* @param array $arguments
*
* @return mixed
*/
public function __call($name, $arguments)
{
return $this->credentialsProvider->$name($arguments);
}
public function __toString()
{
return "credentialsProviderWrap#$this->typeName";
}
/**
* @return ShaHmac1Signature
*/
public function getSignature()
{
return null;
}
}

View File

@@ -0,0 +1,199 @@
<?php
namespace AlibabaCloud\Credentials;
use AlibabaCloud\Credentials\Providers\EcsRamRoleCredentialsProvider;
use AlibabaCloud\Credentials\Credential\CredentialModel;
use AlibabaCloud\Credentials\Signature\ShaHmac1Signature;
use AlibabaCloud\Credentials\Request\Request;
use AlibabaCloud\Credentials\Utils\Filter;
use Exception;
use GuzzleHttp\Exception\GuzzleException;
use InvalidArgumentException;
use RuntimeException;
/**
* @deprecated
* Use the RAM role of an ECS instance to complete the authentication.
*/
class EcsRamRoleCredential implements CredentialsInterface
{
/**
* @var string
*/
private $roleName;
/**
* @var boolean
*/
private $disableIMDSv1;
/**
* @var int
*/
private $metadataTokenDuration;
/**
* EcsRamRoleCredential constructor.
*
* @param $role_name
*/
public function __construct($role_name = null, $disable_imdsv1 = false, $metadata_token_duration = 21600)
{
Filter::roleName($role_name);
$this->roleName = $role_name;
Filter::disableIMDSv1($disable_imdsv1);
$this->disableIMDSv1 = $disable_imdsv1;
$this->metadataTokenDuration = $metadata_token_duration;
}
/**
* @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 AlibabaCloud\Credentials\Providers\Credentials
* @throws Exception
* @throws GuzzleException
*/
protected function getSessionCredential()
{
$params = [
"roleName" => $this->roleName,
'disableIMDSv1' => $this->disableIMDSv1,
'metadataTokenDuration' => $this->metadataTokenDuration,
];
return (new EcsRamRoleCredentialsProvider($params))->getCredentials();
}
/**
* @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();
}
/**
* @return bool
*/
public function isDisableIMDSv1()
{
return $this->disableIMDSv1;
}
/**
* @inheritDoc
*/
public function getCredential()
{
$credentials = $this->getSessionCredential();
return new CredentialModel([
'accessKeyId' => $credentials->getAccessKeyId(),
'accessKeySecret' => $credentials->getAccessKeySecret(),
'securityToken' => $credentials->getSecurityToken(),
'type' => 'ecs_ram_role',
]);
}
}

View File

@@ -0,0 +1,193 @@
<?php
namespace AlibabaCloud\Credentials\Providers;
use AlibabaCloud\Credentials\Utils\Helper;
use RuntimeException;
/**
* @internal This class is intended for internal use within the package.
* Class CLIProfileCredentialsProvider
*
* @package AlibabaCloud\Credentials\Providers
*/
class CLIProfileCredentialsProvider implements CredentialsProvider
{
/**
* @var string
*/
private $profileName;
/**
* @var CredentialsProvider
*/
private $credentialsProvider;
/**
* CLIProfileCredentialsProvider constructor.
*
* @param array $params
*/
public function __construct(array $params = [])
{
$this->filterProfileName($params);
}
private function filterProfileName(array $params)
{
if (Helper::envNotEmpty('ALIBABA_CLOUD_PROFILE')) {
$this->profileName = Helper::env('ALIBABA_CLOUD_PROFILE');
}
if (isset($params['profileName'])) {
$this->profileName = $params['profileName'];
}
}
/**
* @return bool
*/
private function shouldReloadCredentialsProvider()
{
if (is_null($this->credentialsProvider)) {
return true;
}
return false;
}
/**
* @return CredentialsProvider
*/
protected function reloadCredentialsProvider($profileFile, $profileName)
{
if (!Helper::inOpenBasedir($profileFile)) {
throw new RuntimeException('Unable to open credentials file: ' . $profileFile);
}
if (!\is_readable($profileFile) || !\is_file($profileFile)) {
throw new RuntimeException('Credentials file is not readable: ' . $profileFile);
}
$jsonContent = \file_get_contents($profileFile);
$fileArray = json_decode($jsonContent, true);
if (\is_array($fileArray) && !empty($fileArray)) {
if (is_null($profileName) || $profileName === '') {
$profileName = $fileArray['current'];
}
if (isset($fileArray['profiles'])) {
foreach ($fileArray['profiles'] as $profile) {
if (Helper::unsetReturnNull($profile, 'name') === $profileName) {
switch (Helper::unsetReturnNull($profile, 'mode')) {
case 'AK':
return new StaticAKCredentialsProvider([
'accessKeyId' => Helper::unsetReturnNull($profile, 'access_key_id'),
'accessKeySecret' => Helper::unsetReturnNull($profile, 'access_key_secret'),
]);
case 'StsToken':
return new StaticSTSCredentialsProvider([
'accessKeyId' => Helper::unsetReturnNull($profile, 'access_key_id'),
'accessKeySecret' => Helper::unsetReturnNull($profile, 'access_key_secret'),
'securityToken' => Helper::unsetReturnNull($profile, 'sts_token'),
]);
case 'RamRoleArn':
$innerProvider = new StaticAKCredentialsProvider([
'accessKeyId' => Helper::unsetReturnNull($profile, 'access_key_id'),
'accessKeySecret' => Helper::unsetReturnNull($profile, 'access_key_secret'),
]);
return new RamRoleArnCredentialsProvider([
'credentialsProvider' => $innerProvider,
'roleArn' => Helper::unsetReturnNull($profile, 'ram_role_arn'),
'roleSessionName' => Helper::unsetReturnNull($profile, 'ram_session_name'),
'durationSeconds' => Helper::unsetReturnNull($profile, 'expired_seconds'),
'policy' => Helper::unsetReturnNull($profile, 'policy'),
'externalId' => Helper::unsetReturnNull($profile, 'external_id'),
'stsRegionId' => Helper::unsetReturnNull($profile, 'sts_region'),
'enableVpc' => Helper::unsetReturnNull($profile, 'enable_vpc'),
]);
case 'EcsRamRole':
return new EcsRamRoleCredentialsProvider([
'roleName' => Helper::unsetReturnNull($profile, 'ram_role_name'),
]);
case 'OIDC':
return new OIDCRoleArnCredentialsProvider([
'roleArn' => Helper::unsetReturnNull($profile, 'ram_role_arn'),
'oidcProviderArn' => Helper::unsetReturnNull($profile, 'oidc_provider_arn'),
'oidcTokenFilePath' => Helper::unsetReturnNull($profile, 'oidc_token_file'),
'roleSessionName' => Helper::unsetReturnNull($profile, 'ram_session_name'),
'durationSeconds' => Helper::unsetReturnNull($profile, 'expired_seconds'),
'policy' => Helper::unsetReturnNull($profile, 'policy'),
'stsRegionId' => Helper::unsetReturnNull($profile, 'sts_region'),
'enableVpc' => Helper::unsetReturnNull($profile, 'enable_vpc'),
]);
case 'ChainableRamRoleArn':
$previousProvider = $this->reloadCredentialsProvider($profileFile, Helper::unsetReturnNull($profile, 'source_profile'));
return new RamRoleArnCredentialsProvider([
'credentialsProvider' => $previousProvider,
'roleArn' => Helper::unsetReturnNull($profile, 'ram_role_arn'),
'roleSessionName' => Helper::unsetReturnNull($profile, 'ram_session_name'),
'durationSeconds' => Helper::unsetReturnNull($profile, 'expired_seconds'),
'policy' => Helper::unsetReturnNull($profile, 'policy'),
'externalId' => Helper::unsetReturnNull($profile, 'external_id'),
'stsRegionId' => Helper::unsetReturnNull($profile, 'sts_region'),
'enableVpc' => Helper::unsetReturnNull($profile, 'enable_vpc'),
]);
default:
throw new RuntimeException('Unsupported credential mode from CLI credentials file: ' . Helper::unsetReturnNull($profile, 'mode'));
}
}
}
}
}
throw new RuntimeException('Failed to get credential from CLI credentials file: ' . $profileFile);
}
/**
* Get credential.
*
* @return Credentials
* @throws RuntimeException
*/
public function getCredentials()
{
if (Helper::envNotEmpty('ALIBABA_CLOUD_CLI_PROFILE_DISABLED') && Helper::env('ALIBABA_CLOUD_CLI_PROFILE_DISABLED') === true) {
throw new RuntimeException('CLI credentials file is disabled');
}
$cliProfileFile = self::getDefaultFile();
if ($this->shouldReloadCredentialsProvider()) {
$this->credentialsProvider = $this->reloadCredentialsProvider($cliProfileFile, $this->profileName);
}
$credentials = $this->credentialsProvider->getCredentials();
return new Credentials([
'accessKeyId' => $credentials->getAccessKeyId(),
'accessKeySecret' => $credentials->getAccessKeySecret(),
'securityToken' => $credentials->getSecurityToken(),
'providerName' => $this->getProviderName() . '/' . $this->credentialsProvider->getProviderName(),
]);
}
/**
* Get the default credential file.
*
* @return string
*/
private function getDefaultFile()
{
return Helper::getHomeDirectory() .
DIRECTORY_SEPARATOR .
'.aliyun' .
DIRECTORY_SEPARATOR .
'config.json';
}
/**
* @return string
*/
public function getProviderName()
{
return 'cli_profile';
}
}

View File

@@ -0,0 +1,188 @@
<?php
namespace AlibabaCloud\Credentials\Providers;
use AlibabaCloud\Credentials\Credentials;
use AlibabaCloud\Credentials\Utils\Helper;
use Closure;
use InvalidArgumentException;
use RuntimeException;
/**
* @deprecated
* Class ChainProvider
*
* @package AlibabaCloud\Credentials\Providers
*/
class ChainProvider
{
/**
* @var array
*/
private static $customChains;
/**
* @param callable ...$providers
*/
public static function set(...$providers)
{
if (empty($providers)) {
throw new InvalidArgumentException('No providers in chain');
}
foreach ($providers as $provider) {
if (!$provider instanceof Closure) {
throw new InvalidArgumentException('Providers must all be Closures');
}
}
self::$customChains = $providers;
}
/**
* @return bool
*/
public static function hasCustomChain()
{
return (bool)self::$customChains;
}
public static function flush()
{
self::$customChains = [];
}
/**
* @param string $name
*/
public static function customProvider($name)
{
foreach (self::$customChains as $provider) {
$provider();
if (Credentials::has($name)) {
break;
}
}
}
/**
* @param string $name
*/
public static function defaultProvider($name)
{
$providers = [
self::env(),
self::ini(),
self::instance(),
];
foreach ($providers as $provider) {
$provider();
if (Credentials::has($name)) {
break;
}
}
}
/**
* @return Closure
*/
public static function env()
{
return static function () {
$accessKeyId = Helper::envNotEmpty('ALIBABA_CLOUD_ACCESS_KEY_ID');
$accessKeySecret = Helper::envNotEmpty('ALIBABA_CLOUD_ACCESS_KEY_SECRET');
if ($accessKeyId && $accessKeySecret) {
Credentials::set(
self::getDefaultName(),
[
'type' => '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,
]
);
}
};
}
}

View File

@@ -0,0 +1,87 @@
<?php
namespace AlibabaCloud\Credentials\Providers;
/**
* @internal This class is intended for internal use within the package.
* Class Credentials
*
* @package AlibabaCloud\Credentials\Providers
*/
class Credentials
{
/**
* @var string
*/
private $accessKeyId;
/**
* @var string
*/
private $accessKeySecret;
/**
* @var string
*/
private $securityToken;
/**
* @var int
*/
private $expiration;
/**
* @var int
*/
private $providerName;
public function __construct($config = [])
{
if (!empty($config)) {
foreach ($config as $k => $v) {
$this->{$k} = $v;
}
}
}
/**
* @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 int
*/
public function getExpiration()
{
return $this->expiration;
}
/**
* @return string
*/
public function getProviderName()
{
return $this->providerName;
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace AlibabaCloud\Credentials\Providers;
/**
* @internal This class is intended for internal use within the package.
* Interface CredentialsInterface
*
* @codeCoverageIgnore
*/
interface CredentialsProvider
{
/**
* @return Credentials
*/
public function getCredentials();
/**
* @return string
*/
public function getProviderName();
}

View File

@@ -0,0 +1,175 @@
<?php
namespace AlibabaCloud\Credentials\Providers;
use AlibabaCloud\Credentials\Utils\Filter;
use AlibabaCloud\Credentials\Utils\Helper;
use InvalidArgumentException;
use RuntimeException;
use Exception;
/**
* @internal This class is intended for internal use within the package.
* Class DefaultCredentialsProvider
*
* @package AlibabaCloud\Credentials\Providers
*/
class DefaultCredentialsProvider implements CredentialsProvider
{
/**
* @var array
*/
private static $defaultProviders = [];
/**
* @var bool
*/
private $reuseLastProviderEnabled;
/**
* @var CredentialsProvider
*/
private $lastUsedCredentialsProvider;
/**
* @var array
*/
private static $customChain = [];
/**
* DefaultCredentialsProvider constructor.
* @param array $params
*/
public function __construct(array $params = [])
{
$this->filterReuseLastProviderEnabled($params);
$this->createDefaultChain();
Filter::reuseLastProviderEnabled($this->reuseLastProviderEnabled);
}
private function filterReuseLastProviderEnabled(array $params)
{
$this->reuseLastProviderEnabled = true;
if (isset($params['reuseLastProviderEnabled'])) {
$this->reuseLastProviderEnabled = $params['reuseLastProviderEnabled'];
}
}
private function createDefaultChain()
{
self::$defaultProviders = [
new EnvironmentVariableCredentialsProvider(),
];
if (
Helper::envNotEmpty('ALIBABA_CLOUD_ROLE_ARN')
&& Helper::envNotEmpty('ALIBABA_CLOUD_OIDC_PROVIDER_ARN')
&& Helper::envNotEmpty('ALIBABA_CLOUD_OIDC_TOKEN_FILE')
) {
array_push(
self::$defaultProviders,
new OIDCRoleArnCredentialsProvider()
);
}
array_push(
self::$defaultProviders,
new CLIProfileCredentialsProvider()
);
array_push(
self::$defaultProviders,
new ProfileCredentialsProvider()
);
array_push(
self::$defaultProviders,
new EcsRamRoleCredentialsProvider()
);
if (Helper::envNotEmpty('ALIBABA_CLOUD_CREDENTIALS_URI')) {
array_push(
self::$defaultProviders,
new URLCredentialsProvider()
);
}
}
/**
* @param CredentialsProvider ...$providers
*/
public static function set(...$providers)
{
if (empty($providers)) {
throw new InvalidArgumentException('No providers in chain');
}
foreach ($providers as $provider) {
if (!$provider instanceof CredentialsProvider) {
throw new InvalidArgumentException('Providers must all be CredentialsProvider');
}
}
self::$customChain = $providers;
}
/**
* @return bool
*/
public static function hasCustomChain()
{
return (bool) self::$customChain;
}
public static function flush()
{
self::$customChain = [];
}
/**
* Get credential.
*
* @return Credentials
* @throws RuntimeException
*/
public function getCredentials()
{
if ($this->reuseLastProviderEnabled && !is_null($this->lastUsedCredentialsProvider)) {
$credentials = $this->lastUsedCredentialsProvider->getCredentials();
return new Credentials([
'accessKeyId' => $credentials->getAccessKeyId(),
'accessKeySecret' => $credentials->getAccessKeySecret(),
'securityToken' => $credentials->getSecurityToken(),
'providerName' => $this->getProviderName() . '/' . $this->lastUsedCredentialsProvider->getProviderName(),
]);
}
$providerChain = array_merge(
self::$customChain,
self::$defaultProviders
);
$exceptionMessages = [];
foreach ($providerChain as $provider) {
try {
$credentials = $provider->getCredentials();
$this->lastUsedCredentialsProvider = $provider;
return new Credentials([
'accessKeyId' => $credentials->getAccessKeyId(),
'accessKeySecret' => $credentials->getAccessKeySecret(),
'securityToken' => $credentials->getSecurityToken(),
'providerName' => $this->getProviderName() . '/' . $provider->getProviderName(),
]);
} catch (Exception $exception) {
array_push($exceptionMessages, basename(str_replace('\\', '/', get_class($provider))) . ': ' . $exception->getMessage());
}
}
throw new RuntimeException('Unable to load credentials from any of the providers in the chain: ' . implode(', ', $exceptionMessages));
}
/**
* @inheritDoc
*/
public function getProviderName()
{
return "default";
}
}

View File

@@ -0,0 +1,276 @@
<?php
namespace AlibabaCloud\Credentials\Providers;
use AlibabaCloud\Credentials\Utils\Helper;
use AlibabaCloud\Credentials\Utils\Filter;
use AlibabaCloud\Credentials\Request\Request;
use GuzzleHttp\Exception\GuzzleException;
use InvalidArgumentException;
use RuntimeException;
use AlibabaCloud\Credentials\Credential\RefreshResult;
/**
* @internal This class is intended for internal use within the package.
* Class EcsRamRoleCredentialsProvider
*
* @package AlibabaCloud\Credentials\Providers
*/
class EcsRamRoleCredentialsProvider extends SessionCredentialsProvider
{
/**
* @var string
*/
private $metadataHost = 'http://100.100.100.200';
/**
* @var string
*/
private $ecsUri = '/latest/meta-data/ram/security-credentials/';
/**
* @var string
*/
private $metadataTokenUri = '/latest/api/token';
/**
* @var string
*/
private $roleName;
/**
* @var boolean
*/
private $disableIMDSv1 = false;
/**
* @var int
*/
private $metadataTokenDuration = 21600;
/**
* @var int
*/
private $connectTimeout = 1;
/**
* @var int
*/
private $readTimeout = 1;
/**
* EcsRamRoleCredentialsProvider constructor.
*
* @param array $params
* @param array $options
*/
public function __construct(array $params = [], array $options = [])
{
$this->filterOptions($options);
$this->filterRoleName($params);
$this->filterDisableECSIMDSv1($params);
Filter::roleName($this->roleName);
Filter::disableIMDSv1($this->disableIMDSv1);
}
private function filterOptions(array $options)
{
if (isset($options['connectTimeout'])) {
$this->connectTimeout = $options['connectTimeout'];
}
if (isset($options['readTimeout'])) {
$this->readTimeout = $options['readTimeout'];
}
Filter::timeout($this->connectTimeout, $this->readTimeout);
}
private function filterRoleName(array $params)
{
if (Helper::envNotEmpty('ALIBABA_CLOUD_ECS_METADATA')) {
$this->roleName = Helper::env('ALIBABA_CLOUD_ECS_METADATA');
}
if (isset($params['roleName'])) {
$this->roleName = $params['roleName'];
}
}
private function filterDisableECSIMDSv1($params)
{
if (Helper::envNotEmpty('ALIBABA_CLOUD_IMDSV1_DISABLED')) {
$this->disableIMDSv1 = Helper::env('ALIBABA_CLOUD_IMDSV1_DISABLED') === true ? true : false;
}
if (isset($params['disableIMDSv1'])) {
$this->disableIMDSv1 = $params['disableIMDSv1'];
}
}
/**
* Get credentials by request.
*
* @return RefreshResult
* @throws InvalidArgumentException
* @throws RuntimeException
* @throws GuzzleException
*/
public function refreshCredentials()
{
if (Helper::envNotEmpty('ALIBABA_CLOUD_ECS_METADATA_DISABLED') && Helper::env('ALIBABA_CLOUD_ECS_METADATA_DISABLED') === true) {
throw new RuntimeException('IMDS credentials is disabled');
}
if (is_null($this->roleName) || $this->roleName === '') {
$this->roleName = $this->getRoleNameFromMeta();
}
$url = $this->metadataHost . $this->ecsUri . $this->roleName;
$options = Request::commonOptions();
$options['read_timeout'] = $this->readTimeout;
$options['connect_timeout'] = $this->connectTimeout;
$metadataToken = $this->getMetadataToken();
if (!is_null($metadataToken)) {
$options['headers']['X-aliyun-ecs-metadata-token'] = $metadataToken;
}
$result = Request::createClient()->request('GET', $url, $options);
if ($result->getStatusCode() === 404) {
throw new InvalidArgumentException('The role was not found in the instance' . (string) $result);
}
if ($result->getStatusCode() !== 200) {
throw new RuntimeException('Error refreshing credentials from IMDS, statusCode: ' . $result->getStatusCode() . ', result: ' . (string) $result);
}
$credentials = $result->toArray();
if (!isset($credentials['AccessKeyId']) || !isset($credentials['AccessKeySecret']) || !isset($credentials['SecurityToken'])) {
throw new RuntimeException('Error retrieving credentials from IMDS result:' . $result->toJson());
}
if (!isset($credentials['Code']) || $credentials['Code'] !== 'Success') {
throw new RuntimeException('Error retrieving credentials from IMDS result, Code is not Success:' . $result->toJson());
}
return new RefreshResult(new Credentials([
'accessKeyId' => $credentials['AccessKeyId'],
'accessKeySecret' => $credentials['AccessKeySecret'],
'securityToken' => $credentials['SecurityToken'],
'expiration' => \strtotime($credentials['Expiration']),
'providerName' => $this->getProviderName(),
]), $this->getStaleTime(strtotime($credentials["Expiration"])), $this->getPrefetchTime(strtotime($credentials["Expiration"])));
}
/**
* @return string
* @throws InvalidArgumentException
* @throws RuntimeException
* @throws GuzzleException
*/
private function getRoleNameFromMeta()
{
$options = Request::commonOptions();
$options['read_timeout'] = $this->readTimeout;
$options['connect_timeout'] = $this->connectTimeout;
$metadataToken = $this->getMetadataToken();
if (!is_null($metadataToken)) {
$options['headers']['X-aliyun-ecs-metadata-token'] = $metadataToken;
}
$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' . (string) $result);
}
if ($result->getStatusCode() !== 200) {
throw new RuntimeException('Error retrieving role name from result: ' . (string) $result);
}
$role_name = (string) $result;
if (!$role_name) {
throw new RuntimeException('Error retrieving role name from result is empty');
}
return $role_name;
}
/**
* Get metadata token by request.
*
* @return string
* @throws RuntimeException
* @throws GuzzleException
*/
private function getMetadataToken()
{
$url = $this->metadataHost . $this->metadataTokenUri;
$options = Request::commonOptions();
$options['read_timeout'] = $this->readTimeout;
$options['connect_timeout'] = $this->connectTimeout;
$options['headers']['X-aliyun-ecs-metadata-token-ttl-seconds'] = $this->metadataTokenDuration;
$result = Request::createClient()->request('PUT', $url, $options);
if ($result->getStatusCode() != 200) {
if ($this->disableIMDSv1) {
throw new RuntimeException('Failed to get token from ECS Metadata Service. HttpCode= ' . $result->getStatusCode());
}
return null;
}
return (string) $result;
}
/**
* @var int
*/
public function getPrefetchTime($expiration)
{
return $expiration <= 0 ?
time() + (5 * 60) :
time() + (60 * 60);
}
/**
* @return string
*/
public function key()
{
return 'ecs_ram_role#roleName#' . $this->roleName;
}
/**
* @return string
*/
public function getProviderName()
{
return 'ecs_ram_role';
}
/**
* @return string
*/
public function getRoleName()
{
return $this->roleName;
}
/**
* @return bool
*/
public function isDisableIMDSv1()
{
return $this->disableIMDSv1;
}
}

View File

@@ -0,0 +1,65 @@
<?php
namespace AlibabaCloud\Credentials\Providers;
use AlibabaCloud\Credentials\Utils\Helper;
use InvalidArgumentException;
/**
* @internal This class is intended for internal use within the package.
* Class EnvironmentVariableCredentialsProvider
*
* @package AlibabaCloud\Credentials\Providers
*/
class EnvironmentVariableCredentialsProvider implements CredentialsProvider
{
/**
* EnvironmentVariableCredentialsProvider constructor.
*/
public function __construct() {}
/**
* Get credential.
*
* @return Credentials
* @throws InvalidArgumentException
*/
public function getCredentials()
{
if (Helper::envNotEmpty('ALIBABA_CLOUD_ACCESS_KEY_ID')) {
$accessKeyId = Helper::env('ALIBABA_CLOUD_ACCESS_KEY_ID');
} else {
throw new InvalidArgumentException('Access key ID must be specified via environment variable (ALIBABA_CLOUD_ACCESS_KEY_ID)');
}
if (Helper::envNotEmpty('ALIBABA_CLOUD_ACCESS_KEY_SECRET')) {
$accessKeySecret = Helper::env('ALIBABA_CLOUD_ACCESS_KEY_SECRET');
} else {
throw new InvalidArgumentException('Access key Secret must be specified via environment variable (ALIBABA_CLOUD_ACCESS_KEY_SECRET)');
}
if (Helper::envNotEmpty('ALIBABA_CLOUD_SECURITY_TOKEN')) {
$securityToken = Helper::env('ALIBABA_CLOUD_SECURITY_TOKEN');
return new Credentials([
'accessKeyId' => $accessKeyId,
'accessKeySecret' => $accessKeySecret,
'securityToken' => $securityToken,
'providerName' => $this->getProviderName(),
]);
}
return new Credentials([
'accessKeyId' => $accessKeyId,
'accessKeySecret' => $accessKeySecret,
'providerName' => $this->getProviderName(),
]);
}
/**
* @inheritDoc
*/
public function getProviderName()
{
return "env";
}
}

View File

@@ -0,0 +1,268 @@
<?php
namespace AlibabaCloud\Credentials\Providers;
use AlibabaCloud\Credentials\Utils\Helper;
use AlibabaCloud\Credentials\Utils\Filter;
use AlibabaCloud\Credentials\Request\Request;
use GuzzleHttp\Psr7\Uri;
use GuzzleHttp\Exception\GuzzleException;
use InvalidArgumentException;
use RuntimeException;
use Exception;
use AlibabaCloud\Credentials\Credential\RefreshResult;
/**
* @internal This class is intended for internal use within the package.
* Class OIDCRoleArnCredentialsProvider
*
* @package AlibabaCloud\Credentials\Providers
*/
class OIDCRoleArnCredentialsProvider extends SessionCredentialsProvider
{
/**
* @var string
*/
private $roleArn;
/**
* @var string
*/
private $oidcProviderArn;
/**
* @var string
*/
private $oidcTokenFilePath;
/**
* @var string
*/
private $roleSessionName;
/**
* @description role session expiration
* @example 3600
* @var int
*/
private $durationSeconds = 3600;
/**
* @var string
*/
private $policy;
/**
* @var string
*/
private $stsEndpoint;
/**
* @var int
*/
private $connectTimeout = 5;
/**
* @var int
*/
private $readTimeout = 5;
/**
* OIDCRoleArnCredentialsProvider constructor.
*
* @param array $params
* @param array $options
*/
public function __construct(array $params = [], array $options = [])
{
$this->filterOptions($options);
$this->filterRoleArn($params);
$this->filterOIDCProviderArn($params);
$this->filterOIDCTokenFilePath($params);
$this->filterRoleSessionName($params);
$this->filterDurationSeconds($params);
$this->filterPolicy($params);
$this->filterSTSEndpoint($params);
}
private function filterRoleArn(array $params)
{
if (Helper::envNotEmpty('ALIBABA_CLOUD_ROLE_ARN')) {
$this->roleArn = Helper::env('ALIBABA_CLOUD_ROLE_ARN');
}
if (isset($params['roleArn'])) {
$this->roleArn = $params['roleArn'];
}
Filter::roleArn($this->roleArn);
}
private function filterOIDCProviderArn(array $params)
{
if (Helper::envNotEmpty('ALIBABA_CLOUD_OIDC_PROVIDER_ARN')) {
$this->oidcProviderArn = Helper::env('ALIBABA_CLOUD_OIDC_PROVIDER_ARN');
}
if (isset($params['oidcProviderArn'])) {
$this->oidcProviderArn = $params['oidcProviderArn'];
}
Filter::oidcProviderArn($this->oidcProviderArn);
}
private function filterOIDCTokenFilePath(array $params)
{
if (Helper::envNotEmpty('ALIBABA_CLOUD_OIDC_TOKEN_FILE')) {
$this->oidcTokenFilePath = Helper::env('ALIBABA_CLOUD_OIDC_TOKEN_FILE');
}
if (isset($params['oidcTokenFilePath'])) {
$this->oidcTokenFilePath = $params['oidcTokenFilePath'];
}
Filter::oidcTokenFilePath($this->oidcTokenFilePath);
}
private function filterRoleSessionName(array $params)
{
if (Helper::envNotEmpty('ALIBABA_CLOUD_ROLE_SESSION_NAME')) {
$this->roleSessionName = Helper::env('ALIBABA_CLOUD_ROLE_SESSION_NAME');
}
if (isset($params['roleSessionName'])) {
$this->roleSessionName = $params['roleSessionName'];
}
if (is_null($this->roleSessionName) || $this->roleSessionName === '') {
$this->roleSessionName = 'phpSdkRoleSessionName';
}
}
private function filterDurationSeconds(array $params)
{
if (isset($params['durationSeconds'])) {
if (is_int($params['durationSeconds'])) {
$this->durationSeconds = $params['durationSeconds'];
}
}
if ($this->durationSeconds < 900) {
throw new InvalidArgumentException('Role session expiration should be in the range of 900s - max session duration');
}
}
private function filterPolicy(array $params)
{
if (isset($params['policy'])) {
if (is_string($params['policy'])) {
$this->policy = $params['policy'];
}
if (is_array($params['policy'])) {
$this->policy = json_encode($params['policy']);
}
}
}
private function filterSTSEndpoint(array $params)
{
$prefix = 'sts';
if (Helper::envNotEmpty('ALIBABA_CLOUD_VPC_ENDPOINT_ENABLED') || (isset($params['enableVpc']) && $params['enableVpc'] === true)) {
$prefix = 'sts-vpc';
}
if (Helper::envNotEmpty('ALIBABA_CLOUD_STS_REGION')) {
$this->stsEndpoint = $prefix . '.' . Helper::env('ALIBABA_CLOUD_STS_REGION') . '.aliyuncs.com';
}
if (isset($params['stsRegionId'])) {
$this->stsEndpoint = $prefix . '.' . $params['stsRegionId'] . '.aliyuncs.com';
}
if (isset($params['stsEndpoint'])) {
$this->stsEndpoint = $params['stsEndpoint'];
}
if (is_null($this->stsEndpoint) || $this->stsEndpoint === '') {
$this->stsEndpoint = 'sts.aliyuncs.com';
}
}
private function filterOptions(array $options)
{
if (isset($options['connectTimeout'])) {
$this->connectTimeout = $options['connectTimeout'];
}
if (isset($options['readTimeout'])) {
$this->readTimeout = $options['readTimeout'];
}
Filter::timeout($this->connectTimeout, $this->readTimeout);
}
/**
* Get credentials by request.
*
* @return RefreshResult
* @throws RuntimeException
* @throws GuzzleException
*/
public function refreshCredentials()
{
$options = Request::commonOptions();
$options['read_timeout'] = $this->readTimeout;
$options['connect_timeout'] = $this->connectTimeout;
$options['query']['Action'] = 'AssumeRoleWithOIDC';
$options['query']['Version'] = '2015-04-01';
$options['query']['Format'] = 'JSON';
$options['query']['Timestamp'] = gmdate('Y-m-d\TH:i:s\Z');
$options['query']['RoleArn'] = $this->roleArn;
$options['query']['OIDCProviderArn'] = $this->oidcProviderArn;
try {
$oidcToken = file_get_contents($this->oidcTokenFilePath);
$options['query']['OIDCToken'] = $oidcToken;
} catch (Exception $exception) {
throw new InvalidArgumentException($exception->getMessage());
}
$options['query']['RoleSessionName'] = $this->roleSessionName;
$options['query']['DurationSeconds'] = (string) $this->durationSeconds;
if (!is_null($this->policy)) {
$options['query']['Policy'] = $this->policy;
}
$url = (new Uri())->withScheme('https')->withHost($this->stsEndpoint);
$result = Request::createClient()->request('POST', $url, $options);
if ($result->getStatusCode() !== 200) {
throw new RuntimeException('Error refreshing credentials from OIDC, statusCode: ' . $result->getStatusCode() . ', result: ' . (string) $result);
}
$json = $result->toArray();
$credentials = $json['Credentials'];
if (!isset($credentials['AccessKeyId']) || !isset($credentials['AccessKeySecret']) || !isset($credentials['SecurityToken'])) {
throw new RuntimeException('Error retrieving credentials from OIDC result:' . $result->toJson());
}
return new RefreshResult(new Credentials([
'accessKeyId' => $credentials['AccessKeyId'],
'accessKeySecret' => $credentials['AccessKeySecret'],
'securityToken' => $credentials['SecurityToken'],
'expiration' => \strtotime($credentials['Expiration']),
'providerName' => $this->getProviderName(),
]), $this->getStaleTime(strtotime($credentials['Expiration'])));
}
public function key()
{
return 'oidc_role_arn#roleArn#' . $this->roleArn . '#oidcProviderArn#' . $this->oidcProviderArn . '#roleSessionName#' . $this->roleSessionName;
}
public function getProviderName()
{
return 'oidc_role_arn';
}
}

View File

@@ -0,0 +1,188 @@
<?php
namespace AlibabaCloud\Credentials\Providers;
use AlibabaCloud\Credentials\Utils\Helper;
use RuntimeException;
/**
* @internal This class is intended for internal use within the package.
* Class ProfileCredentialsProvider
*
* @package AlibabaCloud\Credentials\Providers
*/
class ProfileCredentialsProvider implements CredentialsProvider
{
/**
* @var string
*/
private $profileName;
/**
* @var string
*/
private $profileFile;
/**
* @var CredentialsProvider
*/
private $credentialsProvider;
/**
* ProfileCredentialsProvider constructor.
*
* @param array $params
*/
public function __construct(array $params = [])
{
$this->filterProfileName($params);
$this->filterProfileFile();
}
private function filterProfileName(array $params)
{
if (Helper::envNotEmpty('ALIBABA_CLOUD_PROFILE')) {
$this->profileName = Helper::env('ALIBABA_CLOUD_PROFILE');
}
if (isset($params['profileName'])) {
$this->profileName = $params['profileName'];
}
if (is_null($this->profileName) || $this->profileName === '') {
$this->profileName = 'default';
}
}
private function filterProfileFile()
{
$this->profileFile = Helper::envNotEmpty('ALIBABA_CLOUD_CREDENTIALS_FILE');
if (!$this->profileFile) {
$this->profileFile = self::getDefaultFile();
}
}
/**
* @return bool
*/
private function shouldReloadCredentialsProvider()
{
if (is_null($this->credentialsProvider)) {
return true;
}
return false;
}
/**
* @return CredentialsProvider
*/
private function reloadCredentialsProvider($profileFile, $profileName)
{
if (!Helper::inOpenBasedir($profileFile)) {
throw new RuntimeException('Unable to open credentials file: ' . $profileFile);
}
if (!\is_readable($profileFile) || !\is_file($profileFile)) {
throw new RuntimeException('Credentials file is not readable: ' . $profileFile);
}
$fileArray = \parse_ini_file($profileFile, true);
if (\is_array($fileArray) && !empty($fileArray)) {
$credentialsConfigures = [];
foreach (\array_change_key_case($fileArray) as $name => $configures) {
if ($name === $profileName) {
$credentialsConfigures = $configures;
break;
}
}
if (\is_array($credentialsConfigures) && !empty($credentialsConfigures)) {
switch (Helper::unsetReturnNull($credentialsConfigures, 'type')) {
case 'access_key':
return new StaticAKCredentialsProvider([
'accessKeyId' => Helper::unsetReturnNull($credentialsConfigures, 'access_key_id'),
'accessKeySecret' => Helper::unsetReturnNull($credentialsConfigures, 'access_key_secret'),
]);
case 'ram_role_arn':
$innerProvider = new StaticAKCredentialsProvider([
'accessKeyId' => Helper::unsetReturnNull($credentialsConfigures, 'access_key_id'),
'accessKeySecret' => Helper::unsetReturnNull($credentialsConfigures, 'access_key_secret'),
]);
return new RamRoleArnCredentialsProvider([
'credentialsProvider' => $innerProvider,
'roleArn' => Helper::unsetReturnNull($credentialsConfigures, 'role_arn'),
'roleSessionName' => Helper::unsetReturnNull($credentialsConfigures, 'role_session_name'),
'policy' => Helper::unsetReturnNull($credentialsConfigures, 'policy'),
]);
case 'ecs_ram_role':
return new EcsRamRoleCredentialsProvider([
'roleName' => Helper::unsetReturnNull($credentialsConfigures, 'role_name'),
]);
case 'oidc_role_arn':
return new OIDCRoleArnCredentialsProvider([
'roleArn' => Helper::unsetReturnNull($credentialsConfigures, 'role_arn'),
'oidcProviderArn' => Helper::unsetReturnNull($credentialsConfigures, 'oidc_provider_arn'),
'oidcTokenFilePath' => Helper::unsetReturnNull($credentialsConfigures, 'oidc_token_file_path'),
'roleSessionName' => Helper::unsetReturnNull($credentialsConfigures, 'role_session_name'),
'policy' => Helper::unsetReturnNull($credentialsConfigures, 'policy'),
]);
case 'rsa_key_pair':
return new RsaKeyPairCredentialsProvider([
'publicKeyId' => Helper::unsetReturnNull($credentialsConfigures, 'public_key_id'),
'privateKeyFile' => Helper::unsetReturnNull($credentialsConfigures, 'private_key_file'),
]);
default:
throw new RuntimeException('Unsupported credential type from credentials file: ' . Helper::unsetReturnNull($credentialsConfigures, 'type'));
}
}
}
throw new RuntimeException('Failed to get credential from credentials file: ' . $profileFile);
}
/**
* Get credential.
*
* @return Credentials
* @throws RuntimeException
*/
public function getCredentials()
{
if ($this->shouldReloadCredentialsProvider()) {
$this->credentialsProvider = $this->reloadCredentialsProvider($this->profileFile, $this->profileName);
}
$credentials = $this->credentialsProvider->getCredentials();
return new Credentials([
'accessKeyId' => $credentials->getAccessKeyId(),
'accessKeySecret' => $credentials->getAccessKeySecret(),
'securityToken' => $credentials->getSecurityToken(),
'providerName' => $this->getProviderName() . '/' . $this->credentialsProvider->getProviderName(),
]);
}
/**
* Get the default credential file.
*
* @return string
*/
private function getDefaultFile()
{
return Helper::getHomeDirectory() .
DIRECTORY_SEPARATOR .
'.alibabacloud' .
DIRECTORY_SEPARATOR .
'credentials';
}
/**
* @return string
*/
public function getProviderName()
{
return 'profile';
}
}

View File

@@ -0,0 +1,321 @@
<?php
namespace AlibabaCloud\Credentials\Providers;
use AlibabaCloud\Credentials\Utils\Helper;
use AlibabaCloud\Credentials\Utils\Filter;
use AlibabaCloud\Credentials\Request\Request;
use GuzzleHttp\Psr7\Uri;
use GuzzleHttp\Exception\GuzzleException;
use InvalidArgumentException;
use RuntimeException;
use AlibabaCloud\Credentials\Credential\RefreshResult;
/**
* @internal This class is intended for internal use within the package.
* Class RamRoleArnCredentialsProvider
*
* @package AlibabaCloud\Credentials\Providers
*/
class RamRoleArnCredentialsProvider extends SessionCredentialsProvider
{
/**
* @var CredentialsProvider
*/
private $credentialsProvider;
/**
* @var string
*/
private $roleArn;
/**
* @var string
*/
private $roleSessionName;
/**
* @description role session expiration
* @example 3600
* @var int
*/
private $durationSeconds = 3600;
/**
* @var string
*/
private $externalId;
/**
* @var string
*/
private $policy;
/**
* @var string
*/
private $stsEndpoint;
/**
* @var int
*/
private $connectTimeout = 5;
/**
* @var int
*/
private $readTimeout = 5;
/**
* RamRoleArnCredentialsProvider constructor.
*
* @param array $params
* @param array $options
*/
public function __construct(array $params = [], array $options = [])
{
$this->filterOptions($options);
$this->filterCredentials($params);
$this->filterRoleArn($params);
$this->filterRoleSessionName($params);
$this->filterDurationSeconds($params);
$this->filterPolicy($params);
$this->filterExternalId($params);
$this->filterSTSEndpoint($params);
}
private function filterRoleArn(array $params)
{
if (Helper::envNotEmpty('ALIBABA_CLOUD_ROLE_ARN')) {
$this->roleArn = Helper::env('ALIBABA_CLOUD_ROLE_ARN');
}
if (isset($params['roleArn'])) {
$this->roleArn = $params['roleArn'];
}
Filter::roleArn($this->roleArn);
}
private function filterRoleSessionName(array $params)
{
if (Helper::envNotEmpty('ALIBABA_CLOUD_ROLE_SESSION_NAME')) {
$this->roleSessionName = Helper::env('ALIBABA_CLOUD_ROLE_SESSION_NAME');
}
if (isset($params['roleSessionName'])) {
$this->roleSessionName = $params['roleSessionName'];
}
if (is_null($this->roleSessionName) || $this->roleSessionName === '') {
$this->roleSessionName = 'phpSdkRoleSessionName';
}
}
private function filterDurationSeconds(array $params)
{
if (isset($params['durationSeconds'])) {
if (is_int($params['durationSeconds'])) {
$this->durationSeconds = $params['durationSeconds'];
}
}
if ($this->durationSeconds < 900) {
throw new InvalidArgumentException('Role session expiration should be in the range of 900s - max session duration');
}
}
private function filterPolicy(array $params)
{
if (isset($params['policy'])) {
if (is_string($params['policy'])) {
$this->policy = $params['policy'];
}
if (is_array($params['policy'])) {
$this->policy = json_encode($params['policy']);
}
}
}
private function filterExternalId(array $params)
{
if (isset($params['externalId'])) {
if (is_string($params['externalId'])) {
$this->externalId = $params['externalId'];
}
}
}
private function filterSTSEndpoint(array $params)
{
$prefix = 'sts';
if (Helper::envNotEmpty('ALIBABA_CLOUD_VPC_ENDPOINT_ENABLED') || (isset($params['enableVpc']) && $params['enableVpc'] === true)) {
$prefix = 'sts-vpc';
}
if (Helper::envNotEmpty('ALIBABA_CLOUD_STS_REGION')) {
$this->stsEndpoint = $prefix . '.' . Helper::env('ALIBABA_CLOUD_STS_REGION') . '.aliyuncs.com';
}
if (isset($params['stsRegionId'])) {
$this->stsEndpoint = $prefix . '.' . $params['stsRegionId'] . '.aliyuncs.com';
}
if (isset($params['stsEndpoint'])) {
$this->stsEndpoint = $params['stsEndpoint'];
}
if (is_null($this->stsEndpoint) || $this->stsEndpoint === '') {
$this->stsEndpoint = 'sts.aliyuncs.com';
}
}
private function filterCredentials(array $params)
{
if (isset($params['credentialsProvider'])) {
if (!($params['credentialsProvider'] instanceof CredentialsProvider)) {
throw new InvalidArgumentException('Invalid credentialsProvider option for ram_role_arn');
}
$this->credentialsProvider = $params['credentialsProvider'];
} else if (isset($params['accessKeyId']) && isset($params['accessKeySecret']) && isset($params['securityToken'])) {
Filter::accessKey($params['accessKeyId'], $params['accessKeySecret']);
Filter::securityToken($params['securityToken']);
$this->credentialsProvider = new StaticSTSCredentialsProvider($params);
} else if (isset($params['accessKeyId']) && isset($params['accessKeySecret'])) {
Filter::accessKey($params['accessKeyId'], $params['accessKeySecret']);
$this->credentialsProvider = new StaticAKCredentialsProvider($params);
} else {
throw new InvalidArgumentException('Missing required credentials option for ram_role_arn');
}
}
private function filterOptions(array $options)
{
if (isset($options['connectTimeout'])) {
$this->connectTimeout = $options['connectTimeout'];
}
if (isset($options['readTimeout'])) {
$this->readTimeout = $options['readTimeout'];
}
Filter::timeout($this->connectTimeout, $this->readTimeout);
}
/**
* Get credentials by request.
*
* @return RefreshResult
* @throws RuntimeException
* @throws GuzzleException
*/
public function refreshCredentials()
{
$options = Request::commonOptions();
$options['read_timeout'] = $this->readTimeout;
$options['connect_timeout'] = $this->connectTimeout;
$options['query']['Action'] = 'AssumeRole';
$options['query']['Version'] = '2015-04-01';
$options['query']['Format'] = 'JSON';
$options['query']['Timestamp'] = gmdate('Y-m-d\TH:i:s\Z');
$options['query']['SignatureMethod'] = 'HMAC-SHA1';
$options['query']['SignatureVersion'] = '1.0';
$options['query']['SignatureNonce'] = Request::uuid(json_encode($options['query']));
$options['query']['RoleArn'] = $this->roleArn;
$options['query']['RoleSessionName'] = $this->roleSessionName;
$options['query']['DurationSeconds'] = (string) $this->durationSeconds;
if (!is_null($this->policy) && $this->policy !== '') {
$options['query']['Policy'] = $this->policy;
}
if (!is_null($this->externalId) && $this->externalId !== '') {
$options['query']['ExternalId'] = $this->externalId;
}
$sessionCredentials = $this->credentialsProvider->getCredentials();
$options['query']['AccessKeyId'] = $sessionCredentials->getAccessKeyId();
if (!is_null($sessionCredentials->getSecurityToken())) {
$options['query']['SecurityToken'] = $sessionCredentials->getSecurityToken();
}
$options['query']['Signature'] = Request::shaHmac1sign(
Request::signString('GET', $options['query']),
$sessionCredentials->getAccessKeySecret() . '&'
);
$url = (new Uri())->withScheme('https')->withHost($this->stsEndpoint);
$result = Request::createClient()->request('GET', $url, $options);
if ($result->getStatusCode() !== 200) {
throw new RuntimeException('Error refreshing credentials from RamRoleArn, statusCode: ' . $result->getStatusCode() . ', result: ' . (string) $result);
}
$json = $result->toArray();
$credentials = $json['Credentials'];
if (!isset($credentials['AccessKeyId']) || !isset($credentials['AccessKeySecret']) || !isset($credentials['SecurityToken'])) {
throw new RuntimeException('Error retrieving credentials from RamRoleArn result:' . $result->toJson());
}
return new RefreshResult(new Credentials([
'accessKeyId' => $credentials['AccessKeyId'],
'accessKeySecret' => $credentials['AccessKeySecret'],
'securityToken' => $credentials['SecurityToken'],
'expiration' => \strtotime($credentials['Expiration']),
'providerName' => $this->getProviderName(),
]), $this->getStaleTime(strtotime($credentials['Expiration'])));
}
public function key()
{
$credentials = $this->credentialsProvider->getCredentials();
return 'ram_role_arn#credential#' . $credentials->getAccessKeyId() . '#roleArn#' . $this->roleArn . '#roleSessionName#' . $this->roleSessionName;
}
public function getProviderName()
{
return 'ram_role_arn/' . $this->credentialsProvider->getProviderName();
}
/**
* @return string
*/
public function getRoleArn()
{
return $this->roleArn;
}
/**
* @return string
*/
public function getRoleSessionName()
{
return $this->roleSessionName;
}
/**
* @return string
*/
public function getPolicy()
{
return $this->policy;
}
/**
* @deprecated
* @return string
*/
public function getOriginalAccessKeyId()
{
return $this->credentialsProvider->getCredentials()->getAccessKeyId();
}
/**
* @deprecated
* @return string
*/
public function getOriginalAccessKeySecret()
{
return $this->credentialsProvider->getCredentials()->getAccessKeySecret();
}
}

View File

@@ -0,0 +1,200 @@
<?php
namespace AlibabaCloud\Credentials\Providers;
use AlibabaCloud\Credentials\Utils\Helper;
use AlibabaCloud\Credentials\Utils\Filter;
use AlibabaCloud\Credentials\Request\Request;
use GuzzleHttp\Psr7\Uri;
use GuzzleHttp\Exception\GuzzleException;
use AlibabaCloud\Credentials\Credential\RefreshResult;
use InvalidArgumentException;
use RuntimeException;
use Exception;
/**
* @internal This class is intended for internal use within the package.
* Class RsaKeyPairCredentialsProvider
*
* @package AlibabaCloud\Credentials\Providers
*/
class RsaKeyPairCredentialsProvider extends SessionCredentialsProvider
{
/**
* @var string
*/
private $publicKeyId;
/**
* @var string
*/
private $privateKey;
/**
* @description role session expiration
* @example 3600
* @var int
*/
private $durationSeconds = 3600;
/**
* @var string
*/
private $stsEndpoint;
/**
* @var int
*/
private $connectTimeout = 5;
/**
* @var int
*/
private $readTimeout = 5;
/**
* RsaKeyPairCredentialsProvider constructor.
*
* @param array $params
* @param array $options
*/
public function __construct(array $params = [], array $options = [])
{
$this->filterOptions($options);
$this->filterDurationSeconds($params);
$this->filterSTSEndpoint($params);
$this->publicKeyId = isset($params['publicKeyId']) ? $params['publicKeyId'] : null;
$privateKeyFile = isset($params['privateKeyFile']) ? $params['privateKeyFile'] : null;
Filter::publicKeyId($this->publicKeyId);
Filter::privateKeyFile($privateKeyFile);
try {
$this->privateKey = file_get_contents($privateKeyFile);
} catch (Exception $exception) {
throw new InvalidArgumentException($exception->getMessage());
}
}
private function filterOptions(array $options)
{
if (isset($options['connectTimeout'])) {
$this->connectTimeout = $options['connectTimeout'];
}
if (isset($options['readTimeout'])) {
$this->readTimeout = $options['readTimeout'];
}
Filter::timeout($this->connectTimeout, $this->readTimeout);
}
private function filterDurationSeconds(array $params)
{
if (isset($params['durationSeconds'])) {
if (is_int($params['durationSeconds'])) {
$this->durationSeconds = $params['durationSeconds'];
}
}
if ($this->durationSeconds < 900) {
throw new InvalidArgumentException('Role session expiration should be in the range of 900s - max session duration');
}
}
private function filterSTSEndpoint(array $params)
{
if (isset($params['stsEndpoint'])) {
$this->stsEndpoint = $params['stsEndpoint'];
}
if (is_null($this->stsEndpoint) || $this->stsEndpoint === '') {
$this->stsEndpoint = 'sts.ap-northeast-1.aliyuncs.com';
}
}
/**
* Get credentials by request.
*
* @return RefreshResult
* @throws RuntimeException
* @throws GuzzleException
*/
public function refreshCredentials()
{
$options = Request::commonOptions();
$options['read_timeout'] = $this->readTimeout;
$options['connect_timeout'] = $this->connectTimeout;
$options['query']['Action'] = 'GenerateSessionAccessKey';
$options['query']['Version'] = '2015-04-01';
$options['query']['Format'] = 'JSON';
$options['query']['Timestamp'] = gmdate('Y-m-d\TH:i:s\Z');
$options['query']['SignatureMethod'] = 'SHA256withRSA';
$options['query']['SignatureType'] = 'PRIVATEKEY';
$options['query']['SignatureVersion'] = '1.0';
$options['query']['SignatureNonce'] = Request::uuid(json_encode($options['query']));
$options['query']['DurationSeconds'] = (string) $this->durationSeconds;
$options['query']['AccessKeyId'] = $this->publicKeyId;
$options['query']['Signature'] = Request::shaHmac256WithRsasign(
Request::signString('GET', $options['query']),
$this->privateKey
);
$url = (new Uri())->withScheme('https')->withHost($this->stsEndpoint);
$result = Request::createClient()->request('GET', $url, $options);
if ($result->getStatusCode() !== 200) {
throw new RuntimeException('Error refreshing credentials from RsaKeyPair, statusCode: ' . $result->getStatusCode() . ', result: ' . (string) $result);
}
$json = $result->toArray();
if (!isset($json['SessionAccessKey']['SessionAccessKeyId']) || !isset($json['SessionAccessKey']['SessionAccessKeySecret'])) {
throw new RuntimeException('Error retrieving credentials from RsaKeyPair result:' . $result->toJson());
}
$credentials = [];
$credentials['AccessKeyId'] = $json['SessionAccessKey']['SessionAccessKeyId'];
$credentials['AccessKeySecret'] = $json['SessionAccessKey']['SessionAccessKeySecret'];
$credentials['Expiration'] = $json['SessionAccessKey']['Expiration'];
$credentials['SecurityToken'] = null;
return new RefreshResult(new Credentials([
'accessKeyId' => $credentials['AccessKeyId'],
'accessKeySecret' => $credentials['AccessKeySecret'],
'securityToken' => $credentials['SecurityToken'],
'expiration' => \strtotime($credentials['Expiration']),
'providerName' => $this->getProviderName(),
]), $this->getStaleTime(strtotime($credentials['Expiration'])));
}
public function key()
{
return 'rsa_key_pair#publicKeyId#' . $this->publicKeyId;
}
public function getProviderName()
{
return 'rsa_key_pair';
}
/**
* @return string
*/
public function getPublicKeyId()
{
return $this->publicKeyId;
}
/**
* @return mixed
*/
public function getPrivateKey()
{
return $this->privateKey;
}
}

View File

@@ -0,0 +1,161 @@
<?php
namespace AlibabaCloud\Credentials\Providers;
use AlibabaCloud\Credentials\Credential\RefreshResult;
abstract class SessionCredentialsProvider implements CredentialsProvider
{
/**
* @var array
*/
protected static $credentialsCache = [];
/**
* Expiration time slot for temporary security credentials.
*
* @var int
*/
protected $expirationSlot = 180;
/**
* @var string
*/
protected $error = 'Result contains no credentials';
/**
* Get the credentials from the cache in the validity period.
*
* @return RefreshResult|null
*/
protected function getCredentialsInCache()
{
if (isset(self::$credentialsCache[$this->key()])) {
$result = self::$credentialsCache[$this->key()];
return $result;
}
return null;
}
/**
* Cache credentials.
*
* @param RefreshResult $credential
*/
protected function cache(RefreshResult $credential)
{
self::$credentialsCache[$this->key()] = $credential;
}
/**
* Get credential.
*
* @return Credentials
*/
public function getCredentials()
{
if ($this->cacheIsStale() || $this->shouldInitiateCachePrefetch()) {
$result = $this->refreshCache();
$this->cache($result);
}
$result = $this->getCredentialsInCache();
return $result->credentials();
}
/**
* @return RefreshResult
*/
protected function refreshCache()
{
try {
return $this->handleFetchedSuccess($this->refreshCredentials());
} catch (\Exception $e) {
return $this->handleFetchedFailure($e);
}
}
/**
* @return RefreshResult
* @throws \Exception
*/
protected function handleFetchedFailure(\Exception $e)
{
$currentCachedValue = $this->getCredentialsInCache();
if (is_null($currentCachedValue)) {
throw $e;
}
if (time() < $currentCachedValue->staleTime()) {
return $currentCachedValue;
}
throw $e;
}
/**
* @return RefreshResult
*/
protected function handleFetchedSuccess(RefreshResult $value)
{
$now = time();
// 过期时间大于15分钟不用管
if ($now < $value->staleTime()) {
return $value;
}
// 不足或等于15分钟但未过期下次会再次刷新
if ($now < $value->staleTime() + 15 * 60) {
$value->staleTime = $now;
return $value;
}
// 已过期看缓存缓存若大于15分钟返回缓存若小于15分钟则稍后重试
if (is_null($this->getCredentialsInCache())) {
throw new \Exception("The fetched credentials have expired and no cache is available.");
} else if ($now < $this->getCredentialsInCache()->staleTime()) {
return $this->getCredentialsInCache();
} else {
// 返回成功,延长有效期 1 分钟
$expectation = mt_rand(50, 70);
$value->staleTime = time() + $expectation;
return $value;
}
}
/**
* @return bool
*/
protected function cacheIsStale()
{
return is_null($this->getCredentialsInCache()) || time() >= $this->getCredentialsInCache()->staleTime();
}
/**
* @return bool
*/
protected function shouldInitiateCachePrefetch()
{
return is_null($this->getCredentialsInCache()) || time() >= $this->getCredentialsInCache()->prefetchTime();
}
/**
* @return int
*/
public function getStaleTime($expiration)
{
return $expiration <= 0 ?
time() + (60 * 60) :
$expiration - (15 * 60);
}
/**
* @return RefreshResult
*/
abstract function refreshCredentials();
/**
* Get the toString of the credentials provider as the key.
*
* @return string
*/
abstract function key();
}

View File

@@ -0,0 +1,78 @@
<?php
namespace AlibabaCloud\Credentials\Providers;
use AlibabaCloud\Credentials\Utils\Helper;
use AlibabaCloud\Credentials\Utils\Filter;
/**
* @internal This class is intended for internal use within the package.
* Class StaticAKCredentialsProvider
*
* @package AlibabaCloud\Credentials\Providers
*/
class StaticAKCredentialsProvider implements CredentialsProvider
{
/**
* @var string
*/
private $accessKeyId;
/**
* @var string
*/
private $accessKeySecret;
/**
* StaticAKCredentialsProvider constructor.
*
* @param array $params
*/
public function __construct(array $params = [])
{
$this->filterAK($params);
}
private function filterAK(array $params)
{
if (Helper::envNotEmpty('ALIBABA_CLOUD_ACCESS_KEY_ID')) {
$this->accessKeyId = Helper::env('ALIBABA_CLOUD_ACCESS_KEY_ID');
}
if (Helper::envNotEmpty('ALIBABA_CLOUD_ACCESS_KEY_SECRET')) {
$this->accessKeySecret = Helper::env('ALIBABA_CLOUD_ACCESS_KEY_SECRET');
}
if (isset($params['accessKeyId'])) {
$this->accessKeyId = $params['accessKeyId'];
}
if (isset($params['accessKeySecret'])) {
$this->accessKeySecret = $params['accessKeySecret'];
}
Filter::accessKey($this->accessKeyId, $this->accessKeySecret);
}
/**
* Get credential.
*
* @return Credentials
*/
public function getCredentials()
{
return new Credentials([
'accessKeyId' => $this->accessKeyId,
'accessKeySecret' => $this->accessKeySecret,
'providerName' => $this->getProviderName(),
]);
}
/**
* @inheritDoc
*/
public function getProviderName()
{
return "static_ak";
}
}

View File

@@ -0,0 +1,92 @@
<?php
namespace AlibabaCloud\Credentials\Providers;
use AlibabaCloud\Credentials\Utils\Helper;
use AlibabaCloud\Credentials\Utils\Filter;
/**
* @internal This class is intended for internal use within the package.
* Class StaticSTSCredentialsProvider
*
* @package AlibabaCloud\Credentials\Providers
*/
class StaticSTSCredentialsProvider implements CredentialsProvider
{
/**
* @var string
*/
private $accessKeyId;
/**
* @var string
*/
private $accessKeySecret;
/**
* @var string
*/
private $securityToken;
/**
* StaticSTSCredentialsProvider constructor.
*
* @param array $params
*/
public function __construct(array $params = [])
{
$this->filterSTS($params);
}
private function filterSTS(array $params)
{
if (Helper::envNotEmpty('ALIBABA_CLOUD_ACCESS_KEY_ID')) {
$this->accessKeyId = Helper::env('ALIBABA_CLOUD_ACCESS_KEY_ID');
}
if (Helper::envNotEmpty('ALIBABA_CLOUD_ACCESS_KEY_SECRET')) {
$this->accessKeySecret = Helper::env('ALIBABA_CLOUD_ACCESS_KEY_SECRET');
}
if (Helper::envNotEmpty('ALIBABA_CLOUD_SECURITY_TOKEN')) {
$this->securityToken = Helper::env('ALIBABA_CLOUD_SECURITY_TOKEN');
}
if (isset($params['accessKeyId'])) {
$this->accessKeyId = $params['accessKeyId'];
}
if (isset($params['accessKeySecret'])) {
$this->accessKeySecret = $params['accessKeySecret'];
}
if (isset($params['securityToken'])) {
$this->securityToken = $params['securityToken'];
}
Filter::accessKey($this->accessKeyId, $this->accessKeySecret);
Filter::securityToken($this->securityToken);
}
/**
* Get credential.
*
* @return Credentials
*/
public function getCredentials()
{
return new Credentials([
'accessKeyId' => $this->accessKeyId,
'accessKeySecret' => $this->accessKeySecret,
'securityToken' => $this->securityToken,
'providerName' => $this->getProviderName(),
]);
}
/**
* @inheritDoc
*/
public function getProviderName()
{
return "static_sts";
}
}

View File

@@ -0,0 +1,126 @@
<?php
namespace AlibabaCloud\Credentials\Providers;
use AlibabaCloud\Credentials\Utils\Helper;
use AlibabaCloud\Credentials\Utils\Filter;
use AlibabaCloud\Credentials\Request\Request;
use GuzzleHttp\Exception\GuzzleException;
use InvalidArgumentException;
use RuntimeException;
use AlibabaCloud\Credentials\Credential\RefreshResult;
/**
* @internal This class is intended for internal use within the package.
* Class URLCredentialsProvider
*
* @package AlibabaCloud\Credentials\Providers
*/
class URLCredentialsProvider extends SessionCredentialsProvider
{
/**
* @var string
*/
private $credentialsURI;
/**
* @var int
*/
private $connectTimeout = 5;
/**
* @var int
*/
private $readTimeout = 5;
/**
* URLCredentialsProvider constructor.
*
* @param array $params
* @param array $options
*/
public function __construct(array $params = [], array $options = [])
{
$this->filterOptions($options);
$this->filterCredentialsURI($params);
}
private function filterOptions(array $options)
{
if (isset($options['connectTimeout'])) {
$this->connectTimeout = $options['connectTimeout'];
}
if (isset($options['readTimeout'])) {
$this->readTimeout = $options['readTimeout'];
}
Filter::timeout($this->connectTimeout, $this->readTimeout);
}
private function filterCredentialsURI(array $params)
{
if (Helper::envNotEmpty('ALIBABA_CLOUD_CREDENTIALS_URI')) {
$this->credentialsURI = Helper::env('ALIBABA_CLOUD_CREDENTIALS_URI');
}
if (isset($params['credentialsURI'])) {
$this->credentialsURI = $params['credentialsURI'];
}
Filter::credentialsURI($this->credentialsURI);
}
/**
* Get credentials by request.
*
* @return RefreshResult
* @throws InvalidArgumentException
* @throws RuntimeException
* @throws GuzzleException
*/
public function refreshCredentials()
{
$options = Request::commonOptions();
$options['read_timeout'] = $this->readTimeout;
$options['connect_timeout'] = $this->connectTimeout;
$result = Request::createClient()->request('GET', $this->credentialsURI, $options);
if ($result->getStatusCode() !== 200) {
throw new RuntimeException('Error refreshing credentials from credentialsURI, statusCode: ' . $result->getStatusCode() . ', result: ' . (string) $result);
}
$credentials = $result->toArray();
if (!isset($credentials['AccessKeyId']) || !isset($credentials['AccessKeySecret']) || !isset($credentials['SecurityToken']) || !isset($credentials['Expiration'])) {
throw new RuntimeException('Error retrieving credentials from credentialsURI result:' . $result->toJson());
}
return new RefreshResult(new Credentials([
'accessKeyId' => $credentials['AccessKeyId'],
'accessKeySecret' => $credentials['AccessKeySecret'],
'securityToken' => $credentials['SecurityToken'],
'expiration' => \strtotime($credentials['Expiration']),
'providerName' => $this->getProviderName(),
]), $this->getStaleTime(strtotime($credentials['Expiration'])));
}
/**
* @return string
*/
public function key()
{
return 'credential_uri#' . $this->credentialsURI;
}
/**
* @return string
*/
public function getProviderName()
{
return 'credential_uri';
}
}

View File

@@ -0,0 +1,242 @@
<?php
namespace AlibabaCloud\Credentials;
use AlibabaCloud\Credentials\Providers\RamRoleArnCredentialsProvider;
use AlibabaCloud\Credentials\Credential\CredentialModel;
use AlibabaCloud\Credentials\Signature\ShaHmac1Signature;
use AlibabaCloud\Credentials\Utils\Filter;
use Exception;
use GuzzleHttp\Exception\GuzzleException;
use InvalidArgumentException;
/**
* @deprecated
* Use the AssumeRole of the RAM account to complete the authentication.
*/
class RamRoleArnCredential implements CredentialsInterface
{
/**
* @var string
*/
private $accessKeyId;
/**
* @var string
*/
private $accessKeySecret;
/**
* @var string
*/
private $roleArn;
/**
* @var string
*/
private $roleSessionName;
/**
* @var string
*/
private $policy;
/**
* @var array
*/
private $config;
/**
* RamRoleArnCredential constructor.
*
* @param array $credential
* @param array $config
*/
public function __construct(array $credential = [], array $config = [])
{
$this->filterParameters($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 AlibabaCloud\Credentials\Providers\Credentials
* @throws Exception
* @throws GuzzleException
*/
protected function getSessionCredential()
{
$params = [
'accessKeyId' => $this->accessKeyId,
'accessKeySecret' => $this->accessKeyId,
'roleArn' => $this->roleArn,
'roleSessionName' => $this->roleSessionName,
'policy' => $this->policy,
];
return (new RamRoleArnCredentialsProvider($params))->getCredentials();
}
/**
* @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();
}
/**
* @inheritDoc
*/
public function getCredential()
{
$credentials = $this->getSessionCredential();
return new CredentialModel([
'accessKeyId' => $credentials->getAccessKeyId(),
'accessKeySecret' => $credentials->getAccessKeySecret(),
'securityToken' => $credentials->getSecurityToken(),
'type' => 'ram_role_arn',
]);
}
}

View File

@@ -0,0 +1,167 @@
<?php
namespace AlibabaCloud\Credentials\Request;
use AlibabaCloud\Credentials\Credentials;
use AlibabaCloud\Credentials\Utils\Helper;
use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;
use AlibabaCloud\Tea\Response;
use Psr\Http\Message\ResponseInterface;
use Exception;
use InvalidArgumentException;
/**
* RESTful RPC Request.
*/
class Request
{
/**
* Request Connect Timeout
*/
const CONNECT_TIMEOUT = 5;
/**
* Request Read Timeout
*/
const READ_TIMEOUT = 5;
/**
* @var array
*/
private static $config = [];
/**
*
* @return array
*/
public static function commonOptions()
{
$options = [];
$options['http_errors'] = false;
$options['connect_timeout'] = self::CONNECT_TIMEOUT;
$options['read_timeout'] = self::READ_TIMEOUT;
$options['headers']['User-Agent'] = Helper::getUserAgent();
// Turn on debug mode based on environment variable.
if (strtolower(Helper::env('DEBUG')) === 'sdk') {
$options['debug'] = true;
}
return $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
* @param string $accessKeySecret
*
* @return string
*/
public static function shaHmac1sign($string, $accessKeySecret)
{
return base64_encode(hash_hmac('sha1', $string, $accessKeySecret, true));
}
/**
* @param string $string
* @param string $accessKeySecret
*
* @return string
*/
public static function shaHmac256sign($string, $accessKeySecret)
{
return base64_encode(hash_hmac('sha256', $string, $accessKeySecret, true));
}
/**
* @param string $string
* @param string $privateKey
*
* @return string
*/
public static function shaHmac256WithRsasign($string, $privateKey)
{
$binarySignature = '';
try {
openssl_sign(
$string,
$binarySignature,
$privateKey,
\OPENSSL_ALGO_SHA256
);
} catch (Exception $exception) {
throw new InvalidArgumentException(
$exception->getMessage()
);
}
return base64_encode($binarySignature);
}
/**
* @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());
$history = Credentials::getHandlerHistory();
$stack->push($history);
} 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);
}
}

View File

@@ -0,0 +1,185 @@
<?php
namespace AlibabaCloud\Credentials;
use AlibabaCloud\Credentials\Providers\RsaKeyPairCredentialsProvider;
use AlibabaCloud\Credentials\Credential\CredentialModel;
use AlibabaCloud\Credentials\Signature\ShaHmac1Signature;
use AlibabaCloud\Credentials\Utils\Filter;
use Exception;
use GuzzleHttp\Exception\GuzzleException;
use InvalidArgumentException;
/**
* @deprecated
* Use the RSA key pair to complete the authentication (supported only on Japanese site)
*/
class RsaKeyPairCredential implements CredentialsInterface
{
/**
* @var string
*/
private $publicKeyId;
/**
* @var string
*/
private $privateKeyFile;
/**
* @var string
*/
private $privateKey;
/**
* @var array
*/
private $config;
/**
* RsaKeyPairCredential constructor.
*
* @param string $public_key_id
* @param string $private_key_file
* @param array $config
*/
public function __construct($public_key_id, $private_key_file, array $config = [])
{
Filter::publicKeyId($public_key_id);
Filter::privateKeyFile($private_key_file);
$this->publicKeyId = $public_key_id;
$this->privateKeyFile = $private_key_file;
$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 AlibabaCloud\Credentials\Providers\Credentials
* @throws Exception
* @throws GuzzleException
*/
protected function getSessionCredential()
{
$params = [
'publicKeyId' => $this->publicKeyId,
'privateKeyFile' => $this->privateKeyFile,
];
return (new RsaKeyPairCredentialsProvider($params))->getCredentials();
}
/**
* @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();
}
/**
* @inheritDoc
*/
public function getCredential()
{
$credentials = $this->getSessionCredential();
return new CredentialModel([
'accessKeyId' => $credentials->getAccessKeyId(),
'accessKeySecret' => $credentials->getAccessKeySecret(),
'securityToken' => $credentials->getSecurityToken(),
'type' => 'rsa_key_pair',
]);
}
}

View File

@@ -0,0 +1,47 @@
<?php
namespace AlibabaCloud\Credentials\Signature;
/**
* Class BearerTokenSignature
*
* @package AlibabaCloud\Credentials\Signature
*/
class BearerTokenSignature implements SignatureInterface
{
/**
* @return string
*/
public function getMethod()
{
return '';
}
/**
* @return string
*/
public function getType()
{
return 'BEARERTOKEN';
}
/**
* @return string
*/
public function getVersion()
{
return '1.0';
}
/**
* @param string $string
* @param string $accessKeySecret
*
* @return string
*/
public function sign($string, $accessKeySecret)
{
return '';
}
}

View File

@@ -0,0 +1,47 @@
<?php
namespace AlibabaCloud\Credentials\Signature;
/**
* Class ShaHmac1Signature
*
* @package AlibabaCloud\Credentials\Signature
*/
class ShaHmac1Signature implements SignatureInterface
{
/**
* @return string
*/
public function getMethod()
{
return 'HMAC-SHA1';
}
/**
* @return string
*/
public function getType()
{
return '';
}
/**
* @return string
*/
public function getVersion()
{
return '1.0';
}
/**
* @param string $string
* @param string $accessKeySecret
*
* @return string
*/
public function sign($string, $accessKeySecret)
{
return base64_encode(hash_hmac('sha1', $string, $accessKeySecret, true));
}
}

View File

@@ -0,0 +1,47 @@
<?php
namespace AlibabaCloud\Credentials\Signature;
/**
* Class ShaHmac256Signature
*
* @package AlibabaCloud\Credentials\Signature
*/
class ShaHmac256Signature implements SignatureInterface
{
/**
* @return string
*/
public function getMethod()
{
return 'HMAC-SHA256';
}
/**
* @return string
*/
public function getType()
{
return '';
}
/**
* @return string
*/
public function getVersion()
{
return '1.0';
}
/**
* @param string $string
* @param string $accessKeySecret
*
* @return string
*/
public function sign($string, $accessKeySecret)
{
return base64_encode(hash_hmac('sha256', $string, $accessKeySecret, true));
}
}

View File

@@ -0,0 +1,64 @@
<?php
namespace AlibabaCloud\Credentials\Signature;
use Exception;
use InvalidArgumentException;
/**
* Class ShaHmac256WithRsaSignature
*
* @package AlibabaCloud\Credentials\Signature
*/
class ShaHmac256WithRsaSignature implements SignatureInterface
{
/**
* @return string
*/
public function getMethod()
{
return 'SHA256withRSA';
}
/**
* @return string
*/
public function getType()
{
return 'PRIVATEKEY';
}
/**
* @return string
*/
public function getVersion()
{
return '1.0';
}
/**
* @param string $string
* @param string $privateKey
*
* @return string
*/
public function sign($string, $privateKey)
{
$binarySignature = '';
try {
openssl_sign(
$string,
$binarySignature,
$privateKey,
\OPENSSL_ALGO_SHA256
);
} catch (Exception $exception) {
throw new InvalidArgumentException(
$exception->getMessage()
);
}
return base64_encode($binarySignature);
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace AlibabaCloud\Credentials\Signature;
/**
* Interface SignatureInterface
*
* @package AlibabaCloud\Credentials\Signature
*/
interface SignatureInterface
{
/**
* @return string
*/
public function getMethod();
/**
* @return string
*/
public function getVersion();
/**
* @param string $string
* @param string $accessKeySecret
*
* @return string
*/
public function sign($string, $accessKeySecret);
/**
* @return string
*/
public function getType();
}

View File

@@ -0,0 +1,115 @@
<?php
namespace AlibabaCloud\Credentials;
use AlibabaCloud\Credentials\Utils\Filter;
use AlibabaCloud\Credentials\Credential\CredentialModel;
use AlibabaCloud\Credentials\Signature\ShaHmac1Signature;
/**
* @deprecated
* Use the STS Token to complete the authentication.
*/
class StsCredential implements CredentialsInterface
{
/**
* @var string
*/
private $accessKeyId;
/**
* @var string
*/
private $accessKeySecret;
/**
* @var string
*/
private $securityToken;
/**
* @var int
*/
private $expiration;
/**
* StsCredential constructor.
*
* @param string $access_key_id Access key ID
* @param string $access_key_secret Access Key Secret
* @param int $expiration
* @param string $security_token Security Token
*/
public function __construct($access_key_id, $access_key_secret, $expiration, $security_token = '')
{
Filter::accessKey($access_key_id, $access_key_secret);
Filter::expiration($expiration);
$this->accessKeyId = $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();
}
/**
* @inheritDoc
*/
public function getCredential()
{
return new CredentialModel([
'accessKeyId' => $this->accessKeyId,
'accessKeySecret' => $this->accessKeySecret,
'securityToken' => $this->securityToken,
'type' => 'sts',
]);
}
}

View File

@@ -0,0 +1,233 @@
<?php
namespace AlibabaCloud\Credentials\Utils;
use InvalidArgumentException;
/**
* Class Filter
*
* @package AlibabaCloud\Credentials\Utils
*/
class Filter
{
/**
* @param $name
*
* @codeCoverageIgnore
* @return string
*/
public static function credentialName($name)
{
if (!is_string($name)) {
throw new InvalidArgumentException('Name must be a string');
}
if ($name === '') {
throw new InvalidArgumentException('Name cannot be empty');
}
return $name;
}
/**
* @param $bearerToken
*
* @return mixed
* @throws InvalidArgumentException
*/
public static function bearerToken($bearerToken)
{
if (!is_string($bearerToken)) {
throw new InvalidArgumentException('bearerToken must be a string');
}
if ($bearerToken === '') {
throw new InvalidArgumentException('bearerToken cannot be empty');
}
return $bearerToken;
}
/**
* @param $publicKeyId
*
* @return mixed
*/
public static function publicKeyId($publicKeyId)
{
if (!is_string($publicKeyId)) {
throw new InvalidArgumentException('publicKeyId must be a string');
}
if ($publicKeyId === '') {
throw new InvalidArgumentException('publicKeyId cannot be empty');
}
return $publicKeyId;
}
/**
* @param $privateKeyFile
*
* @return mixed
*/
public static function privateKeyFile($privateKeyFile)
{
if (!is_string($privateKeyFile)) {
throw new InvalidArgumentException('privateKeyFile must be a string');
}
if ($privateKeyFile === '') {
throw new InvalidArgumentException('privateKeyFile cannot be empty');
}
return $privateKeyFile;
}
/**
* @param string|null $roleName
*/
public static function roleName($roleName)
{
if ($roleName === null) {
return;
}
if (!is_string($roleName)) {
throw new InvalidArgumentException('roleName must be a string');
}
if ($roleName === '') {
throw new InvalidArgumentException('roleName cannot be empty');
}
}
/**
* @param boolean|null $disableIMDSv1
*/
public static function disableIMDSv1($disableIMDSv1)
{
if (!is_bool($disableIMDSv1)) {
throw new InvalidArgumentException('disableIMDSv1 must be a boolean');
}
}
/**
* @param string|null $roleArn
*/
public static function roleArn($roleArn)
{
if (is_null($roleArn) || $roleArn === '') {
throw new InvalidArgumentException('roleArn cannot be empty');
}
}
/**
* @param string|null $roleArn
*/
public static function oidcProviderArn($oidcProviderArn)
{
if (is_null($oidcProviderArn) || $oidcProviderArn === '') {
throw new InvalidArgumentException('oidcProviderArn cannot be empty');
}
}
/**
* @param string|null $roleArn
*/
public static function oidcTokenFilePath($oidcTokenFilePath)
{
if (is_null($oidcTokenFilePath) || $oidcTokenFilePath === '') {
throw new InvalidArgumentException('oidcTokenFilePath cannot be empty');
}
}
/**
* @param string $accessKeyId
* @param string $accessKeySecret
*/
public static function accessKey($accessKeyId, $accessKeySecret)
{
if (!is_string($accessKeyId)) {
throw new InvalidArgumentException('accessKeyId must be a string');
}
if ($accessKeyId === '') {
throw new InvalidArgumentException('accessKeyId cannot be empty');
}
if (!is_string($accessKeySecret)) {
throw new InvalidArgumentException('accessKeySecret must be a string');
}
if ($accessKeySecret === '') {
throw new InvalidArgumentException('accessKeySecret cannot be empty');
}
}
/**
* @param string $securityToken
*/
public static function securityToken($securityToken)
{
if (!is_string($securityToken)) {
throw new InvalidArgumentException('securityToken must be a string');
}
if ($securityToken === '') {
throw new InvalidArgumentException('securityToken cannot be empty');
}
}
/**
* @param int $expiration
*/
public static function expiration($expiration)
{
if (!is_int($expiration)) {
throw new InvalidArgumentException('expiration must be a int');
}
}
/**
* @param int $connectTimeout
* @param int $readTimeout
*/
public static function timeout($connectTimeout, $readTimeout)
{
if (!is_int($connectTimeout)) {
throw new InvalidArgumentException('connectTimeout must be a int');
}
if (!is_int($readTimeout)) {
throw new InvalidArgumentException('readTimeout must be a int');
}
}
/**
* @param string|null $credentialsURI
*/
public static function credentialsURI($credentialsURI)
{
if (!is_string($credentialsURI)) {
throw new InvalidArgumentException('credentialsURI must be a string');
}
if ($credentialsURI === '') {
throw new InvalidArgumentException('credentialsURI cannot be empty');
}
}
/**
* @param boolean|null $reuseLastProviderEnabled
*/
public static function reuseLastProviderEnabled($reuseLastProviderEnabled)
{
if (!is_bool($reuseLastProviderEnabled)) {
throw new InvalidArgumentException('reuseLastProviderEnabled must be a boolean');
}
}
}

View File

@@ -0,0 +1,251 @@
<?php
namespace AlibabaCloud\Credentials\Utils;
use AlibabaCloud\Credentials\Credential;
use org\bovigo\vfs\vfsStream;
use Closure;
/**
* Class Helper
*
* @package AlibabaCloud\Credentials\Utils
*/
class Helper
{
/**
* @param array $arrays
*
* @return array
*/
public static function merge(array $arrays)
{
$result = [];
foreach ($arrays as $array) {
foreach ($array as $key => $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;
}
if (0 === strpos($filename, vfsStream::SCHEME)) {
// 虚拟文件忽略
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;
}
/**
* Snake to camel case.
*
* @param string $str
*
* @return string
*/
public static function snakeToCamelCase($str)
{
$components = explode('_', $str);
$camelCaseStr = $components[0];
for ($i = 1; $i < count($components); $i++) {
$camelCaseStr .= ucfirst($components[$i]);
}
return $camelCaseStr;
}
/**
* Get user agent.
*
* @param string $userAgent
*
* @return string
*/
public static function getUserAgent()
{
return sprintf('AlibabaCloud (%s; %s) PHP/%s Credentials/%s TeaDSL/1', PHP_OS, \PHP_SAPI, PHP_VERSION, Credential::VERSION);
}
/**
* @param array $arrays
* @param string $key
*
* @return mix
*/
public static function unsetReturnNull(array $arrays, $key)
{
if(isset($arrays[$key])) {
return $arrays[$key];
}
return null;
}
}

View File

@@ -0,0 +1,120 @@
<?php
namespace AlibabaCloud\Credentials\Utils;
use Exception;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\Psr7\Response;
use GuzzleHttp\Middleware;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
/**
* Trait MockTrait
*
* @package AlibabaCloud\Credentials\Utils
*/
trait MockTrait
{
/**
* @var array
*/
private static $mockQueue = [];
/**
* @var array
*/
private static $history = [];
/**
* @var MockHandler
*/
private static $mock;
/**
* @param integer $status
* @param array $headers
* @param array|string|object $body
*/
public static function mockResponse($status = 200, array $headers = [], $body = null)
{
if (is_array($body) || is_object($body)) {
$body = json_encode($body);
}
self::$mockQueue[] = new Response($status, $headers, $body);
self::createHandlerStack();
}
private static function createHandlerStack()
{
self::$mock = new MockHandler(self::$mockQueue);
}
/**
* @return MockHandler
*/
public static function getHandlerHistory()
{
return Middleware::history(self::$history);
}
/**
* @param string $message
* @param RequestInterface $request
* @param ResponseInterface|null $response
* @param Exception|null $previous
* @param array $handlerContext
*/
public static function mockRequestException(
$message,
RequestInterface $request,
ResponseInterface $response = null,
Exception $previous = null,
array $handlerContext = []
) {
self::$mockQueue[] = new RequestException(
$message,
$request,
$response,
$previous,
$handlerContext
);
self::createHandlerStack();
}
/**
* @return void
*/
public static function cancelMock()
{
self::$mockQueue = [];
self::$mock = null;
}
/**
* @return bool
*/
public static function hasMock()
{
return (bool)self::$mockQueue;
}
/**
* @return MockHandler
*/
public static function getMock()
{
return self::$mock;
}
/**
* @return array
*/
public static function getHistroy()
{
return self::$history;
}
}