You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

108 lines
3.7 KiB

7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
  1. """
  2. """
  3. import json
  4. from keycloak.exceptions import raise_error_from_response, KeycloakGetError
  5. from .urls_patterns import URL_AUTH, URL_TOKEN, URL_USERINFO, URL_WELL_KNOWN, URL_LOGOUT
  6. from .connection import ConnectionManager
  7. class Keycloak:
  8. def __init__(self, server_url, client_id, realm_name, client_secret_key=None):
  9. self.__client_id = client_id
  10. self.__client_secret_key = client_secret_key
  11. self.__realm_name = realm_name
  12. self.__connection = ConnectionManager(base_url=server_url,
  13. headers={},
  14. timeout=60)
  15. def well_know(self):
  16. """ The most important endpoint to understand is the well-known configuration
  17. endpoint. It lists endpoints and other configuration options relevant to
  18. the OpenID Connect implementation in Keycloak.
  19. :return It lists endpoints and other configuration options relevant.
  20. """
  21. params_path = {"realm-name": self.__realm_name}
  22. data_raw = self.__connection.raw_get(URL_WELL_KNOWN.format(**params_path))
  23. raise_error_from_response(data_raw, KeycloakGetError)
  24. return json.loads(data_raw.text)
  25. def auth_url(self, redirect_uri):
  26. """
  27. http://openid.net/specs/openid-connect-core-1_0.html#AuthorizationEndpoint
  28. :return:
  29. """
  30. return NotImplemented
  31. def token(self, username, password, grant_type=["password",]):
  32. """
  33. The token endpoint is used to obtain tokens. Tokens can either be obtained by
  34. exchanging an authorization code or by supplying credentials directly depending on
  35. what flow is used. The token endpoint is also used to obtain new access tokens
  36. when they expire.
  37. http://openid.net/specs/openid-connect-core-1_0.html#TokenEndpoint
  38. :param username:
  39. :param password:
  40. :param grant_type:
  41. :return:
  42. """
  43. params_path = {"realm-name": self.__realm_name}
  44. payload = {"username": username, "password": password,
  45. "client_id": self.__client_id, "grant_type": grant_type}
  46. if self.__client_secret_key:
  47. payload.update({"client_secret": self.__client_secret_key})
  48. data_raw = self.__connection.raw_post(URL_TOKEN.format(**params_path),
  49. data=payload)
  50. raise_error_from_response(data_raw, KeycloakGetError)
  51. return json.loads(data_raw.text)
  52. def userinfo(self, token):
  53. """
  54. The userinfo endpoint returns standard claims about the authenticated user,
  55. and is protected by a bearer token.
  56. http://openid.net/specs/openid-connect-core-1_0.html#UserInfo
  57. :param token:
  58. :return:
  59. """
  60. self.__connection.add_param_headers("Authorization", "Bearer " + token)
  61. params_path = {"realm-name": self.__realm_name}
  62. data_raw = self.__connection.raw_get(URL_USERINFO.format(**params_path))
  63. raise_error_from_response(data_raw, KeycloakGetError)
  64. return json.loads(data_raw.text)
  65. def logout(self, refresh_token):
  66. """
  67. The logout endpoint logs out the authenticated user.
  68. :param refresh_token:
  69. :return:
  70. """
  71. params_path = {"realm-name": self.__realm_name}
  72. payload = {"client_id": self.__client_id, "refresh_token": refresh_token}
  73. if self.__client_secret_key:
  74. payload.update({"client_secret": self.__client_secret_key})
  75. data_raw = self.__connection.raw_post(URL_LOGOUT.format(**params_path),
  76. data=payload)
  77. raise_error_from_response(data_raw, KeycloakGetError, expected_code=204)
  78. return None