Permalink
Browse files

- quick hack to support the OAuthHandler

  • Loading branch information...
1 parent be4f1f3 commit a38fa1bbbeba22a1d60b2608d5eaf98a6b60a033 @marcus-h marcus-h committed Mar 29, 2011
Showing with 59 additions and 4 deletions.
  1. +40 −0 osc/OAuthHandler.py
  2. +19 −4 osc/conf.py
View
@@ -0,0 +1,40 @@
+import oauth
+import urlparse
+import urllib2
+import sys
+
+class OAuthHandler(urllib2.BaseHandler):
+ def __init__(self, password_mgr = None):
+ if password_mgr is None:
+ password_mgr = urllib2.HTTPPasswordMgr()
+ self.passwd = password_mgr
+ self.add_password = self.passwd.add_password
+
+ def http_error_401(self, req, fp, code, msg, headers):
+ # XXX: desktop clients etc. won't have a consumer token + secret => unknown + unknown will be used
+ auth_req = headers.get('www-authenticate', None)
+ scheme = None
+ if auth_req:
+ mo = urllib2.AbstractBasicAuthHandler.rx.search(auth_req)
+ if mo:
+ scheme = mo.groups()[0]
+ if not auth_req or scheme != 'oauth':
+ return None
+ # default consumer key + secret for desktop clients
+ consumer = oauth.OAuthConsumer('desktop', 'desktop')
+ atoken, secret = self.passwd.find_user_password(None, req.get_full_url())
+ token = oauth.OAuthToken(atoken, secret)
+ query = dict(urlparse.parse_qsl(urlparse.urlsplit(req.get_full_url())[3]))
+ if query.has_key('oauth_token') or req.headers.get('Authorization', '').startswith('OAuth'):
+ return None
+ # XXX: pass the full url - it'll be converted by the oauth module
+ oauthreq = oauth.OAuthRequest.from_consumer_and_token(consumer, token=token,
+ http_method=req.get_method(), http_url=req.get_full_url(), parameters=query)
+ print consumer, token
+ oauthreq.sign_request(oauth.OAuthSignatureMethod_HMAC_SHA1(), consumer, token)
+ req.add_header(*oauthreq.to_header().items()[0])
+ return self.parent.open(req)
+
+ def get_handler(config, password_mgr = None):
+ return OAuthHandler(password_mgr)
+ get_handler = staticmethod(get_handler)
View
@@ -425,11 +425,19 @@ def retry_http_basic_auth(self, host, req, realm):
authhandler_class = OscHTTPBasicAuthHandler
options = config['api_host_options'][apiurl]
+ accepted_auth_methods = ['basic;q=0.5']
# with None as first argument, it will always use this username/password
# combination for urls for which arg2 (apisrv) is a super-url
- authhandler = authhandler_class( \
- urllib2.HTTPPasswordMgrWithDefaultRealm())
- authhandler.add_password(None, apiurl, options['user'], options['pass'])
+ if options.has_key('auth_prot'):
+ # XXX: should the qvalue be configurable?
+ accepted_auth_methods.append('%s;q=0.8' % options['auth_prot'].lower())
+ klass = getattr(__import__(options['auth_prot'] + 'Handler', globals()), options['auth_prot'] + 'Handler')
+ authhandler = klass.get_handler(config)
+ authhandler.add_password(None, apiurl, options['login'], options['pass'])
+ else:
+ authhandler = authhandler_class( \
+ urllib2.HTTPPasswordMgrWithDefaultRealm())
+ authhandler.add_password(None, apiurl, options['user'], options['pass'])
if options['sslcertck']:
try:
@@ -457,6 +465,7 @@ def retry_http_basic_auth(self, host, req, realm):
print >>sys.stderr, "WARNING: SSL certificate checks disabled. Connection is insecure!\n"
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookiejar), authhandler)
opener.addheaders = [('User-agent', 'osc/%s' % __version__)]
+ opener.addheaders.append(('Accept-Authentication', ','.join(set(accepted_auth_methods))))
_build_opener.last_opener = (apiurl, opener)
return opener
@@ -829,6 +838,9 @@ def get_config(override_conffile = None,
http_headers = http_header_regexp.findall(http_headers)
else:
http_headers = []
+ auth_prot = None
+ if cp.has_option(url, 'auth_prot'):
+ auth_prot = cp.get(url, 'auth_prot')
if cp.has_option(url, 'aliases'):
for i in cp.get(url, 'aliases').split(','):
key = i.strip()
@@ -843,7 +855,7 @@ def get_config(override_conffile = None,
'pass': password,
'http_headers': http_headers}
- optional = ('email', 'sslcertck', 'cafile', 'capath')
+ optional = ('email', 'sslcertck', 'cafile', 'capath', 'login')
for key in optional:
if cp.has_option(url, key):
if key == 'sslcertck':
@@ -857,6 +869,9 @@ def get_config(override_conffile = None,
if scheme == 'http':
api_host_options[apiurl]['sslcertck'] = False
+ if auth_prot:
+ api_host_options[apiurl]['auth_prot'] = auth_prot
+
if cp.has_option(url, 'trusted_prj'):
api_host_options[apiurl]['trusted_prj'] = cp.get(url, 'trusted_prj').split(' ')
else:

0 comments on commit a38fa1b

Please sign in to comment.