A corporation manager and dashboard for EVE Online
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 
 

97 lignes
3.3 KiB

  1. # -*- coding: utf-8 -*-
  2. from urllib.parse import urlencode
  3. import requests
  4. from ..exceptions import EVEAPIError
  5. __all__ = ["SSOManager"]
  6. class SSOManager:
  7. """EVE API module for Single Sign-On (SSO)."""
  8. def __init__(self, session):
  9. self._session = session
  10. def get_authorize_url(self, client_id, redirect_uri, scopes=None,
  11. state=None):
  12. """Return a URL that the end user can use to start a login."""
  13. baseurl = "https://login.eveonline.com/oauth/authorize?"
  14. params = {
  15. "response_type": "code",
  16. "redirect_uri": redirect_uri,
  17. "client_id": client_id
  18. }
  19. if scopes:
  20. params["scope"] = " ".join(scopes)
  21. if state is not None:
  22. params["state"] = state
  23. return baseurl + urlencode(params)
  24. def get_access_token(self, client_id, client_secret, code, refresh=False):
  25. """Given an auth code or refresh token, return an access token.
  26. If refresh is True, code should be a refresh token. Otherwise, it
  27. should be an authorization code.
  28. Does a step of OAuth2 and returns a 3-tuple of (access_token,
  29. token_expiry, refresh_token) if successful. Returns None if one of the
  30. arguments is not valid. Raises EVEAPIError if the API did not respond
  31. in a sensible way or looks to be down.
  32. """
  33. url = "https://login.eveonline.com/oauth/token"
  34. params = {"code": code}
  35. if refresh:
  36. params["grant_type"] = "refresh_token"
  37. else:
  38. params["grant_type"] = "authorization_code"
  39. try:
  40. resp = self._session.post(url, data=params, timeout=10,
  41. auth=(client_id, client_secret))
  42. json = resp.json()
  43. except (requests.RequestException, ValueError) as exc:
  44. raise EVEAPIError(str(exc))
  45. if not resp.ok or "error" in json:
  46. return None
  47. if json.get("token_type") != "Bearer":
  48. raise EVEAPIError("invalid token_type in response body")
  49. token = json.get("access_token")
  50. expiry = json.get("expires_in")
  51. refresh = json.get("refresh_token")
  52. if not token or not expiry or not refresh:
  53. raise EVEAPIError("missing data in token response body")
  54. return token, expiry, refresh
  55. def get_character_info(self, token):
  56. """Given an access token, return character info.
  57. If successful, returns a 2-tuple of (character_id, character_name).
  58. Returns None if the token isn't valid. Raises EVEAPIError if the API
  59. did not respond in a sensible way or looks to be down.
  60. """
  61. url = "https://login.eveonline.com/oauth/verify"
  62. headers = {"Authorization": "Bearer " + token}
  63. try:
  64. resp = self._session.get(url, timeout=10, headers=headers)
  65. json = resp.json()
  66. except (requests.RequestException, ValueError) as exc:
  67. raise EVEAPIError(str(exc))
  68. if not resp.ok or "error" in json:
  69. return None
  70. char_id = json.get("CharacterID")
  71. char_name = json.get("CharacterName")
  72. if not char_id or not char_name:
  73. raise EVEAPIError("missing character ID or name in response body")
  74. return char_id, char_name