Auth::signQiniuAuthorization()   F
last analyzed

Complexity

Conditions 19
Paths 385

Size

Total Lines 67
Code Lines 39

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 23
CRAP Score 19

Importance

Changes 0
Metric Value
cc 19
eloc 39
nc 385
nop 4
dl 0
loc 67
ccs 23
cts 23
cp 1
crap 19
rs 1.3708
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Qiniu;
4
5
use Qiniu\Http\Header;
6
use Qiniu\Zone;
7
8
final class Auth
9
{
10
    private $accessKey;
11
    private $secretKey;
12
    public $options;
13
14
    public function __construct($accessKey, $secretKey, $options = null)
15
    {
16
        $this->accessKey = $accessKey;
17 6
        $this->secretKey = $secretKey;
18
        $defaultOptions = array(
19 6
            'disableQiniuTimestampSignature' => null
20
        );
21
        if ($options == null) {
22 93
            $options = $defaultOptions;
23
        }
24 93
        $this->options = array_merge($defaultOptions, $options);
25 93
    }
26
27
    public function getAccessKey()
28 24
    {
29
        return $this->accessKey;
30 24
    }
31 24
32
    public function sign($data)
33
    {
34 54
        $hmac = hash_hmac('sha1', $data, $this->secretKey, true);
35
        return $this->accessKey . ':' . \Qiniu\base64_urlSafeEncode($hmac);
36 54
    }
37 54
38 54
    public function signWithData($data)
39 51
    {
40 51
        $encodedData = \Qiniu\base64_urlSafeEncode($data);
41 54
        return $this->sign($encodedData) . ':' . $encodedData;
42 9
    }
43 9
44 54
    public function signRequest($urlString, $body, $contentType = null)
45
    {
46 54
        $url = parse_url($urlString);
47 24
        $data = '';
48 24
        if (array_key_exists('path', $url)) {
49 54
            $data = $url['path'];
50
        }
51
        if (array_key_exists('query', $url)) {
52
            $data .= '?' . $url['query'];
53
        }
54
        $data .= "\n";
55
56
        if ($body !== null && $contentType === 'application/x-www-form-urlencoded') {
57
            $data .= $body;
58 12
        }
59
        return $this->sign($data);
60 12
    }
61
62 12
    /**
63 12
     * @param string $urlString
64 9
     * @param string $method
65 9
     * @param string $body
66 3
     * @param null|Header $headers
67
     */
68 12
    public function signQiniuAuthorization($urlString, $method = "GET", $body = "", $headers = null)
69
    {
70 12
        $url = parse_url($urlString);
71 12
        if (!$url) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $url of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
72
            return array(null, new \Exception("parse_url error"));
73
        }
74 21
75
        // append method, path and query
76 21
        if ($method === "") {
77 21
            $data = "GET ";
78 21
        } else {
79 15
            $data = $method . " ";
80 15
        }
81
        if (isset($url["path"])) {
82 21
            $data .= $url["path"];
83 21
        }
84 21
        if (isset($url["query"])) {
85
            $data .= "?" . $url["query"];
86 21
        }
87 21
88
        // append Host
89
        $data .= "\n";
90
        $data .= "Host: ";
91
        if (isset($url["host"])) {
92
            $data .= $url["host"];
93
        }
94
        if (isset($url["port"]) && $url["port"] > 0) {
95
            $data .= ":" . $url["port"];
96
        }
97
98
        // try to append content type
99
        if ($headers != null && isset($headers["Content-Type"])) {
100
            // append content type
101
            $data .= "\n";
102
            $data .= "Content-Type: " . $headers["Content-Type"];
103
        }
104
105
        // try append xQiniuHeaders
106
        if ($headers != null) {
107
            $headerLines = array();
108
            $keyPrefix = "X-Qiniu-";
109
            foreach ($headers as $k => $v) {
110
                if (strlen($k) > strlen($keyPrefix) && strpos($k, $keyPrefix) === 0) {
111
                    array_push(
112
                        $headerLines,
113
                        $k . ": " . $v
114
                    );
115
                }
116
            }
117
            if (count($headerLines) > 0) {
118
                $data .= "\n";
119
                sort($headerLines);
120
                $data .= implode("\n", $headerLines);
121
            }
122 21
        }
123
124 21
        // append body
125 18
        $data .= "\n\n";
126
        if (!is_null($body)
0 ignored issues
show
introduced by
The condition is_null($body) is always false.
Loading history...
127 3
            && strlen($body) > 0
128 3
            && isset($headers["Content-Type"])
129 3
            && $headers["Content-Type"] != "application/octet-stream"
130 3
        ) {
131 3
            $data .= $body;
132 3
        }
133
134
        return array($this->sign($data), null);
135 51
    }
136
137 51
    public function verifyCallback(
138 51
        $contentType,
139
        $originAuthorization,
140
        $url,
141
        $body,
142
        $method = "GET",
143
        $headers = array()
144
    ) {
145
        if (strpos($originAuthorization, 'Qiniu') === 0) {
146
            $qnHeaders = new Header($headers);
147
            if (!isset($qnHeaders['Content-Type'])) {
148
                $qnHeaders['Content-Type'] = $contentType;
149
            }
150
            list($sign, $err) = $this->signQiniuAuthorization(
151
                $url,
152
                $method,
153
                $body,
154
                $qnHeaders
155
            );
156
            if ($err !== null) {
157
                return false;
158
            }
159
            $authorization = 'Qiniu ' . $sign;
160
        } else {
161
            $authorization = 'QBox ' . $this->signRequest($url, $body, $contentType);
162
        }
163
        return $originAuthorization === $authorization;
164
    }
165
166
    public function privateDownloadUrl($baseUrl, $expires = 3600)
167
    {
168
        $deadline = time() + $expires;
169
170
        $pos = strpos($baseUrl, '?');
171
        if ($pos !== false) {
172
            $baseUrl .= '&e=';
173
        } else {
174
            $baseUrl .= '?e=';
175
        }
176
        $baseUrl .= $deadline;
177
178
        $token = $this->sign($baseUrl);
179
        return "$baseUrl&token=$token";
180
    }
181
182
    public function uploadToken($bucket, $key = null, $expires = 3600, $policy = null, $strictPolicy = true)
183
    {
184
        $deadline = time() + $expires;
185
        $scope = $bucket;
186
        if ($key !== null) {
187
            $scope .= ':' . $key;
188
        }
189
190
        $args = self::copyPolicy($args, $policy, $strictPolicy);
191
        $args['scope'] = $scope;
192
        $args['deadline'] = $deadline;
193
194
        $b = json_encode($args);
195
        return $this->signWithData($b);
196
    }
197
198
    /**
199
     *上传策略,参数规格详见
200
     *http://developer.qiniu.com/docs/v6/api/reference/security/put-policy.html
201
     */
202
    private static $policyFields = array(
203
        'callbackUrl',
204
        'callbackBody',
205
        'callbackHost',
206
        'callbackBodyType',
207
        'callbackFetchKey',
208
209
        'returnUrl',
210
        'returnBody',
211
212
        'endUser',
213
        'saveKey',
214
        'forceSaveKey',
215
        'insertOnly',
216
217
        'detectMime',
218
        'mimeLimit',
219
        'fsizeMin',
220
        'fsizeLimit',
221
222
        'persistentOps', // 与 persistentWorkflowTemplateID 二选一
223
        'persistentNotifyUrl',
224
        'persistentPipeline',
225
        'persistentType', // 为 `1` 时开启闲时任务
226
        'persistentWorkflowTemplateID', // 与 persistentOps 二选一
227
228
        'deleteAfterDays',
229
        'fileType',
230
        'isPrefixalScope',
231
232
        'transform', // deprecated
233
        'transformFallbackKey', // deprecated
234
        'transformFallbackMode', // deprecated
235
    );
236
237
    private static function copyPolicy(&$policy, $originPolicy, $strictPolicy)
238
    {
239
        if ($originPolicy === null) {
240
            return array();
241
        }
242
        foreach ($originPolicy as $key => $value) {
243
            if (!$strictPolicy || in_array((string)$key, self::$policyFields, true)) {
244
                $policy[$key] = $value;
245
            }
246
        }
247
        return $policy;
248
    }
249
250
    public function authorization($url, $body = null, $contentType = null)
251
    {
252
        $authorization = 'QBox ' . $this->signRequest($url, $body, $contentType);
253
        return array('Authorization' => $authorization);
254
    }
255
256
    public function authorizationV2($url, $method, $body = null, $contentType = null)
257
    {
258
        $headers = new Header();
259
        $result = array();
260
        if ($contentType != null) {
261
            $headers['Content-Type'] = $contentType;
262
            $result['Content-Type'] = $contentType;
263
        }
264
265
        $signDate = gmdate('Ymd\THis\Z', time());
266
        if ($this->options['disableQiniuTimestampSignature'] !== null) {
267
            if (!$this->options['disableQiniuTimestampSignature']) {
268
                $headers['X-Qiniu-Date'] = $signDate;
269
                $result['X-Qiniu-Date'] = $signDate;
270
            }
271
        } elseif (getenv("DISABLE_QINIU_TIMESTAMP_SIGNATURE")) {
272
            if (strtolower(getenv("DISABLE_QINIU_TIMESTAMP_SIGNATURE")) !== "true") {
273
                $headers['X-Qiniu-Date'] = $signDate;
274
                $result['X-Qiniu-Date'] = $signDate;
275
            }
276
        } else {
277
            $headers['X-Qiniu-Date'] = $signDate;
278
            $result['X-Qiniu-Date'] = $signDate;
279
        }
280
281
        list($sign) = $this->signQiniuAuthorization($url, $method, $body, $headers);
282
        $result['Authorization'] = 'Qiniu ' . $sign;
283
        return $result;
284
    }
285
}
286