PageRenderTime 39ms CodeModel.GetById 6ms RepoModel.GetById 0ms app.codeStats 0ms

/social/backends/bitbucket.py

https://github.com/itjp/python-social-auth
Python | 79 lines | 48 code | 6 blank | 25 comment | 8 complexity | e2cf2bd45c8bb9b864629343200aec4f MD5 | raw file
Possible License(s): BSD-3-Clause
  1. """
  2. Bitbucket OAuth support.
  3. This adds support for Bitbucket OAuth service. An application must
  4. be registered first on Bitbucket and the settings BITBUCKET_CONSUMER_KEY
  5. and BITBUCKET_CONSUMER_SECRET must be defined with the corresponding
  6. values.
  7. By default username, email, token expiration time, first name and last name are
  8. stored in extra_data field, check OAuthBackend class for details on how to
  9. extend it.
  10. """
  11. import json
  12. from social.backends.oauth import ConsumerBasedOAuth
  13. class BitbucketOAuth(ConsumerBasedOAuth):
  14. """Bitbucket OAuth authentication backend"""
  15. name = 'bitbucket'
  16. ID_KEY = 'username'
  17. AUTHORIZATION_URL = 'https://bitbucket.org/api/1.0/oauth/authenticate'
  18. REQUEST_TOKEN_URL = 'https://bitbucket.org/api/1.0/oauth/request_token'
  19. ACCESS_TOKEN_URL = 'https://bitbucket.org/api/1.0/oauth/access_token'
  20. EXTRA_DATA = [
  21. ('username', 'username'),
  22. ('expires', 'expires'),
  23. ('email', 'email'),
  24. ('first_name', 'first_name'),
  25. ('last_name', 'last_name')
  26. ]
  27. def get_user_details(self, response):
  28. """Return user details from Bitbucket account"""
  29. return {'username': response.get('username'),
  30. 'email': response.get('email'),
  31. 'fullname': ' '.join((response.get('first_name'),
  32. response.get('last_name'))),
  33. 'first_name': response.get('first_name'),
  34. 'last_name': response.get('last_name')}
  35. @classmethod
  36. def tokens(cls, instance):
  37. """Return the tokens needed to authenticate the access to any API the
  38. service might provide. Bitbucket uses a pair of OAuthToken consisting
  39. on a oauth_token and oauth_token_secret.
  40. instance must be a UserSocialAuth instance.
  41. """
  42. token = super(BitbucketOAuth, cls).tokens(instance)
  43. if token and 'access_token' in token:
  44. token = dict(tok.split('=')
  45. for tok in token['access_token'].split('&'))
  46. return token
  47. def user_data(self, access_token):
  48. """Return user data provided"""
  49. # Bitbucket has a bit of an indirect route to obtain user data from an
  50. # authenticated query: First obtain the user's email via an
  51. # authenticated GET
  52. url = 'https://bitbucket.org/api/1.0/emails/'
  53. request = self.oauth_request(access_token, url)
  54. response = self.fetch_response(request)
  55. try:
  56. # Then retrieve the user's primary email address or the top email
  57. email_addresses = json.loads(response)
  58. for email_address in reversed(email_addresses):
  59. if email_address['active']:
  60. email = email_address['email']
  61. if email_address['primary']:
  62. break
  63. url = 'https://bitbucket.org/api/1.0/users/'
  64. response = self.urlopen(url + email)
  65. user_details = json.load(response)['user']
  66. user_details['email'] = email
  67. return user_details
  68. except ValueError:
  69. return None
  70. return None