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
namespace Qiniu;
3
4
use Qiniu\Http\Header;
5
use Qiniu\Zone;
6
7
final class Auth
8
{
9
    private $accessKey;
10
    private $secretKey;
11
    public $options;
12
13
    public function __construct($accessKey, $secretKey, $options = null)
14
    {
15
        $this->accessKey = $accessKey;
16
        $this->secretKey = $secretKey;
17 6
        $defaultOptions = array(
18
            'disableQiniuTimestampSignature' => null
19 6
        );
20
        if ($options == null) {
21
            $options = $defaultOptions;
22 93
        }
23
        $this->options = array_merge($defaultOptions, $options);
24 93
    }
25 93
26
    public function getAccessKey()
27
    {
28 24
        return $this->accessKey;
29
    }
30 24
31 24
    public function sign($data)
32
    {
33
        $hmac = hash_hmac('sha1', $data, $this->secretKey, true);
34 54
        return $this->accessKey . ':' . \Qiniu\base64_urlSafeEncode($hmac);
35
    }
36 54
37 54
    public function signWithData($data)
38 54
    {
39 51
        $encodedData = \Qiniu\base64_urlSafeEncode($data);
40 51
        return $this->sign($encodedData) . ':' . $encodedData;
41 54
    }
42 9
43 9
    public function signRequest($urlString, $body, $contentType = null)
44 54
    {
45
        $url = parse_url($urlString);
46 54
        $data = '';
47 24
        if (array_key_exists('path', $url)) {
48 24
            $data = $url['path'];
49 54
        }
50
        if (array_key_exists('query', $url)) {
51
            $data .= '?' . $url['query'];
52
        }
53
        $data .= "\n";
54
55
        if ($body !== null && $contentType === 'application/x-www-form-urlencoded') {
56
            $data .= $body;
57
        }
58 12
        return $this->sign($data);
59
    }
60 12
61
    /**
62 12
     * @param string $urlString
63 12
     * @param string $method
64 9
     * @param string $body
65 9
     * @param null|Header $headers
66 3
     */
67
    public function signQiniuAuthorization($urlString, $method = "GET", $body = "", $headers = null)
68 12
    {
69
        $url = parse_url($urlString);
70 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...
71 12
            return array(null, new \Exception("parse_url error"));
72
        }
73
74 21
        // append method, path and query
75
        if ($method === "") {
76 21
            $data = "GET ";
77 21
        } else {
78 21
            $data = $method . " ";
79 15
        }
80 15
        if (isset($url["path"])) {
81
            $data .= $url["path"];
82 21
        }
83 21
        if (isset($url["query"])) {
84 21
            $data .= "?" . $url["query"];
85
        }
86 21
87 21
        // append Host
88
        $data .= "\n";
89
        $data .= "Host: ";
90
        if (isset($url["host"])) {
91
            $data .= $url["host"];
92
        }
93
        if (isset($url["port"]) && $url["port"] > 0) {
94
            $data .= ":" . $url["port"];
95
        }
96
97
        // try append content type
98
        if ($headers != null && isset($headers["Content-Type"])) {
99
            // append content type
100
            $data .= "\n";
101
            $data .= "Content-Type: " . $headers["Content-Type"];
102
        }
103
104
        // try append xQiniuHeaders
105
        if ($headers != null) {
106
            $headerLines = array();
107
            $keyPrefix = "X-Qiniu-";
108
            foreach ($headers as $k => $v) {
109
                if (strlen($k) > strlen($keyPrefix) && strpos($k, $keyPrefix) === 0) {
110
                    array_push(
111
                        $headerLines,
112
                        $k . ": " . $v
113
                    );
114
                }
115
            }
116
            if (count($headerLines) > 0) {
117
                $data .= "\n";
118
                sort($headerLines);
119
                $data .= implode("\n", $headerLines);
120
            }
121
        }
122 21
123
        // append body
124 21
        $data .= "\n\n";
125 18
        if (!is_null($body)
0 ignored issues
show
introduced by
The condition is_null($body) is always false.
Loading history...
126
            && strlen($body) > 0
127 3
            && isset($headers["Content-Type"])
128 3
            && $headers["Content-Type"] != "application/octet-stream"
129 3
        ) {
130 3
            $data .= $body;
131 3
        }
132 3
133
        return array($this->sign($data), null);
134
    }
135 51
136
    public function verifyCallback($contentType, $originAuthorization, $url, $body)
137 51
    {
138 51
        $authorization = 'QBox ' . $this->signRequest($url, $body, $contentType);
139
        return $originAuthorization === $authorization;
140
    }
141
142
    public function privateDownloadUrl($baseUrl, $expires = 3600)
143
    {
144
        $deadline = time() + $expires;
145
146
        $pos = strpos($baseUrl, '?');
147
        if ($pos !== false) {
148
            $baseUrl .= '&e=';
149
        } else {
150
            $baseUrl .= '?e=';
151
        }
152
        $baseUrl .= $deadline;
153
154
        $token = $this->sign($baseUrl);
155
        return "$baseUrl&token=$token";
156
    }
157
158
    public function uploadToken($bucket, $key = null, $expires = 3600, $policy = null, $strictPolicy = true)
159
    {
160
        $deadline = time() + $expires;
161
        $scope = $bucket;
162
        if ($key !== null) {
163
            $scope .= ':' . $key;
164
        }
165
166
        $args = self::copyPolicy($args, $policy, $strictPolicy);
167
        $args['scope'] = $scope;
168
        $args['deadline'] = $deadline;
169
170
        $b = json_encode($args);
171
        return $this->signWithData($b);
172
    }
173
174
    /**
175
     *上传策略,参数规格详见
176
     *http://developer.qiniu.com/docs/v6/api/reference/security/put-policy.html
177
     */
178
    private static $policyFields = array(
179
        'callbackUrl',
180
        'callbackBody',
181
        'callbackHost',
182
        'callbackBodyType',
183
        'callbackFetchKey',
184
185
        'returnUrl',
186
        'returnBody',
187
188
        'endUser',
189
        'saveKey',
190
        'forceSaveKey',
191
        'insertOnly',
192
193
        'detectMime',
194
        'mimeLimit',
195
        'fsizeMin',
196
        'fsizeLimit',
197
198
        'persistentOps',
199
        'persistentNotifyUrl',
200
        'persistentPipeline',
201
202
        'deleteAfterDays',
203
        'fileType',
204
        'isPrefixalScope',
205
206
        'transform', // deprecated
207
        'transformFallbackKey', // deprecated
208
        'transformFallbackMode', // deprecated
209
    );
210
211
    private static function copyPolicy(&$policy, $originPolicy, $strictPolicy)
212
    {
213
        if ($originPolicy === null) {
214
            return array();
215
        }
216
        foreach ($originPolicy as $key => $value) {
217
            if (!$strictPolicy || in_array((string)$key, self::$policyFields, true)) {
218
                $policy[$key] = $value;
219
            }
220
        }
221
        return $policy;
222
    }
223
224
    public function authorization($url, $body = null, $contentType = null)
225
    {
226
        $authorization = 'QBox ' . $this->signRequest($url, $body, $contentType);
227
        return array('Authorization' => $authorization);
228
    }
229
230
    public function authorizationV2($url, $method, $body = null, $contentType = null)
231
    {
232
        $headers = new Header();
233
        $result = array();
234
        if ($contentType != null) {
235
            $headers['Content-Type'] = $contentType;
236
            $result['Content-Type'] = $contentType;
237
        }
238
239
        $signDate = gmdate('Ymd\THis\Z', time());
240
        if ($this->options['disableQiniuTimestampSignature'] !== null) {
241
            if (!$this->options['disableQiniuTimestampSignature']) {
242
                $headers['X-Qiniu-Date'] = $signDate;
243
                $result['X-Qiniu-Date'] = $signDate;
244
            }
245
        } elseif (getenv("DISABLE_QINIU_TIMESTAMP_SIGNATURE")) {
246
            if (strtolower(getenv("DISABLE_QINIU_TIMESTAMP_SIGNATURE")) !== "true") {
247
                $headers['X-Qiniu-Date'] = $signDate;
248
                $result['X-Qiniu-Date'] = $signDate;
249
            }
250
        } else {
251
            $headers['X-Qiniu-Date'] = $signDate;
252
            $result['X-Qiniu-Date'] = $signDate;
253
        }
254
255
        list($sign) = $this->signQiniuAuthorization($url, $method, $body, $headers);
256
        $result['Authorization'] = 'Qiniu ' . $sign;
257
        return $result;
258
    }
259
}
260