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.

220 lines
7.3 KiB

7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
6 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
  1. # -*- coding: utf-8 -*-
  2. #
  3. # The MIT License (MIT)
  4. #
  5. # Copyright (C) 2017 Marcos Pereira <marcospereira.mpj@gmail.com>
  6. #
  7. # Permission is hereby granted, free of charge, to any person obtaining a copy of
  8. # this software and associated documentation files (the "Software"), to deal in
  9. # the Software without restriction, including without limitation the rights to
  10. # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  11. # the Software, and to permit persons to whom the Software is furnished to do so,
  12. # subject to the following conditions:
  13. #
  14. # The above copyright notice and this permission notice shall be included in all
  15. # copies or substantial portions of the Software.
  16. #
  17. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  19. # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  20. # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  21. # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  22. # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23. try:
  24. from urllib.parse import urljoin
  25. except ImportError:
  26. from urlparse import urljoin
  27. import requests
  28. from requests.adapters import HTTPAdapter
  29. from .exceptions import (KeycloakConnectionError)
  30. class ConnectionManager(object):
  31. """ Represents a simple server connection.
  32. Args:
  33. base_url (str): The server URL.
  34. headers (dict): The header parameters of the requests to the server.
  35. timeout (int): Timeout to use for requests to the server.
  36. verify (bool): Verify server SSL.
  37. """
  38. def __init__(self, base_url, headers={}, timeout=60, verify=True):
  39. self._base_url = base_url
  40. self._headers = headers
  41. self._timeout = timeout
  42. self._verify = verify
  43. self._s = requests.Session()
  44. self._s.auth = lambda x: x # don't let requests add auth headers
  45. # retry once to reset connection with Keycloak after tomcat's ConnectionTimeout
  46. # see https://github.com/marcospereirampj/python-keycloak/issues/36
  47. for protocol in ('https://', 'http://'):
  48. adapter = HTTPAdapter(max_retries=1)
  49. # adds POST to retry whitelist
  50. method_whitelist = set(adapter.max_retries.method_whitelist)
  51. method_whitelist.add('POST')
  52. adapter.max_retries.method_whitelist = frozenset(method_whitelist)
  53. self._s.mount(protocol, adapter)
  54. @property
  55. def base_url(self):
  56. """ Return base url in use for requests to the server. """
  57. return self._base_url
  58. @base_url.setter
  59. def base_url(self, value):
  60. """ """
  61. self._base_url = value
  62. @property
  63. def timeout(self):
  64. """ Return timeout in use for request to the server. """
  65. return self._timeout
  66. @timeout.setter
  67. def timeout(self, value):
  68. """ """
  69. self._timeout = value
  70. @property
  71. def verify(self):
  72. """ Return verify in use for request to the server. """
  73. return self._verify
  74. @verify.setter
  75. def verify(self, value):
  76. """ """
  77. self._verify = value
  78. @property
  79. def headers(self):
  80. """ Return header request to the server. """
  81. return self._headers
  82. @headers.setter
  83. def headers(self, value):
  84. """ """
  85. self._headers = value
  86. def param_headers(self, key):
  87. """ Return a specific header parameter.
  88. :arg
  89. key (str): Header parameters key.
  90. :return:
  91. If the header parameters exist, return its value.
  92. """
  93. return self.headers.get(key)
  94. def clean_headers(self):
  95. """ Clear header parameters. """
  96. self.headers = {}
  97. def exist_param_headers(self, key):
  98. """ Check if the parameter exists in the header.
  99. :arg
  100. key (str): Header parameters key.
  101. :return:
  102. If the header parameters exist, return True.
  103. """
  104. return self.param_headers(key) is not None
  105. def add_param_headers(self, key, value):
  106. """ Add a single parameter inside the header.
  107. :arg
  108. key (str): Header parameters key.
  109. value (str): Value to be added.
  110. """
  111. self.headers[key] = value
  112. def del_param_headers(self, key):
  113. """ Remove a specific parameter.
  114. :arg
  115. key (str): Key of the header parameters.
  116. """
  117. self.headers.pop(key, None)
  118. def raw_get(self, path, **kwargs):
  119. """ Submit get request to the path.
  120. :arg
  121. path (str): Path for request.
  122. :return
  123. Response the request.
  124. :exception
  125. HttpError: Can't connect to server.
  126. """
  127. try:
  128. return self._s.get(urljoin(self.base_url, path),
  129. params=kwargs,
  130. headers=self.headers,
  131. timeout=self.timeout,
  132. verify=self.verify)
  133. except Exception as e:
  134. raise KeycloakConnectionError(
  135. "Can't connect to server (%s)" % e)
  136. def raw_post(self, path, data, **kwargs):
  137. """ Submit post request to the path.
  138. :arg
  139. path (str): Path for request.
  140. data (dict): Payload for request.
  141. :return
  142. Response the request.
  143. :exception
  144. HttpError: Can't connect to server.
  145. """
  146. try:
  147. return self._s.post(urljoin(self.base_url, path),
  148. params=kwargs,
  149. data=data,
  150. headers=self.headers,
  151. timeout=self.timeout,
  152. verify=self.verify)
  153. except Exception as e:
  154. raise KeycloakConnectionError(
  155. "Can't connect to server (%s)" % e)
  156. def raw_put(self, path, data, **kwargs):
  157. """ Submit put request to the path.
  158. :arg
  159. path (str): Path for request.
  160. data (dict): Payload for request.
  161. :return
  162. Response the request.
  163. :exception
  164. HttpError: Can't connect to server.
  165. """
  166. try:
  167. return self._s.put(urljoin(self.base_url, path),
  168. params=kwargs,
  169. data=data,
  170. headers=self.headers,
  171. timeout=self.timeout,
  172. verify=self.verify)
  173. except Exception as e:
  174. raise KeycloakConnectionError(
  175. "Can't connect to server (%s)" % e)
  176. def raw_delete(self, path, **kwargs):
  177. """ Submit delete request to the path.
  178. :arg
  179. path (str): Path for request.
  180. :return
  181. Response the request.
  182. :exception
  183. HttpError: Can't connect to server.
  184. """
  185. try:
  186. return self._s.delete(urljoin(self.base_url, path),
  187. params=kwargs,
  188. headers=self.headers,
  189. timeout=self.timeout,
  190. verify=self.verify)
  191. except Exception as e:
  192. raise KeycloakConnectionError(
  193. "Can't connect to server (%s)" % e)