init commit
This commit is contained in:
1
addons/wdsxh/.addonrc
Normal file
1
addons/wdsxh/.addonrc
Normal file
File diff suppressed because one or more lines are too long
153
addons/wdsxh/Wdsxh.php
Normal file
153
addons/wdsxh/Wdsxh.php
Normal file
@@ -0,0 +1,153 @@
|
||||
<?php
|
||||
|
||||
namespace addons\wdsxh;
|
||||
|
||||
use app\admin\model\AuthRule;
|
||||
use app\common\library\Menu;
|
||||
use think\Addons;
|
||||
use think\exception\PDOException;
|
||||
use think\Exception;
|
||||
|
||||
/**
|
||||
* 插件
|
||||
*/
|
||||
class Wdsxh extends Addons
|
||||
{
|
||||
|
||||
/**
|
||||
* 应用初始化
|
||||
*/
|
||||
public function appInit()
|
||||
{
|
||||
// 公共方法
|
||||
require_once __DIR__ . '/helper.php';
|
||||
|
||||
if(!class_exists("\Darabonba\OpenApi\Models\Config")){
|
||||
\think\Loader::addNamespace('Darabonba\OpenApi\Models', ADDON_PATH . 'wdsxh' . DS . 'library' . DS . 'alibabacloud' . DS. 'openapi-core' . DS. 'src' . DS. 'Models' . DS);
|
||||
}
|
||||
|
||||
if(!class_exists("\AlibabaCloud\Dara\Model")){
|
||||
\think\Loader::addNamespace('AlibabaCloud\Dara', ADDON_PATH . 'wdsxh' . DS . 'library' . DS . 'alibabacloud' . DS. 'darabonba' . DS. 'src' . DS);
|
||||
}
|
||||
|
||||
if(!class_exists("\AlibabaCloud\SDK\Dysmsapi\V20170525\Dysmsapi")){
|
||||
\think\Loader::addNamespace('AlibabaCloud\SDK\Dysmsapi\V20170525', ADDON_PATH . 'wdsxh' . DS . 'library' . DS . 'alibabacloud' . DS. 'dysmsapi-20170525' . DS. 'src' . DS);
|
||||
}
|
||||
|
||||
if(!class_exists("\Darabonba\OpenApi\OpenApiClient")){
|
||||
\think\Loader::addNamespace('Darabonba\OpenApi', ADDON_PATH . 'wdsxh' . DS . 'library' . DS . 'alibabacloud' . DS. 'openapi-core' . DS. 'src' . DS);
|
||||
}
|
||||
|
||||
if(!class_exists("\AlibabaCloud\Credentials\Credential")){
|
||||
\think\Loader::addNamespace('AlibabaCloud\Credentials', ADDON_PATH . 'wdsxh' . DS . 'library' . DS . 'alibabacloud' . DS. 'credentials' . DS. 'src' . DS);
|
||||
}
|
||||
|
||||
if(!class_exists("\AlibabaCloud\Tea\Model")){
|
||||
\think\Loader::addNamespace('AlibabaCloud\Tea', ADDON_PATH . 'wdsxh' . DS . 'library' . DS . 'alibabacloud' . DS. 'tea' . DS. 'src' . DS);
|
||||
}
|
||||
|
||||
if(!class_exists("\Adbar\Dot")){
|
||||
\think\Loader::addNamespace('Adbar', ADDON_PATH . 'wdsxh' . DS . 'library' . DS . 'adbario' . DS. 'php-dot-notation' . DS. 'src' . DS);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件安装方法
|
||||
* @return bool
|
||||
*/
|
||||
public function install()
|
||||
{
|
||||
$menu = self::getMenu();
|
||||
Menu::create($menu['new']);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件卸载方法
|
||||
* @return bool
|
||||
*/
|
||||
public function uninstall()
|
||||
{
|
||||
Menu::delete('wdsxh');
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件启用方法
|
||||
* @return bool
|
||||
*/
|
||||
public function enable()
|
||||
{
|
||||
Menu::enable('wdsxh');
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件禁用方法
|
||||
* @return bool
|
||||
*/
|
||||
public function disable()
|
||||
{
|
||||
Menu::disable('wdsxh');
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件升级方法
|
||||
* @return bool
|
||||
*/
|
||||
public function upgrade()
|
||||
{
|
||||
$menu = self::getMenu();
|
||||
if(method_exists(Menu::class, 'upgrade')){
|
||||
Menu::upgrade('wdsxh', $menu['new']);
|
||||
}else {
|
||||
//使用Groupon自带的更新操作
|
||||
self::menuWdsxhUpdate($menu['new'], $menu['old']);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static function getMenu()
|
||||
{
|
||||
$newMenu = [];
|
||||
$config_file = ADDON_PATH . "wdsxh" . DS . 'config' . DS . "menu.php";
|
||||
if (is_file($config_file)) {$newMenu = include $config_file;}
|
||||
$oldMenu = AuthRule::where('name','like',"wdsxh%")->select();
|
||||
$oldMenu = array_column($oldMenu, null, 'name');
|
||||
return ['new' => $newMenu, 'old' => $oldMenu];
|
||||
}
|
||||
|
||||
private static function menuWdsxhUpdate($newMenu, $oldMenu, $parent = 0)
|
||||
{
|
||||
if (!is_numeric($parent)) {
|
||||
$parentRule = AuthRule::getByName($parent);
|
||||
$pid = $parentRule ? $parentRule['id'] : 0;
|
||||
} else {
|
||||
$pid = $parent;
|
||||
}
|
||||
$allow = array_flip(['file', 'name', 'title', 'icon', 'condition', 'remark', 'ismenu', 'weigh']);
|
||||
foreach ($newMenu as $k => $v) {
|
||||
$hasChild = isset($v['sublist']) && $v['sublist'] ? true : false;
|
||||
$data = array_intersect_key($v, $allow);
|
||||
$data['ismenu'] = isset($data['ismenu']) ? $data['ismenu'] : ($hasChild ? 1 : 0);
|
||||
$data['icon'] = isset($data['icon']) ? $data['icon'] : ($hasChild ? 'fa fa-list' : 'fa fa-circle-o');
|
||||
$data['pid'] = $pid;
|
||||
$data['status'] = 'normal';
|
||||
try {
|
||||
if (!isset($oldMenu[$data['name']])) {
|
||||
$menu = AuthRule::create($data);
|
||||
}else{
|
||||
$menu = $oldMenu[$data['name']];
|
||||
}
|
||||
if ($hasChild) {
|
||||
self::menuWdsxhUpdate($v['sublist'], $oldMenu, $menu['id']);
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
new Exception($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
23
addons/wdsxh/bootstrap.js
vendored
Normal file
23
addons/wdsxh/bootstrap.js
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
require.config({
|
||||
paths: {
|
||||
'wdsxh-colorpicker': '../addons/wdsxh/libs/colorpicker/colorpicker',
|
||||
'poster': '../addons/wdsxh/libs/poster',
|
||||
'clipboard': '../addons/wdsxh/libs/clipboard.min',
|
||||
'designer': '../addons/wdsxh/libs/designer',
|
||||
'jquery-contextMenu': '../addons/wdsxh/libs/jquery.contextMenu',
|
||||
'jquery-form': '../addons/wdsxh/libs/jquery.form',
|
||||
'jquery-lazyload': '../addons/wdsxh/libs/jquery.lazyload.min',
|
||||
},
|
||||
// shim依赖配置
|
||||
shim: {
|
||||
'wdsxh-colorpicker': ['css!../addons/wdsxh/libs/colorpicker/colorpicker.css'],
|
||||
'poster': ['css!../addons/wdsxh/libs/poster.css'],
|
||||
'jquery-contextMenu': ['css!../addons/wdsxh/libs/jquery.contextMenu.css'],
|
||||
'animation': ['css!../addons/wdsxh/libs/colorui/animation.css'],
|
||||
'jquery-form': ['css!../addons/wdsxh/libs/colorui/coloriui-forh5.css'],
|
||||
'ColorUi-simplified': ['css!../addons/wdsxh/libs/colorui/ColorUi-simplified.css'],
|
||||
'icon': ['css!../addons/wdsxh/libs/colorui/icon.css'],
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
54
addons/wdsxh/command/Wdsxh.php
Normal file
54
addons/wdsxh/command/Wdsxh.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
namespace addons\wdsxh\command;
|
||||
|
||||
use GatewayWorker\BusinessWorker;
|
||||
use GatewayWorker\Gateway;
|
||||
use GatewayWorker\Register;
|
||||
use think\console\Command;
|
||||
use think\console\Input;
|
||||
use think\console\Output;
|
||||
use Workerman\Worker;
|
||||
|
||||
class Wdsxh extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('wdsxh')
|
||||
->setDescription("启动GatewayWorker服务");
|
||||
}
|
||||
|
||||
/*
|
||||
* 逻辑处理
|
||||
*/
|
||||
protected function execute(Input $input, Output $output)
|
||||
{
|
||||
//逻辑处理
|
||||
//定义端口
|
||||
$port = 1238;
|
||||
// 初始化register
|
||||
new Register('text://0.0.0.0:' . $port);
|
||||
|
||||
//初始化 bussinessWorker 进程
|
||||
$worker = new BusinessWorker();
|
||||
$worker->name = 'chatWorker'; //进程名
|
||||
$worker->count = 4; //进程数
|
||||
$worker->registerAddress = '127.0.0.1:' . $port;
|
||||
|
||||
// 设置处理业务的类,此处制定Events的命名空间
|
||||
$worker->eventHandler = '\app\api\controller\wdsxh\gateway\Events';
|
||||
// 初始化 gateway 进程
|
||||
$gateway = new Gateway("websocket://0.0.0.0:8282");
|
||||
$gateway->name = 'chatGateway'; //Gateway进程名
|
||||
$gateway->count = 4; //Gateway进程数
|
||||
$gateway->lanIp = '127.0.0.1';
|
||||
$gateway->startPort = 2000; //开始端口
|
||||
// $gateway->pingInterval = 60;
|
||||
// $gateway->pingNotResponseLimit = 5;
|
||||
// $gateway->pingData = 'pong';
|
||||
$gateway->registerAddress = '127.0.0.1:' . $port;
|
||||
|
||||
// 运行所有Worker;
|
||||
Worker::runAll();
|
||||
$output->writeln("done");
|
||||
}
|
||||
}
|
||||
37
addons/wdsxh/config.php
Normal file
37
addons/wdsxh/config.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
[
|
||||
'name' => 'theme',
|
||||
'title' => '前台模板',
|
||||
'type' => 'string',
|
||||
'content' => [],
|
||||
'value' => 'default',
|
||||
'rule' => '',
|
||||
'msg' => '',
|
||||
'tip' => '请确保addons/wdsxh/view有相应的目录',
|
||||
'ok' => '',
|
||||
'extend' => '',
|
||||
],
|
||||
[
|
||||
'name' => 'rewrite',
|
||||
'title' => '伪静态',
|
||||
'type' => 'array',
|
||||
'content' => [],
|
||||
'value' => [
|
||||
'index/index' => '/$',
|
||||
'index/about' => '/about/$',
|
||||
'index/contact' => '/contact/$',
|
||||
'index/membership' => '/membership/$',
|
||||
'index/news' => '/news/$',
|
||||
'index/news_detail' => '/news/news_detail/$',
|
||||
'index/header' => '/header/$',
|
||||
'index/footer' => '/footer/$',
|
||||
],
|
||||
'rule' => 'required',
|
||||
'msg' => '',
|
||||
'tip' => '',
|
||||
'ok' => '',
|
||||
'extend' => '',
|
||||
],
|
||||
];
|
||||
4090
addons/wdsxh/config/menu.php
Normal file
4090
addons/wdsxh/config/menu.php
Normal file
File diff suppressed because it is too large
Load Diff
13
addons/wdsxh/config/upgrade.php
Normal file
13
addons/wdsxh/config/upgrade.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
return array (
|
||||
1 =>
|
||||
array (
|
||||
'id' => 1,
|
||||
'createtime' => 1719977841,
|
||||
'version' => '4.1.5',
|
||||
'introduction' => '参考腾讯规则,优化登录方式',
|
||||
'log_content' => '<p><span style="font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, "Microsoft Yahei", Arial, sans-serif;">小程序需要更新</span><br style="font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, "Microsoft Yahei", Arial, sans-serif;"><span style="font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, "Microsoft Yahei", Arial, sans-serif;">【新增】</span><br style="font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, "Microsoft Yahei", Arial, sans-serif;"><span style="font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, "Microsoft Yahei", Arial, sans-serif;">1.增加团体类型可自定义,例如商会,协会,学会,研究会等,默认商会,更新后注意修改</span><br style="font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, "Microsoft Yahei", Arial, sans-serif;"><span style="font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, "Microsoft Yahei", Arial, sans-serif;">【优化】</span><br style="font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, "Microsoft Yahei", Arial, sans-serif;"><span style="font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, "Microsoft Yahei", Arial, sans-serif;">1.参考腾讯规则,优化登录方式,登录时不需要获取手机号,某些功能用到时获取</span><br style="font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, "Microsoft Yahei", Arial, sans-serif;"><span style="font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, "Microsoft Yahei", Arial, sans-serif;">2.优化小程序和公众号数据同步问题,若需两端数据同步,需先搭建公众号再部署小程序</span><br style="font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, "Microsoft Yahei", Arial, sans-serif;"><span style="font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, "Microsoft Yahei", Arial, sans-serif;">【修复】</span><br style="font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, "Microsoft Yahei", Arial, sans-serif;"><span style="font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, "Microsoft Yahei", Arial, sans-serif;">1.公众号版本头像无法修改</span><br style="font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, "Microsoft Yahei", Arial, sans-serif;"><span style="font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, "Microsoft Yahei", Arial, sans-serif;">2.会员风采行业分类样式错乱</span><br style="font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, "Microsoft Yahei", Arial, sans-serif;"><span style="font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, "Microsoft Yahei", Arial, sans-serif;">3.公众号版本推荐会员无法生效</span><br style="font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, "Microsoft Yahei", Arial, sans-serif;"><span style="font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, "Microsoft Yahei", Arial, sans-serif;">4.会员缴费日期不一致</span><br style="font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, "Microsoft Yahei", Arial, sans-serif;"><span style="font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, "Microsoft Yahei", Arial, sans-serif;">5.公众号无法保存图片</span><br style="font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, "Microsoft Yahei", Arial, sans-serif;"><span style="font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, "Microsoft Yahei", Arial, sans-serif;">6.公众号无法调起扫码核销</span><br></p>',
|
||||
'authorized_version_text' => '',
|
||||
),
|
||||
);
|
||||
84
addons/wdsxh/controller/Index.php
Normal file
84
addons/wdsxh/controller/Index.php
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
namespace addons\wdsxh\controller;
|
||||
|
||||
use think\addons\Controller;
|
||||
use think\exception\HttpResponseException;
|
||||
use think\Request;
|
||||
use think\Response;
|
||||
|
||||
class Index extends Controller
|
||||
{
|
||||
// 初始化
|
||||
public function __construct(Request $request = null)
|
||||
{
|
||||
parent::__construct($request);
|
||||
$config = get_addon_config('wdsxh');
|
||||
// 设定主题模板目录
|
||||
$this->view->engine->config('view_path', $this->view->engine->config('view_path') . $config['theme'] . DS);
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
return $this->view->fetch('/index');
|
||||
}
|
||||
|
||||
public function about()
|
||||
{
|
||||
return $this->view->fetch('/about');
|
||||
}
|
||||
|
||||
public function activity()
|
||||
{
|
||||
return $this->view->fetch('/activity');
|
||||
}
|
||||
|
||||
public function album()
|
||||
{
|
||||
return $this->view->fetch('/album');
|
||||
}
|
||||
|
||||
public function contact()
|
||||
{
|
||||
return $this->view->fetch('/contact');
|
||||
}
|
||||
|
||||
public function enterprise()
|
||||
{
|
||||
return $this->view->fetch('/enterprise');
|
||||
}
|
||||
|
||||
public function membership()
|
||||
{
|
||||
return $this->view->fetch('/membership');
|
||||
}
|
||||
|
||||
public function news()
|
||||
{
|
||||
return $this->view->fetch('/news');
|
||||
}
|
||||
|
||||
public function news_detail()
|
||||
{
|
||||
return $this->view->fetch('/news_detail');
|
||||
}
|
||||
|
||||
public function business()
|
||||
{
|
||||
return $this->view->fetch('/business');
|
||||
}
|
||||
|
||||
public function header()
|
||||
{
|
||||
return $this->view->fetch('/header');
|
||||
}
|
||||
|
||||
public function footer()
|
||||
{
|
||||
return $this->view->fetch('/footer');
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
259
addons/wdsxh/helper.php
Normal file
259
addons/wdsxh/helper.php
Normal file
@@ -0,0 +1,259 @@
|
||||
<?php
|
||||
if (!function_exists('wdsxh_get_openid')) {
|
||||
function wdsxh_get_openid($wechat_id,$channel){
|
||||
if ($channel == 1) {
|
||||
$field = 'applet_openid';
|
||||
} else {
|
||||
$field = 'wananchi_openid';
|
||||
}
|
||||
$openid =\app\api\model\wdsxh\UserWechat::where('id',$wechat_id)->value($field);
|
||||
return $openid;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('wdsxh_full_url')) {
|
||||
/**
|
||||
* 补全url
|
||||
*/
|
||||
function wdsxh_full_url($url,$ret=false)
|
||||
{
|
||||
if (empty($url)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if(stripos($url,',') !== false){
|
||||
$urls=explode(',',$url);
|
||||
foreach ($urls as &$row){
|
||||
$row=wdsxh_full_url($row);
|
||||
}
|
||||
return $urls;
|
||||
}
|
||||
|
||||
if (!wdsxh_is_url($url)){
|
||||
$url = cdnurl($url, true);
|
||||
if (!wdsxh_is_url($url)) {
|
||||
$url = request()->domain() . $url;
|
||||
}
|
||||
}
|
||||
return $ret?array($url):$url;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('wdsxh_is_url')) {
|
||||
/**
|
||||
* 是否url
|
||||
*/
|
||||
function wdsxh_is_url($url)
|
||||
{
|
||||
$preg = "/http[s]?:\/\/[\w.]+[\w\/]*[\w.]*\??[\w=&\+\%]*/is";
|
||||
if (preg_match($preg, $url)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('wdsxh_create_order')) {
|
||||
/**
|
||||
* 创建订单编号
|
||||
*/
|
||||
function wdsxh_create_order()
|
||||
{
|
||||
return date('YmdHis') . str_pad(mt_rand(0, 1000), '4', '0', STR_PAD_LEFT);
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('remove_wdsxh_full_url')) {
|
||||
/**
|
||||
* 移除域名
|
||||
*/
|
||||
function remove_wdsxh_full_url($url,$ret=false)
|
||||
{
|
||||
if(stripos($url,',') !== false){
|
||||
$urls=explode(',',$url);
|
||||
foreach ($urls as &$row){
|
||||
$row=remove_wdsxh_full_url($row);
|
||||
}
|
||||
return implode(',',$urls);
|
||||
}
|
||||
$url = remove_wdsxh_cdnurl($url);
|
||||
return $ret?array($url):$url;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('remove_wdsxh_cdnurl')) {
|
||||
|
||||
/**
|
||||
* 移除上传资源的CDN的地址
|
||||
* @param string $url 资源相对地址
|
||||
* @return string
|
||||
*/
|
||||
function remove_wdsxh_cdnurl($url)
|
||||
{
|
||||
$cdnurl = \think\Config::get('upload.cdnurl');
|
||||
if (wdsxh_is_url($url)) {
|
||||
|
||||
if($cdnurl) {
|
||||
$url = str_replace($cdnurl,'',$url);
|
||||
} else {
|
||||
$url = str_replace(request()->domain(),'',$url);
|
||||
}
|
||||
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('wdsxh_create_order')) {
|
||||
/**
|
||||
* 创建订单编号
|
||||
*/
|
||||
function wdsxh_create_order()
|
||||
{
|
||||
return date('YmdHis') . str_pad(mt_rand(0, 1000), '4', '0', STR_PAD_LEFT);
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('wdsxh_distance')) {
|
||||
//计算经纬度距离(php 方法)
|
||||
function wdsxh_distance($lat1, $lon1, $lat2, $lon2) {
|
||||
$earthRadius = 6371000; // 地球半径,单位为米
|
||||
|
||||
$lat1 = deg2rad($lat1);
|
||||
$lon1 = deg2rad($lon1);
|
||||
$lat2 = deg2rad($lat2);
|
||||
$lon2 = deg2rad($lon2);
|
||||
|
||||
$deltaLat = $lat2 - $lat1;
|
||||
$deltaLon = $lon2 - $lon1;
|
||||
$a = sin($deltaLat / 2) * sin($deltaLat / 2) + cos($lat1) * cos($lat2) * sin($deltaLon / 2) * sin($deltaLon / 2);
|
||||
$c = 2 * atan2(sqrt($a), sqrt(1 - $a));
|
||||
$distance = $earthRadius * $c;
|
||||
if ($distance < 1000){
|
||||
$rounded_number = round($distance, 2); // 保留两位小数
|
||||
$distance_number = $rounded_number.'m';
|
||||
}else{
|
||||
$kilometers = $distance / 1000; // 将米转换为千米
|
||||
$rounded_number = round($kilometers, 2); // 保留两位小数
|
||||
$distance_number = $rounded_number.'km';
|
||||
}
|
||||
return $distance_number; // 返回结果保留小数点后两位
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('wdsxh_mkdirs')) {
|
||||
//批量创建目录
|
||||
function wdsxh_mkdirs($path, $mode = "0755") {
|
||||
if(!is_dir($path)) { // 判断目录是否存在
|
||||
|
||||
wdsxh_mkdirs(dirname($path), $mode); // 循环建立目录
|
||||
|
||||
mkdir($path, $mode); // 建立目录
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('wdsxh_hide_phone_number')) {
|
||||
|
||||
function wdsxh_hide_phone_number($phoneNumber) {
|
||||
// 确保手机号格式正确(比如11位手机号)
|
||||
if (strlen($phoneNumber) == 11) {
|
||||
// 使用 substr 来提取手机号的前3位和后4位,中间部分用星号替代
|
||||
return substr($phoneNumber, 0, 3) . '****' . substr($phoneNumber, -4);
|
||||
} else {
|
||||
return "手机号格式不正确";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $str 内容
|
||||
* @param $len 长度
|
||||
* @param string $suffix 后缀
|
||||
* @return string|string[]
|
||||
*/
|
||||
if (!function_exists('wdsxh_cut_str')) {
|
||||
function wdsxh_cut_str($str, $len, $suffix = "...")
|
||||
{
|
||||
$str = strip_tags($str);
|
||||
$str = str_replace("\r\n", "", $str);
|
||||
if (function_exists('mb_substr')) {
|
||||
if (strlen($str) > $len) {
|
||||
$str = mb_substr($str, 0, $len, 'utf-8') . $suffix;
|
||||
}
|
||||
return $str;
|
||||
} else {
|
||||
if (strlen($str) > $len) {
|
||||
$str = substr($str, 0, $len, 'utf-8') . $suffix;
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Desc 更新数组字段相同数据
|
||||
* Create on 2025/3/14 13:36
|
||||
* Create by wangyafang
|
||||
*/
|
||||
if (!function_exists('wdsxh_update_array_child_fieldset')) {
|
||||
function wdsxh_update_array_child_fieldset($person_fieldset, $total_values) {
|
||||
// 将 $total_values 转换为一个哈希表,键为 'field',值为 'val'
|
||||
$value_map = [];
|
||||
foreach ($total_values as $value) {
|
||||
$value_map[$value['field']] = $value['val'];
|
||||
}
|
||||
|
||||
// 遍历 $person_fieldset 数组
|
||||
foreach ($person_fieldset as &$fieldset) {
|
||||
if (in_array($fieldset['field'],array('name','mobile','member_level_id','address','industry_category_id'))) {
|
||||
continue;
|
||||
}
|
||||
if (in_array($fieldset['type'],array('image','video','cert','file'))) {
|
||||
continue;
|
||||
}
|
||||
if (isset($value_map[$fieldset['label']])) {
|
||||
$fieldset['value'] = $value_map[$fieldset['label']];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $person_fieldset;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Desc 编辑器 XSS 过滤
|
||||
* Create on 2025/4/21 14:16
|
||||
* Create by wangyafang
|
||||
*/
|
||||
if (!function_exists('wdsxh_xss_filter')) {
|
||||
function wdsxh_xss_filter($content) {
|
||||
$config = \HTMLPurifier_Config::createDefault();
|
||||
$config->set('HTML.Allowed', 'p,br,b,strong,i,em,a[href|title],ul,ol,li,img[src|alt|title|width|height|style]');
|
||||
$config->set('HTML.Doctype', 'XHTML 1.0 Strict');
|
||||
$config->set('HTML.TidyLevel', 'medium');
|
||||
$config->set('AutoFormat.AutoParagraph', true);
|
||||
$config->set('AutoFormat.RemoveEmpty', true);
|
||||
$config->set('URI.AllowedSchemes', ['http' => true, 'https' => true]);
|
||||
$config->set('URI.DisableExternal', false); // 允许外部资源(图片)
|
||||
$config->set('URI.DisableResources', false); // 允许资源加载(图片)
|
||||
$config->set('Attr.AllowedFrameTargets', []);
|
||||
$config->set('Attr.EnableID', false);
|
||||
$config->set('Cache.DefinitionImpl', null); // 禁用缓存
|
||||
|
||||
$purifier = new \HTMLPurifier($config);
|
||||
$content = $purifier->purify($content);
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
8
addons/wdsxh/info.ini
Normal file
8
addons/wdsxh/info.ini
Normal file
@@ -0,0 +1,8 @@
|
||||
name = wdsxh
|
||||
title = 商协会系统
|
||||
intro = 商会系统
|
||||
author = myworld
|
||||
website = https://www.fastadmin.net
|
||||
version = 4.4.0
|
||||
state = 1
|
||||
url = /addons/wdsxh.html
|
||||
5461
addons/wdsxh/install.sql
Normal file
5461
addons/wdsxh/install.sql
Normal file
File diff suppressed because one or more lines are too long
82
addons/wdsxh/library/AlibabaCloudSms.php
Normal file
82
addons/wdsxh/library/AlibabaCloudSms.php
Normal file
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 麦沃德科技赋能开发者,助力中小企业发展
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2024 www.wdadmin.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Wdadmin系统产品软件并不是自由软件,不加密,并不代表开源,未经许可不可自由转售和商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: MY WORLD Team <bd@maiwd.cn> www.wdadmin.cn
|
||||
// +----------------------------------------------------------------------
|
||||
/**
|
||||
* Class Sample
|
||||
* Desc 阿里云短信demo
|
||||
* Create on 2025/5/22 13:35
|
||||
* Create by wangyafang
|
||||
*/
|
||||
|
||||
namespace addons\wdsxh\library;
|
||||
|
||||
|
||||
|
||||
|
||||
use addons\qcloudsms\library\SmsSingleSender;
|
||||
use addons\qcloudsms\library\SmsVoiceVerifyCodeSender;
|
||||
use addons\qcloudsms\library\TtsVoiceSender;
|
||||
use AlibabaCloud\SDK\Dysmsapi\V20170525\Dysmsapi;
|
||||
use \Exception;
|
||||
use AlibabaCloud\Tea\Exception\TeaError;
|
||||
use AlibabaCloud\Tea\Utils\Utils;
|
||||
|
||||
use Darabonba\OpenApi\Models\Config;
|
||||
use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\SendSmsRequest;
|
||||
use AlibabaCloud\Tea\Utils\Utils\RuntimeOptions;
|
||||
|
||||
class AlibabaCloudSms {
|
||||
|
||||
/**
|
||||
* 使用凭据初始化账号Client
|
||||
* @return Dysmsapi Client
|
||||
*/
|
||||
public static function createClient(){
|
||||
// 工程代码建议使用更安全的无AK方式,凭据配置方式请参见:https://help.aliyun.com/document_detail/311677.html。
|
||||
$configObj = (new \app\admin\model\wdsxh\Config())->where('id',1)->find();
|
||||
$config = new Config([
|
||||
'type' => 'access_key',
|
||||
'accessKeyId' => $configObj['alibaba_cloud_access_key_id'],
|
||||
'accessKeySecret' => $configObj['alibaba_cloud_access_key_secret'],
|
||||
]);
|
||||
// Endpoint 请参考 https://api.aliyun.com/product/Dysmsapi
|
||||
$config->endpoint = "dysmsapi.aliyuncs.com";
|
||||
return new Dysmsapi($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $args
|
||||
* @return void
|
||||
*/
|
||||
public static function main($args){
|
||||
$client = self::createClient();
|
||||
|
||||
$configObj = (new \app\admin\model\wdsxh\Config())->where('id',1)->find();
|
||||
$args['signName'] = $configObj['alibaba_cloud_sign_name'];
|
||||
$sendSmsRequest = new SendSmsRequest($args);
|
||||
$runtime = new \AlibabaCloud\Dara\Models\RuntimeOptions();
|
||||
try {
|
||||
// 复制代码运行请自行打印 API 的返回值
|
||||
$res = $client->sendSmsWithOptions($sendSmsRequest, $runtime);
|
||||
return $res;
|
||||
}
|
||||
catch (Exception $error) {
|
||||
if (!($error instanceof TeaError)) {
|
||||
$error = new TeaError([], $error->getMessage(), $error->getCode(), $error);
|
||||
}
|
||||
|
||||
return $error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
51
addons/wdsxh/library/Encryptor.php
Normal file
51
addons/wdsxh/library/Encryptor.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 麦沃德科技赋能开发者,助力中小企业发展
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2024 www.wdadmin.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Wdadmin系统产品软件并不是自由软件,不加密,并不代表开源,未经许可不可自由转售和商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: MY WORLD Team <bd@maiwd.cn> www.wdadmin.cn
|
||||
// +----------------------------------------------------------------------
|
||||
/**
|
||||
* Class Encryptor
|
||||
* Desc 加密和解密函数
|
||||
* Create on 2024/10/30 10:29
|
||||
* Create by wangyafang
|
||||
*/
|
||||
|
||||
namespace addons\wdsxh\library;
|
||||
|
||||
|
||||
class Encryptor
|
||||
{
|
||||
private $encryption_key;
|
||||
private $iv;
|
||||
|
||||
public function __construct($key,$iv) {
|
||||
if (strlen($key) !== 16) {
|
||||
throw new \think\Exception('Encryption key must be 32 bytes long.');
|
||||
}
|
||||
$this->encryption_key = $key;
|
||||
$this->iv = $iv; // fixed IV (16 bytes for AES-256-CBC)
|
||||
}
|
||||
|
||||
public function encrypt($data) {
|
||||
|
||||
// Encrypt the data using the fixed IV
|
||||
$encrypted = openssl_encrypt($data, 'aes-256-cbc', $this->encryption_key, 0, $this->iv);
|
||||
return base64_encode($encrypted);
|
||||
}
|
||||
|
||||
public function decrypt($data) {
|
||||
// Decode the base64 encoded string
|
||||
$data = base64_decode($data);
|
||||
// Decrypt the data using the fixed IV
|
||||
return openssl_decrypt($data, 'aes-256-cbc', $this->encryption_key, 0, $this->iv);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
468
addons/wdsxh/library/Wxapp.php
Normal file
468
addons/wdsxh/library/Wxapp.php
Normal file
@@ -0,0 +1,468 @@
|
||||
<?php
|
||||
|
||||
namespace addons\wdsxh\library;
|
||||
|
||||
use app\admin\model\wdsxh\Config;
|
||||
use app\admin\model\wdsxh\mall\Order;
|
||||
use EasyWeChat\Factory;
|
||||
use think\Exception;
|
||||
use think\Log;
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Psr7\Request;
|
||||
use GuzzleHttp\Pool;
|
||||
use GuzzleHttp\Exception\ClientException;
|
||||
|
||||
/**
|
||||
* 微信处理类
|
||||
*/
|
||||
class Wxapp
|
||||
{
|
||||
public static function wxappInit($type = 0)
|
||||
{
|
||||
try {
|
||||
$site = (new \app\admin\model\wdsxh\Config())->where('id',1)->find();
|
||||
|
||||
if ($type == 1) {
|
||||
if (empty($site['mch_id'])) {
|
||||
throw new \think\Exception('微信支付商户号未配置');
|
||||
}
|
||||
if (empty($site['key'])) {
|
||||
throw new \think\Exception('微信支付秘钥未配置');
|
||||
}
|
||||
}
|
||||
$appid = trim($site['applet_appid']);
|
||||
$secret = trim($site['applet_secret']);
|
||||
if ($type == 2) {
|
||||
$appid = trim($site['wananchi_appid']);
|
||||
$secret = trim($site['wananchi_secret']);
|
||||
}
|
||||
|
||||
$config = [
|
||||
'app_id' => $appid,
|
||||
'secret' => $secret,
|
||||
'mch_id' => empty($site['mch_id']) ? '' : trim($site['mch_id']),
|
||||
'key' => empty($site['key']) ? '' : trim($site['key']),
|
||||
'cert_path' => empty($site['cert_path']) ? '' : ROOT_PATH . 'public' . trim($site['cert_path']),
|
||||
'key_path' => empty($site['key_path']) ? '' : ROOT_PATH . 'public' . trim($site['key_path']),
|
||||
'notify_url' => '',
|
||||
'response_type' => 'array',
|
||||
'log' => [
|
||||
'level' => 'debug',
|
||||
'file' => RUNTIME_PATH . 'wechat.log',
|
||||
],
|
||||
];
|
||||
if ($type == 0) {
|
||||
return Factory::miniProgram($config);
|
||||
} else {
|
||||
return Factory::payment($config);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
die($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public static function getApp()
|
||||
{
|
||||
return self::wxappInit();
|
||||
}
|
||||
|
||||
public static function getPay()
|
||||
{
|
||||
return self::wxappInit(1);
|
||||
}
|
||||
|
||||
public static function getPayWxofficial()
|
||||
{
|
||||
return self::wxappInit(2);
|
||||
}
|
||||
|
||||
public static function wxlogin($code)
|
||||
{
|
||||
return self::getApp()->auth->session($code);
|
||||
}
|
||||
|
||||
public static function unify($body, $sn, $money, $openid, $notify_url)
|
||||
{
|
||||
$pay = self::getPay();
|
||||
$result = $pay->order->unify([
|
||||
'body' => $body,
|
||||
'out_trade_no' => $sn,
|
||||
'total_fee' => $money * 100,
|
||||
'notify_url' => $notify_url,
|
||||
'trade_type' => 'JSAPI',
|
||||
'openid' => $openid,
|
||||
]);
|
||||
if ($result && $result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS' && isset($result['prepay_id'])) {
|
||||
return $pay->jssdk->bridgeConfig($result['prepay_id'], false);
|
||||
} else {
|
||||
Log::record([
|
||||
'body' => $body,
|
||||
'out_trade_no' => $sn,
|
||||
'total_fee' => $money * 100,
|
||||
'notify_url' => $notify_url,
|
||||
'trade_type' => 'JSAPI',
|
||||
'openid' => $openid,
|
||||
], 'info');
|
||||
Log::record($result, 'info');
|
||||
throw new \think\Exception(isset($result['return_msg']) ? $result['return_msg'] : '统一下单发生错误');
|
||||
}
|
||||
}
|
||||
|
||||
public static function unify_wxofficial($body, $sn, $money, $openid, $notify_url)
|
||||
{
|
||||
$pay = self::getPayWxofficial();
|
||||
$result = $pay->order->unify([
|
||||
'body' => $body,
|
||||
'out_trade_no' => $sn,
|
||||
'total_fee' => $money * 100,
|
||||
'notify_url' => $notify_url,
|
||||
'trade_type' => 'JSAPI',
|
||||
'openid' => $openid,
|
||||
]);
|
||||
|
||||
if ($result && $result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS' && isset($result['prepay_id'])) {
|
||||
return $pay->jssdk->bridgeConfig($result['prepay_id'], false);
|
||||
} else {
|
||||
Log::record([
|
||||
'body' => $body,
|
||||
'out_trade_no' => $sn,
|
||||
'total_fee' => $money * 100,
|
||||
'notify_url' => $notify_url,
|
||||
'trade_type' => 'JSAPI',
|
||||
'openid' => $openid,
|
||||
], 'info');
|
||||
Log::record($result, 'info');
|
||||
throw new \think\Exception(isset($result['err_code_des']) ? $result['err_code_des'] : '统一下单发生错误');
|
||||
}
|
||||
}
|
||||
|
||||
public static function weixinunify($body, $sn, $money, $openid, $notify_url)
|
||||
{
|
||||
$pay = self::getPay();
|
||||
$result = $pay->order->unify([
|
||||
'body' => $body,
|
||||
'out_trade_no' => $sn,
|
||||
'total_fee' => $money * 100,
|
||||
'notify_url' => $notify_url,
|
||||
'trade_type' => 'MWEB',
|
||||
'openid' => $openid,
|
||||
]);
|
||||
p($result);
|
||||
if ($result && $result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS' && isset($result['prepay_id'])) {
|
||||
return $pay->jssdk->bridgeConfig($result['prepay_id'], false);
|
||||
} else {
|
||||
Log::record([
|
||||
'body' => $body,
|
||||
'out_trade_no' => $sn,
|
||||
'total_fee' => $money * 100,
|
||||
'notify_url' => $notify_url,
|
||||
'trade_type' => 'JSAPI',
|
||||
'openid' => $openid,
|
||||
], 'info');
|
||||
Log::record($result, 'info');
|
||||
throw new \think\Exception(isset($result['return_msg']) ? $result['return_msg'] : '统一下单发生错误');
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 退款操作
|
||||
*/
|
||||
public static function payRefund($number, $refundNumber, $refundFee, $config = null)
|
||||
{
|
||||
$pay = self::getPay();
|
||||
try {
|
||||
$result = $pay->refund->byOutTradeNumber($number, $refundNumber, intval($refundFee * 100), intval($refundFee * 100), $config ? $config : [
|
||||
'refund_desc' => '支付后退款',
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
die($e->getMessage());
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function phone($code, $iv, $encryptedData)
|
||||
{
|
||||
$app = self::getApp();
|
||||
$openid = $app->auth->session($code);
|
||||
if (empty($openid['openid']) || empty($openid['session_key'])) {
|
||||
throw new \think\Exception('小程序登录失败');
|
||||
}
|
||||
return $app->encryptor->decryptData($openid['session_key'], $iv, $encryptedData);
|
||||
}
|
||||
|
||||
public static function getQrcode($path)
|
||||
{
|
||||
$app = self::getApp();
|
||||
$response = $app->app_code->get($path, array('width' => 280, 'is_hyaline' => true));
|
||||
//$response = $app->app_code->getQrCode($path,280);
|
||||
if ($response instanceof \EasyWeChat\Kernel\Http\StreamResponse) {
|
||||
$savePath = ROOT_PATH . 'public' . DS . 'uploads'.DS.'wdsxh'.DS.'qrcode' . DS;
|
||||
if (!is_dir($savePath)) {
|
||||
mkdir($savePath, 0777, true);
|
||||
}
|
||||
$filename = time() . mt_rand(1000, 9999) . '.png';
|
||||
$response->saveAs($savePath, $filename);
|
||||
return $savePath . $filename;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function subscribeMessage($template_id, $openid, $page, $data)
|
||||
{
|
||||
if(empty($template_id) || empty($openid) || empty($data)){
|
||||
return false;
|
||||
}
|
||||
$app = self::getApp();
|
||||
$accessToken = $app->access_token;
|
||||
$token = $accessToken->getToken(true);
|
||||
$url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token={$token['access_token']}";
|
||||
$content = [
|
||||
'template_id' => trim($template_id),
|
||||
'touser' => '',
|
||||
'page' => trim($page),
|
||||
'data' => $data,
|
||||
];
|
||||
//$response=$app->subscribe_message->send($data);
|
||||
$client = new Client();
|
||||
$openids = [];
|
||||
if (is_string($openid)) {
|
||||
$openids[] = $openid;
|
||||
} elseif (is_array($openid)) {
|
||||
$openids = $openid;
|
||||
} else {
|
||||
throw new Exception('openid类型错误');
|
||||
}
|
||||
try {
|
||||
$requests = function ($total) use ($client, $url, $content, $openids) {
|
||||
foreach ($openids as $row) {
|
||||
$content['touser'] = $row;
|
||||
yield function () use ($client, $url, $content) {
|
||||
$options = [
|
||||
'headers' => ['Content-Type' => 'application/json'],
|
||||
'body' => json_encode($content)
|
||||
];
|
||||
return $client->postAsync($url, $options);
|
||||
};
|
||||
}
|
||||
};
|
||||
$res = [];
|
||||
$pool = new Pool($client, $requests(count($openids)), [
|
||||
'concurrency' => count($openids),
|
||||
'fulfilled' => function ($response, $index) use (&$res) {
|
||||
$res[$index] = json_decode($response->getBody()->getContents(), true);
|
||||
},
|
||||
'rejected' => function ($reason, $index) use (&$res) {
|
||||
$res[$index] = $reason;
|
||||
},
|
||||
]);
|
||||
$promise = $pool->promise();
|
||||
$promise->wait();
|
||||
} catch (Exception $e) {
|
||||
throw new Exception($e->getMessage());
|
||||
} catch (ClientException $e) {
|
||||
throw new Exception($e->getMessage());
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
public static function uniformSend($openid, $mp_template_msg)
|
||||
{
|
||||
$app = self::getApp();
|
||||
$accessToken = $app->access_token;
|
||||
$token = $accessToken->getToken();
|
||||
$url = 'https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token=' . $token['access_token'];
|
||||
$data = [
|
||||
'touser' => $openid,
|
||||
'mp_template_msg' => $mp_template_msg
|
||||
];
|
||||
$response = self::httpPost($url, $data);
|
||||
|
||||
}
|
||||
|
||||
private static function httpPost($url, $data)
|
||||
{
|
||||
$curlPost = json_encode($data);
|
||||
$curl = curl_init();
|
||||
curl_setopt($curl, CURLOPT_URL, $url);
|
||||
curl_setopt($curl, CURLOPT_HEADER, false);
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($curl, CURLOPT_NOBODY, true);
|
||||
curl_setopt($curl, CURLOPT_POST, true);
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, $curlPost);
|
||||
$return_str = curl_exec($curl);
|
||||
curl_close($curl);
|
||||
return $return_str;
|
||||
}
|
||||
|
||||
public static function checkSecurityText($openId,$content)
|
||||
{
|
||||
$app = self::getApp();
|
||||
$accessToken = $app->access_token;
|
||||
$token = $accessToken->getToken();
|
||||
$url = "https://api.weixin.qq.com/wxa/msg_sec_check?access_token=".$token['access_token'];
|
||||
$data = [
|
||||
'openid' => $openId,
|
||||
'scene' => 2,
|
||||
'version' => 2,
|
||||
'content' => $content,
|
||||
];
|
||||
$response = self::httpPostCheckText($url, $data);
|
||||
|
||||
$result = json_decode($response,true);
|
||||
if ($result['errcode'] != 0) {
|
||||
if ($result['errcode'] == 40001) {
|
||||
$token = $accessToken->getToken(true);
|
||||
$url = "https://api.weixin.qq.com/wxa/msg_sec_check?access_token=".$token['access_token'];
|
||||
$fileType = mb_detect_encoding($content, array('UTF-8','GBK','LATIN1','BIG5'));
|
||||
if($fileType != 'UTF-8') {
|
||||
$content = mb_convert_encoding($content ,'utf-8', $fileType);
|
||||
}
|
||||
$data = [
|
||||
'openid' => $openId,
|
||||
'scene' => 2,
|
||||
'version' => 2,
|
||||
'content' => $content,
|
||||
];
|
||||
$response = self::httpPostCheckText($url, $data);
|
||||
$result = json_decode($response,true);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
if (isset($result['errcode']) && $result['errcode'] == 0 && isset($result['result']) && $result['result']['suggest']=='pass') {
|
||||
return 1;
|
||||
} else {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
private static function httpPostCheckText($url, $data)
|
||||
{
|
||||
$curlPost = json_encode($data, JSON_UNESCAPED_UNICODE);
|
||||
$curl = curl_init();
|
||||
curl_setopt($curl, CURLOPT_URL, $url);
|
||||
curl_setopt($curl, CURLOPT_HEADER, false);
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($curl, CURLOPT_NOBODY, true);
|
||||
curl_setopt($curl, CURLOPT_POST, true);
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, $curlPost);
|
||||
$return_str = curl_exec($curl);
|
||||
curl_close($curl);
|
||||
return $return_str;
|
||||
}
|
||||
|
||||
//订单发货
|
||||
//$order_number_type = 订单单号类型,用于确认需要上传详情的订单。枚举值1,使用下单商户号和商户侧单号;枚举值2,使用微信支付单号
|
||||
//transaction_id = 原支付交易对应的微信订单号
|
||||
//delivery_mode = 发货模式,发货模式枚举值:1、UNIFIED_DELIVERY(统一发货)2、SPLIT_DELIVERY(分拆发货) 示例值: UNIFIED_DELIVERY
|
||||
//logistics_type = 物流模式,发货方式枚举值:1、实体物流配送采用快递公司进行实体物流配送形式 2、同城配送 3、虚拟商品,虚拟商品,例如话费充值,点卡等,无实体配送形式 4、用户自提
|
||||
//tracking_no = 物流单号,物流快递发货时必填,示例值: 323244567777 字符字节限制: [1, 128]
|
||||
//express_company = 物流公司编码,快递公司ID,参见「查询物流公司编码列表」,物流快递发货时必填, 示例值: DHL 字符字节限制: [1, 128]
|
||||
//item_desc = 商品信息,例如:微信红包抱枕*1个,限120个字以内
|
||||
//consignor_contact = 寄件人联系方式,寄件人联系方式,采用掩码传输,最后4位数字不能打掩码 示例值: `189****1234, 021-****1234, ****1234, 0**2-***1234, 0**2-******23-10, ****123-8008` 值限制: 0 ≤ value ≤ 1024
|
||||
//upload_time = 上传时间,用于标识请求的先后顺序 示例值: `2022-12-15T13:29:35.120+08:00`
|
||||
//openid = 用户标识,用户在小程序appid下的唯一标识。 下单前需获取到用户的Openid 示例值: oUpF8uMuAJO_M2pxb1Q9zNjWeS6o 字符字节限制: [1, 128]
|
||||
public static function upload_shipping_info($order_number_type,$transaction_id,$delivery_mode,$logistics_type,$tracking_no,$express_company,$item_desc,$consignor_contact,$openid)
|
||||
{
|
||||
$app = self::getApp();
|
||||
$accessToken = $app->access_token;
|
||||
$token = $accessToken->getToken();
|
||||
$url = 'https://api.weixin.qq.com/wxa/sec/order/upload_shipping_info?access_token='.$token['access_token'];
|
||||
$data = [
|
||||
'order_key' => [
|
||||
'order_number_type' => $order_number_type,
|
||||
'transaction_id' => $transaction_id,
|
||||
],
|
||||
'delivery_mode' => $delivery_mode,
|
||||
'logistics_type' => $logistics_type,
|
||||
'shipping_list' => [
|
||||
[
|
||||
'tracking_no' => $tracking_no,
|
||||
'express_company' => $express_company,
|
||||
'item_desc' => $item_desc,
|
||||
'contact' => [
|
||||
'consignor_contact' => '+86-'.$consignor_contact,
|
||||
],
|
||||
],
|
||||
],
|
||||
'upload_time' => date('Y-m-d',time()).'T'.date('h:i:s',time()).'.120+08:00',
|
||||
'payer' => [
|
||||
'openid' => $openid,
|
||||
],
|
||||
];
|
||||
Log::record($data,'delivery_data');
|
||||
$response = self::httpPosts($url, $data);
|
||||
$response = json_decode($response, true);
|
||||
if ($response['errcode'] == 0){
|
||||
$data = [
|
||||
'code' => $response['errcode'],
|
||||
'errmsg' => $response['errmsg'],
|
||||
];;
|
||||
return $data;
|
||||
}else{
|
||||
$data = [
|
||||
'code' => $response['errcode'],
|
||||
'errmsg' => $response['errmsg'],
|
||||
];
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static function get_order($transaction_id)
|
||||
{
|
||||
$app = self::getApp();
|
||||
$accessToken = $app->access_token;
|
||||
$token = $accessToken->getToken();
|
||||
$url = 'https://api.weixin.qq.com/wxa/sec/order/get_order?access_token='.$token['access_token'];
|
||||
$data = [
|
||||
'transaction_id' => $transaction_id,
|
||||
"merchant_id"=> (new Config())->where('id',1)->value('mch_id'),
|
||||
"merchant_trade_no"=> (new Order())->where('trade_no',$transaction_id)->value('order_no'),
|
||||
];
|
||||
Log::record($data,'get_order');
|
||||
$response = self::httpPosts($url, $data);
|
||||
$response = json_decode($response, true);
|
||||
if ($response['errcode'] == 0){
|
||||
$data = [
|
||||
'code' => $response['errcode'],
|
||||
'errmsg' => $response['errmsg'],
|
||||
'order'=>isset($response['order']) ? $response['order'] : [],
|
||||
];;
|
||||
return $data;
|
||||
}else{
|
||||
$data = [
|
||||
'code' => $response['errcode'],
|
||||
'errmsg' => $response['errmsg'],
|
||||
];
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
private static function httpPosts($url, $data)
|
||||
{
|
||||
$curlPost = json_encode($data, JSON_UNESCAPED_UNICODE); // 确保以 UTF-8 编码发送数据
|
||||
$curl = curl_init();
|
||||
curl_setopt($curl, CURLOPT_URL, $url);
|
||||
curl_setopt($curl, CURLOPT_HEADER, false);
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); // 允许获取返回内容
|
||||
curl_setopt($curl, CURLOPT_POST, true);
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, $curlPost);
|
||||
|
||||
// 设置 HTTP 头信息,确保是 UTF-8 编码
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, [
|
||||
'Content-Type: application/json; charset=UTF-8',
|
||||
]);
|
||||
$return_str = curl_exec($curl);
|
||||
// 错误检查
|
||||
if(curl_errno($curl)) {
|
||||
// 错误处理
|
||||
echo 'Curl error: ' . curl_error($curl);
|
||||
}
|
||||
curl_close($curl);
|
||||
// 返回响应结果
|
||||
return $return_str;
|
||||
}
|
||||
|
||||
}
|
||||
120
addons/wdsxh/library/Wxofficial/Jssdk.php
Normal file
120
addons/wdsxh/library/Wxofficial/Jssdk.php
Normal file
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
namespace addons\wdsxh\library\Wxofficial;
|
||||
|
||||
class Jssdk {
|
||||
private $appId;
|
||||
private $appSecret;
|
||||
|
||||
public function __construct($appId, $appSecret) {
|
||||
$this->appId = $appId;
|
||||
$this->appSecret = $appSecret;
|
||||
}
|
||||
|
||||
public function getSignPackage($url) {
|
||||
$jsapiTicket = $this->getJsApiTicket();
|
||||
|
||||
// 注意 URL 一定要动态获取,不能 hardcode.
|
||||
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
|
||||
//$url = "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
|
||||
$url = (!empty($url)) ? $url : "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
|
||||
|
||||
|
||||
$timestamp = time();
|
||||
$nonceStr = $this->createNonceStr();
|
||||
|
||||
// 这里参数的顺序要按照 key 值 ASCII 码升序排序
|
||||
$string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr×tamp=$timestamp&url=$url";
|
||||
|
||||
$signature = sha1($string);
|
||||
|
||||
$signPackage = array(
|
||||
"appId" => $this->appId,
|
||||
"nonceStr" => $nonceStr,
|
||||
"timestamp" => $timestamp,
|
||||
"url" => $url,
|
||||
"signature" => $signature,
|
||||
"rawString" => $string
|
||||
);
|
||||
return $signPackage;
|
||||
}
|
||||
|
||||
private function createNonceStr($length = 16) {
|
||||
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
$str = "";
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
|
||||
private function getJsApiTicket() {
|
||||
// jsapi_ticket 应该全局存储与更新,以下代码以写入到文件中做示例
|
||||
$data = json_decode($this->get_php_file("jsapi_ticket.php"));
|
||||
if ($data->expire_time < time()) {
|
||||
$accessToken = $this->getAccessToken();
|
||||
// 如果是企业号用以下 URL 获取 ticket
|
||||
// $url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=$accessToken";
|
||||
$url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=$accessToken";
|
||||
$res = json_decode($this->httpGet($url));
|
||||
$ticket = $res->ticket;
|
||||
if ($ticket) {
|
||||
$data->expire_time = time() + 7000;
|
||||
$data->jsapi_ticket = $ticket;
|
||||
$this->set_php_file("jsapi_ticket.php", json_encode($data));
|
||||
}
|
||||
} else {
|
||||
$ticket = $data->jsapi_ticket;
|
||||
}
|
||||
|
||||
return $ticket;
|
||||
}
|
||||
|
||||
private function getAccessToken() {
|
||||
// access_token 应该全局存储与更新,以下代码以写入到文件中做示例
|
||||
$data = json_decode($this->get_php_file("access_token.php"));
|
||||
if ($data->expire_time < time()) {
|
||||
// 如果是企业号用以下URL获取access_token
|
||||
// $url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=$this->appId&corpsecret=$this->appSecret";
|
||||
$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$this->appId&secret=$this->appSecret";
|
||||
$res = json_decode($this->httpGet($url));
|
||||
$access_token = $res->access_token;
|
||||
if ($access_token) {
|
||||
$data->expire_time = time() + 7000;
|
||||
$data->access_token = $access_token;
|
||||
$this->set_php_file("access_token.php", json_encode($data));
|
||||
}
|
||||
} else {
|
||||
$access_token = $data->access_token;
|
||||
}
|
||||
return $access_token;
|
||||
}
|
||||
|
||||
private function httpGet($url) {
|
||||
$curl = curl_init();
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($curl, CURLOPT_TIMEOUT, 500);
|
||||
// 为保证第三方服务器与微信服务器之间数据传输的安全性,所有微信接口采用https方式调用,必须使用下面2行代码打开ssl安全校验。
|
||||
// 如果在部署过程中代码在此处验证失败,请到 http://curl.haxx.se/ca/cacert.pem 下载新的证书判别文件。
|
||||
//todo 上架把下面2个屏蔽掉
|
||||
// curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
|
||||
// curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, true);
|
||||
curl_setopt($curl, CURLOPT_URL, $url);
|
||||
|
||||
$res = curl_exec($curl);
|
||||
curl_close($curl);
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
private function get_php_file($filename) {
|
||||
return trim(substr(file_get_contents(ROOT_PATH.DIRECTORY_SEPARATOR.'addons'.DIRECTORY_SEPARATOR.'wdsxh'.DIRECTORY_SEPARATOR.'library'.DIRECTORY_SEPARATOR.'Wxofficial'.DIRECTORY_SEPARATOR.$filename), 15));
|
||||
}
|
||||
private function set_php_file($filename, $content) {
|
||||
|
||||
$fp = fopen(ROOT_PATH.DIRECTORY_SEPARATOR.'addons'.DIRECTORY_SEPARATOR.'wdsxh'.DIRECTORY_SEPARATOR.'library'.DIRECTORY_SEPARATOR.'Wxofficial'.DIRECTORY_SEPARATOR.$filename, "w");
|
||||
fwrite($fp, "<?php exit();?>" . $content);
|
||||
fclose($fp);
|
||||
}
|
||||
}
|
||||
|
||||
2
addons/wdsxh/library/Wxofficial/access_token.php
Normal file
2
addons/wdsxh/library/Wxofficial/access_token.php
Normal file
@@ -0,0 +1,2 @@
|
||||
<?php exit();?>
|
||||
{"access_token":"","expire_time":0}
|
||||
2
addons/wdsxh/library/Wxofficial/jsapi_ticket.php
Normal file
2
addons/wdsxh/library/Wxofficial/jsapi_ticket.php
Normal file
@@ -0,0 +1,2 @@
|
||||
<?php exit();?>
|
||||
{"jsapi_ticket":"","expire_time":0}
|
||||
21
addons/wdsxh/library/adbario/php-dot-notation/LICENSE.md
Normal file
21
addons/wdsxh/library/adbario/php-dot-notation/LICENSE.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# The MIT License (MIT)
|
||||
|
||||
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.
|
||||
29
addons/wdsxh/library/adbario/php-dot-notation/composer.json
Normal file
29
addons/wdsxh/library/adbario/php-dot-notation/composer.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "adbario/php-dot-notation",
|
||||
"description": "PHP dot notation access to arrays",
|
||||
"keywords": ["dotnotation", "arrayaccess"],
|
||||
"homepage": "https://github.com/adbario/php-dot-notation",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Riku Särkinen",
|
||||
"email": "riku@adbar.io"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^5.5 || ^7.0 || ^8.0",
|
||||
"ext-json": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8|^5.7|^6.6|^7.5|^8.5|^9.5",
|
||||
"squizlabs/php_codesniffer": "^3.6"
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/helpers.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Adbar\\": "src"
|
||||
}
|
||||
}
|
||||
}
|
||||
623
addons/wdsxh/library/adbario/php-dot-notation/src/Dot.php
Normal file
623
addons/wdsxh/library/adbario/php-dot-notation/src/Dot.php
Normal file
@@ -0,0 +1,623 @@
|
||||
<?php
|
||||
/**
|
||||
* Dot - PHP dot notation access to arrays
|
||||
*
|
||||
* @author Riku Särkinen <riku@adbar.io>
|
||||
* @link https://github.com/adbario/php-dot-notation
|
||||
* @license https://github.com/adbario/php-dot-notation/blob/2.x/LICENSE.md (MIT License)
|
||||
*/
|
||||
namespace Adbar;
|
||||
|
||||
use Countable;
|
||||
use ArrayAccess;
|
||||
use ArrayIterator;
|
||||
use JsonSerializable;
|
||||
use IteratorAggregate;
|
||||
|
||||
/**
|
||||
* Dot
|
||||
*
|
||||
* This class provides a dot notation access and helper functions for
|
||||
* working with arrays of data. Inspired by Laravel Collection.
|
||||
*/
|
||||
class Dot implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable
|
||||
{
|
||||
/**
|
||||
* The stored items
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $items = [];
|
||||
|
||||
|
||||
/**
|
||||
* The delimiter (alternative to a '.') to be used.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $delimiter = '.';
|
||||
|
||||
|
||||
/**
|
||||
* Create a new Dot instance
|
||||
*
|
||||
* @param mixed $items
|
||||
* @param string $delimiter
|
||||
*/
|
||||
public function __construct($items = [], $delimiter = '.')
|
||||
{
|
||||
$this->items = $this->getArrayItems($items);
|
||||
$this->delimiter = strlen($delimiter) ? $delimiter : '.';
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a given key / value pair or pairs
|
||||
* if the key doesn't exist already
|
||||
*
|
||||
* @param array|int|string $keys
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function add($keys, $value = null)
|
||||
{
|
||||
if (is_array($keys)) {
|
||||
foreach ($keys as $key => $value) {
|
||||
$this->add($key, $value);
|
||||
}
|
||||
} elseif (is_null($this->get($keys))) {
|
||||
$this->set($keys, $value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all the stored items
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function all()
|
||||
{
|
||||
return $this->items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the contents of a given key or keys
|
||||
*
|
||||
* @param array|int|string|null $keys
|
||||
*/
|
||||
public function clear($keys = null)
|
||||
{
|
||||
if (is_null($keys)) {
|
||||
$this->items = [];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$keys = (array) $keys;
|
||||
|
||||
foreach ($keys as $key) {
|
||||
$this->set($key, []);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the given key or keys
|
||||
*
|
||||
* @param array|int|string $keys
|
||||
*/
|
||||
public function delete($keys)
|
||||
{
|
||||
$keys = (array) $keys;
|
||||
|
||||
foreach ($keys as $key) {
|
||||
if ($this->exists($this->items, $key)) {
|
||||
unset($this->items[$key]);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$items = &$this->items;
|
||||
$segments = explode($this->delimiter, $key);
|
||||
$lastSegment = array_pop($segments);
|
||||
|
||||
foreach ($segments as $segment) {
|
||||
if (!isset($items[$segment]) || !is_array($items[$segment])) {
|
||||
continue 2;
|
||||
}
|
||||
|
||||
$items = &$items[$segment];
|
||||
}
|
||||
|
||||
unset($items[$lastSegment]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given key exists in the provided array.
|
||||
*
|
||||
* @param array $array Array to validate
|
||||
* @param int|string $key The key to look for
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function exists($array, $key)
|
||||
{
|
||||
return array_key_exists($key, $array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flatten an array with the given character as a key delimiter
|
||||
*
|
||||
* @param string $delimiter
|
||||
* @param array|null $items
|
||||
* @param string $prepend
|
||||
* @return array
|
||||
*/
|
||||
public function flatten($delimiter = '.', $items = null, $prepend = '')
|
||||
{
|
||||
$flatten = [];
|
||||
|
||||
if (is_null($items)) {
|
||||
$items = $this->items;
|
||||
}
|
||||
|
||||
if (!func_num_args()) {
|
||||
$delimiter = $this->delimiter;
|
||||
}
|
||||
|
||||
foreach ($items as $key => $value) {
|
||||
if (is_array($value) && !empty($value)) {
|
||||
$flatten = array_merge(
|
||||
$flatten,
|
||||
$this->flatten($delimiter, $value, $prepend.$key.$delimiter)
|
||||
);
|
||||
} else {
|
||||
$flatten[$prepend.$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $flatten;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value of a given key
|
||||
*
|
||||
* @param int|string|null $key
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($key = null, $default = null)
|
||||
{
|
||||
if (is_null($key)) {
|
||||
return $this->items;
|
||||
}
|
||||
|
||||
if ($this->exists($this->items, $key)) {
|
||||
return $this->items[$key];
|
||||
}
|
||||
|
||||
if (strpos($key, $this->delimiter) === false) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
$items = $this->items;
|
||||
|
||||
foreach (explode($this->delimiter, $key) as $segment) {
|
||||
if (!is_array($items) || !$this->exists($items, $segment)) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
$items = &$items[$segment];
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the given items as an array
|
||||
*
|
||||
* @param mixed $items
|
||||
* @return array
|
||||
*/
|
||||
protected function getArrayItems($items)
|
||||
{
|
||||
if (is_array($items)) {
|
||||
return $items;
|
||||
} elseif ($items instanceof self) {
|
||||
return $items->all();
|
||||
}
|
||||
|
||||
return (array) $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a given key or keys exists
|
||||
*
|
||||
* @param array|int|string $keys
|
||||
* @return bool
|
||||
*/
|
||||
public function has($keys)
|
||||
{
|
||||
$keys = (array) $keys;
|
||||
|
||||
if (!$this->items || $keys === []) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($keys as $key) {
|
||||
$items = $this->items;
|
||||
|
||||
if ($this->exists($items, $key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (explode($this->delimiter, $key) as $segment) {
|
||||
if (!is_array($items) || !$this->exists($items, $segment)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$items = $items[$segment];
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a given key or keys are empty
|
||||
*
|
||||
* @param array|int|string|null $keys
|
||||
* @return bool
|
||||
*/
|
||||
public function isEmpty($keys = null)
|
||||
{
|
||||
if (is_null($keys)) {
|
||||
return empty($this->items);
|
||||
}
|
||||
|
||||
$keys = (array) $keys;
|
||||
|
||||
foreach ($keys as $key) {
|
||||
if (!empty($this->get($key))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge a given array or a Dot object with the given key
|
||||
* or with the whole Dot object
|
||||
*
|
||||
* @param array|string|self $key
|
||||
* @param array|self $value
|
||||
*/
|
||||
public function merge($key, $value = [])
|
||||
{
|
||||
if (is_array($key)) {
|
||||
$this->items = array_merge($this->items, $key);
|
||||
} elseif (is_string($key)) {
|
||||
$items = (array) $this->get($key);
|
||||
$value = array_merge($items, $this->getArrayItems($value));
|
||||
|
||||
$this->set($key, $value);
|
||||
} elseif ($key instanceof self) {
|
||||
$this->items = array_merge($this->items, $key->all());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively merge a given array or a Dot object with the given key
|
||||
* or with the whole Dot object.
|
||||
*
|
||||
* Duplicate keys are converted to arrays.
|
||||
*
|
||||
* @param array|string|self $key
|
||||
* @param array|self $value
|
||||
*/
|
||||
public function mergeRecursive($key, $value = [])
|
||||
{
|
||||
if (is_array($key)) {
|
||||
$this->items = array_merge_recursive($this->items, $key);
|
||||
} elseif (is_string($key)) {
|
||||
$items = (array) $this->get($key);
|
||||
$value = array_merge_recursive($items, $this->getArrayItems($value));
|
||||
|
||||
$this->set($key, $value);
|
||||
} elseif ($key instanceof self) {
|
||||
$this->items = array_merge_recursive($this->items, $key->all());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively merge a given array or a Dot object with the given key
|
||||
* or with the whole Dot object.
|
||||
*
|
||||
* Instead of converting duplicate keys to arrays, the value from
|
||||
* given array will replace the value in Dot object.
|
||||
*
|
||||
* @param array|string|self $key
|
||||
* @param array|self $value
|
||||
*/
|
||||
public function mergeRecursiveDistinct($key, $value = [])
|
||||
{
|
||||
if (is_array($key)) {
|
||||
$this->items = $this->arrayMergeRecursiveDistinct($this->items, $key);
|
||||
} elseif (is_string($key)) {
|
||||
$items = (array) $this->get($key);
|
||||
$value = $this->arrayMergeRecursiveDistinct($items, $this->getArrayItems($value));
|
||||
|
||||
$this->set($key, $value);
|
||||
} elseif ($key instanceof self) {
|
||||
$this->items = $this->arrayMergeRecursiveDistinct($this->items, $key->all());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges two arrays recursively. In contrast to array_merge_recursive,
|
||||
* duplicate keys are not converted to arrays but rather overwrite the
|
||||
* value in the first array with the duplicate value in the second array.
|
||||
*
|
||||
* @param array $array1 Initial array to merge
|
||||
* @param array $array2 Array to recursively merge
|
||||
* @return array
|
||||
*/
|
||||
protected function arrayMergeRecursiveDistinct(array $array1, array $array2)
|
||||
{
|
||||
$merged = &$array1;
|
||||
|
||||
foreach ($array2 as $key => $value) {
|
||||
if (is_array($value) && isset($merged[$key]) && is_array($merged[$key])) {
|
||||
$merged[$key] = $this->arrayMergeRecursiveDistinct($merged[$key], $value);
|
||||
} else {
|
||||
$merged[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $merged;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value of a given key and
|
||||
* delete the key
|
||||
*
|
||||
* @param int|string|null $key
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function pull($key = null, $default = null)
|
||||
{
|
||||
if (is_null($key)) {
|
||||
$value = $this->all();
|
||||
$this->clear();
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
$value = $this->get($key, $default);
|
||||
$this->delete($key);
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Push a given value to the end of the array
|
||||
* in a given key
|
||||
*
|
||||
* @param mixed $key
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function push($key, $value = null)
|
||||
{
|
||||
if (is_null($value)) {
|
||||
$this->items[] = $key;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$items = $this->get($key);
|
||||
|
||||
if (is_array($items) || is_null($items)) {
|
||||
$items[] = $value;
|
||||
$this->set($key, $items);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace all values or values within the given key
|
||||
* with an array or Dot object
|
||||
*
|
||||
* @param array|string|self $key
|
||||
* @param array|self $value
|
||||
*/
|
||||
public function replace($key, $value = [])
|
||||
{
|
||||
if (is_array($key)) {
|
||||
$this->items = array_replace($this->items, $key);
|
||||
} elseif (is_string($key)) {
|
||||
$items = (array) $this->get($key);
|
||||
$value = array_replace($items, $this->getArrayItems($value));
|
||||
|
||||
$this->set($key, $value);
|
||||
} elseif ($key instanceof self) {
|
||||
$this->items = array_replace($this->items, $key->all());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a given key / value pair or pairs
|
||||
*
|
||||
* @param array|int|string $keys
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function set($keys, $value = null)
|
||||
{
|
||||
if (is_array($keys)) {
|
||||
foreach ($keys as $key => $value) {
|
||||
$this->set($key, $value);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$items = &$this->items;
|
||||
|
||||
foreach (explode($this->delimiter, $keys) as $key) {
|
||||
if (!isset($items[$key]) || !is_array($items[$key])) {
|
||||
$items[$key] = [];
|
||||
}
|
||||
|
||||
$items = &$items[$key];
|
||||
}
|
||||
|
||||
$items = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace all items with a given array
|
||||
*
|
||||
* @param mixed $items
|
||||
*/
|
||||
public function setArray($items)
|
||||
{
|
||||
$this->items = $this->getArrayItems($items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace all items with a given array as a reference
|
||||
*
|
||||
* @param array $items
|
||||
*/
|
||||
public function setReference(array &$items)
|
||||
{
|
||||
$this->items = &$items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value of a given key or all the values as JSON
|
||||
*
|
||||
* @param mixed $key
|
||||
* @param int $options
|
||||
* @return string
|
||||
*/
|
||||
public function toJson($key = null, $options = 0)
|
||||
{
|
||||
if (is_string($key)) {
|
||||
return json_encode($this->get($key), $options);
|
||||
}
|
||||
|
||||
$options = $key === null ? 0 : $key;
|
||||
|
||||
return json_encode($this->items, $options);
|
||||
}
|
||||
|
||||
/*
|
||||
* --------------------------------------------------------------
|
||||
* ArrayAccess interface
|
||||
* --------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Check if a given key exists
|
||||
*
|
||||
* @param int|string $key
|
||||
* @return bool
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetExists($key)
|
||||
{
|
||||
return $this->has($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value of a given key
|
||||
*
|
||||
* @param int|string $key
|
||||
* @return mixed
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetGet($key)
|
||||
{
|
||||
return $this->get($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a given value to the given key
|
||||
*
|
||||
* @param int|string|null $key
|
||||
* @param mixed $value
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetSet($key, $value)
|
||||
{
|
||||
if (is_null($key)) {
|
||||
$this->items[] = $value;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->set($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the given key
|
||||
*
|
||||
* @param int|string $key
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetUnset($key)
|
||||
{
|
||||
$this->delete($key);
|
||||
}
|
||||
|
||||
/*
|
||||
* --------------------------------------------------------------
|
||||
* Countable interface
|
||||
* --------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Return the number of items in a given key
|
||||
*
|
||||
* @param int|string|null $key
|
||||
* @return int
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function count($key = null)
|
||||
{
|
||||
return count($this->get($key));
|
||||
}
|
||||
|
||||
/*
|
||||
* --------------------------------------------------------------
|
||||
* IteratorAggregate interface
|
||||
* --------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get an iterator for the stored items
|
||||
*
|
||||
* @return \ArrayIterator
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function getIterator()
|
||||
{
|
||||
return new ArrayIterator($this->items);
|
||||
}
|
||||
|
||||
/*
|
||||
* --------------------------------------------------------------
|
||||
* JsonSerializable interface
|
||||
* --------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Return items for JSON serialization
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function jsonSerialize()
|
||||
{
|
||||
return $this->items;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/**
|
||||
* Dot - PHP dot notation access to arrays
|
||||
*
|
||||
* @author Riku Särkinen <riku@adbar.io>
|
||||
* @link https://github.com/adbario/php-dot-notation
|
||||
* @license https://github.com/adbario/php-dot-notation/blob/2.x/LICENSE.md (MIT License)
|
||||
*/
|
||||
|
||||
use Adbar\Dot;
|
||||
|
||||
if (! function_exists('dot')) {
|
||||
/**
|
||||
* Create a new Dot object with the given items and optional delimiter
|
||||
*
|
||||
* @param mixed $items
|
||||
* @param string $delimiter
|
||||
* @return \Adbar\Dot
|
||||
*/
|
||||
function dot($items, $delimiter = '.')
|
||||
{
|
||||
return new Dot($items, $delimiter);
|
||||
}
|
||||
}
|
||||
18
addons/wdsxh/library/alibabacloud/credentials/CHANGELOG.md
Normal file
18
addons/wdsxh/library/alibabacloud/credentials/CHANGELOG.md
Normal 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.
|
||||
@@ -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
|
||||
13
addons/wdsxh/library/alibabacloud/credentials/LICENSE.md
Normal file
13
addons/wdsxh/library/alibabacloud/credentials/LICENSE.md
Normal 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.
|
||||
88
addons/wdsxh/library/alibabacloud/credentials/NOTICE.md
Normal file
88
addons/wdsxh/library/alibabacloud/credentials/NOTICE.md
Normal 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.
|
||||
21
addons/wdsxh/library/alibabacloud/credentials/SECURITY.md
Normal file
21
addons/wdsxh/library/alibabacloud/credentials/SECURITY.md
Normal 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.
|
||||
@@ -0,0 +1,6 @@
|
||||
Upgrading Guide
|
||||
===============
|
||||
|
||||
1.x
|
||||
-----------------------
|
||||
- This is the first version. See <https://github.com/aliyun/credentials-php> for more information.
|
||||
107
addons/wdsxh/library/alibabacloud/credentials/composer.json
Normal file
107
addons/wdsxh/library/alibabacloud/credentials/composer.json
Normal 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/*"
|
||||
}
|
||||
}
|
||||
@@ -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',
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -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',
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
268
addons/wdsxh/library/alibabacloud/credentials/src/Credential.php
Normal file
268
addons/wdsxh/library/alibabacloud/credentials/src/Credential.php
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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',
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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';
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
]
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
@@ -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';
|
||||
}
|
||||
}
|
||||
@@ -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';
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
@@ -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';
|
||||
}
|
||||
}
|
||||
@@ -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',
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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',
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -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 '';
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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',
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
65
addons/wdsxh/library/alibabacloud/darabonba/.php_cs.dist
Normal file
65
addons/wdsxh/library/alibabacloud/darabonba/.php_cs.dist
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
/*
|
||||
* This document has been generated with
|
||||
* https://mlocati.github.io/php-cs-fixer-configurator/#version:2.15|configurator
|
||||
* you can change this configuration by importing this file.
|
||||
*/
|
||||
|
||||
return PhpCsFixer\Config::create()
|
||||
->setRiskyAllowed(true)
|
||||
->setIndent(' ')
|
||||
->setRules([
|
||||
'@PSR2' => true,
|
||||
'@PhpCsFixer' => true,
|
||||
'@Symfony:risky' => true,
|
||||
'concat_space' => ['spacing' => 'one'],
|
||||
'array_syntax' => ['syntax' => 'short'],
|
||||
'array_indentation' => true,
|
||||
'combine_consecutive_unsets' => true,
|
||||
'method_separation' => true,
|
||||
'single_quote' => true,
|
||||
'declare_equal_normalize' => true,
|
||||
'function_typehint_space' => true,
|
||||
'hash_to_slash_comment' => true,
|
||||
'include' => true,
|
||||
'lowercase_cast' => true,
|
||||
'no_multiline_whitespace_before_semicolons' => true,
|
||||
'no_leading_import_slash' => true,
|
||||
'no_multiline_whitespace_around_double_arrow' => true,
|
||||
'no_spaces_around_offset' => true,
|
||||
'no_unneeded_control_parentheses' => true,
|
||||
'no_unused_imports' => true,
|
||||
'no_whitespace_before_comma_in_array' => true,
|
||||
'no_whitespace_in_blank_line' => true,
|
||||
'object_operator_without_whitespace' => true,
|
||||
'single_blank_line_before_namespace' => true,
|
||||
'single_class_element_per_statement' => true,
|
||||
'space_after_semicolon' => true,
|
||||
'standardize_not_equals' => true,
|
||||
'ternary_operator_spaces' => true,
|
||||
'trailing_comma_in_multiline_array' => true,
|
||||
'trim_array_spaces' => true,
|
||||
'unary_operator_spaces' => true,
|
||||
'whitespace_after_comma_in_array' => true,
|
||||
'no_extra_consecutive_blank_lines' => [
|
||||
'curly_brace_block',
|
||||
'extra',
|
||||
'parenthesis_brace_block',
|
||||
'square_brace_block',
|
||||
'throw',
|
||||
'use',
|
||||
],
|
||||
'binary_operator_spaces' => [
|
||||
'align_double_arrow' => true,
|
||||
'align_equals' => true,
|
||||
],
|
||||
'braces' => [
|
||||
'allow_single_line_closure' => true,
|
||||
],
|
||||
])
|
||||
->setFinder(
|
||||
PhpCsFixer\Finder::create()
|
||||
->exclude('vendor')
|
||||
->exclude('tests')
|
||||
->in(__DIR__)
|
||||
);
|
||||
148
addons/wdsxh/library/alibabacloud/darabonba/CHANGELOG.md
Normal file
148
addons/wdsxh/library/alibabacloud/darabonba/CHANGELOG.md
Normal file
@@ -0,0 +1,148 @@
|
||||
# CHANGELOG
|
||||
|
||||
## 3.1.22 - 2021-05-11
|
||||
|
||||
- Deprecate `stream_for` method.
|
||||
|
||||
## 3.1.21 - 2021-03-15
|
||||
|
||||
- Supported set proxy&timeout on request.
|
||||
|
||||
## 3.1.20 - 2020-12-02
|
||||
|
||||
- Fix the warning when the Tea::merge method received empty arguments.
|
||||
|
||||
## 3.1.19 - 2020-10-09
|
||||
|
||||
- Fix the error when the code value is a string.
|
||||
|
||||
## 3.1.18 - 2020-09-28
|
||||
|
||||
- Require Guzzle Version 7.0
|
||||
|
||||
## 3.1.17 - 2020-09-24
|
||||
|
||||
- TeaUnableRetryError support get error info.
|
||||
|
||||
## 3.1.16 - 2020-08-31
|
||||
|
||||
- Fix the Maximum function nesting level error when repeated network requests.
|
||||
|
||||
## 3.1.15 - 2020-07-28
|
||||
|
||||
- Improved validatePattern method.
|
||||
|
||||
## 3.1.14 - 2020-07-03
|
||||
|
||||
- Supported set properties of TeaError with `ErrorInfo`.
|
||||
|
||||
## 3.1.13 - 2020-06-09
|
||||
|
||||
- Reduce dependencies.
|
||||
|
||||
## 3.1.12 - 2020-05-13
|
||||
|
||||
- Add validate method.
|
||||
- Supported validate maximun&minimun of property.
|
||||
|
||||
## 3.1.11 - 2020-05-07
|
||||
|
||||
- Fixed error when class is undefined.
|
||||
|
||||
## 3.1.10 - 2020-05-07
|
||||
|
||||
- Fixed error when '$item' of array is null
|
||||
|
||||
## 3.1.9 - 2020-04-13
|
||||
|
||||
- TeaUnableRetryError add $lastException param.
|
||||
|
||||
## 3.1.8 - 2020-04-02
|
||||
|
||||
- Added some static methods of Model to validate fields of Model.
|
||||
|
||||
## 3.1.7 - 2020-03-27
|
||||
|
||||
- Improve Tea::isRetryable method.
|
||||
|
||||
## 3.1.6 - 2020-03-25
|
||||
|
||||
- Fixed bug when body is StreamInterface.
|
||||
|
||||
## 3.1.5 - 2020-03-25
|
||||
|
||||
- Improve Model.toMap method.
|
||||
- Improve Tea.merge method.
|
||||
- Fixed tests.
|
||||
|
||||
## 3.1.4 - 2020-03-20
|
||||
|
||||
- Added Tea::merge method.
|
||||
- Change Tea::isRetryable method.
|
||||
|
||||
## 3.1.3 - 2020-03-20
|
||||
|
||||
- Model: added toModel method.
|
||||
|
||||
## 3.1.2 - 2020-03-19
|
||||
|
||||
- Model constructor supported array type parameter.
|
||||
|
||||
## 3.1.1 - 2020-03-18
|
||||
|
||||
- Fixed bug : set method failed.
|
||||
- Fixed bug : get empty contents form body.
|
||||
|
||||
## 3.1.0 - 2020-03-13
|
||||
|
||||
- TeaUnableRetryError add 'lastRequest' property.
|
||||
- Change Tea.send() method return.
|
||||
- Fixed Tea. allowRetry() method.
|
||||
|
||||
## 3.0.0 - 2020-02-14
|
||||
- Rename package name.
|
||||
|
||||
## 2.0.3 - 2020-02-14
|
||||
- Improved Exception.
|
||||
|
||||
## 2.0.2 - 2019-09-11
|
||||
- Supported `String`.
|
||||
|
||||
## 2.0.1 - 2019-08-15
|
||||
- Supported `IteratorAggregate`.
|
||||
|
||||
## 2.0.0 - 2019-08-14
|
||||
- Design `Request` as a standard `PsrRequest`.
|
||||
|
||||
## 1.0.10 - 2019-08-12
|
||||
- Added `__toString` for `Response`.
|
||||
|
||||
## 1.0.9 - 2019-08-01
|
||||
- Updated `Middleware`.
|
||||
|
||||
## 1.0.8 - 2019-07-29
|
||||
- Supported `TransferStats`.
|
||||
|
||||
## 1.0.7 - 2019-07-27
|
||||
- Improved request.
|
||||
|
||||
## 1.0.6 - 2019-07-23
|
||||
- Trim key for parameter.
|
||||
|
||||
## 1.0.5 - 2019-07-23
|
||||
- Supported default protocol.
|
||||
|
||||
## 1.0.4 - 2019-07-22
|
||||
- Added `toArray()`.
|
||||
|
||||
## 1.0.3 - 2019-05-02
|
||||
- Improved `Request`.
|
||||
|
||||
## 1.0.2 - 2019-05-02
|
||||
- Added getHeader/getHeaders.
|
||||
|
||||
## 1.0.1 - 2019-04-02
|
||||
- Improved design.
|
||||
|
||||
## 1.0.0 - 2019-05-02
|
||||
- Initial release of the AlibabaCloud Tea Version 1.0.0 on Packagist See <https://github.com/aliyun/tea-php> for more information.
|
||||
13
addons/wdsxh/library/alibabacloud/darabonba/LICENSE.md
Normal file
13
addons/wdsxh/library/alibabacloud/darabonba/LICENSE.md
Normal 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.
|
||||
27
addons/wdsxh/library/alibabacloud/darabonba/README.md
Normal file
27
addons/wdsxh/library/alibabacloud/darabonba/README.md
Normal file
@@ -0,0 +1,27 @@
|
||||
|
||||

|
||||
|
||||
## Alibaba Cloud Tea for Java
|
||||
|
||||
[](https://github.com/aliyun/tea-php/actions/workflows/ci.yml)
|
||||
[](https://codecov.io/gh/aliyun/tea-php)
|
||||
[](https://packagist.org/packages/alibabacloud/tea)
|
||||
[](https://packagist.org/packages/alibabacloud/tea)
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
composer require alibabacloud/tea --optimize-autoloader
|
||||
```
|
||||
|
||||
> Some users may not be able to install due to network problems, you can try to switch the Composer mirror.
|
||||
|
||||
## Changelog
|
||||
|
||||
Detailed changes for each release are documented in the [release notes](CHANGELOG.md).
|
||||
|
||||
## License
|
||||
|
||||
[Apache-2.0](LICENSE.md)
|
||||
|
||||
Copyright (c) 2009-present, Alibaba Cloud All rights reserved.
|
||||
79
addons/wdsxh/library/alibabacloud/darabonba/composer.json
Normal file
79
addons/wdsxh/library/alibabacloud/darabonba/composer.json
Normal file
@@ -0,0 +1,79 @@
|
||||
{
|
||||
"name": "alibabacloud/darabonba",
|
||||
"homepage": "https://www.alibabacloud.com/",
|
||||
"description": "Client of Darabonba for PHP",
|
||||
"keywords": [
|
||||
"tea",
|
||||
"client",
|
||||
"alibabacloud",
|
||||
"cloud"
|
||||
],
|
||||
"type": "library",
|
||||
"license": "Apache-2.0",
|
||||
"support": {
|
||||
"source": "https://github.com/aliyun/tea-php",
|
||||
"issues": "https://github.com/aliyun/tea-php/issues"
|
||||
},
|
||||
"authors": [
|
||||
{
|
||||
"name": "Alibaba Cloud SDK",
|
||||
"email": "sdk-team@alibabacloud.com",
|
||||
"homepage": "http://www.alibabacloud.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.5",
|
||||
"ext-curl": "*",
|
||||
"ext-json": "*",
|
||||
"ext-libxml": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-openssl": "*",
|
||||
"ext-simplexml": "*",
|
||||
"ext-xmlwriter": "*",
|
||||
"adbario/php-dot-notation": "^2.4",
|
||||
"alibabacloud/tea": "^3.2",
|
||||
"guzzlehttp/guzzle": "^6.3|^7.0",
|
||||
"monolog/monolog": "^1.0|^2.1",
|
||||
"psr/http-message": "^0.11.0|^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/dotenv": "^3.4",
|
||||
"phpunit/phpunit": "^4.8.35|^5.4.3|^9.3",
|
||||
"symfony/var-dumper": "^3.4"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-sockets": "To use client-side monitoring"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"AlibabaCloud\\Dara\\": "src"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"AlibabaCloud\\Dara\\Tests\\": "tests"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true,
|
||||
"preferred-install": "dist",
|
||||
"optimize-autoloader": true
|
||||
},
|
||||
"prefer-stable": true,
|
||||
"minimum-stability": "dev",
|
||||
"scripts": {
|
||||
"cs": "phpcs --standard=PSR2 -n ./",
|
||||
"cbf": "phpcbf --standard=PSR2 -n ./",
|
||||
"fixer": "php-cs-fixer fix ./",
|
||||
"unit": [
|
||||
"@clearCache",
|
||||
"XDEBUG_MODE=coverage phpunit --testsuite=Unit --colors=always --coverage-xml ./coverage/xml --coverage-html ./coverage/html --coverage-clover ./coverage/coverage.clover"
|
||||
],
|
||||
"feature": [
|
||||
"@clearCache",
|
||||
"phpunit --testsuite=Feature --colors=always"
|
||||
],
|
||||
"clearCache": "rm -rf cache/*",
|
||||
"coverage": "open cache/coverage/index.html"
|
||||
}
|
||||
}
|
||||
372
addons/wdsxh/library/alibabacloud/darabonba/src/Dara.php
Normal file
372
addons/wdsxh/library/alibabacloud/darabonba/src/Dara.php
Normal file
@@ -0,0 +1,372 @@
|
||||
<?php
|
||||
|
||||
namespace AlibabaCloud\Dara;
|
||||
|
||||
use Adbar\Dot;
|
||||
use AlibabaCloud\Dara\Exception\DaraException;
|
||||
use AlibabaCloud\Dara\RetryPolicy\RetryOptions;
|
||||
use AlibabaCloud\Dara\RetryPolicy\RetryPolicyContext;
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\HandlerStack;
|
||||
use GuzzleHttp\RequestOptions;
|
||||
use GuzzleHttp\Middleware;
|
||||
use GuzzleHttp\Promise\PromiseInterface;
|
||||
use GuzzleHttp\TransferStats;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\UriInterface;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Class Dara.
|
||||
*/
|
||||
class Dara
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $config = [];
|
||||
|
||||
const MAX_DELAY_TIME = 120 * 1000;
|
||||
const MIN_DELAY_TIME = 100;
|
||||
|
||||
public static function config(array $config)
|
||||
{
|
||||
self::$config = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws GuzzleException
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public static function send(Request $request, array $config = [])
|
||||
{
|
||||
if (method_exists($request, 'getPsrRequest')) {
|
||||
$request = $request->getPsrRequest();
|
||||
}
|
||||
|
||||
$config = self::resolveConfig($config);
|
||||
$res = self::client()->send(
|
||||
$request,
|
||||
$config
|
||||
);
|
||||
|
||||
return new Response($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return PromiseInterface
|
||||
*/
|
||||
public static function sendAsync(RequestInterface $request, array $config = [])
|
||||
{
|
||||
if (method_exists($request, 'getPsrRequest')) {
|
||||
$request = $request->getPsrRequest();
|
||||
}
|
||||
|
||||
$config = self::resolveConfig($config);
|
||||
|
||||
return self::client()->sendAsync(
|
||||
$request,
|
||||
$config
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Client
|
||||
*/
|
||||
public static function client(array $config = [])
|
||||
{
|
||||
if (isset(self::$config['handler'])) {
|
||||
$stack = self::$config['handler'];
|
||||
} else {
|
||||
$stack = HandlerStack::create();
|
||||
$stack->push(Middleware::mapResponse(static function (ResponseInterface $response) {
|
||||
return new Response($response);
|
||||
}));
|
||||
}
|
||||
|
||||
self::$config['handler'] = $stack;
|
||||
|
||||
if (!isset(self::$config['on_stats'])) {
|
||||
self::$config['on_stats'] = function (TransferStats $stats) {
|
||||
Response::$info = $stats->getHandlerStats();
|
||||
};
|
||||
}
|
||||
|
||||
$new_config = Helper::merge([self::$config, $config]);
|
||||
return new Client($new_config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
* @param string|UriInterface $uri
|
||||
* @param array $options
|
||||
*
|
||||
* @throws GuzzleException
|
||||
*
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public static function request($method, $uri, $options = [])
|
||||
{
|
||||
return self::client()->request($method, $uri, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
* @param string $uri
|
||||
* @param array $options
|
||||
*
|
||||
* @throws GuzzleException
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function string($method, $uri, $options = [])
|
||||
{
|
||||
return (string) self::client()->request($method, $uri, $options)
|
||||
->getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
* @param string|UriInterface $uri
|
||||
* @param array $options
|
||||
*
|
||||
* @return PromiseInterface
|
||||
*/
|
||||
public static function requestAsync($method, $uri, $options = [])
|
||||
{
|
||||
return self::client()->requestAsync($method, $uri, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|UriInterface $uri
|
||||
* @param array $options
|
||||
*
|
||||
* @throws GuzzleException
|
||||
*
|
||||
* @return null|mixed
|
||||
*/
|
||||
public static function getHeaders($uri, $options = [])
|
||||
{
|
||||
return self::request('HEAD', $uri, $options)->getHeaders();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|UriInterface $uri
|
||||
* @param string $key
|
||||
* @param null|mixed $default
|
||||
*
|
||||
* @throws GuzzleException
|
||||
*
|
||||
* @return null|mixed
|
||||
*/
|
||||
public static function getHeader($uri, $key, $default = null)
|
||||
{
|
||||
$headers = self::getHeaders($uri);
|
||||
|
||||
return isset($headers[$key][0]) ? $headers[$key][0] : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $retryTimes
|
||||
* @param float $now
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function allowRetry(array $runtime, $retryTimes, $now)
|
||||
{
|
||||
unset($now);
|
||||
if (!isset($retryTimes) || null === $retryTimes || !\is_numeric($retryTimes)) {
|
||||
return false;
|
||||
}
|
||||
if ($retryTimes > 0 && (empty($runtime) || !isset($runtime['retryable']) || !$runtime['retryable'] || !isset($runtime['maxAttempts']))) {
|
||||
return false;
|
||||
}
|
||||
$maxAttempts = $runtime['maxAttempts'];
|
||||
$retry = empty($maxAttempts) ? 0 : (int) $maxAttempts;
|
||||
|
||||
return $retry >= $retryTimes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $retryTimes
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function getBackoffTime(array $runtime, $retryTimes)
|
||||
{
|
||||
$backOffTime = 0;
|
||||
$policy = isset($runtime['policy']) ? $runtime['policy'] : '';
|
||||
|
||||
if (empty($policy) || 'no' == $policy) {
|
||||
return $backOffTime;
|
||||
}
|
||||
|
||||
$period = isset($runtime['period']) ? $runtime['period'] : '';
|
||||
if (null !== $period && '' !== $period) {
|
||||
$backOffTime = (int) $period;
|
||||
if ($backOffTime <= 0) {
|
||||
return $retryTimes;
|
||||
}
|
||||
}
|
||||
|
||||
return $backOffTime;
|
||||
}
|
||||
|
||||
public static function sleep($time)
|
||||
{
|
||||
sleep($time);
|
||||
}
|
||||
|
||||
public static function isRetryable($retry, $retryTimes = 0)
|
||||
{
|
||||
if ($retry instanceof DaraException) {
|
||||
return true;
|
||||
}
|
||||
if (\is_array($retry)) {
|
||||
$max = isset($retry['maxAttempts']) ? (int) ($retry['maxAttempts']) : 3;
|
||||
|
||||
return $retryTimes <= $max;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param RetryOptions $options
|
||||
* @param RetryPolicyContext $optctxions
|
||||
* @return bool
|
||||
*/
|
||||
public static function shouldRetry($options, $ctx) {
|
||||
if($ctx->getRetryCount() === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!$options || !$options->getRetryable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$retriesAttempted = $ctx->getRetryCount();
|
||||
$ex = $ctx->getException();
|
||||
$conditions = $options->getNoRetryCondition();
|
||||
|
||||
foreach ($conditions as $condition) {
|
||||
if (in_array($ex->getName(), $condition->getException()) || in_array($ex->getErrCode(), $condition->getErrorCode())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$conditions = $options->getRetryCondition();
|
||||
foreach ($conditions as $condition) {
|
||||
if (!in_array($ex->getName(), $condition->getException()) && !in_array($ex->getErrCode(), $condition->getErrorCode())) {
|
||||
continue;
|
||||
}
|
||||
if ($retriesAttempted >= $condition->getMaxAttempts()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param RetryOptions $options
|
||||
* @param RetryPolicyContext $optctxions
|
||||
* @return int
|
||||
*/
|
||||
public static function getBackoffDelay($options, $ctx) {
|
||||
$ex = $ctx->getException();
|
||||
$fullClassName = get_class($ex);
|
||||
$classNameParts = explode('\\', $fullClassName);
|
||||
$className = end($classNameParts);
|
||||
$conditions = $options->getRetryCondition();
|
||||
foreach ($conditions as $condition) {
|
||||
|
||||
if (!in_array($className, $condition->getException()) && !in_array($ex->getErrCode(), $condition->getErrorCode())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$maxDelay = $condition->getMaxDelay() ?: self::MAX_DELAY_TIME;
|
||||
$retryAfter = method_exists($ex, 'getRetryAfter') ? $ex->getRetryAfter() : null;
|
||||
|
||||
if ($retryAfter !== null) {
|
||||
return min($retryAfter, $maxDelay);
|
||||
}
|
||||
|
||||
|
||||
$backoff = $condition->getBackoff();
|
||||
if (!isset($backoff) || null === $backoff) {
|
||||
return self::MIN_DELAY_TIME;
|
||||
}
|
||||
|
||||
return min($backoff->getDelayTime($ctx), $maxDelay);
|
||||
}
|
||||
|
||||
return self::MIN_DELAY_TIME;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed|Model[] ...$item
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function merge(...$item)
|
||||
{
|
||||
$tmp = [];
|
||||
$n = 0;
|
||||
foreach ($item as $i) {
|
||||
if (\is_object($i)) {
|
||||
if ($i instanceof Model) {
|
||||
$i = $i->toMap();
|
||||
} else {
|
||||
$i = json_decode(json_encode($i), true);
|
||||
}
|
||||
}
|
||||
if (null === $i) {
|
||||
continue;
|
||||
}
|
||||
if (\is_array($i)) {
|
||||
$tmp[$n++] = $i;
|
||||
}
|
||||
}
|
||||
|
||||
if (\count($tmp)) {
|
||||
return \call_user_func_array('array_merge', $tmp);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
private static function resolveConfig(array $config = [])
|
||||
{
|
||||
$options = new Dot(['http_errors' => false]);
|
||||
if (isset($config['httpProxy']) && !empty($config['httpProxy'])) {
|
||||
$options->set('proxy.http', $config['httpProxy']);
|
||||
}
|
||||
if (isset($config['httpsProxy']) && !empty($config['httpsProxy'])) {
|
||||
$options->set('proxy.https', $config['httpsProxy']);
|
||||
}
|
||||
if (isset($config['noProxy']) && !empty($config['noProxy'])) {
|
||||
$options->set('proxy.no', $config['noProxy']);
|
||||
}
|
||||
if (isset($config['ignoreSSL']) && !empty($config['ignoreSSL'])) {
|
||||
$options->set('verify',!((bool)$config['ignoreSSL']));
|
||||
}
|
||||
if (isset($config['stream']) && !empty($config['stream'])) {
|
||||
$options->set(RequestOptions::STREAM, (bool)$config['stream']);
|
||||
}
|
||||
// readTimeout&connectTimeout unit is millisecond
|
||||
$read_timeout = isset($config['readTimeout']) && !empty($config['readTimeout']) ? (int) $config['readTimeout'] : 3000;
|
||||
$con_timeout = isset($config['connectTimeout']) && !empty($config['connectTimeout']) ? (int) $config['connectTimeout'] : 3000;
|
||||
// timeout unit is second
|
||||
$options->set('timeout', ($read_timeout + $con_timeout) / 1000);
|
||||
|
||||
return $options->all();
|
||||
}
|
||||
}
|
||||
148
addons/wdsxh/library/alibabacloud/darabonba/src/Date.php
Normal file
148
addons/wdsxh/library/alibabacloud/darabonba/src/Date.php
Normal file
@@ -0,0 +1,148 @@
|
||||
<?php
|
||||
|
||||
namespace AlibabaCloud\Dara;
|
||||
|
||||
use DateTime;
|
||||
use DateTimeZone;
|
||||
use DateInterval;
|
||||
use AlibabaCloud\Dara\Exception\DaraException;
|
||||
|
||||
class Date
|
||||
{
|
||||
private $date = null;
|
||||
|
||||
public function __construct($date = 'now') {
|
||||
$pattern = '/(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}(?:\.\d+)?)(?: \+?(\d{4}))?/';
|
||||
if (ctype_digit($date) || is_numeric($date)) {
|
||||
$this->date = (new DateTime())->setTimestamp($date);
|
||||
} elseif (preg_match($pattern, $date, $matches)) {
|
||||
$timeStr = $matches[1];
|
||||
$tzStr = isset($matches[2]) ? $matches[2] : null;
|
||||
|
||||
if ($tzStr) {
|
||||
$timezone = new DateTimeZone($this->convertTzOffsetToTzString($tzStr));
|
||||
$this->date = DateTime::createFromFormat('Y-m-d H:i:s.u', $timeStr, $timezone);
|
||||
} else {
|
||||
$this->date = new DateTime($timeStr);
|
||||
}
|
||||
} else {
|
||||
$this->date = new DateTime($date);
|
||||
}
|
||||
if($this->date === false || is_null($this->date)) {
|
||||
throw new DaraException([], $date . ' is not a valid time str.');
|
||||
}
|
||||
}
|
||||
|
||||
private function convertTzOffsetToTzString($offset) {
|
||||
$sign = (intval($offset) >= 0) ? '+' : '-';
|
||||
$hours = substr($offset, 0, 2);
|
||||
$minutes = substr($offset, 2, 2);
|
||||
return $sign . $hours . ':' . $minutes;
|
||||
}
|
||||
|
||||
public function format($layout) {
|
||||
$layout = strtr($layout, [
|
||||
'yyyy' => 'Y', 'yy' => 'y',
|
||||
'MM' => 'm', 'M' => 'n',
|
||||
'DD' => 'd', 'D' => 'j',
|
||||
'HH' => 'H', 'H' => 'G',
|
||||
'hh' => 'h', 'h' => 'g',
|
||||
'mm' => 'i', 'm' => 'i',
|
||||
'ss' => 's', 's' => 's',
|
||||
'A' => 'A', 'a' => 'a',
|
||||
'E' => 'N', 'YYYY' => 'Y',
|
||||
]);
|
||||
return $this->date->format($layout);
|
||||
}
|
||||
|
||||
public function UTC($time = null)
|
||||
{
|
||||
$utcDate = clone $this->date;
|
||||
$utcDate->setTimezone(new DateTimeZone('UTC'));
|
||||
return $utcDate->format('Y-m-d H:i:s.u O \\U\\T\\C');
|
||||
}
|
||||
|
||||
public function unix() {
|
||||
$date = $this->date;
|
||||
return $date->getTimestamp();
|
||||
}
|
||||
|
||||
public function sub($unit, $amount) {
|
||||
$interval = new DateInterval('P' . strtoupper($amount) . strtoupper((string)$unit));
|
||||
$this->date->sub($interval);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function add($unit, $amount) {
|
||||
$interval = new DateInterval('P' . strtoupper($amount) . strtoupper((string)$unit));
|
||||
$this->date->add($interval);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function diff($diffDate, $unit = null) {
|
||||
$interval = $this->date->diff($diffDate->getDateObject());
|
||||
switch ($unit) {
|
||||
case 'year':
|
||||
return $interval->y;
|
||||
case 'month':
|
||||
return $interval->m;
|
||||
case 'day':
|
||||
return $interval->d;
|
||||
case 'hour':
|
||||
return $interval->h;
|
||||
case 'minute':
|
||||
return $interval->i;
|
||||
case 'second':
|
||||
return $interval->s;
|
||||
default:
|
||||
return ($interval->days * 24 * 60 * 60) +
|
||||
($interval->h * 60 * 60) +
|
||||
($interval->i * 60) +
|
||||
$interval->s;
|
||||
}
|
||||
}
|
||||
|
||||
public function hour() {
|
||||
return (int)$this->date->format('H');
|
||||
}
|
||||
|
||||
public function minute() {
|
||||
return (int)$this->date->format('i');
|
||||
}
|
||||
|
||||
public function second() {
|
||||
return (int)$this->date->format('s');
|
||||
}
|
||||
|
||||
public function month() {
|
||||
return (int)$this->date->format('n');
|
||||
}
|
||||
|
||||
public function year() {
|
||||
return (int)$this->date->format('Y');
|
||||
}
|
||||
|
||||
public function dayOfMonth() {
|
||||
return (int)$this->date->format('j');
|
||||
}
|
||||
|
||||
public function dayOfWeek() {
|
||||
$weekday = (int)$this->date->format('w');
|
||||
return $weekday === 0 ? 7 : $weekday;
|
||||
}
|
||||
|
||||
public function weekOfYear() {
|
||||
$week = (int)$this->date->format('W');
|
||||
$weekday = (int)$this->date->format('w');
|
||||
|
||||
if ($weekday === 0 && $this->date->format('z') === (string)($this->date->format('L') ? '365' : '364')) {
|
||||
return (int)$this->date->sub(new DateInterval('P1D'))->format('W');
|
||||
}
|
||||
|
||||
return $week;
|
||||
}
|
||||
|
||||
public function getDateObject() {
|
||||
return clone $this->date;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace AlibabaCloud\Dara\Exception;
|
||||
|
||||
use AlibabaCloud\Tea\Exception\TeaError;
|
||||
|
||||
/**
|
||||
* Class DaraException.
|
||||
*/
|
||||
class DaraException extends TeaError
|
||||
{
|
||||
public $message = '';
|
||||
public $errCode = '';
|
||||
public $data;
|
||||
public $name = '';
|
||||
public $statusCode;
|
||||
public $description;
|
||||
public $accessDeniedDetail;
|
||||
public $errorInfo;
|
||||
|
||||
/**
|
||||
* DaraError DaraException.
|
||||
*
|
||||
* @param array $errorInfo
|
||||
* @param string $message
|
||||
* @param int $code
|
||||
* @param null|\Throwable $previous
|
||||
*/
|
||||
public function __construct($errorInfo = [], $message = '', $code = '', $previous = null)
|
||||
{
|
||||
parent::__construct($errorInfo, $message, $code, $previous);
|
||||
$this->errorInfo = $errorInfo;
|
||||
$this->name = 'BaseError';
|
||||
if (!empty($errorInfo)) {
|
||||
$properties = ['name', 'message', 'errCode', 'data', 'description', 'accessDeniedDetail'];
|
||||
foreach ($properties as $property) {
|
||||
if (isset($errorInfo[$property])) {
|
||||
$this->{$property} = $errorInfo[$property];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getErrCode()
|
||||
{
|
||||
return $this->errCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getErrorInfo()
|
||||
{
|
||||
return $this->errorInfo;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
namespace AlibabaCloud\Dara\Exception;
|
||||
|
||||
/**
|
||||
* Class DaraRespException.
|
||||
*/
|
||||
class DaraRespException extends DaraException
|
||||
{
|
||||
public $statusCode;
|
||||
protected $retryAfter;
|
||||
public $data;
|
||||
public $accessDeniedDetail;
|
||||
public $description;
|
||||
|
||||
/**
|
||||
* DaraRespException constructor.
|
||||
*
|
||||
* @param array $errorInfo
|
||||
* @param string $message
|
||||
* @param int $code
|
||||
* @param null|\Throwable $previous
|
||||
*/
|
||||
public function __construct($errorInfo = [], $message = '', $code = 0, $previous = null)
|
||||
{
|
||||
parent::__construct($errorInfo, (string) $message, (int) $code, $previous);
|
||||
$this->name = 'ResponseError';
|
||||
if (!empty($errorInfo)) {
|
||||
$properties = ['retryAfter', 'statusCode', 'data', 'description', 'accessDeniedDetail'];
|
||||
foreach ($properties as $property) {
|
||||
if (isset($errorInfo[$property])) {
|
||||
$this->{$property} = $errorInfo[$property];
|
||||
if ($property === 'data' && isset($errorInfo['data']['statusCode'])) {
|
||||
$this->statusCode = $errorInfo['data']['statusCode'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getErrorInfo()
|
||||
{
|
||||
return $this->errorInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getStatusCode()
|
||||
{
|
||||
return $this->statusCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getRetryAfter()
|
||||
{
|
||||
return $this->retryAfter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getAccessDeniedDetail()
|
||||
{
|
||||
return $this->accessDeniedDetail;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getData()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace AlibabaCloud\Dara\Exception;
|
||||
|
||||
/**
|
||||
* Class DaraRetryException
|
||||
*/
|
||||
class DaraRespException extends DaraException
|
||||
{
|
||||
/**
|
||||
* DaraRetryException constructor.
|
||||
*
|
||||
* @param string $message
|
||||
* @param int $code
|
||||
* @param null|\Throwable $previous
|
||||
*/
|
||||
public function __construct($message = '', $code = 0, $previous = null)
|
||||
{
|
||||
parent::__construct([], $message, $code, $previous);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace AlibabaCloud\Dara\Exception;
|
||||
|
||||
use AlibabaCloud\Dara\Request;
|
||||
use AlibabaCloud\Dara\RetryPolicy\RetryPolicyContext;
|
||||
|
||||
/**
|
||||
* Class DaraUnableRetryException.
|
||||
*/
|
||||
class DaraUnableRetryException extends DaraException
|
||||
{
|
||||
private $lastRequest;
|
||||
private $lastException;
|
||||
|
||||
/**
|
||||
* DaraUnableRetryException constructor.
|
||||
*
|
||||
* @param Request $lastRequest
|
||||
* @param null|\Exception $lastException
|
||||
*/
|
||||
public function __construct($lastRequest, $lastException = null)
|
||||
{
|
||||
if($lastRequest instanceof RetryPolicyContext) {
|
||||
$lastException = $lastRequest->getException();
|
||||
$lastRequest = $lastRequest->getHttpRequest();
|
||||
}
|
||||
$error_info = [];
|
||||
if (null !== $lastException && $lastException instanceof DaraException) {
|
||||
$error_info = $lastException->getErrorInfo();
|
||||
}
|
||||
parent::__construct($error_info, $lastException->getMessage(), $lastException->getCode(), $lastException);
|
||||
$this->lastRequest = $lastRequest;
|
||||
$this->lastException = $lastException;
|
||||
}
|
||||
|
||||
public function getLastRequest()
|
||||
{
|
||||
return $this->lastRequest;
|
||||
}
|
||||
|
||||
public function getLastException()
|
||||
{
|
||||
return $this->lastException;
|
||||
}
|
||||
}
|
||||
116
addons/wdsxh/library/alibabacloud/darabonba/src/File.php
Normal file
116
addons/wdsxh/library/alibabacloud/darabonba/src/File.php
Normal file
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
namespace AlibabaCloud\Dara;
|
||||
|
||||
use AlibabaCloud\Dara\Date;
|
||||
use GuzzleHttp\Psr7\Stream;
|
||||
use GuzzleHttp\Psr7\Utils;
|
||||
use AlibabaCloud\Dara\Exception\DaraException;
|
||||
|
||||
class File
|
||||
{
|
||||
private $_path;
|
||||
private $_stat = null;
|
||||
private $_fd = false;
|
||||
private $_position = 0;
|
||||
|
||||
public function __construct($path) {
|
||||
$this->_path = $path;
|
||||
}
|
||||
|
||||
public function path() {
|
||||
return $this->_path;
|
||||
}
|
||||
|
||||
public function createTime() {
|
||||
if (!$this->_stat) {
|
||||
$this->_stat = stat($this->_path);
|
||||
}
|
||||
return new Date($this->_stat['ctime']);
|
||||
}
|
||||
|
||||
public function modifyTime() {
|
||||
if (!$this->_stat) {
|
||||
$this->_stat = stat($this->_path);
|
||||
}
|
||||
return new Date($this->_stat['mtime']);
|
||||
}
|
||||
|
||||
public function length() {
|
||||
if (!$this->_stat) {
|
||||
$this->_stat = stat($this->_path);
|
||||
}
|
||||
return $this->_stat['size'];
|
||||
}
|
||||
|
||||
public function read($size) {
|
||||
if (!$this->_fd) {
|
||||
$this->_fd = fopen($this->_path, 'a+');
|
||||
}
|
||||
$position = ftell($this->_fd);
|
||||
$position = ftell($this->_fd);
|
||||
fseek($this->_fd, $this->_position);
|
||||
$data = fread($this->_fd, $size);
|
||||
$bytesRead = strlen($data);
|
||||
if (!$bytesRead) {
|
||||
return null;
|
||||
}
|
||||
$this->_position += $bytesRead;
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function write($data) {
|
||||
if (!$this->_fd) {
|
||||
$this->_fd = fopen($this->_path, 'a+');
|
||||
}
|
||||
|
||||
fwrite($this->_fd, $data);
|
||||
fflush($this->_fd);
|
||||
clearstatcache();
|
||||
$this->_stat = stat($this->_path);
|
||||
}
|
||||
|
||||
public function close() {
|
||||
if ($this->_fd) {
|
||||
fclose($this->_fd);
|
||||
$this->_fd = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $path
|
||||
* @return bool
|
||||
*/
|
||||
public static function exists($path) {
|
||||
return file_exists($path);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $path
|
||||
* @return Stream
|
||||
*/
|
||||
public static function createReadStream($path) {
|
||||
try {
|
||||
$stream = Utils::streamFor(fopen($path, 'r'));
|
||||
return $stream;
|
||||
} catch (Exception $e) {
|
||||
throw new DaraException([], "Unable to open file for reading: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $path
|
||||
* @return Stream
|
||||
*/
|
||||
public static function createWriteStream($path) {
|
||||
try {
|
||||
$stream = Utils::streamFor(fopen($path, 'a+'));
|
||||
return $stream;
|
||||
} catch (Exception $e) {
|
||||
throw new DaraException([], "Unable to open file for writing: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
112
addons/wdsxh/library/alibabacloud/darabonba/src/Helper.php
Normal file
112
addons/wdsxh/library/alibabacloud/darabonba/src/Helper.php
Normal file
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
namespace AlibabaCloud\Dara;
|
||||
|
||||
class Helper
|
||||
{
|
||||
/**
|
||||
* @param string $content
|
||||
* @param string $prefix
|
||||
* @param string $end
|
||||
* @param string[] $filter
|
||||
*
|
||||
* @return string|string[]
|
||||
*/
|
||||
public static function findFromString($content, $prefix, $end, $filter = ['"', ' '])
|
||||
{
|
||||
$len = mb_strlen($prefix);
|
||||
$pos = mb_strpos($content, $prefix);
|
||||
if (false === $pos) {
|
||||
return '';
|
||||
}
|
||||
$pos_end = mb_strpos($content, $end, $pos);
|
||||
$str = mb_substr($content, $pos + $len, $pos_end - $pos - $len);
|
||||
|
||||
return str_replace($filter, '', $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $str
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isJson($str)
|
||||
{
|
||||
json_decode($str);
|
||||
|
||||
return \JSON_ERROR_NONE == json_last_error();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isBytes($value)
|
||||
{
|
||||
if (!\is_array($value)) {
|
||||
return false;
|
||||
}
|
||||
$i = 0;
|
||||
foreach ($value as $k => $ord) {
|
||||
if ($k !== $i) {
|
||||
return false;
|
||||
}
|
||||
if (!\is_int($ord)) {
|
||||
return false;
|
||||
}
|
||||
if ($ord < 0 || $ord > 255) {
|
||||
return false;
|
||||
}
|
||||
++$i;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a bytes to string(utf8).
|
||||
*
|
||||
* @param array $bytes
|
||||
*
|
||||
* @return string the return string
|
||||
*/
|
||||
public static function toString($bytes)
|
||||
{
|
||||
$str = '';
|
||||
foreach ($bytes as $ch) {
|
||||
$str .= \chr($ch);
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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;
|
||||
}
|
||||
}
|
||||
138
addons/wdsxh/library/alibabacloud/darabonba/src/Model.php
Normal file
138
addons/wdsxh/library/alibabacloud/darabonba/src/Model.php
Normal file
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
namespace AlibabaCloud\Dara;
|
||||
|
||||
class Model
|
||||
{
|
||||
protected $_name = [];
|
||||
protected $_required = [];
|
||||
|
||||
public function __construct($config = [])
|
||||
{
|
||||
if (!empty($config)) {
|
||||
foreach ($config as $k => $v) {
|
||||
$this->{$k} = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getName($name = null)
|
||||
{
|
||||
if (null === $name) {
|
||||
return $this->_name;
|
||||
}
|
||||
|
||||
return isset($this->_name[$name]) ? $this->_name[$name] : $name;
|
||||
}
|
||||
|
||||
public function toMap()
|
||||
{
|
||||
$map = get_object_vars($this);
|
||||
foreach ($map as $k => $m) {
|
||||
if (0 === strpos($k, '_')) {
|
||||
unset($map[$k]);
|
||||
}
|
||||
}
|
||||
$res = [];
|
||||
foreach ($map as $k => $v) {
|
||||
$name = isset($this->_name[$k]) ? $this->_name[$k] : $k;
|
||||
$res[$name] = $v;
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function validate()
|
||||
{
|
||||
$vars = get_object_vars($this);
|
||||
foreach ($vars as $k => $v) {
|
||||
if (isset($this->_required[$k]) && $this->_required[$k] && empty($v)) {
|
||||
throw new \InvalidArgumentException("{$k} is required.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function copyWithoutStream() {
|
||||
$map = $this->toArray(true);
|
||||
$calledClass = get_called_class();
|
||||
|
||||
if (method_exists($calledClass, 'fromMap')) {
|
||||
return $calledClass::fromMap($map);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static function validateRequired($fieldName, $field, $val = null)
|
||||
{
|
||||
if (true === $val && null === $field) {
|
||||
throw new \InvalidArgumentException($fieldName . ' is required');
|
||||
}
|
||||
}
|
||||
|
||||
public static function validateMaxLength($fieldName, $field, $val = null)
|
||||
{
|
||||
if (null !== $field && \strlen($field) > (int) $val) {
|
||||
throw new \InvalidArgumentException($fieldName . ' is exceed max-length: ' . $val);
|
||||
}
|
||||
}
|
||||
|
||||
public static function validateMinLength($fieldName, $field, $val = null)
|
||||
{
|
||||
if (null !== $field && \strlen($field) < (int) $val) {
|
||||
throw new \InvalidArgumentException($fieldName . ' is less than min-length: ' . $val);
|
||||
}
|
||||
}
|
||||
|
||||
public static function validatePattern($fieldName, $field, $regex = '')
|
||||
{
|
||||
if (null !== $field && '' !== $field && !preg_match("/^{$regex}$/", $field)) {
|
||||
throw new \InvalidArgumentException($fieldName . ' is not match ' . $regex);
|
||||
}
|
||||
}
|
||||
|
||||
public static function validateMaximum($fieldName, $field, $val)
|
||||
{
|
||||
if (null !== $field && $field > $val) {
|
||||
throw new \InvalidArgumentException($fieldName . ' cannot be greater than ' . $val);
|
||||
}
|
||||
}
|
||||
|
||||
public static function validateMinimum($fieldName, $field, $val)
|
||||
{
|
||||
if (null !== $field && $field < $val) {
|
||||
throw new \InvalidArgumentException($fieldName . ' cannot be less than ' . $val);
|
||||
}
|
||||
}
|
||||
|
||||
public static function validateArray($arr)
|
||||
{
|
||||
if (null === $arr) {
|
||||
return;
|
||||
}
|
||||
foreach($arr as $item) {
|
||||
if($item instanceof Model) {
|
||||
$item->validate();
|
||||
} else if(is_array($item)){
|
||||
self::validateArray($item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $map
|
||||
* @param Model $model
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function toModel($map, $model)
|
||||
{
|
||||
$names = $model->getName();
|
||||
$names = array_flip($names);
|
||||
foreach ($map as $key => $value) {
|
||||
$name = isset($names[$key]) ? $names[$key] : $key;
|
||||
$model->{$name} = $value;
|
||||
}
|
||||
|
||||
return $model;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
// This file is auto-generated, don't edit it. Thanks.
|
||||
namespace AlibabaCloud\Dara\Models;
|
||||
|
||||
use AlibabaCloud\Dara\Model;
|
||||
|
||||
class ExtendsParameters extends Model {
|
||||
public $headers;
|
||||
public $queries;
|
||||
public function validate() {}
|
||||
public function toMap() {
|
||||
$res = [];
|
||||
if (null !== $this->headers) {
|
||||
$res['headers'] = $this->headers;
|
||||
}
|
||||
|
||||
if (null !== $this->queries) {
|
||||
$res['queries'] = $this->queries;
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
/**
|
||||
* @param array $map
|
||||
* @return ExtendsParameters
|
||||
*/
|
||||
public static function fromMap($map = []) {
|
||||
$model = new self();
|
||||
if(isset($map['headers'])){
|
||||
$model->headers = $map['headers'];
|
||||
}
|
||||
|
||||
if(isset($map['queries'])){
|
||||
$model->queries = $map['queries'];
|
||||
}
|
||||
return $model;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace AlibabaCloud\Dara\Models;
|
||||
|
||||
use AlibabaCloud\Dara\Model;
|
||||
|
||||
class FileField extends Model
|
||||
{
|
||||
public $filename;
|
||||
public $contentType;
|
||||
public $content;
|
||||
|
||||
public function __construct($config = [])
|
||||
{
|
||||
$this->_required = [
|
||||
'filename' => true,
|
||||
'contentType' => true,
|
||||
'content' => true,
|
||||
];
|
||||
parent::__construct($config);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,273 @@
|
||||
<?php
|
||||
|
||||
// This file is auto-generated, don't edit it. Thanks.
|
||||
namespace AlibabaCloud\Dara\Models;
|
||||
|
||||
use AlibabaCloud\Dara\Model;
|
||||
|
||||
/**
|
||||
* The common runtime options model
|
||||
*/
|
||||
class RuntimeOptions extends Model {
|
||||
protected $_name = [
|
||||
'autoretry' => 'autoretry',
|
||||
'ignoreSSL' => 'ignoreSSL',
|
||||
'key' => 'key',
|
||||
'cert' => 'cert',
|
||||
'ca' => 'ca',
|
||||
'maxAttempts' => 'max_attempts',
|
||||
'backoffPolicy' => 'backoff_policy',
|
||||
'backoffPeriod' => 'backoff_period',
|
||||
'readTimeout' => 'readTimeout',
|
||||
'connectTimeout' => 'connectTimeout',
|
||||
'httpProxy' => 'httpProxy',
|
||||
'httpsProxy' => 'httpsProxy',
|
||||
'noProxy' => 'noProxy',
|
||||
'maxIdleConns' => 'maxIdleConns',
|
||||
'localAddr' => 'localAddr',
|
||||
'socks5Proxy' => 'socks5Proxy',
|
||||
'socks5NetWork' => 'socks5NetWork',
|
||||
'keepAlive' => 'keepAlive',
|
||||
];
|
||||
public function validate() {}
|
||||
public function toMap() {
|
||||
$res = [];
|
||||
if (null !== $this->autoretry) {
|
||||
$res['autoretry'] = $this->autoretry;
|
||||
}
|
||||
if (null !== $this->ignoreSSL) {
|
||||
$res['ignoreSSL'] = $this->ignoreSSL;
|
||||
}
|
||||
if (null !== $this->key) {
|
||||
$res['key'] = $this->key;
|
||||
}
|
||||
if (null !== $this->cert) {
|
||||
$res['cert'] = $this->cert;
|
||||
}
|
||||
if (null !== $this->ca) {
|
||||
$res['ca'] = $this->ca;
|
||||
}
|
||||
if (null !== $this->maxAttempts) {
|
||||
$res['max_attempts'] = $this->maxAttempts;
|
||||
}
|
||||
if (null !== $this->backoffPolicy) {
|
||||
$res['backoff_policy'] = $this->backoffPolicy;
|
||||
}
|
||||
if (null !== $this->backoffPeriod) {
|
||||
$res['backoff_period'] = $this->backoffPeriod;
|
||||
}
|
||||
if (null !== $this->readTimeout) {
|
||||
$res['readTimeout'] = $this->readTimeout;
|
||||
}
|
||||
if (null !== $this->connectTimeout) {
|
||||
$res['connectTimeout'] = $this->connectTimeout;
|
||||
}
|
||||
if (null !== $this->httpProxy) {
|
||||
$res['httpProxy'] = $this->httpProxy;
|
||||
}
|
||||
if (null !== $this->httpsProxy) {
|
||||
$res['httpsProxy'] = $this->httpsProxy;
|
||||
}
|
||||
if (null !== $this->noProxy) {
|
||||
$res['noProxy'] = $this->noProxy;
|
||||
}
|
||||
if (null !== $this->maxIdleConns) {
|
||||
$res['maxIdleConns'] = $this->maxIdleConns;
|
||||
}
|
||||
if (null !== $this->localAddr) {
|
||||
$res['localAddr'] = $this->localAddr;
|
||||
}
|
||||
if (null !== $this->socks5Proxy) {
|
||||
$res['socks5Proxy'] = $this->socks5Proxy;
|
||||
}
|
||||
if (null !== $this->socks5NetWork) {
|
||||
$res['socks5NetWork'] = $this->socks5NetWork;
|
||||
}
|
||||
if (null !== $this->keepAlive) {
|
||||
$res['keepAlive'] = $this->keepAlive;
|
||||
}
|
||||
if (null !== $this->extendsParameters) {
|
||||
$res['extendsParameters'] = null !== $this->extendsParameters ? $this->extendsParameters->toMap() : null;
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
/**
|
||||
* @param array $map
|
||||
* @return RuntimeOptions
|
||||
*/
|
||||
public static function fromMap($map = []) {
|
||||
$model = new self();
|
||||
if(isset($map['autoretry'])){
|
||||
$model->autoretry = $map['autoretry'];
|
||||
}
|
||||
if(isset($map['ignoreSSL'])){
|
||||
$model->ignoreSSL = $map['ignoreSSL'];
|
||||
}
|
||||
if(isset($map['key'])){
|
||||
$model->key = $map['key'];
|
||||
}
|
||||
if(isset($map['cert'])){
|
||||
$model->cert = $map['cert'];
|
||||
}
|
||||
if(isset($map['ca'])){
|
||||
$model->ca = $map['ca'];
|
||||
}
|
||||
if(isset($map['max_attempts'])){
|
||||
$model->maxAttempts = $map['max_attempts'];
|
||||
}
|
||||
if(isset($map['backoff_policy'])){
|
||||
$model->backoffPolicy = $map['backoff_policy'];
|
||||
}
|
||||
if(isset($map['backoff_period'])){
|
||||
$model->backoffPeriod = $map['backoff_period'];
|
||||
}
|
||||
if(isset($map['readTimeout'])){
|
||||
$model->readTimeout = $map['readTimeout'];
|
||||
}
|
||||
if(isset($map['connectTimeout'])){
|
||||
$model->connectTimeout = $map['connectTimeout'];
|
||||
}
|
||||
if(isset($map['httpProxy'])){
|
||||
$model->httpProxy = $map['httpProxy'];
|
||||
}
|
||||
if(isset($map['httpsProxy'])){
|
||||
$model->httpsProxy = $map['httpsProxy'];
|
||||
}
|
||||
if(isset($map['noProxy'])){
|
||||
$model->noProxy = $map['noProxy'];
|
||||
}
|
||||
if(isset($map['maxIdleConns'])){
|
||||
$model->maxIdleConns = $map['maxIdleConns'];
|
||||
}
|
||||
if(isset($map['localAddr'])){
|
||||
$model->localAddr = $map['localAddr'];
|
||||
}
|
||||
if(isset($map['socks5Proxy'])){
|
||||
$model->socks5Proxy = $map['socks5Proxy'];
|
||||
}
|
||||
if(isset($map['socks5NetWork'])){
|
||||
$model->socks5NetWork = $map['socks5NetWork'];
|
||||
}
|
||||
if(isset($map['keepAlive'])){
|
||||
$model->keepAlive = $map['keepAlive'];
|
||||
}
|
||||
if(isset($map['extendsParameters'])){
|
||||
$model->extendsParameters = ExtendsParameters::fromMap($map['extendsParameters']);
|
||||
}
|
||||
return $model;
|
||||
}
|
||||
/**
|
||||
* @description whether to try again
|
||||
* @var bool
|
||||
*/
|
||||
public $autoretry;
|
||||
|
||||
/**
|
||||
* @description ignore SSL validation
|
||||
* @var bool
|
||||
*/
|
||||
public $ignoreSSL;
|
||||
|
||||
/**
|
||||
* @description privite key for client certificate
|
||||
* @var string
|
||||
*/
|
||||
public $key;
|
||||
|
||||
/**
|
||||
* @description client certificate
|
||||
* @var string
|
||||
*/
|
||||
public $cert;
|
||||
|
||||
/**
|
||||
* @description server certificate
|
||||
* @var string
|
||||
*/
|
||||
public $ca;
|
||||
|
||||
/**
|
||||
* @description maximum number of retries
|
||||
* @var int
|
||||
*/
|
||||
public $maxAttempts;
|
||||
|
||||
/**
|
||||
* @description backoff policy
|
||||
* @var string
|
||||
*/
|
||||
public $backoffPolicy;
|
||||
|
||||
/**
|
||||
* @description backoff period
|
||||
* @var int
|
||||
*/
|
||||
public $backoffPeriod;
|
||||
|
||||
/**
|
||||
* @description read timeout
|
||||
* @var int
|
||||
*/
|
||||
public $readTimeout;
|
||||
|
||||
/**
|
||||
* @description connect timeout
|
||||
* @var int
|
||||
*/
|
||||
public $connectTimeout;
|
||||
|
||||
/**
|
||||
* @description http proxy url
|
||||
* @var string
|
||||
*/
|
||||
public $httpProxy;
|
||||
|
||||
/**
|
||||
* @description https Proxy url
|
||||
* @var string
|
||||
*/
|
||||
public $httpsProxy;
|
||||
|
||||
/**
|
||||
* @description agent blacklist
|
||||
* @var string
|
||||
*/
|
||||
public $noProxy;
|
||||
|
||||
/**
|
||||
* @description maximum number of connections
|
||||
* @var int
|
||||
*/
|
||||
public $maxIdleConns;
|
||||
|
||||
/**
|
||||
* @description local addr
|
||||
* @var string
|
||||
*/
|
||||
public $localAddr;
|
||||
|
||||
/**
|
||||
* @description SOCKS5 proxy
|
||||
* @var string
|
||||
*/
|
||||
public $socks5Proxy;
|
||||
|
||||
/**
|
||||
* @description SOCKS5 netWork
|
||||
* @var string
|
||||
*/
|
||||
public $socks5NetWork;
|
||||
|
||||
/**
|
||||
* @description whether to enable keep-alive
|
||||
* @var bool
|
||||
*/
|
||||
public $keepAlive;
|
||||
|
||||
/**
|
||||
* @description Extends Parameters
|
||||
* @var ExtendsParameters
|
||||
*/
|
||||
public $extendsParameters;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace AlibabaCloud\Dara\Models;
|
||||
|
||||
use AlibabaCloud\Dara\Model;
|
||||
|
||||
class SSEEvent extends Model {
|
||||
public $data;
|
||||
public $id;
|
||||
public $event;
|
||||
public $retry;
|
||||
|
||||
public function __construct($data = array()) {
|
||||
$this->data = isset($data['data']) ? $data['data'] : null;
|
||||
$this->id = isset($data['id']) ? $data['id'] : null;
|
||||
$this->event = isset($data['event']) ? $data['event'] : null;
|
||||
$this->retry = isset($data['retry']) ? $data['retry'] : null;
|
||||
}
|
||||
|
||||
public function validate() { }
|
||||
|
||||
public function toArray()
|
||||
{
|
||||
$res = [];
|
||||
if (null !== $this->data) {
|
||||
$res['data'] = $this->data;
|
||||
}
|
||||
|
||||
if (null !== $this->id) {
|
||||
$res['id'] = $this->id;
|
||||
}
|
||||
|
||||
if (null !== $this->event) {
|
||||
$res['event'] = $this->event;
|
||||
}
|
||||
|
||||
if (null !== $this->retry) {
|
||||
$res['retry'] = $this->retry;
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function toMap()
|
||||
{
|
||||
return $this->toArray();
|
||||
}
|
||||
|
||||
public static function fromMap($map = [])
|
||||
{
|
||||
$model = new self();
|
||||
if (isset($map['data'])) {
|
||||
if(!empty($map['data'])){
|
||||
$model->data = [];
|
||||
foreach($map['data'] as $key => $value) {
|
||||
$model->data[$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($map['id'])) {
|
||||
$model->id = $map['id'];
|
||||
}
|
||||
|
||||
if (isset($map['event'])) {
|
||||
$model->event = $map['event'];
|
||||
}
|
||||
|
||||
if (isset($map['retry'])) {
|
||||
$model->retry = $map['retry'];
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace AlibabaCloud\Dara;
|
||||
|
||||
use ArrayIterator;
|
||||
use IteratorAggregate;
|
||||
use ReflectionObject;
|
||||
use Traversable;
|
||||
|
||||
/**
|
||||
* Class Parameter.
|
||||
*/
|
||||
abstract class Parameter implements IteratorAggregate
|
||||
{
|
||||
/**
|
||||
* @return ArrayIterator|Traversable
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function getIterator()
|
||||
{
|
||||
return new ArrayIterator($this->toArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getRealParameters()
|
||||
{
|
||||
$array = [];
|
||||
$obj = new ReflectionObject($this);
|
||||
$properties = $obj->getProperties();
|
||||
|
||||
foreach ($properties as $property) {
|
||||
$docComment = $property->getDocComment();
|
||||
$key = trim(Helper::findFromString($docComment, '@real', "\n"));
|
||||
$value = $property->getValue($this);
|
||||
$array[$key] = $value;
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return $this->getRealParameters();
|
||||
}
|
||||
}
|
||||
123
addons/wdsxh/library/alibabacloud/darabonba/src/Request.php
Normal file
123
addons/wdsxh/library/alibabacloud/darabonba/src/Request.php
Normal file
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
|
||||
namespace AlibabaCloud\Dara;
|
||||
|
||||
use GuzzleHttp\Psr7\Request as PsrRequest;
|
||||
use InvalidArgumentException;
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
|
||||
/**
|
||||
* Class Request.
|
||||
*/
|
||||
class Request extends PsrRequest
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $protocol = 'https';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $pathname = '/';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $headers = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $query = [];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $body;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $port;
|
||||
|
||||
public $method;
|
||||
|
||||
public function __construct($method = 'GET', $uri = '', array $headers = [], $body = null, $version = '1.1')
|
||||
{
|
||||
parent::__construct($method, $uri, $headers, $body, $version);
|
||||
$this->method = $method;
|
||||
}
|
||||
|
||||
/**
|
||||
* These fields are compatible if you define other fields.
|
||||
* Mainly for compatibility situations where the code generator cannot generate set properties.
|
||||
*
|
||||
* @return PsrRequest
|
||||
*/
|
||||
public function getPsrRequest()
|
||||
{
|
||||
$this->assertQuery($this->query);
|
||||
|
||||
$request = clone $this;
|
||||
|
||||
$uri = $request->getUri();
|
||||
if ($this->query) {
|
||||
$uri = $uri->withQuery(http_build_query($this->query));
|
||||
}
|
||||
|
||||
if ($this->port) {
|
||||
$uri = $uri->withPort($this->port);
|
||||
}
|
||||
|
||||
if ($this->protocol) {
|
||||
$uri = $uri->withScheme($this->protocol);
|
||||
}
|
||||
|
||||
if ($this->pathname) {
|
||||
$uri = $uri->withPath($this->pathname);
|
||||
}
|
||||
|
||||
if (isset($this->headers['host'])) {
|
||||
$uri = $uri->withHost($this->headers['host']);
|
||||
}
|
||||
|
||||
$request = $request->withUri($uri);
|
||||
$request = $request->withMethod($this->method);
|
||||
|
||||
if ('' !== $this->body && null !== $this->body) {
|
||||
if ($this->body instanceof StreamInterface) {
|
||||
$request = $request->withBody($this->body);
|
||||
} else {
|
||||
$body = $this->body;
|
||||
if (Helper::isBytes($this->body)) {
|
||||
$body = Helper::toString($this->body);
|
||||
}
|
||||
if (\function_exists('\GuzzleHttp\Psr7\stream_for')) {
|
||||
// @deprecated stream_for will be removed in guzzlehttp/psr7:2.0
|
||||
$request = $request->withBody(\GuzzleHttp\Psr7\stream_for($body));
|
||||
} else {
|
||||
$request = $request->withBody(\GuzzleHttp\Psr7\Utils::streamFor($body));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->headers) {
|
||||
foreach ($this->headers as $key => $value) {
|
||||
$request = $request->withHeader($key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
return $request;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $query
|
||||
*/
|
||||
private function assertQuery($query)
|
||||
{
|
||||
if (!\is_array($query) && $query !== null) {
|
||||
throw new InvalidArgumentException('Query must be array.');
|
||||
}
|
||||
}
|
||||
}
|
||||
379
addons/wdsxh/library/alibabacloud/darabonba/src/Response.php
Normal file
379
addons/wdsxh/library/alibabacloud/darabonba/src/Response.php
Normal file
@@ -0,0 +1,379 @@
|
||||
<?php
|
||||
|
||||
namespace AlibabaCloud\Dara;
|
||||
|
||||
use Adbar\Dot;
|
||||
use ArrayAccess;
|
||||
use Countable;
|
||||
use GuzzleHttp\Psr7\Response as PsrResponse;
|
||||
use GuzzleHttp\TransferStats;
|
||||
use IteratorAggregate;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
use AlibabaCloud\Dara\Util\StringUtil;
|
||||
|
||||
/**
|
||||
* Class Response.
|
||||
*/
|
||||
class Response extends PsrResponse implements ArrayAccess, IteratorAggregate, Countable
|
||||
{
|
||||
public $headers = [];
|
||||
public $statusCode;
|
||||
public $statusMessage = '';
|
||||
|
||||
/**
|
||||
* @var TransferStats
|
||||
*/
|
||||
public static $info;
|
||||
|
||||
/**
|
||||
* @var StreamInterface
|
||||
*/
|
||||
public $body;
|
||||
/**
|
||||
* Instance of the Dot.
|
||||
*
|
||||
* @var Dot
|
||||
*/
|
||||
protected $dot;
|
||||
|
||||
/**
|
||||
* Response constructor.
|
||||
*/
|
||||
public function __construct(ResponseInterface $response)
|
||||
{
|
||||
parent::__construct(
|
||||
$response->getStatusCode(),
|
||||
$response->getHeaders(),
|
||||
$response->getBody(),
|
||||
$response->getProtocolVersion(),
|
||||
$response->getReasonPhrase()
|
||||
);
|
||||
$this->headers = $response->getHeaders();
|
||||
$this->body = $response->getBody();
|
||||
$this->statusCode = $response->getStatusCode();
|
||||
if ($this->body->isSeekable()) {
|
||||
$this->body->seek(0);
|
||||
}
|
||||
|
||||
$contentType = $this->getHeaderLine('Content-Type');
|
||||
|
||||
if(StringUtil::hasPrefix($contentType, 'text/event-stream')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Helper::isJson((string) $this->getBody())) {
|
||||
$this->dot = new Dot($this->toArray());
|
||||
} else {
|
||||
$this->dot = new Dot();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return (string) $this->getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return null|mixed
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
$data = $this->dot->all();
|
||||
if (!isset($data[$name])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return json_decode(json_encode($data))->{$name};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function __set($name, $value)
|
||||
{
|
||||
$this->dot->set($name, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function __isset($name)
|
||||
{
|
||||
return $this->dot->has($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $offset
|
||||
*/
|
||||
public function __unset($offset)
|
||||
{
|
||||
$this->dot->delete($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return \GuzzleHttp\json_decode((string) $this->getBody(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|int|string $keys
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function add($keys, $value = null)
|
||||
{
|
||||
return $this->dot->add($keys, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function all()
|
||||
{
|
||||
return $this->dot->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null|array|int|string $keys
|
||||
*/
|
||||
public function clear($keys = null)
|
||||
{
|
||||
return $this->dot->clear($keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|int|string $keys
|
||||
*/
|
||||
public function delete($keys)
|
||||
{
|
||||
return $this->dot->delete($keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $delimiter
|
||||
* @param null|array $items
|
||||
* @param string $prepend
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function flatten($delimiter = '.', $items = null, $prepend = '')
|
||||
{
|
||||
return $this->dot->flatten($delimiter, $items, $prepend);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null|int|string $key
|
||||
* @param mixed $default
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($key = null, $default = null)
|
||||
{
|
||||
return $this->dot->get($key, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|int|string $keys
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has($keys)
|
||||
{
|
||||
return $this->dot->has($keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null|array|int|string $keys
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isEmpty($keys = null)
|
||||
{
|
||||
return $this->dot->isEmpty($keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|self|string $key
|
||||
* @param array|self $value
|
||||
*/
|
||||
public function merge($key, $value = [])
|
||||
{
|
||||
return $this->dot->merge($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|self|string $key
|
||||
* @param array|self $value
|
||||
*/
|
||||
public function mergeRecursive($key, $value = [])
|
||||
{
|
||||
return $this->dot->mergeRecursive($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|self|string $key
|
||||
* @param array|self $value
|
||||
*/
|
||||
public function mergeRecursiveDistinct($key, $value = [])
|
||||
{
|
||||
return $this->dot->mergeRecursiveDistinct($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null|int|string $key
|
||||
* @param mixed $default
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function pull($key = null, $default = null)
|
||||
{
|
||||
return $this->dot->pull($key, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null|int|string $key
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function push($key = null, $value = null)
|
||||
{
|
||||
return $this->dot->push($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace all values or values within the given key
|
||||
* with an array or Dot object.
|
||||
*
|
||||
* @param array|self|string $key
|
||||
* @param array|self $value
|
||||
*/
|
||||
public function replace($key, $value = [])
|
||||
{
|
||||
return $this->dot->replace($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a given key / value pair or pairs.
|
||||
*
|
||||
* @param array|int|string $keys
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function set($keys, $value = null)
|
||||
{
|
||||
return $this->dot->set($keys, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace all items with a given array.
|
||||
*
|
||||
* @param mixed $items
|
||||
*/
|
||||
public function setArray($items)
|
||||
{
|
||||
return $this->dot->setArray($items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace all items with a given array as a reference.
|
||||
*/
|
||||
public function setReference(array &$items)
|
||||
{
|
||||
return $this->dot->setReference($items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value of a given key or all the values as JSON.
|
||||
*
|
||||
* @param mixed $key
|
||||
* @param int $options
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toJson($key = null, $options = 0)
|
||||
{
|
||||
return $this->dot->toJson($key, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve an external iterator.
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function getIterator()
|
||||
{
|
||||
return $this->dot->getIterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether a offset exists.
|
||||
*
|
||||
* @param $offset
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return $this->dot->offsetExists($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset to retrieve.
|
||||
*
|
||||
* @param $offset
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return $this->dot->offsetGet($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset to set.
|
||||
*
|
||||
* @param $offset
|
||||
* @param $value
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
$this->dot->offsetSet($offset, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset to unset.
|
||||
*
|
||||
* @param $offset
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
$this->dot->offsetUnset($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Count elements of an object.
|
||||
*
|
||||
* @param null $key
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function count($key = null)
|
||||
{
|
||||
return $this->dot->count($key);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace AlibabaCloud\Dara\RetryPolicy;
|
||||
|
||||
use AlibabaCloud\Dara\Exception\DaraException;
|
||||
use AlibabaCloud\Dara\RetryPolicy\BackoffPolicy;
|
||||
use AlibabaCloud\Dara\RetryPolicy\EqualJitterBackoffPolicy;
|
||||
use AlibabaCloud\Dara\RetryPolicy\ExponentialBackoffPolicy;
|
||||
use AlibabaCloud\Dara\RetryPolicy\FixedBackoffPolicy;
|
||||
use AlibabaCloud\Dara\RetryPolicy\FullJitterBackoffPolicy;
|
||||
use AlibabaCloud\Dara\RetryPolicy\RandomBackoffPolic;
|
||||
|
||||
interface BackoffPolicyInterface {
|
||||
public function getDelayTime($ctx);
|
||||
}
|
||||
|
||||
abstract class BackoffPolicy implements BackoffPolicyInterface {
|
||||
|
||||
protected $policy;
|
||||
|
||||
public function __construct($option) {
|
||||
$this->policy = $option['policy'];
|
||||
}
|
||||
|
||||
abstract public function getDelayTime($ctx);
|
||||
|
||||
public static function newBackoffPolicy($option) {
|
||||
switch($option['policy']) {
|
||||
case 'Fixed':
|
||||
return new FixedBackoffPolicy($option);
|
||||
case 'Random':
|
||||
return new RandomBackoffPolicy($option);
|
||||
case 'Exponential':
|
||||
return new ExponentialBackoffPolicy($option);
|
||||
case 'EqualJitter':
|
||||
case 'ExponentialWithEqualJitter':
|
||||
return new EqualJitterBackoffPolicy($option);
|
||||
case 'FullJitter':
|
||||
case 'ExponentialWithFullJitter':
|
||||
return new FullJitterBackoffPolicy($option);
|
||||
default:
|
||||
throw new DaraException([], "Invalid backoff policy");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace AlibabaCloud\Dara\RetryPolicy;
|
||||
|
||||
use AlibabaCloud\Dara\Exception\DaraException;
|
||||
use AlibabaCloud\Dara\RetryPolicy\BackoffPolicy;
|
||||
|
||||
|
||||
class EqualJitterBackoffPolicy extends BackoffPolicy {
|
||||
private $period;
|
||||
private $cap;
|
||||
|
||||
public function __construct(array $option) {
|
||||
parent::__construct($option);
|
||||
if (!isset($option['period'])) {
|
||||
throw new InvalidArgumentException("Period must be specified.");
|
||||
}
|
||||
$this->period = $option['period'];
|
||||
// 默认值: 3 天
|
||||
$this->cap = isset($option['cap']) ? $option['cap'] : 3 * 24 * 60 * 60 * 1000;
|
||||
}
|
||||
|
||||
public function getDelayTime($ctx) {
|
||||
$ceil = min(pow(2, $ctx->getRetryCount() * $this->period), $this->cap);
|
||||
return $ceil / 2 + mt_rand(0, $ceil / 2);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace AlibabaCloud\Dara\RetryPolicy;
|
||||
|
||||
use AlibabaCloud\Dara\Exception\DaraException;
|
||||
use AlibabaCloud\Dara\RetryPolicy\BackoffPolicy;
|
||||
|
||||
|
||||
class ExponentialBackoffPolicy extends BackoffPolicy {
|
||||
private $period;
|
||||
private $cap;
|
||||
|
||||
public function __construct(array $option) {
|
||||
parent::__construct($option);
|
||||
if (!isset($option['period'])) {
|
||||
throw new DaraException("Period must be specified.");
|
||||
}
|
||||
$this->period = $option['period'];
|
||||
// 默认值: 3 天
|
||||
$this->cap = isset($option['cap']) ? $option['cap'] : 3 * 24 * 60 * 60 * 1000;
|
||||
}
|
||||
|
||||
public function getDelayTime($ctx) {
|
||||
$randomTime = pow(2, $ctx->getRetryCount() * $this->period);
|
||||
return ($randomTime > $this->cap) ? $this->cap : $randomTime;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace AlibabaCloud\Dara\RetryPolicy;
|
||||
|
||||
use AlibabaCloud\Dara\Exception\DaraException;
|
||||
use AlibabaCloud\Dara\RetryPolicy\BackoffPolicy;
|
||||
|
||||
|
||||
class FixedBackoffPolicy extends BackoffPolicy {
|
||||
private $period;
|
||||
|
||||
public function __construct(array $option) {
|
||||
parent::__construct($option);
|
||||
if (!isset($option['period'])) {
|
||||
throw new DaraException([], "Period must be specified.");
|
||||
}
|
||||
$this->period = $option['period'];
|
||||
}
|
||||
|
||||
public function getDelayTime($ctx) {
|
||||
return $this->period;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace AlibabaCloud\Dara\RetryPolicy;
|
||||
|
||||
use AlibabaCloud\Dara\Exception\DaraException;
|
||||
use AlibabaCloud\Dara\RetryPolicy\BackoffPolicy;
|
||||
|
||||
|
||||
class FullJitterBackoffPolicy extends BackoffPolicy {
|
||||
private $period;
|
||||
private $cap;
|
||||
|
||||
public function __construct(array $option) {
|
||||
parent::__construct($option);
|
||||
if (!isset($option['period'])) {
|
||||
throw new DaraException("Period must be specified.");
|
||||
}
|
||||
$this->period = $option['period'];
|
||||
// 默认值: 3 天
|
||||
$this->cap = isset($option['cap']) ? $option['cap'] : 3 * 24 * 60 * 60 * 1000;
|
||||
}
|
||||
|
||||
public function getDelayTime($ctx) {
|
||||
$ceil = min(pow(2, $ctx->getRetryCount() * $this->period), $this->cap);
|
||||
return mt_rand(0, $ceil);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace AlibabaCloud\Dara\RetryPolicy;
|
||||
|
||||
use AlibabaCloud\Dara\Exception\DaraException;
|
||||
use AlibabaCloud\Dara\RetryPolicy\BackoffPolicy;
|
||||
|
||||
|
||||
class RandomBackoffPolicy extends BackoffPolicy {
|
||||
private $period;
|
||||
private $cap;
|
||||
|
||||
public function __construct(array $option) {
|
||||
parent::__construct($option);
|
||||
if (!isset($option['period'])) {
|
||||
throw new DaraException([], "Period must be specified.");
|
||||
}
|
||||
$this->period = $option['period'];
|
||||
$this->cap = isset($option['cap']) ? $option['cap'] : 20000;
|
||||
}
|
||||
|
||||
public function getDelayTime($ctx) {
|
||||
$randomTime = mt_rand(0, $ctx->getRetryCount() * $this->period);
|
||||
return ($randomTime > $this->cap) ? $this->cap : $randomTime;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace AlibabaCloud\Dara\RetryPolicy;
|
||||
|
||||
use AlibabaCloud\Dara\RetryPolicy\BackoffPolicy;
|
||||
use AlibabaCloud\Dara\Exception\DaraException;
|
||||
|
||||
class RetryCondition {
|
||||
private $maxAttempts;
|
||||
private $backoff = null;
|
||||
private $exception = [];
|
||||
private $errorCode = [];
|
||||
private $maxDelay;
|
||||
|
||||
public function __construct($condition) {
|
||||
|
||||
if(isset($condition['maxAttempts'])) {
|
||||
$this->maxAttempts = $condition['maxAttempts'];
|
||||
}
|
||||
|
||||
$this->backoff = isset($condition['backoff']) ? $condition['backoff'] : null;
|
||||
$this->exception = isset($condition['exception']) ? $condition['exception'] : [];
|
||||
$this->errorCode = isset($condition['errorCode']) ? $condition['errorCode'] : [];
|
||||
$this->maxDelay = isset($condition['maxDelay']) ? $condition['maxDelay'] : [];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getMaxAttempts() {
|
||||
return $this->maxAttempts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BackoffPolicy
|
||||
*/
|
||||
public function getBackoff() {
|
||||
return $this->backoff;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getException() {
|
||||
return $this->exception;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getErrorCode() {
|
||||
return $this->errorCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getMaxDelay() {
|
||||
return $this->maxDelay;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace AlibabaCloud\Dara\RetryPolicy;
|
||||
|
||||
use AlibabaCloud\Dara\RetryPolicy\BackoffPolicy;
|
||||
use AlibabaCloud\Dara\RetryPolicy\RetryCondition;
|
||||
|
||||
class RetryOptions {
|
||||
private $retryable;
|
||||
private $retryCondition;
|
||||
private $noRetryCondition;
|
||||
|
||||
public function __construct($options) {
|
||||
$this->retryable = $options['retryable'];
|
||||
$this->retryCondition = array_map(function ($condition) {
|
||||
if($condition instanceof RetryCondition) {
|
||||
return $condition;
|
||||
}
|
||||
return new RetryCondition($condition);
|
||||
}, isset($options['retryCondition']) ? $options['retryCondition'] : []);
|
||||
|
||||
$this->noRetryCondition = array_map(function ($condition) {
|
||||
if($condition instanceof RetryCondition) {
|
||||
return $condition;
|
||||
}
|
||||
return new RetryCondition($condition);
|
||||
}, isset($options['noRetryCondition']) ? $options['noRetryCondition'] : []);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function getRetryable() {
|
||||
return $this->retryable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return RetryCondition[]
|
||||
*/
|
||||
public function getRetryCondition() {
|
||||
return $this->retryCondition;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return RetryCondition[]
|
||||
*/
|
||||
public function getNoRetryCondition() {
|
||||
return $this->noRetryCondition;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace AlibabaCloud\Dara\RetryPolicy;
|
||||
|
||||
use AlibabaCloud\Dara\RetryPolicy\BackoffPolicy;
|
||||
use AlibabaCloud\Dara\Request;
|
||||
use AlibabaCloud\Dara\Response;
|
||||
use AlibabaCloud\Dara\Exception\DaraException;
|
||||
|
||||
class RetryPolicyContext {
|
||||
private $key;
|
||||
private $retriesAttempted;
|
||||
private $httpRequest;
|
||||
private $httpResponse;
|
||||
private $exception;
|
||||
|
||||
public function __construct($options) {
|
||||
$this->key = isset($options['key']) ? $options['key'] : '';
|
||||
$this->retriesAttempted = isset($options['retriesAttempted']) ? $options['retriesAttempted'] : 0;
|
||||
$this->httpRequest = isset($options['httpRequest']) ? $options['httpRequest'] : null;
|
||||
$this->httpResponse = isset($options['httpResponse']) ? $options['httpResponse'] : null;
|
||||
$this->exception = isset($options['exception']) ? $options['exception'] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getRetryCount(){
|
||||
return $this->retriesAttempted;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getKey() {
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Request
|
||||
*/
|
||||
public function getHttpRequest() {
|
||||
return $this->httpRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function getHttpResponse() {
|
||||
return $this->httpResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return DaraException
|
||||
*/
|
||||
public function getException() {
|
||||
return $this->exception;
|
||||
}
|
||||
}
|
||||
152
addons/wdsxh/library/alibabacloud/darabonba/src/Url.php
Normal file
152
addons/wdsxh/library/alibabacloud/darabonba/src/Url.php
Normal file
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
|
||||
namespace AlibabaCloud\Dara;
|
||||
|
||||
class Url
|
||||
{
|
||||
|
||||
private $url = '';
|
||||
|
||||
private $path = '';
|
||||
|
||||
private $pathname = '';
|
||||
|
||||
private $protocol = '';
|
||||
|
||||
private $hostname = '';
|
||||
|
||||
private $host = '';
|
||||
|
||||
private $port = '';
|
||||
|
||||
private $hash = '';
|
||||
|
||||
private $search = '';
|
||||
|
||||
private $auth = '';
|
||||
|
||||
public function __construct($str) {
|
||||
$this->url = $str;
|
||||
}
|
||||
|
||||
public function path() {
|
||||
if(empty($this->path)) {
|
||||
return ;
|
||||
}
|
||||
$pathname = $this->pathname();
|
||||
$query = $this->search();
|
||||
$this->path = $pathname . '?' . $query;
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
public function pathname() {
|
||||
if(empty($this->pathname)) {
|
||||
return $this->pathname;
|
||||
}
|
||||
$this->pathname = parse_url($ref, PHP_URL_PATH);
|
||||
return $this->pathname;
|
||||
}
|
||||
|
||||
public function protocol() {
|
||||
if(empty($this->protocol)) {
|
||||
return $this->protocol;
|
||||
}
|
||||
$this->protocol = parse_url($ref, PHP_URL_SCHEME);
|
||||
return $this->protocol;
|
||||
}
|
||||
|
||||
public function hostname() {
|
||||
if(empty($this->hostname)) {
|
||||
return $this->hostname;
|
||||
}
|
||||
$this->hostname = parse_url($ref, PHP_URL_HOST);
|
||||
return $this->hostname;
|
||||
}
|
||||
|
||||
public function host() {
|
||||
if(empty($this->host)) {
|
||||
return ;
|
||||
}
|
||||
$hostname = $this->hostname();
|
||||
$port = $this->port();
|
||||
$this->host = $hostname . $port;
|
||||
return $this->host;
|
||||
}
|
||||
|
||||
public function port() {
|
||||
if(empty($this->port)) {
|
||||
return $this->port;
|
||||
}
|
||||
$this->port = parse_url($ref, PHP_URL_PORT);
|
||||
return $this->port;
|
||||
}
|
||||
|
||||
public function hash() {
|
||||
if(empty($this->hash)) {
|
||||
return $this->hash;
|
||||
}
|
||||
$this->hash = parse_url($ref, PHP_URL_FRAGMENT);
|
||||
return $this->hash;
|
||||
}
|
||||
|
||||
public function search() {
|
||||
if(empty($this->search)) {
|
||||
return $this->search;
|
||||
}
|
||||
$this->search = parse_url($ref, PHP_URL_QUERY);
|
||||
return $this->search;
|
||||
}
|
||||
|
||||
public function href() {
|
||||
return $this->href;
|
||||
}
|
||||
|
||||
public function auth() {
|
||||
if(empty($this->auth)) {
|
||||
return $this->auth;
|
||||
}
|
||||
$username = parse_url($ref, PHP_URL_USER);
|
||||
$password = parse_url($ref, PHP_URL_PASS);
|
||||
$this->auth = $username . ':' . $password;
|
||||
return $this->auth;
|
||||
}
|
||||
|
||||
public static function parse($url) {
|
||||
return new self($url);
|
||||
}
|
||||
|
||||
public static function urlEncode($url) {
|
||||
if (empty($raw)) {
|
||||
throw new \InvalidArgumentException('not a valid value for parameter');
|
||||
}
|
||||
$str = urlencode($raw);
|
||||
$str = str_replace("%20", "+", $str);
|
||||
$str = str_replace("%2A", "*", $str);
|
||||
return $str;
|
||||
}
|
||||
|
||||
public static function percentEncode($raw) {
|
||||
if($raw === null) {
|
||||
return null;
|
||||
}
|
||||
$encoded = urlencode($raw);
|
||||
$encoded = str_replace('+', '%20', $encoded);
|
||||
$encoded = str_replace('*', '%2A', $encoded);
|
||||
$encoded = str_replace('%7E', '~', $encoded);
|
||||
return $encoded;
|
||||
}
|
||||
|
||||
public static function pathEncode($path) {
|
||||
if (empty($raw) || $raw === '/') {
|
||||
return $raw;
|
||||
}
|
||||
$arr = explode('/', $raw);
|
||||
$ret = '';
|
||||
foreach ($arr as $i => $path) {
|
||||
$str = self::percentEncode($path);
|
||||
$ret .= "$str/";
|
||||
}
|
||||
return substr($ret, 0, -1);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
|
||||
namespace AlibabaCloud\Dara\Util;
|
||||
|
||||
use XmlWriter;
|
||||
|
||||
/**
|
||||
* Based on: http://stackoverflow.com/questions/99350/passing-php-associative-arrays-to-and-from-xml.
|
||||
*/
|
||||
class ArrayToXml
|
||||
{
|
||||
private $version;
|
||||
private $encoding;
|
||||
|
||||
/**
|
||||
* Construct ArrayToXML object with selected version and encoding
|
||||
* for available values check XmlWriter docs http://www.php.net/manual/en/function.xmlwriter-start-document.php.
|
||||
*
|
||||
* @param string $xmlVersion XML Version, default 1.0
|
||||
* @param string $xmlEncoding XML Encoding, default UTF-8
|
||||
*/
|
||||
public function __construct($xmlVersion = '1.0', $xmlEncoding = 'utf-8')
|
||||
{
|
||||
$this->version = $xmlVersion;
|
||||
$this->encoding = $xmlEncoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build an XML Data Set.
|
||||
*
|
||||
* @param array $data Associative Array containing values to be parsed into an XML Data Set(s)
|
||||
* @param string $startElement Root Opening Tag, default data
|
||||
*
|
||||
* @return string XML String containing values
|
||||
* @return mixed Boolean false on failure, string XML result on success
|
||||
*/
|
||||
public function buildXML($data, $startElement = 'data')
|
||||
{
|
||||
if (!\is_array($data)) {
|
||||
$err = 'Invalid variable type supplied, expected array not found on line ' . __LINE__ . ' in Class: ' . __CLASS__ . ' Method: ' . __METHOD__;
|
||||
trigger_error($err);
|
||||
|
||||
return false; //return false error occurred
|
||||
}
|
||||
$xml = new XmlWriter();
|
||||
$xml->openMemory();
|
||||
$xml->startDocument($this->version, $this->encoding);
|
||||
$xml->startElement($startElement);
|
||||
$data = $this->writeAttr($xml, $data);
|
||||
$this->writeEl($xml, $data);
|
||||
$xml->endElement(); //write end element
|
||||
//returns the XML results
|
||||
return $xml->outputMemory(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write keys in $data prefixed with @ as XML attributes, if $data is an array.
|
||||
* When an @ prefixed key is found, a '%' key is expected to indicate the element itself,
|
||||
* and '#' prefixed key indicates CDATA content.
|
||||
*
|
||||
* @param XMLWriter $xml object
|
||||
* @param array $data with attributes filtered out
|
||||
*
|
||||
* @return array $data | $nonAttributes
|
||||
*/
|
||||
protected function writeAttr(XMLWriter $xml, $data)
|
||||
{
|
||||
if (\is_array($data)) {
|
||||
$nonAttributes = [];
|
||||
foreach ($data as $key => $val) {
|
||||
//handle an attribute with elements
|
||||
if ('@' == $key[0]) {
|
||||
$xml->writeAttribute(substr($key, 1), $val);
|
||||
} elseif ('%' == $key[0]) {
|
||||
if (\is_array($val)) {
|
||||
$nonAttributes = $val;
|
||||
} else {
|
||||
$xml->text($val);
|
||||
}
|
||||
} elseif ('#' == $key[0]) {
|
||||
if (\is_array($val)) {
|
||||
$nonAttributes = $val;
|
||||
} else {
|
||||
$xml->startElement(substr($key, 1));
|
||||
$xml->writeCData($val);
|
||||
$xml->endElement();
|
||||
}
|
||||
} elseif ('!' == $key[0]) {
|
||||
if (\is_array($val)) {
|
||||
$nonAttributes = $val;
|
||||
} else {
|
||||
$xml->writeCData($val);
|
||||
}
|
||||
} //ignore normal elements
|
||||
else {
|
||||
$nonAttributes[$key] = $val;
|
||||
}
|
||||
}
|
||||
|
||||
return $nonAttributes;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write XML as per Associative Array.
|
||||
*
|
||||
* @param XMLWriter $xml object
|
||||
* @param array $data Associative Data Array
|
||||
*/
|
||||
protected function writeEl(XMLWriter $xml, $data)
|
||||
{
|
||||
foreach ($data as $key => $value) {
|
||||
if (\is_array($value) && !$this->isAssoc($value)) { //numeric array
|
||||
foreach ($value as $itemValue) {
|
||||
if (\is_array($itemValue)) {
|
||||
$xml->startElement($key);
|
||||
$itemValue = $this->writeAttr($xml, $itemValue);
|
||||
$this->writeEl($xml, $itemValue);
|
||||
$xml->endElement();
|
||||
} else {
|
||||
$itemValue = $this->writeAttr($xml, $itemValue);
|
||||
$xml->writeElement($key, "{$itemValue}");
|
||||
}
|
||||
}
|
||||
} elseif (\is_array($value)) { //associative array
|
||||
$xml->startElement($key);
|
||||
$value = $this->writeAttr($xml, $value);
|
||||
$this->writeEl($xml, $value);
|
||||
$xml->endElement();
|
||||
} else { //scalar
|
||||
$value = $this->writeAttr($xml, $value);
|
||||
$xml->writeElement($key, "{$value}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if array is associative with string based keys
|
||||
* FROM: http://stackoverflow.com/questions/173400/php-arrays-a-good-way-to-check-if-an-array-is-associative-or-sequential/4254008#4254008.
|
||||
*
|
||||
* @param array $array Array to check
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isAssoc($array)
|
||||
{
|
||||
return (bool) \count(array_filter(array_keys($array), 'is_string'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
namespace AlibabaCloud\Dara\Util;
|
||||
|
||||
use AlibabaCloud\Dara\Exception\DaraException;
|
||||
|
||||
class BytesUtil
|
||||
{
|
||||
private static function is_bytes($value)
|
||||
{
|
||||
if (!\is_array($value)) {
|
||||
return false;
|
||||
}
|
||||
$i = 0;
|
||||
foreach ($value as $k => $ord) {
|
||||
if ($k !== $i) {
|
||||
return false;
|
||||
}
|
||||
if (!\is_int($ord)) {
|
||||
return false;
|
||||
}
|
||||
if ($ord < 0 || $ord > 255) {
|
||||
return false;
|
||||
}
|
||||
++$i;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function from($input, $encoding = 'utf-8')
|
||||
{
|
||||
$buffer = '';
|
||||
|
||||
if (self::is_bytes($input)) {
|
||||
return $input;
|
||||
} elseif (is_string($input)) {
|
||||
switch (strtolower($encoding)) {
|
||||
case 'utf-8':
|
||||
case 'utf8':
|
||||
$buffer = $input;
|
||||
break;
|
||||
case 'base64':
|
||||
$decoded = base64_decode($input);
|
||||
if ($decoded === false) {
|
||||
throw new DaraException([], 'Invalid base64 input.');
|
||||
}
|
||||
$buffer = $decoded;
|
||||
break;
|
||||
case 'hex':
|
||||
$decoded = hex2bin($input);
|
||||
if ($decoded === false) {
|
||||
throw new DaraException([], 'Invalid hex input.');
|
||||
}
|
||||
$buffer = $decoded;
|
||||
break;
|
||||
default:
|
||||
throw new DaraException([], 'Unsupported encoding type.');
|
||||
}
|
||||
} else {
|
||||
throw new DaraException([], 'Input must be an bytes or a string.');
|
||||
}
|
||||
|
||||
$result = [];
|
||||
for ($i = 0, $len = strlen($buffer); $i < $len; $i++) {
|
||||
$result[] = ord($buffer[$i]);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param int[] $bytes
|
||||
* @return string
|
||||
*/
|
||||
public static function toString($bytes, $type = 'utf8')
|
||||
{
|
||||
if (\is_string($bytes)) {
|
||||
return $bytes;
|
||||
}
|
||||
$str = '';
|
||||
foreach ($bytes as $ch) {
|
||||
$str .= \chr($ch);
|
||||
}
|
||||
|
||||
if($type == 'hex') {
|
||||
return bin2hex($str);
|
||||
}
|
||||
|
||||
if($type == 'base64') {
|
||||
return base64_encode($str);
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
109
addons/wdsxh/library/alibabacloud/darabonba/src/Util/Console.php
Normal file
109
addons/wdsxh/library/alibabacloud/darabonba/src/Util/Console.php
Normal file
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
namespace AlibabaCloud\Dara\Util;
|
||||
|
||||
use Monolog\Handler\AbstractProcessingHandler;
|
||||
use Monolog\Handler\StreamHandler;
|
||||
use Monolog\Logger;
|
||||
|
||||
/**
|
||||
* This is a console module.
|
||||
*/
|
||||
class Console
|
||||
{
|
||||
/**
|
||||
* @var Logger
|
||||
*/
|
||||
private static $loggerDriver;
|
||||
|
||||
/**
|
||||
* Console val with log level into stdout.
|
||||
*
|
||||
* @param string $val the printing string
|
||||
*
|
||||
* @throws \Exception
|
||||
*
|
||||
* @example \[LOG\] tea console example
|
||||
*/
|
||||
public static function log($val)
|
||||
{
|
||||
self::logger()->log(200, $val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Console val with info level into stdout.
|
||||
*
|
||||
* @param string $val the printing string
|
||||
*
|
||||
* @throws \Exception
|
||||
*
|
||||
* @example \[INFO\] tea console example
|
||||
*/
|
||||
public static function info($val)
|
||||
{
|
||||
self::logger()->info($val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Console val with warning level into stdout.
|
||||
*
|
||||
* @param string $val the printing string
|
||||
*
|
||||
* @throws \Exception
|
||||
*
|
||||
* @example \[WARNING\] tea console example
|
||||
*/
|
||||
public static function warning($val)
|
||||
{
|
||||
self::logger()->warning($val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Console val with debug level into stdout.
|
||||
*
|
||||
* @param string $val the printing string
|
||||
*
|
||||
* @throws \Exception
|
||||
*
|
||||
* @example \[DEBUG\] tea console example
|
||||
*/
|
||||
public static function debug($val)
|
||||
{
|
||||
self::logger()->debug($val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Console val with error level into stderr.
|
||||
*
|
||||
* @param string $val the printing string
|
||||
*
|
||||
* @throws \Exception
|
||||
*
|
||||
* @example \[ERROR\] tea console example
|
||||
*/
|
||||
public static function error($val)
|
||||
{
|
||||
self::logger()->error($val);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AbstractProcessingHandler $handler
|
||||
*/
|
||||
public static function pushHandler($handler)
|
||||
{
|
||||
self::$loggerDriver->pushHandler($handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Logger
|
||||
*/
|
||||
public static function logger()
|
||||
{
|
||||
if (null === self::$loggerDriver) {
|
||||
self::$loggerDriver = new Logger('tea-console-log');
|
||||
self::$loggerDriver->pushHandler(new StreamHandler('php://stderr', 0));
|
||||
}
|
||||
|
||||
return self::$loggerDriver;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,330 @@
|
||||
<?php
|
||||
|
||||
namespace AlibabaCloud\Dara\Util;
|
||||
|
||||
use AlibabaCloud\Dara\Models\FileField;
|
||||
use GuzzleHttp\Psr7\Stream;
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @coversNothing
|
||||
*/
|
||||
class FileFormStream implements StreamInterface
|
||||
{
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
private $stream;
|
||||
private $index = 0;
|
||||
private $form = [];
|
||||
private $boundary = '';
|
||||
private $streaming = false;
|
||||
private $keys = [];
|
||||
|
||||
/**
|
||||
* @var Stream
|
||||
*/
|
||||
private $currStream;
|
||||
|
||||
private $size;
|
||||
private $uri;
|
||||
private $seekable;
|
||||
private $readable = true;
|
||||
private $writable = true;
|
||||
|
||||
public function __construct($map, $boundary)
|
||||
{
|
||||
$this->stream = fopen('php://memory', 'a+');
|
||||
$this->form = $map;
|
||||
$this->boundary = $boundary;
|
||||
$this->keys = array_keys($map);
|
||||
do {
|
||||
$read = $this->readForm(1024);
|
||||
} while (null !== $read);
|
||||
$meta = stream_get_meta_data($this->stream);
|
||||
$this->seekable = $meta['seekable'];
|
||||
$this->uri = $this->getMetadata('uri');
|
||||
$this->seek(0);
|
||||
$this->seek(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the stream when the destructed.
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$this->close();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
try {
|
||||
$this->seek(0);
|
||||
|
||||
return (string) stream_get_contents($this->stream);
|
||||
} catch (\Exception $e) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $length
|
||||
*
|
||||
* @return false|int|string
|
||||
*/
|
||||
public function readForm($length)
|
||||
{
|
||||
if ($this->streaming) {
|
||||
if (null !== $this->currStream) {
|
||||
// @var string $content
|
||||
$content = $this->currStream->read($length);
|
||||
if (false !== $content && '' !== $content) {
|
||||
fwrite($this->stream, $content);
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
return $this->next("\r\n");
|
||||
}
|
||||
|
||||
return $this->next();
|
||||
}
|
||||
$keysCount = \count($this->keys);
|
||||
if ($this->index > $keysCount) {
|
||||
return null;
|
||||
}
|
||||
if ($keysCount > 0) {
|
||||
if ($this->index < $keysCount) {
|
||||
$this->streaming = true;
|
||||
|
||||
$name = $this->keys[$this->index];
|
||||
$field = $this->form[$name];
|
||||
if (!empty($field) && $field instanceof FileField) {
|
||||
if (!empty($field->content)) {
|
||||
$this->currStream = $field->content;
|
||||
|
||||
$str = '--' . $this->boundary . "\r\n" .
|
||||
'Content-Disposition: form-data; name="' . $name . '"; filename="' . $field->filename . "\"\r\n" .
|
||||
'Content-Type: ' . $field->contentType . "\r\n\r\n";
|
||||
$this->write($str);
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
return $this->next();
|
||||
}
|
||||
$val = $field;
|
||||
$str = '--' . $this->boundary . "\r\n" .
|
||||
'Content-Disposition: form-data; name="' . $name . "\"\r\n\r\n" .
|
||||
$val . "\r\n";
|
||||
fwrite($this->stream, $str);
|
||||
|
||||
return $str;
|
||||
}
|
||||
if ($this->index == $keysCount) {
|
||||
return $this->next('--' . $this->boundary . "--\r\n");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getContents()
|
||||
{
|
||||
if (!isset($this->stream)) {
|
||||
throw new \RuntimeException('Stream is detached');
|
||||
}
|
||||
|
||||
$contents = stream_get_contents($this->stream);
|
||||
|
||||
if (false === $contents) {
|
||||
throw new \RuntimeException('Unable to read stream contents');
|
||||
}
|
||||
|
||||
return $contents;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
if (isset($this->stream)) {
|
||||
if (\is_resource($this->stream)) {
|
||||
fclose($this->stream);
|
||||
}
|
||||
$this->detach();
|
||||
}
|
||||
}
|
||||
|
||||
public function detach()
|
||||
{
|
||||
if (!isset($this->stream)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$result = $this->stream;
|
||||
unset($this->stream);
|
||||
$this->size = $this->uri = null;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getSize()
|
||||
{
|
||||
if (null !== $this->size) {
|
||||
return $this->size;
|
||||
}
|
||||
|
||||
if (!isset($this->stream)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Clear the stat cache if the stream has a URI
|
||||
if ($this->uri) {
|
||||
clearstatcache(true, $this->uri);
|
||||
}
|
||||
|
||||
$stats = fstat($this->stream);
|
||||
if (isset($stats['size'])) {
|
||||
$this->size = $stats['size'];
|
||||
|
||||
return $this->size;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function isReadable()
|
||||
{
|
||||
return $this->readable;
|
||||
}
|
||||
|
||||
public function isWritable()
|
||||
{
|
||||
return $this->writable;
|
||||
}
|
||||
|
||||
public function isSeekable()
|
||||
{
|
||||
return $this->seekable;
|
||||
}
|
||||
|
||||
public function eof()
|
||||
{
|
||||
if (!isset($this->stream)) {
|
||||
throw new \RuntimeException('Stream is detached');
|
||||
}
|
||||
|
||||
return feof($this->stream);
|
||||
}
|
||||
|
||||
public function tell()
|
||||
{
|
||||
if (!isset($this->stream)) {
|
||||
throw new \RuntimeException('Stream is detached');
|
||||
}
|
||||
|
||||
$result = ftell($this->stream);
|
||||
|
||||
if (false === $result) {
|
||||
throw new \RuntimeException('Unable to determine stream position');
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function rewind()
|
||||
{
|
||||
$this->seek(0);
|
||||
}
|
||||
|
||||
public function seek($offset, $whence = SEEK_SET)
|
||||
{
|
||||
$whence = (int) $whence;
|
||||
|
||||
if (!isset($this->stream)) {
|
||||
throw new \RuntimeException('Stream is detached');
|
||||
}
|
||||
if (!$this->seekable) {
|
||||
throw new \RuntimeException('Stream is not seekable');
|
||||
}
|
||||
if (-1 === fseek($this->stream, $offset, $whence)) {
|
||||
throw new \RuntimeException('Unable to seek to stream position ' . $offset . ' with whence ' . var_export($whence, true));
|
||||
}
|
||||
}
|
||||
|
||||
public function read($length)
|
||||
{
|
||||
if (!isset($this->stream)) {
|
||||
throw new \RuntimeException('Stream is detached');
|
||||
}
|
||||
if (!$this->readable) {
|
||||
throw new \RuntimeException('Cannot read from non-readable stream');
|
||||
}
|
||||
if ($length < 0) {
|
||||
throw new \RuntimeException('Length parameter cannot be negative');
|
||||
}
|
||||
|
||||
if (0 === $length) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$string = fread($this->stream, $length);
|
||||
if (false === $string) {
|
||||
throw new \RuntimeException('Unable to read from stream');
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
public function write($string)
|
||||
{
|
||||
if (!isset($this->stream)) {
|
||||
throw new \RuntimeException('Stream is detached');
|
||||
}
|
||||
if (!$this->writable) {
|
||||
throw new \RuntimeException('Cannot write to a non-writable stream');
|
||||
}
|
||||
|
||||
// We can't know the size after writing anything
|
||||
$this->size = null;
|
||||
$result = fwrite($this->stream, $string);
|
||||
|
||||
if (false === $result) {
|
||||
throw new \RuntimeException('Unable to write to stream');
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getMetadata($key = null)
|
||||
{
|
||||
if (!isset($this->stream)) {
|
||||
return $key ? null : [];
|
||||
}
|
||||
|
||||
$meta = stream_get_meta_data($this->stream);
|
||||
|
||||
return isset($meta[$key]) ? $meta[$key] : null;
|
||||
}
|
||||
|
||||
private function next($endStr = '')
|
||||
{
|
||||
$this->streaming = false;
|
||||
++$this->index;
|
||||
$this->write($endStr);
|
||||
$this->currStream = null;
|
||||
|
||||
return $endStr;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user