Test Failed
Push — master ( c3510e...e80ff5 )
by frey
03:59
created

src/Plugins/GetFederationToken.php (1 issue)

Labels
Severity
1
<?php
2
3
namespace Freyo\Flysystem\QcloudCOSv5\Plugins;
4
5
use League\Flysystem\Plugin\AbstractPlugin;
6
7
class GetFederationToken extends AbstractPlugin
8
{
9
    /**
10
     * Get the method name.
11
     *
12
     * @return string
13
     */
14
    public function getMethod()
15
    {
16
        return 'getFederationToken';
17
    }
18
19
    /**
20
     * @param string $path
21
     * @param int $seconds
22
     * @param callable $customPolicy
23
     * @param string $name
24
     *
25
     * @return bool|array
26
     */
27
    public function handle($path = '', $seconds = 7200, callable $customPolicy = null, $name = 'cos')
28
    {
29
        $policy = is_callable($customPolicy)
30
            ? $this->getCustomPolicy($customPolicy, $path)
0 ignored issues
show
It seems like $customPolicy can also be of type null; however, parameter $callable of Freyo\Flysystem\QcloudCO...oken::getCustomPolicy() does only seem to accept callable, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

30
            ? $this->getCustomPolicy(/** @scrutinizer ignore-type */ $customPolicy, $path)
Loading history...
31
            : $this->getPolicy($path);
32
33
        $params = [
34
            'durationSeconds' => $seconds,
35
            'name' => $name,
36
            'policy' => urlencode($policy)
37
        ];
38
39
        return $this->request($params, 'GetFederationToken');
40
    }
41
42
    /**
43
     * @param callable $callable
44
     * @param $path
45
     *
46
     * @return string
47
     */
48
    protected function getCustomPolicy(callable $callable, $path)
49
    {
50
        $policy = call_user_func($callable, $path, $this->getConfig());
51
52
        return json_encode($policy, JSON_UNESCAPED_SLASHES);
53
    }
54
55
    /**
56
     * @param $path
57
     *
58
     * @return string
59
     */
60
    protected function getPolicy($path)
61
    {
62
        $appId = $this->getCredentials()['appId'];
63
64
        $region = $this->getConfig()->get('region');
65
        $bucket = $this->getConfig()->get('bucket');
66
67
        $policy = [
68
            'version' => '2.0',
69
            'statement' => [
70
                'action' => [
71
                    // 简单上传
72
                    'name/cos:PutObject',
73
                    // 分片上传操作
74
                    'name/cos:InitiateMultipartUpload',
75
                    'name/cos:ListMultipartUploads',
76
                    'name/cos:ListParts',
77
                    'name/cos:UploadPart',
78
                    'name/cos:CompleteMultipartUpload',
79
                ],
80
                'effect' => 'allow',
81
                'principal' => ['qcs' => ['*']],
82
                'resource' => [
83
                    "qcs::cos:$region:uid/$appId:prefix//$appId/$bucket/",
84
                    "qcs::cos:$region:uid/$appId:prefix//$appId/$bucket/$path",
85
                ],
86
            ],
87
        ];
88
89
        return json_encode($policy, JSON_UNESCAPED_SLASHES);
90
    }
91
92
    /**
93
     * @return \League\Flysystem\Config
94
     */
95
    protected function getConfig()
96
    {
97
        return $this->filesystem->getConfig();
98
    }
99
100
    /**
101
     * @return array
102
     */
103
    protected function getCredentials()
104
    {
105
        return $this->getConfig()->get('credentials');
106
    }
107
108
    /**
109
     * @param array $args
110
     * @param $action
111
     *
112
     * @return bool|array
113
     */
114
    protected function request(array $args, $action)
115
    {
116
        $client = $this->getHttpClient();
117
118
        $response = $client->post('/v2/index.php', [
119
            'form_params' => $this->buildFormParams($args, $action),
120
        ]);
121
122
        $contents = $response->getBody()->getContents();
123
124
        return $this->normalize($contents);
125
    }
126
127
    /**
128
     * @return \GuzzleHttp\Client
129
     */
130
    protected function getHttpClient()
131
    {
132
        return new \GuzzleHttp\Client([
133
            'verify' => false,
134
            'base_uri' => 'https://sts.api.qcloud.com',
135
        ]);
136
    }
137
138
    /**
139
     * @param array $params
140
     * @param string $action
141
     *
142
     * @return array
143
     */
144
    protected function buildFormParams(array $params, $action)
145
    {
146
        $params = $this->addCommonParams($params, $action);
147
148
        return $this->addSignature($params);
149
    }
150
151
    /**
152
     * @param array $params
153
     * @param string $action
154
     *
155
     * @return array
156
     */
157
    protected function addCommonParams(array $params, $action)
158
    {
159
        return array_merge([
160
            'Region' => $this->getConfig()->get('region'),
161
            'Action' => $action,
162
            'SecretId' => $this->getCredentials()['secretId'],
163
            'Timestamp' => time(),
164
            'Nonce' => rand(1, 65535),
165
        ], $params);
166
    }
167
168
    /**
169
     * @param array $params
170
     *
171
     * @return array
172
     */
173
    protected function addSignature(array $params)
174
    {
175
        $params['Signature'] = $this->getSignature($params);
176
177
        return $params;
178
    }
179
180
    /**
181
     * @param array $params
182
     *
183
     * @return string
184
     */
185
    protected function getSignature(array $params)
186
    {
187
        ksort($params);
188
189
        $srcStr = 'POSTsts.api.qcloud.com/v2/index.php?' . urldecode(http_build_query($params));
190
191
        return base64_encode(hash_hmac('sha1', $srcStr, $this->getCredentials()['secretKey'], true));
192
    }
193
194
    /**
195
     * @param string $contents
196
     *
197
     * @return bool|array
198
     */
199
    protected function normalize($contents)
200
    {
201
        $data = json_decode($contents, true);
202
203
        if (json_last_error() !== JSON_ERROR_NONE || $data['code'] !== 0) {
204
            return false;
205
        }
206
207
        return $data['data'];
208
    }
209
}
210