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.

259 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. # Create user
  169. username = str(uuid.uuid4())
  170. password = str(uuid.uuid4())
  171. user_id = admin.create_user(
  172. payload={
  173. "username": username,
  174. "email": f"{username}@test.test",
  175. "enabled": True,
  176. "credentials": [{"type": "password", "value": password}],
  177. }
  178. )
  179. yield (
  180. KeycloakOpenID(
  181. server_url=f"http://{env.KEYCLOAK_HOST}:{env.KEYCLOAK_PORT}",
  182. realm_name=realm,
  183. client_id=client,
  184. client_secret_key=secret,
  185. ),
  186. username,
  187. password,
  188. )
  189. # Cleanup
  190. admin.delete_client(client_id=client_id)
  191. admin.delete_user(user_id=user_id)
  192. @pytest.fixture
  193. def realm(admin: KeycloakAdmin) -> str:
  194. """Fixture for a new random realm."""
  195. realm_name = str(uuid.uuid4())
  196. admin.create_realm(payload={"realm": realm_name, "enabled": True})
  197. yield realm_name
  198. admin.delete_realm(realm_name=realm_name)
  199. @pytest.fixture
  200. def user(admin: KeycloakAdmin, realm: str) -> str:
  201. """Fixture for a new random user."""
  202. admin.realm_name = realm
  203. username = str(uuid.uuid4())
  204. user_id = admin.create_user(payload={"username": username, "email": f"{username}@test.test"})
  205. yield user_id
  206. admin.delete_user(user_id=user_id)
  207. @pytest.fixture
  208. def group(admin: KeycloakAdmin, realm: str) -> str:
  209. """Fixture for a new random group."""
  210. admin.realm_name = realm
  211. group_name = str(uuid.uuid4())
  212. group_id = admin.create_group(payload={"name": group_name})
  213. yield group_id
  214. admin.delete_group(group_id=group_id)
  215. @pytest.fixture
  216. def client(admin: KeycloakAdmin, realm: str) -> str:
  217. """Fixture for a new random client."""
  218. admin.realm_name = realm
  219. client = str(uuid.uuid4())
  220. client_id = admin.create_client(payload={"name": client, "clientId": client})
  221. yield client_id
  222. admin.delete_client(client_id=client_id)