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.

233 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
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. proxies (dict): The proxies servers requests is sent by.
  38. """
  39. def __init__(self, base_url, headers={}, timeout=60, verify=True, proxies=None):
  40. self._base_url = base_url
  41. self._headers = headers
  42. self._timeout = timeout
  43. self._verify = verify
  44. self._s = requests.Session()
  45. self._s.auth = lambda x: x # don't let requests add auth headers
  46. # retry once to reset connection with Keycloak after tomcat's ConnectionTimeout
  47. # see https://github.com/marcospereirampj/python-keycloak/issues/36
  48. for protocol in ("https://", "http://"):
  49. adapter = HTTPAdapter(max_retries=1)
  50. # adds POST to retry whitelist
  51. allowed_methods = set(adapter.max_retries.allowed_methods)
  52. allowed_methods.add("POST")
  53. adapter.max_retries.allowed_methods = frozenset(allowed_methods)
  54. self._s.mount(protocol, adapter)
  55. if proxies:
  56. self._s.proxies.update(proxies)
  57. def __del__(self):
  58. self._s.close()
  59. @property
  60. def base_url(self):
  61. """Return base url in use for requests to the server."""
  62. return self._base_url
  63. @base_url.setter
  64. def base_url(self, value):
  65. """ """
  66. self._base_url = value
  67. @property
  68. def timeout(self):
  69. """Return timeout in use for request to the server."""
  70. return self._timeout
  71. @timeout.setter
  72. def timeout(self, value):
  73. """ """
  74. self._timeout = value
  75. @property
  76. def verify(self):
  77. """Return verify in use for request to the server."""
  78. return self._verify
  79. @verify.setter
  80. def verify(self, value):
  81. """ """
  82. self._verify = value
  83. @property
  84. def headers(self):
  85. """Return header request to the server."""
  86. return self._headers
  87. @headers.setter
  88. def headers(self, value):
  89. """ """
  90. self._headers = value
  91. def param_headers(self, key):
  92. """Return a specific header parameter.
  93. :arg
  94. key (str): Header parameters key.
  95. :return:
  96. If the header parameters exist, return its value.
  97. """
  98. return self.headers.get(key)
  99. def clean_headers(self):
  100. """Clear header parameters."""
  101. self.headers = {}
  102. def exist_param_headers(self, key):
  103. """Check if the parameter exists in the header.
  104. :arg
  105. key (str): Header parameters key.
  106. :return:
  107. If the header parameters exist, return True.
  108. """
  109. return self.param_headers(key) is not None
  110. def add_param_headers(self, key, value):
  111. """Add a single parameter inside the header.
  112. :arg
  113. key (str): Header parameters key.
  114. value (str): Value to be added.
  115. """
  116. self.headers[key] = value
  117. def del_param_headers(self, key):
  118. """Remove a specific parameter.
  119. :arg
  120. key (str): Key of the header parameters.
  121. """
  122. self.headers.pop(key, None)
  123. def raw_get(self, path, **kwargs):
  124. """Submit get request to the path.
  125. :arg
  126. path (str): Path for request.
  127. :return
  128. Response the request.
  129. :exception
  130. HttpError: Can't connect to server.
  131. """
  132. try:
  133. return self._s.get(
  134. urljoin(self.base_url, path),
  135. params=kwargs,
  136. headers=self.headers,
  137. timeout=self.timeout,
  138. verify=self.verify,
  139. )
  140. except Exception as e:
  141. raise KeycloakConnectionError("Can't connect to server (%s)" % e)
  142. def raw_post(self, path, data, **kwargs):
  143. """Submit post request to the path.
  144. :arg
  145. path (str): Path for request.
  146. data (dict): Payload for request.
  147. :return
  148. Response the request.
  149. :exception
  150. HttpError: Can't connect to server.
  151. """
  152. try:
  153. return self._s.post(
  154. urljoin(self.base_url, path),
  155. params=kwargs,
  156. data=data,
  157. headers=self.headers,
  158. timeout=self.timeout,
  159. verify=self.verify,
  160. )
  161. except Exception as e:
  162. raise KeycloakConnectionError("Can't connect to server (%s)" % e)
  163. def raw_put(self, path, data, **kwargs):
  164. """Submit put request to the path.
  165. :arg
  166. path (str): Path for request.
  167. data (dict): Payload for request.
  168. :return
  169. Response the request.
  170. :exception
  171. HttpError: Can't connect to server.
  172. """
  173. try:
  174. return self._s.put(
  175. urljoin(self.base_url, path),
  176. params=kwargs,
  177. data=data,
  178. headers=self.headers,
  179. timeout=self.timeout,
  180. verify=self.verify,
  181. )
  182. except Exception as e:
  183. raise KeycloakConnectionError("Can't connect to server (%s)" % e)
  184. def raw_delete(self, path, data={}, **kwargs):
  185. """Submit delete request to the path.
  186. :arg
  187. path (str): Path for request.
  188. data (dict): Payload for request.
  189. :return
  190. Response the request.
  191. :exception
  192. HttpError: Can't connect to server.
  193. """
  194. try:
  195. return self._s.delete(
  196. urljoin(self.base_url, path),
  197. params=kwargs,
  198. data=data,
  199. headers=self.headers,
  200. timeout=self.timeout,
  201. verify=self.verify,
  202. )
  203. except Exception as e:
  204. raise KeycloakConnectionError("Can't connect to server (%s)" % e)