omab/django-social-auth — pull request #282 by marmida (2012-03-06 06:45:07+00:00)
Title: OAuth2 backend bails on HTTP 400s in access token requests

From [the spec section about error responses to access token requests](http://tools.ietf.org/html/draft-ietf-oauth-v2-23#section-4.1.4):

> The authorization server responds with an HTTP 400 (Bad Request) status code and includes the following parameters with the response

This code is in `BaseOAuth2.auth_complete`:

response = simplejson.loads(urlopen(request).read())

And because `urllib2.urlopen` will raise `HTTPError` whenever it sees a response that's not 2xx, that causes an unhandled exception.

The code block just below that line tries to handle that case:

if response.get('error'):
error = response.get('error_description') or response.get('error')
raise ValueError('OAuth2 authentication failed: %s' % error)

But it's never reached.

`ConsumerBasedOAuth.auth_complete` looks like it does something anticipating this status code:

except HTTPError, e:
if e.code == 400:
raise AuthCanceled(self)
else:
raise

I have added a patch that handles 400s in the same way, although I'm not certain if `AuthCanceled` or `AuthFailed` is more appropriate for the OAuth2 scenario.