Initial commit: queue workspace

Made-with: Cursor
This commit is contained in:
apple
2026-03-21 02:55:24 +08:00
commit 78de918c37
12388 changed files with 1840126 additions and 0 deletions

View File

@@ -0,0 +1,7 @@
composer.phar
/vendor/
.idea/
# Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#commit-your-composer-lock-file-to-version-control
# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
# composer.lock

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 腾讯云
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,109 @@
## 获取 SDK
- composer 安装
```
创建composer.json的文件内容如下
{
"require":{
"qcloud_sts/qcloud-sts-sdk": "3.0.*"
}
}
```
## 查看示例
请查看 [demo 示例](https://github.com/tencentyun/qcloud-cos-sts-sdk/tree/master/php/demo)里面描述了如何调用SDK。
## 接口说明
### getTempKeys
获取临时密钥接口
### 参数说明
|字段|类型|描述|
| ---- | ---- | ---- |
|secretId|string| 云 API 密钥 Id|
|secretKey|string| 云 API 密钥 key|
|durationSeconds|long| 要申请的临时密钥最长有效时间,单位秒,默认 1800最大可设置 7200 |
|bucket|string| 存储桶名称bucketName-appid, 如 test-125000000|
|region|string| 存储桶所属地域,如 ap-guangzhou|
|allowPrefix|string|资源的前缀,如授予操作所有资源,则为`*`如授予操作某个路径a下的所有资源,则为 `a/*`如授予只能操作特定的文件a/test.jpg, 则为`a/test.jpg`|
|allowActions|array| 授予 COS API 权限集合, 如简单上传操作name/cos:PutObject|
|policy|array| 策略:由 allowActions、bucket、region、allowPrefix字段组成的描述授权的具体信息|
### 返回值说明
|字段|类型|描述|
| ---- | ---- | ---- |
|credentials | string | 临时密钥信息 |
|tmpSecretId | string | 临时密钥 Id可用于计算签名 |
|tmpSecretKey | string | 临时密钥 Key可用于计算签名 |
|sessionToken | string | 请求时需要用的 token 字符串,最终请求 COS API 时,需要放在 Header 的 x-cos-security-token 字段 |
|startTime | string | 密钥的起始时间,是 UNIX 时间戳 |
|expiredTime | string | 密钥的失效时间,是 UNIX 时间戳 |
### 返回数据示例
```
{
"expiredTime": 1589258683,
"expiration": "2020-05-12T04:44:43Z",
"credentials": {
"sessionToken": "Biypn6exa48PpMe7wFerEnNMpBKKPQo180c57e0a5275ebae506d7851a85f36a4P0TV5UFR3FYJjsoZA1tk6uRKoDRzc6-60BmwLqdS75OhjHEa7GlVYpL_ofKQJTpPKziKX7FnI10D_6qtLdjzf2NdsyUtQEd5kPpDCOQJZn9-BpleqWQe8oyH_2u7xi2f0FtjCYaoGIZ_lUqlILXQwr0B0t3hLfL4xNE-EmVjUlUXa16HxVCn4_hJetqo9LmI0AgLOjCbYx9aVrsV10eDsRta-TQSIXmJNP3aJ6oz8d8GBTgTE1I2qSFDnv9pjtQKW8HZWI_glPIfmHXCCwAESxEFL_owGz839Va0qYhF6LkfVmsuoU1zNcvJR1w3cIE6izV3SKHaOtWaew3IOervuOPoN3S2oYGNwv2EavtDAWyUBIeI7X6nMVzlpnyJ-3bkIhOq9QVIQAs8wh5A0u9mvKWugT5t6qgyEgvEZSj9k6p-JjwxMgLC6s5uK1i_nnf4fN7ZQ6I-JAfHnH4jEDiVtJgXqfuWPX_vnzskyR2Co6E",
"tmpSecretId": "AKIDTRPc-oe6c_avPSRwFVsPDyy3IoAr3szMajlOGuoEXY1232YLy6j4f-xZ5zL-NBMG",
"tmpSecretKey": "2v29SZztGYk6SGwHYm\/chJXdD3zPRFasmPoJiCmlR\/I="
},
"requestId": "69ef6295-b981-464d-9816-9c2ef92189d1",
"startTime": 1589256883
}
```
### getRoleCredential
申请扮演角色
### 参数说明
|字段|类型|描述|必选|
| ---- | ---- | ---- | ----|
|roleArn|string|角色的资源描述,可在 [访问管理](https://console.cloud.tencent.com/cam/role) 点击角色名获取。| 是 |
|secretId|string| 云 API 密钥 Id| 是 |
|secretKey|string| 云 API 密钥 key| 是 |
|endpoint|string| 接入点,内网填写"internal.tencentcloudapi.com",外网填写"tencentcloudapi.com"| 是 |
|durationSeconds|long| 要申请的临时密钥最长有效时间,单位秒,默认 1800最大可设置 7200 | 否 |
|bucket|string| 存储桶名称bucketName-appid, 如 test-125000000| 是 |
|region|string| 存储桶所属地域,如 ap-guangzhou| 是 |
|allowPrefix|string|资源的前缀,如授予操作所有资源,则为`*`如授予操作某个路径a下的所有资源,则为 `a/*`如授予只能操作特定的文件a/test.jpg, 则为`a/test.jpg`| 是 |
|allowActions|array| 授予 COS API 权限集合, 如简单上传操作name/cos:PutObject| 是 |
|policy|array| 策略:由 allowActions、bucket、region、allowPrefix字段组成的描述授权的具体信息| 否 |
|externalId|string| 角色外部ID| 否 |
### 返回值说明
|字段|类型|描述|
| ---- | ---- | ---- |
|credentials | string | 临时密钥信息 |
|tmpSecretId | string | 临时密钥 Id可用于计算签名 |
|tmpSecretKey | string | 临时密钥 Key可用于计算签名 |
|sessionToken | string | 请求时需要用的 token 字符串,最终请求 COS API 时,需要放在 Header 的 x-cos-security-token 字段 |
|startTime | string | 密钥的起始时间,是 UNIX 时间戳 |
|expiredTime | string | 密钥的失效时间,是 UNIX 时间戳 |
### 返回数据示例
```
{
"Response": {
"Credentials": {
"Token": "da1e9d2ee9dda83506832d5ecb903b790132dfe340001",
"TmpSecretId": "AKID65zyIP0mpXtaI******WIQVMn1umNH58",
"TmpSecretKey": "q95K84wrzuEGoc*******52boxvp71yoh"
},
"ExpiredTime": 1543914376,
"Expiration": "2018-12-04T09:06:16Z",
"RequestId": "4daec797-9cd2-4f09-9e7a-7d4c43b2a74c"
}
}
```

View File

@@ -0,0 +1,28 @@
{
"name": "qcloud_sts/qcloud-sts-sdk",
"description": "PHP SDK for QCloud STS",
"keywords": [
"qcloud", "sts", "cos", "php"
],
"homepage": "https://github.com/tencentyun/qcloud-cos-sts-sdk",
"license": "MIT",
"authors": [
{
"name": "qcloudterminal",
"email": "qcloudterminal@gmail.com"
},
{
"name": "tuunalai",
"email": "550566181@qq.com"
}
],
"autoload": {
"psr-4": {
"QCloud\\COSSTS\\": "src"
}
},
"require": {
"php": ">=5.3.0",
"ext-curl": "*"
}
}

View File

@@ -0,0 +1,59 @@
<?php
namespace QCloud\COSSTS;
class Scope{
var $action;
var $bucket;
var $region;
var $resourcePrefix;
var $effect = 'allow';
function __construct($action, $bucket, $region, $resourcePrefix){
$this->action = $action;
$this->bucket = $bucket;
$this->region = $region;
$this->resourcePrefix = $resourcePrefix;
}
function set_effect($isAllow){
if($isAllow){
$this->effect = 'allow';
}else{
$this->effect = 'deny';
}
}
function get_action(){
if($this->action == null){
throw new \Exception("action == null");
}
return $this->action;
}
function get_resource(){
if($this->bucket == null){
throw new \Exception("bucket == null");
}
if($this->region == null){
throw new \Exception("region == null");
}
if($this->resourcePrefix == null){
throw new \Exception("resourcePrefix == null");
}
$index = strripos($this->bucket, '-');
if($index < 0){
throw new Exception("bucket is invalid: " . $this->bucket);
}
$appid = substr($this->bucket, $index + 1);
if(!(strpos($this->resourcePrefix, '/') === 0)){
$this->resourcePrefix = '/' . $this->resourcePrefix;
}
return 'qcs::cos:' . $this->region . ':uid/' . $appid . ':' . $this->bucket . $this->resourcePrefix;
}
function get_effect(){
return $this->effect;
}
}
?>

View File

@@ -0,0 +1,298 @@
<?php
namespace QCloud\COSSTS;
class Sts{
// 临时密钥计算样例
function _hex2bin($data) {
$len = strlen($data);
return pack("H" . $len, $data);
}
// obj 转 query string
function json2str($obj, $notEncode = false) {
ksort($obj);
$arr = array();
if(!is_array($obj)){
throw new \Exception('$obj must be an array, the actual value is:' . json_encode($obj));
}
foreach ($obj as $key => $val) {
array_push($arr, $key . '=' . ($notEncode ? $val : rawurlencode($val)));
}
return join('&', $arr);
}
// 计算临时密钥用的签名
function getSignature($opt, $key, $method, $config) {
$host = "sts.tencentcloudapi.com";
if (array_key_exists('domain', $config)) {
$host = $config['domain'];
}
if (array_key_exists('endpoint', $config)) {
$host = "sts." . $config['endpoint'];
}
$formatString = $method . $host . '/?' . $this->json2str($opt, 1);
$sign = hash_hmac('sha1', $formatString, $key);
$sign = base64_encode($this->_hex2bin($sign));
return $sign;
}
// v2接口的key首字母小写v3改成大写此处做了向下兼容
function backwardCompat($result) {
if(!is_array($result)){
throw new \Exception('$result must be an array, the actual value is:' . json_encode($result));
}
$compat = array();
foreach ($result as $key => $value) {
if(is_array($value)) {
$compat[lcfirst($key)] = $this->backwardCompat($value);
} elseif ($key == 'Token') {
$compat['sessionToken'] = $value;
} else {
$compat[lcfirst($key)] = $value;
}
}
return $compat;
}
// 获取临时密钥
function getTempKeys($config) {
$result = null;
try{
if(array_key_exists('policy', $config)){
$policy = $config['policy'];
}else{
if(array_key_exists('bucket', $config)){
$ShortBucketName = substr($config['bucket'],0, strripos($config['bucket'], '-'));
$AppId = substr($config['bucket'], 1 + strripos($config['bucket'], '-'));
}else{
throw new \Exception("bucket== null");
}
if(array_key_exists('allowPrefix', $config)){
if(!(strpos($config['allowPrefix'], '/') === 0)){
$config['allowPrefix'] = '/' . $config['allowPrefix'];
}
}else{
throw new \Exception("allowPrefix == null");
}
if(!array_key_exists('region', $config)) {
throw new \Exception("region == null");
}
$policy = array(
'version'=> '2.0',
'statement'=> array(
array(
'action'=> $config['allowActions'],
'effect'=> 'allow',
'resource'=> array(
'qcs::cos:' . $config['region'] . ':uid/' . $AppId . ':' . $config['bucket'] . $config['allowPrefix']
)
)
)
);
}
$policyStr = str_replace('\\/', '/', json_encode($policy));
$Action = 'GetFederationToken';
$Nonce = rand(10000, 20000);
$Timestamp = time();
$Method = 'POST';
if(array_key_exists('durationSeconds', $config)){
if(!(is_integer($config['durationSeconds']))){
throw new \Exception("durationSeconds must be a int type");
}
}
$params = array(
'SecretId'=> $config['secretId'],
'Timestamp'=> $Timestamp,
'Nonce'=> $Nonce,
'Action'=> $Action,
'DurationSeconds'=> $config['durationSeconds'],
'Version'=>'2018-08-13',
'Name'=> 'cos',
'Region'=> $config['region'],
'Policy'=> urlencode($policyStr)
);
$params['Signature'] = $this->getSignature($params, $config['secretKey'], $Method, $config);
$url = 'https://sts.tencentcloudapi.com/';
if(array_key_exists('url', $config)) {
$url = $config['url'];
}
if(!array_key_exists('url', $config) && array_key_exists('domain', $config)) {
$url = 'https://sts.' . $config['domain'];
}
if(array_key_exists('endpoint', $config)) {
$url = 'https://sts.' . $config['endpoint'];
}
$ch = curl_init($url);
if(array_key_exists('proxy', $config)){
$config['proxy'] && curl_setopt($ch, CURLOPT_PROXY, $config['proxy']);
}
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,0);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $this->json2str($params));
$result = curl_exec($ch);
if(curl_errno($ch)) $result = curl_error($ch);
curl_close($ch);
$result = json_decode($result, 1);
if (isset($result['Response'])) {
$result = $result['Response'];
if(isset($result['Error'])){
throw new \Exception("get cam failed");
}
$result['startTime'] = $result['ExpiredTime'] - $config['durationSeconds'];
}
$result = $this->backwardCompat($result);
return $result;
}catch(\Exception $e){
if($result == null){
$result = "error: " . $e->getMessage();
}else{
$result = json_encode($result);
}
throw new \Exception($result);
}
}
//申请角色授权
function getRoleCredential($config) {
$result = null;
try{
if(array_key_exists('policy', $config)){
$policy = $config['policy'];
}else{
if(array_key_exists('bucket', $config)){
$ShortBucketName = substr($config['bucket'],0, strripos($config['bucket'], '-'));
$AppId = substr($config['bucket'], 1 + strripos($config['bucket'], '-'));
}else{
throw new \Exception("bucket== null");
}
if(array_key_exists('allowPrefix', $config)){
if(!(strpos($config['allowPrefix'], '/') === 0)){
$config['allowPrefix'] = '/' . $config['allowPrefix'];
}
}else{
throw new \Exception("allowPrefix == null");
}
if(!array_key_exists('region', $config)) {
throw new \Exception("region == null");
}
$policy = array(
'version'=> '2.0',
'statement'=> array(
array(
'action'=> $config['allowActions'],
'effect'=> 'allow',
'resource'=> array(
'qcs::cos:' . $config['region'] . ':uid/' . $AppId . ':' . $config['bucket'] . $config['allowPrefix']
)
)
)
);
}
if (array_key_exists('roleArn', $config)) {
$RoleArn = $config['roleArn'];
} else {
throw new \Exception("roleArn == null");
}
$policyStr = str_replace('\\/', '/', json_encode($policy));
$Action = 'AssumeRole';
$Nonce = rand(10000, 20000);
$Timestamp = time();
$Method = 'POST';
$ExternalId = "";
if (array_key_exists('externalId', $config)) {
$ExternalId = $config['externalId'];
}
if(array_key_exists('durationSeconds', $config)){
if(!(is_integer($config['durationSeconds']))){
throw new \Exception("durationSeconds must be a int type");
}
}
$params = array(
'SecretId'=> $config['secretId'],
'Timestamp'=> $Timestamp,
'RoleArn'=> $RoleArn,
'Action'=> $Action,
'Nonce'=> $Nonce,
'DurationSeconds'=> $config['durationSeconds'],
'Version'=>'2018-08-13',
'RoleSessionName'=> 'cos',
'Region'=> $config['region'],
'ExternalId' => $ExternalId,
'Policy'=> urlencode($policyStr)
);
$params['Signature'] = $this->getSignature($params, $config['secretKey'], $Method, $config);
$url = 'https://sts.internal.tencentcloudapi.com/';
if(array_key_exists('endpoint', $config)) {
$url = 'https://sts.' . $config['endpoint'];
}
$ch = curl_init($url);
if(array_key_exists('proxy', $config)){
$config['proxy'] && curl_setopt($ch, CURLOPT_PROXY, $config['proxy']);
}
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,0);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $this->json2str($params));
$result = curl_exec($ch);
if(curl_errno($ch)) $result = curl_error($ch);
curl_close($ch);
$result = json_decode($result, 1);
if (isset($result['Response'])) {
$result = $result['Response'];
if(isset($result['Error'])){
throw new \Exception("get cam failed");
}
$result['startTime'] = $result['ExpiredTime'] - $config['durationSeconds'];
}
$result = $this->backwardCompat($result);
return $result;
}catch(\Exception $e){
if($result == null){
$result = "error: " . $e->getMessage();
}else{
$result = json_encode($result);
}
throw new \Exception($result);
}
}
// get policy
function getPolicy($scopes){
if (!is_array($scopes)){
return null;
}
$statements = array();
for($i=0, $counts=count($scopes); $i < $counts; $i++){
$actions=array();
$resources = array();
array_push($actions, $scopes[$i]->get_action());
array_push($resources, $scopes[$i]->get_resource());
$statement = array(
'action' => $actions,
'effect' => $scopes[$i]->get_effect(),
'resource' => $resources
);
array_push($statements, $statement);
}
$policy = array(
'version' => '2.0',
'statement' => $statements
);
return $policy;
}
}
?>