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.

260 lines
7.1 KiB

  1. """Fixtures for tests."""
  2. import os
  3. import uuid
  4. import pytest
  5. from keycloak import KeycloakAdmin, KeycloakOpenID
  6. class KeycloakTestEnv(object):
  7. """Wrapper for test Keycloak connection configuration.
  8. :param host: Hostname
  9. :type host: str
  10. :param port: Port
  11. :type port: str
  12. :param username: Admin username
  13. :type username: str
  14. :param password: Admin password
  15. :type password: str
  16. """
  17. def __init__(
  18. self,
  19. host: str = os.environ["KEYCLOAK_HOST"],
  20. port: str = os.environ["KEYCLOAK_PORT"],
  21. username: str = os.environ["KEYCLOAK_ADMIN"],
  22. password: str = os.environ["KEYCLOAK_ADMIN_PASSWORD"],
  23. ):
  24. """Init method."""
  25. self.KEYCLOAK_HOST = host
  26. self.KEYCLOAK_PORT = port
  27. self.KEYCLOAK_ADMIN = username
  28. self.KEYCLOAK_ADMIN_PASSWORD = password
  29. @property
  30. def KEYCLOAK_HOST(self):
  31. """Hostname getter."""
  32. return self._KEYCLOAK_HOST
  33. @KEYCLOAK_HOST.setter
  34. def KEYCLOAK_HOST(self, value: str):
  35. """Hostname setter."""
  36. self._KEYCLOAK_HOST = value
  37. @property
  38. def KEYCLOAK_PORT(self):
  39. """Port getter."""
  40. return self._KEYCLOAK_PORT
  41. @KEYCLOAK_PORT.setter
  42. def KEYCLOAK_PORT(self, value: str):
  43. """Port setter."""
  44. self._KEYCLOAK_PORT = value
  45. @property
  46. def KEYCLOAK_ADMIN(self):
  47. """Admin username getter."""
  48. return self._KEYCLOAK_ADMIN
  49. @KEYCLOAK_ADMIN.setter
  50. def KEYCLOAK_ADMIN(self, value: str):
  51. """Admin username setter."""
  52. self._KEYCLOAK_ADMIN = value
  53. @property
  54. def KEYCLOAK_ADMIN_PASSWORD(self):
  55. """Admin password getter."""
  56. return self._KEYCLOAK_ADMIN_PASSWORD
  57. @KEYCLOAK_ADMIN_PASSWORD.setter
  58. def KEYCLOAK_ADMIN_PASSWORD(self, value: str):
  59. """Admin password setter."""
  60. self._KEYCLOAK_ADMIN_PASSWORD = value
  61. @pytest.fixture
  62. def env():
  63. """Fixture for getting the test environment configuration object."""
  64. return KeycloakTestEnv()
  65. @pytest.fixture
  66. def admin(env: KeycloakTestEnv):
  67. """Fixture for initialized KeycloakAdmin class."""
  68. return KeycloakAdmin(
  69. server_url=f"http://{env.KEYCLOAK_HOST}:{env.KEYCLOAK_PORT}",
  70. username=env.KEYCLOAK_ADMIN,
  71. password=env.KEYCLOAK_ADMIN_PASSWORD,
  72. )
  73. @pytest.fixture
  74. def oid(env: KeycloakTestEnv, realm: str, admin: KeycloakAdmin):
  75. """Fixture for initialized KeycloakOpenID class."""
  76. # Set the realm
  77. admin.realm_name = realm
  78. # Create client
  79. client = str(uuid.uuid4())
  80. client_id = admin.create_client(
  81. payload={
  82. "name": client,
  83. "clientId": client,
  84. "enabled": True,
  85. "publicClient": True,
  86. "protocol": "openid-connect",
  87. }
  88. )
  89. # Return OID
  90. yield KeycloakOpenID(
  91. server_url=f"http://{env.KEYCLOAK_HOST}:{env.KEYCLOAK_PORT}",
  92. realm_name=realm,
  93. client_id=client,
  94. )
  95. # Cleanup
  96. admin.delete_client(client_id=client_id)
  97. @pytest.fixture
  98. def oid_with_credentials(env: KeycloakTestEnv, realm: str, admin: KeycloakAdmin):
  99. """Fixture for an initialized KeycloakOpenID class and a random user credentials."""
  100. # Set the realm
  101. admin.realm_name = realm
  102. # Create client
  103. client = str(uuid.uuid4())
  104. secret = str(uuid.uuid4())
  105. client_id = admin.create_client(
  106. payload={
  107. "name": client,
  108. "clientId": client,
  109. "enabled": True,
  110. "publicClient": False,
  111. "protocol": "openid-connect",
  112. "secret": secret,
  113. "clientAuthenticatorType": "client-secret",
  114. }
  115. )
  116. # Create user
  117. username = str(uuid.uuid4())
  118. password = str(uuid.uuid4())
  119. user_id = admin.create_user(
  120. payload={
  121. "username": username,
  122. "email": f"{username}@test.test",
  123. "enabled": True,
  124. "credentials": [{"type": "password", "value": password}],
  125. }
  126. )
  127. yield (
  128. KeycloakOpenID(
  129. server_url=f"http://{env.KEYCLOAK_HOST}:{env.KEYCLOAK_PORT}",
  130. realm_name=realm,
  131. client_id=client,
  132. client_secret_key=secret,
  133. ),
  134. username,
  135. password,
  136. )
  137. # Cleanup
  138. admin.delete_client(client_id=client_id)
  139. admin.delete_user(user_id=user_id)
  140. @pytest.fixture
  141. def oid_with_credentials_authz(env: KeycloakTestEnv, realm: str, admin: KeycloakAdmin):
  142. """Fixture for an initialized KeycloakOpenID class and a random user credentials."""
  143. # Set the realm
  144. admin.realm_name = realm
  145. # Create client
  146. client = str(uuid.uuid4())
  147. secret = str(uuid.uuid4())
  148. client_id = admin.create_client(
  149. payload={
  150. "name": client,
  151. "clientId": client,
  152. "enabled": True,
  153. "publicClient": False,
  154. "protocol": "openid-connect",
  155. "secret": secret,
  156. "clientAuthenticatorType": "client-secret",
  157. "authorizationServicesEnabled": True,
  158. "serviceAccountsEnabled": True,
  159. }
  160. )
  161. admin.create_client_authz_role_based_policy(
  162. client_id=client_id,
  163. payload={
  164. "name": "test-authz-rb-policy",
  165. "roles": [{"id": admin.get_realm_role(role_name="offline_access")["id"]}],
  166. },
  167. )
  168. admin.create_client_authz_resource
  169. # Create user
  170. username = str(uuid.uuid4())
  171. password = str(uuid.uuid4())
  172. user_id = admin.create_user(
  173. payload={
  174. "username": username,
  175. "email": f"{username}@test.test",
  176. "enabled": True,
  177. "credentials": [{"type": "password", "value": password}],
  178. }
  179. )
  180. yield (
  181. KeycloakOpenID(
  182. server_url=f"http://{env.KEYCLOAK_HOST}:{env.KEYCLOAK_PORT}",
  183. realm_name=realm,
  184. client_id=client,
  185. client_secret_key=secret,
  186. ),
  187. username,
  188. password,
  189. )
  190. # Cleanup
  191. admin.delete_client(client_id=client_id)
  192. admin.delete_user(user_id=user_id)
  193. @pytest.fixture
  194. def realm(admin: KeycloakAdmin) -> str:
  195. """Fixture for a new random realm."""
  196. realm_name = str(uuid.uuid4())
  197. admin.create_realm(payload={"realm": realm_name, "enabled": True})
  198. yield realm_name
  199. admin.delete_realm(realm_name=realm_name)
  200. @pytest.fixture
  201. def user(admin: KeycloakAdmin, realm: str) -> str:
  202. """Fixture for a new random user."""
  203. admin.realm_name = realm
  204. username = str(uuid.uuid4())
  205. user_id = admin.create_user(payload={"username": username, "email": f"{username}@test.test"})
  206. yield user_id
  207. admin.delete_user(user_id=user_id)
  208. @pytest.fixture
  209. def group(admin: KeycloakAdmin, realm: str) -> str:
  210. """Fixture for a new random group."""
  211. admin.realm_name = realm
  212. group_name = str(uuid.uuid4())
  213. group_id = admin.create_group(payload={"name": group_name})
  214. yield group_id
  215. admin.delete_group(group_id=group_id)
  216. @pytest.fixture
  217. def client(admin: KeycloakAdmin, realm: str) -> str:
  218. """Fixture for a new random client."""
  219. admin.realm_name = realm
  220. client = str(uuid.uuid4())
  221. client_id = admin.create_client(payload={"name": client, "clientId": client})
  222. yield client_id
  223. admin.delete_client(client_id=client_id)