Repository: buildbot/buildbot

Issue:
GitHubAuth fails under Python 3.4
Received this traceback in the log after clicking the 'Login via GitHub' link and authorizing the app:

```
2017-06-25 04:02:00+0000 [-] While rendering resource:
        Traceback (most recent call last):
          File "/data/buildbot/test-master/venv/lib/python3.4/site-packages/twisted/internet/defer.py", line 1442, in gotResult
            _inlineCallbacks(r, g, deferred)
          File "/data/buildbot/test-master/venv/lib/python3.4/site-packages/twisted/internet/defer.py", line 1432, in _inlineCallbacks
            deferred.errback()
          File "/data/buildbot/test-master/venv/lib/python3.4/site-packages/twisted/internet/defer.py", line 500, in errback
            self._startRunCallbacks(fail)
          File "/data/buildbot/test-master/venv/lib/python3.4/site-packages/twisted/internet/defer.py", line 567, in _startRunCallbacks
            self._runCallbacks()
        --- <exception caught here> ---
          File "/data/buildbot/test-master/venv/lib/python3.4/site-packages/twisted/internet/defer.py", line 653, in _runCallbacks
            current.result = callback(current.result, *args, **kw)
          File "/data/buildbot/test-master/venv/lib/python3.4/site-packages/buildbot/www/resource.py", line 91, in failHttpError
            f.trap(Error)
          File "/data/buildbot/test-master/venv/lib/python3.4/site-packages/twisted/python/failure.py", line 346, in trap
            self.raiseException()
          File "/data/buildbot/test-master/venv/lib/python3.4/site-packages/twisted/python/failure.py", line 372, in raiseException
            raise self.value.with_traceback(self.tb)
          File "/data/buildbot/test-master/venv/lib/python3.4/site-packages/twisted/internet/defer.py", line 653, in _runCallbacks
            current.result = callback(current.result, *args, **kw)
          File "/data/buildbot/test-master/venv/lib/python3.4/site-packages/buildbot/www/resource.py", line 84, in failHttpRedirect
            f.trap(Redirect)
          File "/data/buildbot/test-master/venv/lib/python3.4/site-packages/twisted/python/failure.py", line 346, in trap
            self.raiseException()
          File "/data/buildbot/test-master/venv/lib/python3.4/site-packages/twisted/python/failure.py", line 372, in raiseException
            raise self.value.with_traceback(self.tb)
          File "/data/buildbot/test-master/venv/lib/python3.4/site-packages/twisted/internet/defer.py", line 1384, in _inlineCallbacks
            result = result.throwExceptionIntoGenerator(g)
          File "/data/buildbot/test-master/venv/lib/python3.4/site-packages/twisted/python/failure.py", line 393, in throwExceptionIntoGenerator
            return g.throw(self.type, self.value, self.tb)
          File "/data/buildbot/test-master/venv/lib/python3.4/site-packages/buildbot/www/oauth2.py", line 55, in renderLogin
            details = yield self.auth.verifyCode(code)
          File "/data/buildbot/test-master/venv/lib/python3.4/site-packages/twisted/python/threadpool.py", line 250, in inContext
            result = inContext.theWork()
          File "/data/buildbot/test-master/venv/lib/python3.4/site-packages/twisted/python/threadpool.py", line 266, in <lambda>
            inContext.theWork = lambda: context.call(ctx, func, *args, **kw)
          File "/data/buildbot/test-master/venv/lib/python3.4/site-packages/twisted/python/context.py", line 122, in callWithContext
            return self.currentContext().callWithContext(ctx, func, *args, **kw)
          File "/data/buildbot/test-master/venv/lib/python3.4/site-packages/twisted/python/context.py", line 85, in callWithContext
            return func(*args,**kw)
          File "/data/buildbot/test-master/venv/lib/python3.4/site-packages/buildbot/www/oauth2.py", line 163, in thd
            session = self.createSessionFromToken(content)
          File "/data/buildbot/test-master/venv/lib/python3.4/site-packages/buildbot/www/oauth2.py", line 119, in createSessionFromToken
            s.params = {'access_token': token['access_token']}
        builtins.TypeError: byte indices must be integers, not str
```

Python: 3.4.3 (Ubuntu 14.04 system python3; running from a venv)
Buildbot: 0.9.8 (all deps latest)
Configuration: [this](https://github.com/rodrigc/buildmaster-config/blob/buildbot-nine/master/master.cfg)

Works fine (as far as I can tell; first time I've tried it) under Python 2.7.


Discussion:

Resolving patch:
diff --git a/master/buildbot/www/oauth2.py b/master/buildbot/www/oauth2.py
--- a/master/buildbot/www/oauth2.py
+++ b/master/buildbot/www/oauth2.py
@@ -30,6 +30,7 @@
 from twisted.internet import threads
 
 from buildbot import config
+from buildbot.util import bytes2unicode
 from buildbot.util.logger import Logger
 from buildbot.www import auth
 from buildbot.www import resource
@@ -157,14 +158,15 @@ def thd():
             response = requests.post(
                 url, data=data, auth=auth, verify=self.sslVerify)
             response.raise_for_status()
+            responseContent = bytes2unicode(response.content)
             try:
-                content = json.loads(response.content)
+                content = json.loads(responseContent)
             except ValueError:
-                content = parse_qs(response.content)
+                content = parse_qs(responseContent)
                 for k, v in iteritems(content):
                     content[k] = v[0]
             except TypeError:
-                content = response.content
+                content = responseContent
 
             session = self.createSessionFromToken(content)
             return self.getUserInfoFromOAuthClient(session)


Test patch: