[Checkins] SVN: lovely.buildouthttp/trunk/ implemented github private download

Bernd Dorn bernd.dorn at lovelysystems.com
Wed Mar 24 04:52:03 EDT 2010


Log message for revision 110140:
  implemented github private download

Changed:
  U   lovely.buildouthttp/trunk/CHANGES.txt
  U   lovely.buildouthttp/trunk/README.txt
  U   lovely.buildouthttp/trunk/src/lovely/buildouthttp/buildouthttp.py

-=-
Modified: lovely.buildouthttp/trunk/CHANGES.txt
===================================================================
--- lovely.buildouthttp/trunk/CHANGES.txt	2010-03-24 08:17:32 UTC (rev 110139)
+++ lovely.buildouthttp/trunk/CHANGES.txt	2010-03-24 08:52:03 UTC (rev 110140)
@@ -2,7 +2,12 @@
 Changes for lovely.buildouthttp
 ===============================
 
+trunk
+=====
 
+- added github authentication, which now allows to download from
+  private github repositories
+
 2009/09/22 0.2.3:
 =================
 

Modified: lovely.buildouthttp/trunk/README.txt
===================================================================
--- lovely.buildouthttp/trunk/README.txt	2010-03-24 08:17:32 UTC (rev 110139)
+++ lovely.buildouthttp/trunk/README.txt	2010-03-24 08:52:03 UTC (rev 110140)
@@ -23,7 +23,15 @@
 file ~/.buildout/.httpauth:
 Example com realm, http://www.example.com, username, secret
 
+Github Private Downloads
+========================
 
+Private downloads on http://github.com/ are protected by a user token
+(see: http://github.com/blog/170-token-authentication). This extension
+allows to use such urls too. It uses the global git configuration for
+``github.user`` and ``github.token``. For setting up this config see
+http://github.com/blog/180-local-github-config.
+
 Credits
 =======
 

Modified: lovely.buildouthttp/trunk/src/lovely/buildouthttp/buildouthttp.py
===================================================================
--- lovely.buildouthttp/trunk/src/lovely/buildouthttp/buildouthttp.py	2010-03-24 08:17:32 UTC (rev 110139)
+++ lovely.buildouthttp/trunk/src/lovely/buildouthttp/buildouthttp.py	2010-03-24 08:52:03 UTC (rev 110140)
@@ -20,8 +20,52 @@
 import sys
 import csv
 import logging
+import subprocess
+import urllib
+
 log = logging.getLogger('lovely.buildouthttp')
 
+def get_github_credentials():
+
+    """returns the credentials for the local git installation by using
+    git config"""
+
+    pipe = subprocess.Popen("git config github.token",
+                            shell=True,
+                            stdout=subprocess.PIPE).stdout
+    token = pipe.readline().strip()
+    pipe.close()
+    pipe = subprocess.Popen("git config github.user",
+                            shell=True,
+                            stdout=subprocess.PIPE).stdout
+    login = pipe.readline().strip()
+    pipe.close()
+    if login and token:
+        log.debug("Found github credentials for user %r", login)
+        return login, token
+
+
+class GithubHandler(urllib2.BaseHandler):
+
+    """This handler creates a post request with login and token, see
+    http://github.com/blog/170-token-authentication for details"""
+
+    def __init__(self, login, token):
+        self._login = login
+        self._token = token
+
+    def https_request(self, req):
+        if req.get_method() == 'GET' and req.get_host() == 'github.com':
+            log.debug("Found private github url %r", req.get_full_url())
+            data = urllib.urlencode(dict(login=self._login,
+                                         token=self._token))
+            timeout = getattr(req, 'timeout', 60)
+            if hasattr(req, 'timeout'):
+                timeout = req.timeout
+            req = urllib2.Request(req.get_full_url(), data)
+            req.timeout = timeout
+        return req
+
 class CredHandler(urllib2.HTTPBasicAuthHandler):
 
     """This handler adds basic auth credentials to the request upon a 401
@@ -39,22 +83,22 @@
     def http_error_401(self, req, fp, code, msg, headers):
         log.debug('getting url: %r' % req.get_full_url())
         try:
-            res =  urllib2.HTTPBasicAuthHandler.http_error_401(self,req, fp, code,
-                                                           msg,
-                                                           headers)
+            res =  urllib2.HTTPBasicAuthHandler.http_error_401(
+                self,req, fp, code, msg, headers)
         except urllib2.HTTPError, err:
-            log.error('failed to get url: %r %r' % (req.get_full_url(), err.code))
+            log.error('failed to get url: %r %r', req.get_full_url(), err.code)
             raise
         except Exception, err:
-            log.error('failed to get url: %r %s' % (req.get_full_url(), str(err)))
+            log.error('failed to get url: %r %s', req.get_full_url(), str(err))
             raise
         else:
             if res is None:
-                log.error('failed to get url: %r, check your realm' % req.get_full_url())
+                log.error('failed to get url: %r, check your realm',
+                          req.get_full_url())
             elif res.code>=400:
-                log.error('failed to get url: %r %r' % (res.url, res.code))
+                log.error('failed to get url: %r %r', res.url, res.code)
             else:
-                log.debug('got url: %r %r' % (res.url, res.code))
+                log.debug('got url: %r %r', res.url, res.code)
             return res
 
 def install(buildout=None, pwd_path=None):
@@ -86,6 +130,7 @@
     >>> f.close()
     >>> install(pwd_path=fp)
     """
+
     try:
         pwd_path = pwd_path or os.path.join(os.path.expanduser('~'),
                                   '.buildout',
@@ -94,8 +139,15 @@
     except IOError, e:
         log.warn('Could not load authentication information: %s' % e)
         return
+
     reader = csv.reader(pwdsf)
     auth_handler = CredHandler()
+    github_creds = get_github_credentials()
+    new_handlers = []
+    if github_creds:
+        new_handlers.append(GithubHandler(*github_creds))
+
+    use_auth_handler = False
     for l, row in enumerate(reader):
         if len(row) != 4:
             raise RuntimeError(
@@ -104,9 +156,14 @@
         realm, uris, user, password = (el.strip() for el in row)
         log.debug('Added credentials %r, %r' % (realm, uris))
         auth_handler.add_password(realm, uris, user, password)
-        handlers = []
+        use_auth_handler = True
+    if use_auth_handler:
+        new_handlers.append(auth_handler)
+    if new_handlers:
         if urllib2._opener is not None:
-            handlers[:] = urllib2._opener.handlers
-        handlers.insert(0, auth_handler)
+            handlers = urllib2._opener.handlers[:]
+            handlers[:0] = new_handlers
+        else:
+            handlers = new_handlers
         opener = urllib2.build_opener(*handlers)
         urllib2.install_opener(opener)



More information about the checkins mailing list