Completed
Pull Request — master (#190)
by r
25:30
created

Auth   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 157
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 88.89%

Importance

Changes 13
Bugs 1 Features 2
Metric Value
c 13
b 1
f 2
dl 0
loc 157
ccs 56
cts 63
cp 0.8889
rs 10
wmc 23
lcom 1
cbo 1

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A getAccessKey() 0 4 1
A sign() 0 5 1
A signWithData() 0 5 1
B signRequest() 0 17 5
A verifyCallback() 0 5 1
A privateDownloadUrl() 0 15 2
B uploadToken() 0 30 4
B copyPolicy() 0 15 6
A authorization() 0 5 1
1
<?php
2
namespace Qiniu;
3
4
use Qiniu;
5
use Qiniu\Zone;
6
7
final class Auth
8
{
9
    private $accessKey;
10
    private $secretKey;
11
12
    public function __construct($accessKey, $secretKey)
13
    {
14
        $this->accessKey = $accessKey;
15
        $this->secretKey = $secretKey;
16
    }
17 90
18
    public function getAccessKey()
19 90
    {
20 90
        return $this->accessKey;
21
    }
22
23 24
    public function sign($data)
24
    {
25 24
        $hmac = hash_hmac('sha1', $data, $this->secretKey, true);
26 24
        return $this->accessKey . ':' . \Qiniu\base64_urlSafeEncode($hmac);
27
    }
28
29 51
    public function signWithData($data)
30
    {
31 51
        $data = \Qiniu\base64_urlSafeEncode($data);
32 51
        return $this->sign($data) . ':' . $data;
33 51
    }
34 48
35 48
    public function signRequest($urlString, $body, $contentType = null)
36 51
    {
37 6
        $url = parse_url($urlString);
38 6
        $data = '';
39 51
        if (array_key_exists('path', $url)) {
40
            $data = $url['path'];
41 51
        }
42 24
        if (array_key_exists('query', $url)) {
43 24
            $data .= '?' . $url['query'];
44 51
        }
45
        $data .= "\n";
46
47
        if ($body !== null && $contentType === 'application/x-www-form-urlencoded') {
48
            $data .= $body;
49
        }
50
        return $this->sign($data);
51
    }
52
53 12
    public function verifyCallback($contentType, $originAuthorization, $url, $body)
54
    {
55 12
        $authorization = 'QBox ' . $this->signRequest($url, $body, $contentType);
56
        return $originAuthorization === $authorization;
57 12
    }
58 12
59 9
    public function privateDownloadUrl($baseUrl, $expires = 3600)
60 9
    {
61 3
        $deadline = time() + $expires;
62
63 12
        $pos = strpos($baseUrl, '?');
64
        if ($pos !== false) {
65 12
            $baseUrl .= '&e=';
66 12
        } else {
67
            $baseUrl .= '?e=';
68
        }
69 24
        $baseUrl .= $deadline;
70
71
        $token = $this->sign($baseUrl);
72
        return "$baseUrl&token=$token";
73
    }
74
75
    public function uploadToken(
76 24
        $bucket,
77 24
        $key = null,
78 24
        $expires = 3600,
79 15
        $policy = null,
80 15
        $strictPolicy = true,
81 24
        Zone $zone = null
82 24
    ) {
83 21
        $deadline = time() + $expires;
84 21
        $scope = $bucket;
85 21
        if ($key !== null) {
86 21
            $scope .= ':' . $key;
87
        }
88
        $args = array();
89
        $args = self::copyPolicy($args, $policy, $strictPolicy);
90
        $args['scope'] = $scope;
91
        $args['deadline'] = $deadline;
92
93
        if ($zone === null) {
94
            $zone = new Zone();
95
        }
96
97
        list($upHosts, $err) = $zone->getUpHosts($this->accessKey, $bucket);
98
        if ($err === null) {
99
            $args['upHosts'] = $upHosts;
100
        }
101
        
102
        $b = json_encode($args);
103
        return $this->signWithData($b);
104
    }
105
106
    /**
107
     *上传策略,参数规格详见
108
     *http://developer.qiniu.com/docs/v6/api/reference/security/put-policy.html
109
     */
110
    private static $policyFields = array(
111
        'callbackUrl',
112
        'callbackBody',
113
        'callbackHost',
114
        'callbackBodyType',
115
        'callbackFetchKey',
116
117
        'returnUrl',
118
        'returnBody',
119
120
        'endUser',
121 24
        'saveKey',
122
        'insertOnly',
123 24
124 18
        'detectMime',
125
        'mimeLimit',
126 6
        'fsizeMin',
127 6
        'fsizeLimit',
128 3
129
        'persistentOps',
130 3
        'persistentNotifyUrl',
131 3
        'persistentPipeline',
132 3
        
133 3
        'deleteAfterDays',
134 3
135
        'upHosts',
136
    );
137 48
138
    private static $deprecatedPolicyFields = array(
139 48
        'asyncOps',
140 48
    );
141
142
    private static function copyPolicy(&$policy, $originPolicy, $strictPolicy)
143
    {
144
        if ($originPolicy === null) {
145
            return array();
146
        }
147
        foreach ($originPolicy as $key => $value) {
148
            if (in_array((string) $key, self::$deprecatedPolicyFields, true)) {
149
                throw new \InvalidArgumentException("{$key} has deprecated");
150
            }
151
            if (!$strictPolicy || in_array((string) $key, self::$policyFields, true)) {
152
                $policy[$key] = $value;
153
            }
154
        }
155
        return $policy;
156
    }
157
158
    public function authorization($url, $body = null, $contentType = null)
159
    {
160
        $authorization = 'QBox ' . $this->signRequest($url, $body, $contentType);
161
        return array('Authorization' => $authorization);
162
    }
163
}
164