asana.py 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. """
  2. Obtain
  3. ASANA_CLIENT_ID & ASANA_CLIENT_SECRET
  4. and put into sentry.conf.py
  5. """
  6. import requests
  7. from social_auth.backends import BaseOAuth2, OAuthBackend
  8. from social_auth.exceptions import AuthCanceled, AuthUnknownError
  9. ASANA_TOKEN_EXCHANGE_URL = "https://app.asana.com/-/oauth_token"
  10. ASANA_AUTHORIZATION_URL = "https://app.asana.com/-/oauth_authorize"
  11. ASANA_USER_DETAILS_URL = "https://app.asana.com/api/1.0/users/me"
  12. class AsanaBackend(OAuthBackend):
  13. """Asana OAuth authentication backend"""
  14. name = "asana"
  15. EXTRA_DATA = [
  16. ("email", "email"),
  17. ("name", "full_name"),
  18. ("gid", "id"),
  19. ("refresh_token", "refresh_token"),
  20. ]
  21. ID_KEY = "gid"
  22. def get_user_details(self, response):
  23. """Return user details from Asana account"""
  24. return {
  25. "email": response.get("email"),
  26. "id": response.get("gid"),
  27. "full_name": response.get("name"),
  28. }
  29. class AsanaAuth(BaseOAuth2):
  30. """Asana OAuth authentication mechanism"""
  31. AUTHORIZATION_URL = ASANA_AUTHORIZATION_URL
  32. ACCESS_TOKEN_URL = ASANA_TOKEN_EXCHANGE_URL
  33. AUTH_BACKEND = AsanaBackend
  34. SETTINGS_KEY_NAME = "ASANA_CLIENT_ID"
  35. SETTINGS_SECRET_NAME = "ASANA_CLIENT_SECRET"
  36. REDIRECT_STATE = False
  37. def user_data(self, access_token, *args, **kwargs):
  38. """Loads user data from service"""
  39. headers = {"Authorization": f"Bearer {access_token}"}
  40. try:
  41. resp = requests.get(ASANA_USER_DETAILS_URL, headers=headers)
  42. resp.raise_for_status()
  43. return resp.json()["data"]
  44. except ValueError:
  45. return None
  46. def auth_complete(self, *args, **kwargs):
  47. """Completes logging process, must return user instance"""
  48. self.process_error(self.data)
  49. params = self.auth_complete_params(self.validate_state())
  50. response = requests.post(self.ACCESS_TOKEN_URL, data=params, headers=self.auth_headers())
  51. if response.status_code == 400:
  52. raise AuthCanceled(self)
  53. response.raise_for_status()
  54. try:
  55. response_json = response.json()
  56. except (ValueError, KeyError):
  57. raise AuthUnknownError(self)
  58. response_json.pop("data")
  59. self.process_error(response_json)
  60. return self.do_auth(response_json["access_token"], response=response_json, *args, **kwargs)
  61. # Backend definition
  62. BACKENDS = {"asana": AsanaAuth}