Skip to content

Commit 0dbde38

Browse files
committed
add Qiniu auth verify callback
1 parent 02d2e2e commit 0dbde38

File tree

3 files changed

+305
-186
lines changed

3 files changed

+305
-186
lines changed

qiniu/auth.py

Lines changed: 93 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -195,22 +195,56 @@ def __upload_token(self, policy):
195195
return self.token_with_data(data)
196196

197197
def verify_callback(
198-
self,
199-
origin_authorization,
200-
url,
201-
body,
202-
content_type='application/x-www-form-urlencoded'):
203-
"""回调验证
204-
205-
Args:
206-
origin_authorization: 回调时请求Header中的Authorization字段
207-
url: 回调请求的url
208-
body: 回调请求的body
209-
content_type: 回调请求body的Content-Type
210-
211-
Returns:
212-
返回true表示验证成功,返回false表示验证失败
198+
self,
199+
origin_authorization,
200+
url,
201+
body,
202+
content_type='application/x-www-form-urlencoded',
203+
method='GET',
204+
headers=None
205+
):
213206
"""
207+
Qbox 回调验证
208+
209+
Parameters
210+
----------
211+
origin_authorization: str
212+
回调时请求 Header 中的 Authorization 字段
213+
url: str
214+
回调请求的 url
215+
body: str
216+
回调请求的 body
217+
content_type: str
218+
回调请求的 Content-Type
219+
method: str
220+
回调请求的 method,Qiniu 签名必须传入,默认 GET
221+
headers: dict
222+
回调请求的 headers,Qiniu 签名必须传入,默认为空字典
223+
224+
Returns
225+
-------
226+
bool
227+
返回 True 表示验证成功,返回 False 表示验证失败
228+
"""
229+
if headers is None:
230+
headers = {}
231+
232+
# 兼容 Qiniu 签名
233+
if origin_authorization.startswith("Qiniu"):
234+
qn_auth = QiniuMacAuth(
235+
access_key=self.__access_key,
236+
secret_key=self.__secret_key,
237+
disable_qiniu_timestamp_signature=True
238+
)
239+
return qn_auth.verify_callback(
240+
origin_authorization,
241+
url=url,
242+
body=body,
243+
content_type=content_type,
244+
method=method,
245+
headers=headers
246+
)
247+
214248
token = self.token_of_request(url, body, content_type)
215249
authorization = 'QBox {0}'.format(token)
216250
return origin_authorization == authorization
@@ -327,6 +361,50 @@ def qiniu_headers(self, headers):
327361
'%s: %s' % (canonical_mime_header_key(key), headers.get(key)) for key in sorted(qiniu_fields)
328362
])
329363

364+
def verify_callback(
365+
self,
366+
origin_authorization,
367+
url,
368+
body,
369+
content_type='application/x-www-form-urlencoded',
370+
method='GET',
371+
headers=None
372+
):
373+
"""
374+
Qiniu 回调验证
375+
376+
Parameters
377+
----------
378+
origin_authorization: str
379+
回调时请求 Header 中的 Authorization 字段
380+
url: str
381+
回调请求的 url
382+
body: str
383+
回调请求的 body
384+
content_type: str
385+
回调请求的 Content-Type
386+
method: str
387+
回调请求的 Method
388+
headers: dict
389+
回调请求的 headers
390+
391+
Returns
392+
-------
393+
394+
"""
395+
if headers is None:
396+
headers = {}
397+
token = self.token_of_request(
398+
method=method,
399+
host=headers.get('Host', None),
400+
url=url,
401+
qheaders=self.qiniu_headers(headers),
402+
content_type=content_type,
403+
body=body
404+
)
405+
authorization = 'Qiniu {0}'.format(token)
406+
return origin_authorization == authorization
407+
330408
@staticmethod
331409
def __checkKey(access_key, secret_key):
332410
if not (access_key and secret_key):

test_qiniu.py

Lines changed: 0 additions & 171 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,6 @@
4545
hostscache_dir = None
4646

4747

48-
dummy_access_key = 'abcdefghklmnopq'
49-
dummy_secret_key = '1234567890'
50-
dummy_auth = Auth(dummy_access_key, dummy_secret_key)
51-
52-
5348
def rand_string(length):
5449
lib = string.ascii_uppercase
5550
return ''.join([random.choice(lib) for i in range(0, length)])
@@ -193,172 +188,6 @@ def test_decode_entry(self):
193188
assert key == c.get('expect').get('key'), c.get('msg')
194189

195190

196-
class AuthTestCase(unittest.TestCase):
197-
def test_token(self):
198-
token = dummy_auth.token('test')
199-
assert token == 'abcdefghklmnopq:mSNBTR7uS2crJsyFr2Amwv1LaYg='
200-
201-
def test_token_with_data(self):
202-
token = dummy_auth.token_with_data('test')
203-
assert token == 'abcdefghklmnopq:-jP8eEV9v48MkYiBGs81aDxl60E=:dGVzdA=='
204-
205-
def test_noKey(self):
206-
with pytest.raises(ValueError):
207-
Auth(None, None).token('nokey')
208-
with pytest.raises(ValueError):
209-
Auth('', '').token('nokey')
210-
211-
def test_token_of_request(self):
212-
token = dummy_auth.token_of_request('https://www.qiniu.com?go=1', 'test', '')
213-
assert token == 'abcdefghklmnopq:cFyRVoWrE3IugPIMP5YJFTO-O-Y='
214-
token = dummy_auth.token_of_request('https://www.qiniu.com?go=1', 'test', 'application/x-www-form-urlencoded')
215-
assert token == 'abcdefghklmnopq:svWRNcacOE-YMsc70nuIYdaa1e4='
216-
217-
def test_QiniuMacRequestsAuth(self):
218-
auth = QiniuMacAuth("ak", "sk")
219-
test_cases = [
220-
{
221-
"method": "GET",
222-
"host": None,
223-
"url": "",
224-
"qheaders": {
225-
"X-Qiniu-": "a",
226-
"X-Qiniu": "b",
227-
"Content-Type": "application/x-www-form-urlencoded",
228-
},
229-
"content_type": "application/x-www-form-urlencoded",
230-
"body": "{\"name\": \"test\"}",
231-
"except_sign_token": "ak:0i1vKClRDWFyNkcTFzwcE7PzX74=",
232-
},
233-
{
234-
"method": "GET",
235-
"host": None,
236-
"url": "",
237-
"qheaders": {
238-
"Content-Type": "application/json",
239-
},
240-
"content_type": "application/json",
241-
"body": "{\"name\": \"test\"}",
242-
"except_sign_token": "ak:K1DI0goT05yhGizDFE5FiPJxAj4=",
243-
},
244-
{
245-
"method": "POST",
246-
"host": None,
247-
"url": "",
248-
"qheaders": {
249-
"Content-Type": "application/json",
250-
"X-Qiniu": "b",
251-
},
252-
"content_type": "application/json",
253-
"body": "{\"name\": \"test\"}",
254-
"except_sign_token": "ak:0ujEjW_vLRZxebsveBgqa3JyQ-w=",
255-
},
256-
{
257-
"method": "GET",
258-
"host": "upload.qiniup.com",
259-
"url": "http://upload.qiniup.com",
260-
"qheaders": {
261-
"X-Qiniu-": "a",
262-
"X-Qiniu": "b",
263-
"Content-Type": "application/x-www-form-urlencoded",
264-
},
265-
"content_type": "application/x-www-form-urlencoded",
266-
"body": "{\"name\": \"test\"}",
267-
"except_sign_token": "ak:GShw5NitGmd5TLoo38nDkGUofRw=",
268-
},
269-
{
270-
"method": "GET",
271-
"host": "upload.qiniup.com",
272-
"url": "http://upload.qiniup.com",
273-
"qheaders": {
274-
"Content-Type": "application/json",
275-
"X-Qiniu-Bbb": "BBB",
276-
"X-Qiniu-Aaa": "DDD",
277-
"X-Qiniu-": "a",
278-
"X-Qiniu": "b",
279-
},
280-
"content_type": "application/json",
281-
"body": "{\"name\": \"test\"}",
282-
"except_sign_token": "ak:DhNA1UCaBqSHCsQjMOLRfVn63GQ=",
283-
},
284-
{
285-
"method": "GET",
286-
"host": "upload.qiniup.com",
287-
"url": "http://upload.qiniup.com",
288-
"qheaders": {
289-
"Content-Type": "application/x-www-form-urlencoded",
290-
"X-Qiniu-Bbb": "BBB",
291-
"X-Qiniu-Aaa": "DDD",
292-
"X-Qiniu-": "a",
293-
"X-Qiniu": "b",
294-
},
295-
"content_type": "application/x-www-form-urlencoded",
296-
"body": "name=test&language=go",
297-
"except_sign_token": "ak:KUAhrYh32P9bv0COD8ugZjDCmII=",
298-
},
299-
{
300-
"method": "GET",
301-
"host": "upload.qiniup.com",
302-
"url": "http://upload.qiniup.com",
303-
"qheaders": {
304-
"Content-Type": "application/x-www-form-urlencoded",
305-
"X-Qiniu-Bbb": "BBB",
306-
"X-Qiniu-Aaa": "DDD",
307-
},
308-
"content_type": "application/x-www-form-urlencoded",
309-
"body": "name=test&language=go",
310-
"except_sign_token": "ak:KUAhrYh32P9bv0COD8ugZjDCmII=",
311-
},
312-
{
313-
"method": "GET",
314-
"host": "upload.qiniup.com",
315-
"url": "http://upload.qiniup.com/mkfile/sdf.jpg",
316-
"qheaders": {
317-
"Content-Type": "application/x-www-form-urlencoded",
318-
"X-Qiniu-Bbb": "BBB",
319-
"X-Qiniu-Aaa": "DDD",
320-
"X-Qiniu-": "a",
321-
"X-Qiniu": "b",
322-
},
323-
"content_type": "application/x-www-form-urlencoded",
324-
"body": "name=test&language=go",
325-
"except_sign_token": "ak:fkRck5_LeyfwdkyyLk-hyNwGKac=",
326-
},
327-
{
328-
"method": "GET",
329-
"host": "upload.qiniup.com",
330-
"url": "http://upload.qiniup.com/mkfile/sdf.jpg?s=er3&df",
331-
"qheaders": {
332-
"Content-Type": "application/x-www-form-urlencoded",
333-
"X-Qiniu-Bbb": "BBB",
334-
"X-Qiniu-Aaa": "DDD",
335-
"X-Qiniu-": "a",
336-
"X-Qiniu": "b",
337-
},
338-
"content_type": "application/x-www-form-urlencoded",
339-
"body": "name=test&language=go",
340-
"except_sign_token": "ak:PUFPWsEUIpk_dzUvvxTTmwhp3p4=",
341-
},
342-
]
343-
344-
for test_case in test_cases:
345-
sign_token = auth.token_of_request(
346-
method=test_case["method"],
347-
host=test_case["host"],
348-
url=test_case["url"],
349-
qheaders=auth.qiniu_headers(test_case["qheaders"]),
350-
content_type=test_case["content_type"],
351-
body=test_case["body"],
352-
)
353-
assert sign_token == test_case["except_sign_token"]
354-
355-
def test_verify_callback(self):
356-
body = 'name=sunflower.jpg&hash=Fn6qeQi4VDLQ347NiRm-RlQx_4O2&location=Shanghai&price=1500.00&uid=123'
357-
url = 'test.qiniu.com/callback'
358-
ok = dummy_auth.verify_callback('QBox abcdefghklmnopq:ZWyeM5ljWMRFwuPTPOwQ4RwSto4=', url, body)
359-
assert ok
360-
361-
362191
class BucketTestCase(unittest.TestCase):
363192
q = Auth(access_key, secret_key)
364193
bucket = BucketManager(q)

0 commit comments

Comments
 (0)