6 class OAuthHandler(urllib2.BaseHandler):
7 def __init__(self, password_mgr = None):
8 if password_mgr is None:
9 password_mgr = urllib2.HTTPPasswordMgr()
10 self.passwd = password_mgr
11 self.add_password = self.passwd.add_password
13 def http_error_401(self, req, fp, code, msg, headers):
14 # XXX: desktop clients etc. won't have a consumer token + secret => unknown + unknown will be used
15 auth_req = headers.get('www-authenticate', None)
18 mo = urllib2.AbstractBasicAuthHandler.rx.search(auth_req)
20 scheme = mo.groups()[0]
21 if not auth_req or scheme != 'oauth':
23 # default consumer key + secret for desktop clients
24 consumer = oauth.OAuthConsumer('desktop', 'desktop')
25 atoken, secret = self.passwd.find_user_password(None, req.get_full_url())
26 token = oauth.OAuthToken(atoken, secret)
27 query = dict(urlparse.parse_qsl(urlparse.urlsplit(req.get_full_url())[3]))
28 if query.has_key('oauth_token') or req.headers.get('Authorization', '').startswith('OAuth'):
30 # XXX: pass the full url - it'll be converted by the oauth module
31 oauthreq = oauth.OAuthRequest.from_consumer_and_token(consumer, token=token,
32 http_method=req.get_method(), http_url=req.get_full_url(), parameters=query)
34 oauthreq.sign_request(oauth.OAuthSignatureMethod_HMAC_SHA1(), consumer, token)
35 req.add_header(*oauthreq.to_header().items()[0])
36 return self.parent.open(req)
38 def get_handler(config, password_mgr = None):
39 return OAuthHandler(password_mgr)
40 get_handler = staticmethod(get_handler)