Authentication
Поиск
Скачать
Feeds
#!/usr/bin/python
# -*- coding: utf-8 -*-
import hmac, sha, time, urllib, urllib2
from base64 import b64encode
from audiomicro.utils.hash import SecurityUtils
class AudiomicroAuthHandler(urllib2.HTTPHandler):
""" Implemention of Authentication Header from API Doc
Usage:
aa = AudiomicroAuthHandler()
aa.set_auth(access_key, secret_key)
opener = urllib2.build_opener(aa)
r = opener.open(URL)
"""
CanonicalizedResource = ('fileID', 'CategoryID', 'Q')
def set_auth(self, access_key, secret_key):
""" Set authentication tokens """
self.access_key = access_key
self.secret_key = secret_key
def http_request(self, request):
if hasattr(self, 'access_key'):
# Build StringToSign
string_to_sign = self.string_to_sign(request)
if self._debuglevel > 0: print string_to_sign
# Add authorization header
request.add_unredirected_header('Authorization', 'AUDIOMICRO '+ \
self.access_key +':'+ b64encode(self.sign(string_to_sign)) )
if self._debuglevel > 0: print request.get_header('Authorization')
return request
https_request = http_request
def sign(self, s):
return hmac.new(self.secret_key, msg=s, digestmod=sha).digest()
def string_to_sign(self, request):
""" StringToSign builder """
# GET or POST
rv = request.get_method() +"\n"
# Content-MD5 if present should be added to StringToSign
if request.has_header('Content-MD5'):
rv += request.get_header('Content-MD5')
rv += "\n"
if request.has_header('Content-Type'):
rv += request.get_header('Content-Type')
rv += "\n"
# Date header should be exists in request
if not request.has_header('Date'):
request.add_unredirected_header('Date',
time.strftime("%a, %d %b %Y %H:%M:%S %z"))
rv += request.get_header('Date') + "\n"
# Get the URI part from URL
params = urllib.splitquery(request.get_selector())
query = [part.split('=', 1) for part in params[1].split('&')]
# .. and build CanonicalizedResource
canonicalized_resource = params[0][0] == '/' and params[0] or '/'+ params[0]
canonicalized_params = []
for q in query:
# Check if the URI part in CanonicalizedResource list
if q[0] in self.__class__.CanonicalizedResource:
canonicalized_params.append('='.join(q))
if canonicalized_params:
canonicalized_resource += '?' + '&'.join(canonicalized_params)
rv += canonicalized_resource
return rv
class AudiomicroAuthHandlerURL(AudiomicroAuthHandler):
""" Implementon of Query String Authentication from API Doc
Usage:
aa = AudiomicroAuthHandlerURL()
aa.set_auth(access_key, secret_key)
opener = urllib2.build_opener(aa)
r = opener.open(URL)
"""
def __init__(self, expire_delta=3600, debuglevel=0):
AudiomicroAuthHandler.__init__(self, debuglevel)
self.expire_delta=expire_delta
def http_request(self, request):
if hasattr(self, 'access_key'):
string_to_sign, expires = self.string_to_sign(request)
if self._debuglevel > 0: print string_to_sign
params = urllib.splitquery(request.get_selector())
if params[1]: # URL parameters is not empty
request._Request__r_host+= '&'
request._Request__original += '&'
else:
request._Request__r_host += '?'
request._Request__original += '?'
signature = b64encode(self.sign(string_to_sign))
if self._debuglevel > 0:
print urllib.urlencode({'Signature': signature}).split('=', 1)[1]
q_sign = 'AccessKeyId='+ self.access_key + '&Expires='+ expires + \
'&'+ urllib.urlencode({'Signature': signature})
request._Request__r_host += q_sign
request._Request__original += q_sign
return request
https_request = http_request
def string_to_sign(self, request):
""" StringToSign builder. Only GET method may used in this handler
Function returned StringToSign and Expires
"""
if request.has_data():
raise ValueError, "Only GET request may singed by this method"
else:
rv = "GET\n"
if request.has_header('Content-MD5'):
rv += request.get_header('Content-MD5')
rv += "\n"
if request.has_header('Content-Type'):
rv += request.get_header('Content-Type')
rv += "\n"
# Create Expires: now() + some time in secods (3600 by default)
Expires = str(int(time.time()) + self.expire_delta)
rv += Expires + "\n"
# Get the URI part from URL
params = urllib.splitquery(request.get_selector())
query = [part.split('=', 1) for part in params[1].split('&')]
# .. and build CanonicalizedResource
canonicalized_resource = params[0][0] == '/' and params[0] or '/'+ params[0]
canonicalized_params = []
for q in query:
# Check if the URI part in CanonicalizedResource list
if q[0] in self.__class__.CanonicalizedResource:
canonicalized_params.append('='.join(q))
if canonicalized_params:
canonicalized_resource += '?' + '&'.join(canonicalized_params)
rv += canonicalized_resource
return rv, Expires
if __name__ == '__main__':
PARAMS=urllib.urlencode({'CategoryID': '2'})
URL = 'http://api.audiomicro.com/api/1.1/categories/browse/?%(params)s&PerPage=10' %{'params': PARAMS}
access_key = '0PN5J17HBGZHT7JJ3X82'
secret_key = 'uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o'
aa = AudiomicroAuthHandlerURL()
aa.set_auth(access_key, secret_key)
opener = urllib2.build_opener(aa)
r = opener.open(URL)
print r.read()