PageRenderTime 48ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/social_auth/backends/contrib/bitbucket.py

https://github.com/seaeast/django-social-auth
Python | 108 lines | 87 code | 5 blank | 16 comment | 0 complexity | 39313c2157998b0a93e0af011c49f751 MD5 | raw file
Possible License(s): BSD-3-Clause, BSD-2-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. from django.utils import simplejson
  12. from social_auth.backends import ConsumerBasedOAuth, OAuthBackend, USERNAME
  13. from social_auth.utils import setting, dsa_urlopen
  14. # Bitbucket configuration
  15. BITBUCKET_SERVER = 'bitbucket.org/api/1.0'
  16. BITBUCKET_REQUEST_TOKEN_URL = 'https://%s/oauth/request_token' % \
  17. BITBUCKET_SERVER
  18. BITBUCKET_ACCESS_TOKEN_URL = 'https://%s/oauth/access_token' % BITBUCKET_SERVER
  19. BITBUCKET_AUTHORIZATION_URL = 'https://%s/oauth/authenticate' % \
  20. BITBUCKET_SERVER
  21. BITBUCKET_EMAIL_DATA_URL = 'https://%s/emails/' % BITBUCKET_SERVER
  22. BITBUCKET_USER_DATA_URL = 'https://%s/users/' % BITBUCKET_SERVER
  23. class BitbucketBackend(OAuthBackend):
  24. """Bitbucket OAuth authentication backend"""
  25. name = 'bitbucket'
  26. EXTRA_DATA = [
  27. ('username', 'username'),
  28. ('expires', setting('SOCIAL_AUTH_EXPIRATION', 'expires')),
  29. ('email', 'email'),
  30. ('first_name', 'first_name'),
  31. ('last_name', 'last_name')
  32. ]
  33. def get_user_details(self, response):
  34. """Return user details from Bitbucket account"""
  35. return {USERNAME: response.get('username'),
  36. 'email': response.get('email'),
  37. 'fullname': ' '.join((response.get('first_name'),
  38. response.get('last_name'))),
  39. 'first_name': response.get('first_name'),
  40. 'last_name': response.get('last_name')}
  41. def get_user_id(self, details, response):
  42. """Return the user id, Bitbucket only provides username as a unique
  43. identifier"""
  44. return response['username']
  45. @classmethod
  46. def tokens(cls, instance):
  47. """Return the tokens needed to authenticate the access to any API the
  48. service might provide. Bitbucket uses a pair of OAuthToken consisting
  49. on a oauth_token and oauth_token_secret.
  50. instance must be a UserSocialAuth instance.
  51. """
  52. token = super(BitbucketBackend, cls).tokens(instance)
  53. if token and 'access_token' in token:
  54. token = dict(tok.split('=')
  55. for tok in token['access_token'].split('&'))
  56. return token
  57. class BitbucketAuth(ConsumerBasedOAuth):
  58. """Bitbucket OAuth authentication mechanism"""
  59. AUTHORIZATION_URL = BITBUCKET_AUTHORIZATION_URL
  60. REQUEST_TOKEN_URL = BITBUCKET_REQUEST_TOKEN_URL
  61. ACCESS_TOKEN_URL = BITBUCKET_ACCESS_TOKEN_URL
  62. SERVER_URL = BITBUCKET_SERVER
  63. AUTH_BACKEND = BitbucketBackend
  64. SETTINGS_KEY_NAME = 'BITBUCKET_CONSUMER_KEY'
  65. SETTINGS_SECRET_NAME = 'BITBUCKET_CONSUMER_SECRET'
  66. def user_data(self, access_token):
  67. """Return user data provided"""
  68. # Bitbucket has a bit of an indirect route to obtain user data from an
  69. # authenticated query: First obtain the user's email via an
  70. # authenticated GET
  71. url = BITBUCKET_EMAIL_DATA_URL
  72. request = self.oauth_request(access_token, url)
  73. response = self.fetch_response(request)
  74. try:
  75. # Then retrieve the user's primary email address or the top email
  76. email_addresses = simplejson.loads(response)
  77. for email_address in reversed(email_addresses):
  78. if email_address['active']:
  79. email = email_address['email']
  80. if email_address['primary']:
  81. break
  82. # Then return the user data using a normal GET with the
  83. # BITBUCKET_USER_DATA_URL and the user's email
  84. response = dsa_urlopen(BITBUCKET_USER_DATA_URL + email)
  85. user_details = simplejson.load(response)['user']
  86. user_details['email'] = email
  87. return user_details
  88. except ValueError:
  89. return None
  90. return None
  91. # Backend definition
  92. BACKENDS = {
  93. 'bitbucket': BitbucketAuth,
  94. }