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.

1780 lines
66 KiB

  1. import pytest
  2. import keycloak
  3. from keycloak import KeycloakAdmin
  4. from keycloak.connection import ConnectionManager
  5. from keycloak.exceptions import (
  6. KeycloakAuthenticationError,
  7. KeycloakDeleteError,
  8. KeycloakGetError,
  9. KeycloakPostError,
  10. KeycloakPutError,
  11. )
  12. def test_keycloak_version():
  13. assert keycloak.__version__, keycloak.__version__
  14. def test_keycloak_admin_bad_init(env):
  15. with pytest.raises(TypeError) as err:
  16. KeycloakAdmin(
  17. server_url=f"http://{env.KEYCLOAK_HOST}:{env.KEYCLOAK_PORT}",
  18. username=env.KEYCLOAK_ADMIN,
  19. password=env.KEYCLOAK_ADMIN_PASSWORD,
  20. auto_refresh_token=1,
  21. )
  22. assert err.match("Expected a list of strings")
  23. with pytest.raises(TypeError) as err:
  24. KeycloakAdmin(
  25. server_url=f"http://{env.KEYCLOAK_HOST}:{env.KEYCLOAK_PORT}",
  26. username=env.KEYCLOAK_ADMIN,
  27. password=env.KEYCLOAK_ADMIN_PASSWORD,
  28. auto_refresh_token=["patch"],
  29. )
  30. assert err.match("Unexpected method in auto_refresh_token")
  31. def test_keycloak_admin_init(env):
  32. admin = KeycloakAdmin(
  33. server_url=f"http://{env.KEYCLOAK_HOST}:{env.KEYCLOAK_PORT}",
  34. username=env.KEYCLOAK_ADMIN,
  35. password=env.KEYCLOAK_ADMIN_PASSWORD,
  36. )
  37. assert admin.server_url == f"http://{env.KEYCLOAK_HOST}:{env.KEYCLOAK_PORT}", admin.server_url
  38. assert admin.realm_name == "master", admin.realm_name
  39. assert isinstance(admin.connection, ConnectionManager), type(admin.connection)
  40. assert admin.client_id == "admin-cli", admin.client_id
  41. assert admin.client_secret_key is None, admin.client_secret_key
  42. assert admin.verify, admin.verify
  43. assert admin.username == env.KEYCLOAK_ADMIN, admin.username
  44. assert admin.password == env.KEYCLOAK_ADMIN_PASSWORD, admin.password
  45. assert admin.totp is None, admin.totp
  46. assert admin.token is not None, admin.token
  47. assert admin.auto_refresh_token == list(), admin.auto_refresh_token
  48. assert admin.user_realm_name is None, admin.user_realm_name
  49. assert admin.custom_headers is None, admin.custom_headers
  50. assert admin.token
  51. admin = KeycloakAdmin(
  52. server_url=f"http://{env.KEYCLOAK_HOST}:{env.KEYCLOAK_PORT}",
  53. username=env.KEYCLOAK_ADMIN,
  54. password=env.KEYCLOAK_ADMIN_PASSWORD,
  55. realm_name=None,
  56. user_realm_name="master",
  57. )
  58. assert admin.token
  59. admin = KeycloakAdmin(
  60. server_url=f"http://{env.KEYCLOAK_HOST}:{env.KEYCLOAK_PORT}",
  61. username=env.KEYCLOAK_ADMIN,
  62. password=env.KEYCLOAK_ADMIN_PASSWORD,
  63. realm_name=None,
  64. user_realm_name=None,
  65. )
  66. assert admin.token
  67. admin.create_realm(payload={"realm": "authz", "enabled": True})
  68. admin.realm_name = "authz"
  69. admin.create_client(
  70. payload={
  71. "name": "authz-client",
  72. "clientId": "authz-client",
  73. "authorizationServicesEnabled": True,
  74. "serviceAccountsEnabled": True,
  75. "clientAuthenticatorType": "client-secret",
  76. "directAccessGrantsEnabled": False,
  77. "enabled": True,
  78. "implicitFlowEnabled": False,
  79. "publicClient": False,
  80. }
  81. )
  82. secret = admin.generate_client_secrets(client_id=admin.get_client_id("authz-client"))
  83. assert KeycloakAdmin(
  84. server_url=f"http://{env.KEYCLOAK_HOST}:{env.KEYCLOAK_PORT}",
  85. user_realm_name="authz",
  86. client_id="authz-client",
  87. client_secret_key=secret["value"],
  88. ).token
  89. admin.delete_realm(realm_name="authz")
  90. assert (
  91. KeycloakAdmin(
  92. server_url=f"http://{env.KEYCLOAK_HOST}:{env.KEYCLOAK_PORT}",
  93. username=None,
  94. password=None,
  95. client_secret_key=None,
  96. custom_headers={"custom": "header"},
  97. ).token
  98. is None
  99. )
  100. def test_realms(admin: KeycloakAdmin):
  101. # Get realms
  102. realms = admin.get_realms()
  103. assert len(realms) == 1, realms
  104. assert "master" == realms[0]["realm"]
  105. # Create a test realm
  106. res = admin.create_realm(payload={"realm": "test"})
  107. assert res == b"", res
  108. # Create the same realm, should fail
  109. with pytest.raises(KeycloakPostError) as err:
  110. res = admin.create_realm(payload={"realm": "test"})
  111. assert err.match('409: b\'{"errorMessage":"Conflict detected. See logs for details"}\'')
  112. # Create the same realm, skip_exists true
  113. res = admin.create_realm(payload={"realm": "test"}, skip_exists=True)
  114. assert res == {"msg": "Already exists"}, res
  115. # Get a single realm
  116. res = admin.get_realm(realm_name="test")
  117. assert res["realm"] == "test"
  118. # Get non-existing realm
  119. with pytest.raises(KeycloakGetError) as err:
  120. admin.get_realm(realm_name="non-existent")
  121. assert err.match('404: b\'{"error":"Realm not found."}\'')
  122. # Update realm
  123. res = admin.update_realm(realm_name="test", payload={"accountTheme": "test"})
  124. assert res == dict(), res
  125. # Check that the update worked
  126. res = admin.get_realm(realm_name="test")
  127. assert res["realm"] == "test"
  128. assert res["accountTheme"] == "test"
  129. # Update wrong payload
  130. with pytest.raises(KeycloakPutError) as err:
  131. admin.update_realm(realm_name="test", payload={"wrong": "payload"})
  132. assert err.match('400: b\'{"error":"Unrecognized field')
  133. # Check that get realms returns both realms
  134. realms = admin.get_realms()
  135. realm_names = [x["realm"] for x in realms]
  136. assert len(realms) == 2, realms
  137. assert "master" in realm_names, realm_names
  138. assert "test" in realm_names, realm_names
  139. # Delete the realm
  140. res = admin.delete_realm(realm_name="test")
  141. assert res == dict(), res
  142. # Check that the realm does not exist anymore
  143. with pytest.raises(KeycloakGetError) as err:
  144. admin.get_realm(realm_name="test")
  145. assert err.match('404: b\'{"error":"Realm not found."}\'')
  146. # Delete non-existing realm
  147. with pytest.raises(KeycloakDeleteError) as err:
  148. admin.delete_realm(realm_name="non-existent")
  149. assert err.match('404: b\'{"error":"Realm not found."}\'')
  150. def test_import_export_realms(admin: KeycloakAdmin, realm: str):
  151. admin.realm_name = realm
  152. realm_export = admin.export_realm(export_clients=True, export_groups_and_role=True)
  153. assert realm_export != dict(), realm_export
  154. admin.delete_realm(realm_name=realm)
  155. admin.realm_name = "master"
  156. res = admin.import_realm(payload=realm_export)
  157. assert res == b"", res
  158. # Test bad import
  159. with pytest.raises(KeycloakPostError) as err:
  160. admin.import_realm(payload=dict())
  161. assert err.match('500: b\'{"error":"unknown_error"}\'')
  162. def test_users(admin: KeycloakAdmin, realm: str):
  163. admin.realm_name = realm
  164. # Check no users present
  165. users = admin.get_users()
  166. assert users == list(), users
  167. # Test create user
  168. user_id = admin.create_user(payload={"username": "test", "email": "test@test.test"})
  169. assert user_id is not None, user_id
  170. # Test create the same user
  171. with pytest.raises(KeycloakPostError) as err:
  172. admin.create_user(payload={"username": "test", "email": "test@test.test"})
  173. assert err.match('409: b\'{"errorMessage":"User exists with same username"}\'')
  174. # Test create the same user, exists_ok true
  175. user_id_2 = admin.create_user(
  176. payload={"username": "test", "email": "test@test.test"}, exist_ok=True
  177. )
  178. assert user_id == user_id_2
  179. # Test get user
  180. user = admin.get_user(user_id=user_id)
  181. assert user["username"] == "test", user["username"]
  182. assert user["email"] == "test@test.test", user["email"]
  183. # Test update user
  184. res = admin.update_user(user_id=user_id, payload={"firstName": "Test"})
  185. assert res == dict(), res
  186. user = admin.get_user(user_id=user_id)
  187. assert user["firstName"] == "Test"
  188. # Test update user fail
  189. with pytest.raises(KeycloakPutError) as err:
  190. admin.update_user(user_id=user_id, payload={"wrong": "payload"})
  191. assert err.match('400: b\'{"error":"Unrecognized field')
  192. # Test get users again
  193. users = admin.get_users()
  194. usernames = [x["username"] for x in users]
  195. assert "test" in usernames
  196. # Test users counts
  197. count = admin.users_count()
  198. assert count == 1, count
  199. # Test users count with query
  200. count = admin.users_count(query={"username": "notpresent"})
  201. assert count == 0
  202. # Test user groups
  203. groups = admin.get_user_groups(user_id=user["id"])
  204. assert len(groups) == 0
  205. # Test user groups bad id
  206. with pytest.raises(KeycloakGetError) as err:
  207. admin.get_user_groups(user_id="does-not-exist")
  208. assert err.match('404: b\'{"error":"User not found"}\'')
  209. # Test logout
  210. res = admin.user_logout(user_id=user["id"])
  211. assert res == dict(), res
  212. # Test logout fail
  213. with pytest.raises(KeycloakPostError) as err:
  214. admin.user_logout(user_id="non-existent-id")
  215. assert err.match('404: b\'{"error":"User not found"}\'')
  216. # Test consents
  217. res = admin.user_consents(user_id=user["id"])
  218. assert len(res) == 0, res
  219. # Test consents fail
  220. with pytest.raises(KeycloakGetError) as err:
  221. admin.user_consents(user_id="non-existent-id")
  222. assert err.match('404: b\'{"error":"User not found"}\'')
  223. # Test delete user
  224. res = admin.delete_user(user_id=user_id)
  225. assert res == dict(), res
  226. with pytest.raises(KeycloakGetError) as err:
  227. admin.get_user(user_id=user_id)
  228. err.match('404: b\'{"error":"User not found"}\'')
  229. # Test delete fail
  230. with pytest.raises(KeycloakDeleteError) as err:
  231. admin.delete_user(user_id="non-existent-id")
  232. assert err.match('404: b\'{"error":"User not found"}\'')
  233. def test_users_pagination(admin: KeycloakAdmin, realm: str):
  234. admin.realm_name = realm
  235. for ind in range(admin.PAGE_SIZE + 50):
  236. username = f"user_{ind}"
  237. admin.create_user(payload={"username": username, "email": f"{username}@test.test"})
  238. users = admin.get_users()
  239. assert len(users) == admin.PAGE_SIZE + 50, len(users)
  240. users = admin.get_users(query={"first": 100})
  241. assert len(users) == 50, len(users)
  242. users = admin.get_users(query={"max": 20})
  243. assert len(users) == 20, len(users)
  244. def test_idps(admin: KeycloakAdmin, realm: str):
  245. admin.realm_name = realm
  246. # Create IDP
  247. res = admin.create_idp(
  248. payload=dict(
  249. providerId="github", alias="github", config=dict(clientId="test", clientSecret="test")
  250. )
  251. )
  252. assert res == b"", res
  253. # Test create idp fail
  254. with pytest.raises(KeycloakPostError) as err:
  255. admin.create_idp(payload={"providerId": "does-not-exist", "alias": "something"})
  256. assert err.match("Invalid identity provider id"), err
  257. # Test listing
  258. idps = admin.get_idps()
  259. assert len(idps) == 1
  260. assert "github" == idps[0]["alias"]
  261. # Test IdP update
  262. res = admin.update_idp(idp_alias="github", payload=idps[0])
  263. assert res == {}, res
  264. # Test adding a mapper
  265. res = admin.add_mapper_to_idp(
  266. idp_alias="github",
  267. payload={
  268. "identityProviderAlias": "github",
  269. "identityProviderMapper": "github-user-attribute-mapper",
  270. "name": "test",
  271. },
  272. )
  273. assert res == b"", res
  274. # Test mapper fail
  275. with pytest.raises(KeycloakPostError) as err:
  276. admin.add_mapper_to_idp(idp_alias="does-no-texist", payload=dict())
  277. assert err.match('404: b\'{"error":"HTTP 404 Not Found"}\'')
  278. # Test IdP mappers listing
  279. idp_mappers = admin.get_idp_mappers(idp_alias="github")
  280. assert len(idp_mappers) == 1
  281. # Test IdP mapper update
  282. res = admin.update_mapper_in_idp(
  283. idp_alias="github",
  284. mapper_id=idp_mappers[0]["id"],
  285. # For an obscure reason, keycloak expect all fields
  286. payload={
  287. "id": idp_mappers[0]["id"],
  288. "identityProviderAlias": "github-alias",
  289. "identityProviderMapper": "github-user-attribute-mapper",
  290. "name": "test",
  291. "config": idp_mappers[0]["config"],
  292. },
  293. )
  294. assert res == dict(), res
  295. # Test delete
  296. res = admin.delete_idp(idp_alias="github")
  297. assert res == dict(), res
  298. # Test delete fail
  299. with pytest.raises(KeycloakDeleteError) as err:
  300. admin.delete_idp(idp_alias="does-not-exist")
  301. assert err.match('404: b\'{"error":"HTTP 404 Not Found"}\'')
  302. def test_user_credentials(admin: KeycloakAdmin, user: str):
  303. res = admin.set_user_password(user_id=user, password="booya", temporary=True)
  304. assert res == dict(), res
  305. # Test user password set fail
  306. with pytest.raises(KeycloakPutError) as err:
  307. admin.set_user_password(user_id="does-not-exist", password="")
  308. assert err.match('404: b\'{"error":"User not found"}\'')
  309. credentials = admin.get_credentials(user_id=user)
  310. assert len(credentials) == 1
  311. assert credentials[0]["type"] == "password", credentials
  312. # Test get credentials fail
  313. with pytest.raises(KeycloakGetError) as err:
  314. admin.get_credentials(user_id="does-not-exist")
  315. assert err.match('404: b\'{"error":"User not found"}\'')
  316. res = admin.delete_credential(user_id=user, credential_id=credentials[0]["id"])
  317. assert res == dict(), res
  318. # Test delete fail
  319. with pytest.raises(KeycloakDeleteError) as err:
  320. admin.delete_credential(user_id=user, credential_id="does-not-exist")
  321. assert err.match('404: b\'{"error":"Credential not found"}\'')
  322. def test_social_logins(admin: KeycloakAdmin, user: str):
  323. res = admin.add_user_social_login(
  324. user_id=user, provider_id="gitlab", provider_userid="test", provider_username="test"
  325. )
  326. assert res == dict(), res
  327. admin.add_user_social_login(
  328. user_id=user, provider_id="github", provider_userid="test", provider_username="test"
  329. )
  330. assert res == dict(), res
  331. # Test add social login fail
  332. with pytest.raises(KeycloakPostError) as err:
  333. admin.add_user_social_login(
  334. user_id="does-not-exist",
  335. provider_id="does-not-exist",
  336. provider_userid="test",
  337. provider_username="test",
  338. )
  339. assert err.match('404: b\'{"error":"User not found"}\'')
  340. res = admin.get_user_social_logins(user_id=user)
  341. assert res == list(), res
  342. # Test get social logins fail
  343. with pytest.raises(KeycloakGetError) as err:
  344. admin.get_user_social_logins(user_id="does-not-exist")
  345. assert err.match('404: b\'{"error":"User not found"}\'')
  346. res = admin.delete_user_social_login(user_id=user, provider_id="gitlab")
  347. assert res == {}, res
  348. res = admin.delete_user_social_login(user_id=user, provider_id="github")
  349. assert res == {}, res
  350. with pytest.raises(KeycloakDeleteError) as err:
  351. admin.delete_user_social_login(user_id=user, provider_id="instagram")
  352. assert err.match('404: b\'{"error":"Link not found"}\''), err
  353. def test_server_info(admin: KeycloakAdmin):
  354. info = admin.get_server_info()
  355. assert set(info.keys()) == {
  356. "systemInfo",
  357. "memoryInfo",
  358. "profileInfo",
  359. "themes",
  360. "socialProviders",
  361. "identityProviders",
  362. "providers",
  363. "protocolMapperTypes",
  364. "builtinProtocolMappers",
  365. "clientInstallations",
  366. "componentTypes",
  367. "passwordPolicies",
  368. "enums",
  369. }, info.keys()
  370. def test_groups(admin: KeycloakAdmin, user: str):
  371. # Test get groups
  372. groups = admin.get_groups()
  373. assert len(groups) == 0
  374. # Test create group
  375. group_id = admin.create_group(payload={"name": "main-group"})
  376. assert group_id is not None, group_id
  377. # Test create subgroups
  378. subgroup_id_1 = admin.create_group(payload={"name": "subgroup-1"}, parent=group_id)
  379. subgroup_id_2 = admin.create_group(payload={"name": "subgroup-2"}, parent=group_id)
  380. # Test create group fail
  381. with pytest.raises(KeycloakPostError) as err:
  382. admin.create_group(payload={"name": "subgroup-1"}, parent=group_id)
  383. assert err.match('409: b\'{"error":"unknown_error"}\''), err
  384. # Test skip exists OK
  385. subgroup_id_1_eq = admin.create_group(
  386. payload={"name": "subgroup-1"}, parent=group_id, skip_exists=True
  387. )
  388. assert subgroup_id_1_eq is None
  389. # Test get groups again
  390. groups = admin.get_groups()
  391. assert len(groups) == 1, groups
  392. assert len(groups[0]["subGroups"]) == 2, groups["subGroups"]
  393. assert groups[0]["id"] == group_id
  394. assert {x["id"] for x in groups[0]["subGroups"]} == {subgroup_id_1, subgroup_id_2}
  395. # Test get groups query
  396. groups = admin.get_groups(query={"max": 10})
  397. assert len(groups) == 1, groups
  398. assert len(groups[0]["subGroups"]) == 2, groups["subGroups"]
  399. assert groups[0]["id"] == group_id
  400. assert {x["id"] for x in groups[0]["subGroups"]} == {subgroup_id_1, subgroup_id_2}
  401. # Test get group
  402. res = admin.get_group(group_id=subgroup_id_1)
  403. assert res["id"] == subgroup_id_1, res
  404. assert res["name"] == "subgroup-1"
  405. assert res["path"] == "/main-group/subgroup-1"
  406. # Test get group fail
  407. with pytest.raises(KeycloakGetError) as err:
  408. admin.get_group(group_id="does-not-exist")
  409. assert err.match('404: b\'{"error":"Could not find group by id"}\''), err
  410. # Create 1 more subgroup
  411. subsubgroup_id_1 = admin.create_group(payload={"name": "subsubgroup-1"}, parent=subgroup_id_2)
  412. main_group = admin.get_group(group_id=group_id)
  413. # Test nested searches
  414. res = admin.get_subgroups(group=main_group, path="/main-group/subgroup-2/subsubgroup-1")
  415. assert res is not None, res
  416. assert res["id"] == subsubgroup_id_1
  417. # Test empty search
  418. res = admin.get_subgroups(group=main_group, path="/none")
  419. assert res is None, res
  420. # Test get group by path
  421. res = admin.get_group_by_path(path="/main-group/subgroup-1")
  422. assert res is None, res
  423. res = admin.get_group_by_path(path="/main-group/subgroup-1", search_in_subgroups=True)
  424. assert res is not None, res
  425. assert res["id"] == subgroup_id_1, res
  426. res = admin.get_group_by_path(
  427. path="/main-group/subgroup-2/subsubgroup-1/test", search_in_subgroups=True
  428. )
  429. assert res is None, res
  430. res = admin.get_group_by_path(
  431. path="/main-group/subgroup-2/subsubgroup-1", search_in_subgroups=True
  432. )
  433. assert res is not None, res
  434. assert res["id"] == subsubgroup_id_1
  435. res = admin.get_group_by_path(path="/main-group")
  436. assert res is not None, res
  437. assert res["id"] == group_id, res
  438. # Test group members
  439. res = admin.get_group_members(group_id=subgroup_id_2)
  440. assert len(res) == 0, res
  441. # Test fail group members
  442. with pytest.raises(KeycloakGetError) as err:
  443. admin.get_group_members(group_id="does-not-exist")
  444. assert err.match('404: b\'{"error":"Could not find group by id"}\'')
  445. res = admin.group_user_add(user_id=user, group_id=subgroup_id_2)
  446. assert res == dict(), res
  447. res = admin.get_group_members(group_id=subgroup_id_2)
  448. assert len(res) == 1, res
  449. assert res[0]["id"] == user
  450. # Test get group members query
  451. res = admin.get_group_members(group_id=subgroup_id_2, query={"max": 10})
  452. assert len(res) == 1, res
  453. assert res[0]["id"] == user
  454. with pytest.raises(KeycloakDeleteError) as err:
  455. admin.group_user_remove(user_id="does-not-exist", group_id=subgroup_id_2)
  456. assert err.match('404: b\'{"error":"User not found"}\''), err
  457. res = admin.group_user_remove(user_id=user, group_id=subgroup_id_2)
  458. assert res == dict(), res
  459. # Test set permissions
  460. res = admin.group_set_permissions(group_id=subgroup_id_2, enabled=True)
  461. assert res["enabled"], res
  462. res = admin.group_set_permissions(group_id=subgroup_id_2, enabled=False)
  463. assert not res["enabled"], res
  464. with pytest.raises(KeycloakPutError) as err:
  465. admin.group_set_permissions(group_id=subgroup_id_2, enabled="blah")
  466. assert err.match('500: b\'{"error":"unknown_error"}\''), err
  467. # Test update group
  468. res = admin.update_group(group_id=subgroup_id_2, payload={"name": "new-subgroup-2"})
  469. assert res == dict(), res
  470. assert admin.get_group(group_id=subgroup_id_2)["name"] == "new-subgroup-2"
  471. # test update fail
  472. with pytest.raises(KeycloakPutError) as err:
  473. admin.update_group(group_id="does-not-exist", payload=dict())
  474. assert err.match('404: b\'{"error":"Could not find group by id"}\''), err
  475. # Test delete
  476. res = admin.delete_group(group_id=group_id)
  477. assert res == dict(), res
  478. assert len(admin.get_groups()) == 0
  479. # Test delete fail
  480. with pytest.raises(KeycloakDeleteError) as err:
  481. admin.delete_group(group_id="does-not-exist")
  482. assert err.match('404: b\'{"error":"Could not find group by id"}\''), err
  483. def test_clients(admin: KeycloakAdmin, realm: str):
  484. admin.realm_name = realm
  485. # Test get clients
  486. clients = admin.get_clients()
  487. assert len(clients) == 6, clients
  488. assert {x["name"] for x in clients} == set(
  489. [
  490. "${client_admin-cli}",
  491. "${client_security-admin-console}",
  492. "${client_account-console}",
  493. "${client_broker}",
  494. "${client_account}",
  495. "${client_realm-management}",
  496. ]
  497. ), clients
  498. # Test create client
  499. client_id = admin.create_client(payload={"name": "test-client", "clientId": "test-client"})
  500. assert client_id, client_id
  501. with pytest.raises(KeycloakPostError) as err:
  502. admin.create_client(payload={"name": "test-client", "clientId": "test-client"})
  503. assert err.match('409: b\'{"errorMessage":"Client test-client already exists"}\''), err
  504. client_id_2 = admin.create_client(
  505. payload={"name": "test-client", "clientId": "test-client"}, skip_exists=True
  506. )
  507. assert client_id == client_id_2, client_id_2
  508. # Test get client
  509. res = admin.get_client(client_id=client_id)
  510. assert res["clientId"] == "test-client", res
  511. assert res["name"] == "test-client", res
  512. assert res["id"] == client_id, res
  513. with pytest.raises(KeycloakGetError) as err:
  514. admin.get_client(client_id="does-not-exist")
  515. assert err.match('404: b\'{"error":"Could not find client"}\'')
  516. assert len(admin.get_clients()) == 7
  517. # Test get client id
  518. assert admin.get_client_id(client_name="test-client") == client_id
  519. assert admin.get_client_id(client_name="does-not-exist") is None
  520. # Test update client
  521. res = admin.update_client(client_id=client_id, payload={"name": "test-client-change"})
  522. assert res == dict(), res
  523. with pytest.raises(KeycloakPutError) as err:
  524. admin.update_client(client_id="does-not-exist", payload={"name": "test-client-change"})
  525. assert err.match('404: b\'{"error":"Could not find client"}\'')
  526. # Test client mappers
  527. res = admin.get_mappers_from_client(client_id=client_id)
  528. assert len(res) == 0
  529. with pytest.raises(KeycloakPostError) as err:
  530. admin.add_mapper_to_client(client_id="does-not-exist", payload=dict())
  531. assert err.match('404: b\'{"error":"Could not find client"}\'')
  532. res = admin.add_mapper_to_client(
  533. client_id=client_id,
  534. payload={
  535. "name": "test-mapper",
  536. "protocol": "openid-connect",
  537. "protocolMapper": "oidc-usermodel-attribute-mapper",
  538. },
  539. )
  540. assert res == b""
  541. assert len(admin.get_mappers_from_client(client_id=client_id)) == 1
  542. mapper = admin.get_mappers_from_client(client_id=client_id)[0]
  543. with pytest.raises(KeycloakPutError) as err:
  544. admin.update_client_mapper(client_id=client_id, mapper_id="does-not-exist", payload=dict())
  545. assert err.match('404: b\'{"error":"Model not found"}\'')
  546. mapper["config"]["user.attribute"] = "test"
  547. res = admin.update_client_mapper(client_id=client_id, mapper_id=mapper["id"], payload=mapper)
  548. assert res == dict()
  549. res = admin.remove_client_mapper(client_id=client_id, client_mapper_id=mapper["id"])
  550. assert res == dict()
  551. with pytest.raises(KeycloakDeleteError) as err:
  552. admin.remove_client_mapper(client_id=client_id, client_mapper_id=mapper["id"])
  553. assert err.match('404: b\'{"error":"Model not found"}\'')
  554. # Test client sessions
  555. with pytest.raises(KeycloakGetError) as err:
  556. admin.get_client_all_sessions(client_id="does-not-exist")
  557. assert err.match('404: b\'{"error":"Could not find client"}\'')
  558. assert admin.get_client_all_sessions(client_id=client_id) == list()
  559. assert admin.get_client_sessions_stats() == list()
  560. # Test authz
  561. auth_client_id = admin.create_client(
  562. payload={
  563. "name": "authz-client",
  564. "clientId": "authz-client",
  565. "authorizationServicesEnabled": True,
  566. "serviceAccountsEnabled": True,
  567. }
  568. )
  569. res = admin.get_client_authz_settings(client_id=auth_client_id)
  570. assert res["allowRemoteResourceManagement"]
  571. assert res["decisionStrategy"] == "UNANIMOUS"
  572. assert len(res["policies"]) >= 0
  573. with pytest.raises(KeycloakGetError) as err:
  574. admin.get_client_authz_settings(client_id=client_id)
  575. assert err.match('500: b\'{"error":"HTTP 500 Internal Server Error"}\'')
  576. # Authz resources
  577. res = admin.get_client_authz_resources(client_id=auth_client_id)
  578. assert len(res) == 1
  579. assert res[0]["name"] == "Default Resource"
  580. with pytest.raises(KeycloakGetError) as err:
  581. admin.get_client_authz_resources(client_id=client_id)
  582. assert err.match('500: b\'{"error":"unknown_error"}\'')
  583. res = admin.create_client_authz_resource(
  584. client_id=auth_client_id, payload={"name": "test-resource"}
  585. )
  586. assert res["name"] == "test-resource", res
  587. test_resource_id = res["_id"]
  588. with pytest.raises(KeycloakPostError) as err:
  589. admin.create_client_authz_resource(
  590. client_id=auth_client_id, payload={"name": "test-resource"}
  591. )
  592. assert err.match('409: b\'{"error":"invalid_request"')
  593. assert admin.create_client_authz_resource(
  594. client_id=auth_client_id, payload={"name": "test-resource"}, skip_exists=True
  595. ) == {"msg": "Already exists"}
  596. res = admin.get_client_authz_resources(client_id=auth_client_id)
  597. assert len(res) == 2
  598. assert {x["name"] for x in res} == {"Default Resource", "test-resource"}
  599. # Authz policies
  600. res = admin.get_client_authz_policies(client_id=auth_client_id)
  601. assert len(res) == 1, res
  602. assert res[0]["name"] == "Default Policy"
  603. assert len(admin.get_client_authz_policies(client_id=client_id)) == 1
  604. with pytest.raises(KeycloakGetError) as err:
  605. admin.get_client_authz_policies(client_id="does-not-exist")
  606. assert err.match('404: b\'{"error":"Could not find client"}\'')
  607. role_id = admin.get_realm_role(role_name="offline_access")["id"]
  608. res = admin.create_client_authz_role_based_policy(
  609. client_id=auth_client_id,
  610. payload={"name": "test-authz-rb-policy", "roles": [{"id": role_id}]},
  611. )
  612. assert res["name"] == "test-authz-rb-policy", res
  613. with pytest.raises(KeycloakPostError) as err:
  614. admin.create_client_authz_role_based_policy(
  615. client_id=auth_client_id,
  616. payload={"name": "test-authz-rb-policy", "roles": [{"id": role_id}]},
  617. )
  618. assert err.match('409: b\'{"error":"Policy with name')
  619. assert admin.create_client_authz_role_based_policy(
  620. client_id=auth_client_id,
  621. payload={"name": "test-authz-rb-policy", "roles": [{"id": role_id}]},
  622. skip_exists=True,
  623. ) == {"msg": "Already exists"}
  624. assert len(admin.get_client_authz_policies(client_id=auth_client_id)) == 2
  625. # Test authz permissions
  626. res = admin.get_client_authz_permissions(client_id=auth_client_id)
  627. assert len(res) == 1, res
  628. assert res[0]["name"] == "Default Permission"
  629. assert len(admin.get_client_authz_permissions(client_id=client_id)) == 1
  630. with pytest.raises(KeycloakGetError) as err:
  631. admin.get_client_authz_permissions(client_id="does-not-exist")
  632. assert err.match('404: b\'{"error":"Could not find client"}\'')
  633. res = admin.create_client_authz_resource_based_permission(
  634. client_id=auth_client_id,
  635. payload={"name": "test-permission-rb", "resources": [test_resource_id]},
  636. )
  637. assert res, res
  638. assert res["name"] == "test-permission-rb"
  639. assert res["resources"] == [test_resource_id]
  640. with pytest.raises(KeycloakPostError) as err:
  641. admin.create_client_authz_resource_based_permission(
  642. client_id=auth_client_id,
  643. payload={"name": "test-permission-rb", "resources": [test_resource_id]},
  644. )
  645. assert err.match('409: b\'{"error":"Policy with name')
  646. assert admin.create_client_authz_resource_based_permission(
  647. client_id=auth_client_id,
  648. payload={"name": "test-permission-rb", "resources": [test_resource_id]},
  649. skip_exists=True,
  650. ) == {"msg": "Already exists"}
  651. assert len(admin.get_client_authz_permissions(client_id=auth_client_id)) == 2
  652. # Test authz scopes
  653. res = admin.get_client_authz_scopes(client_id=auth_client_id)
  654. assert len(res) == 0, res
  655. with pytest.raises(KeycloakGetError) as err:
  656. admin.get_client_authz_scopes(client_id=client_id)
  657. assert err.match('500: b\'{"error":"unknown_error"}\'')
  658. # Test service account user
  659. res = admin.get_client_service_account_user(client_id=auth_client_id)
  660. assert res["username"] == "service-account-authz-client", res
  661. with pytest.raises(KeycloakGetError) as err:
  662. admin.get_client_service_account_user(client_id=client_id)
  663. assert err.match('400: b\'{"error":"unknown_error"}\'')
  664. # Test delete client
  665. res = admin.delete_client(client_id=auth_client_id)
  666. assert res == dict(), res
  667. with pytest.raises(KeycloakDeleteError) as err:
  668. admin.delete_client(client_id=auth_client_id)
  669. assert err.match('404: b\'{"error":"Could not find client"}\'')
  670. # Test client credentials
  671. admin.create_client(
  672. payload={
  673. "name": "test-confidential",
  674. "enabled": True,
  675. "protocol": "openid-connect",
  676. "publicClient": False,
  677. "redirectUris": ["http://localhost/*"],
  678. "webOrigins": ["+"],
  679. "clientId": "test-confidential",
  680. "secret": "test-secret",
  681. "clientAuthenticatorType": "client-secret",
  682. }
  683. )
  684. with pytest.raises(KeycloakGetError) as err:
  685. admin.get_client_secrets(client_id="does-not-exist")
  686. assert err.match('404: b\'{"error":"Could not find client"}\'')
  687. secrets = admin.get_client_secrets(
  688. client_id=admin.get_client_id(client_name="test-confidential")
  689. )
  690. assert secrets == {"type": "secret", "value": "test-secret"}
  691. with pytest.raises(KeycloakPostError) as err:
  692. admin.generate_client_secrets(client_id="does-not-exist")
  693. assert err.match('404: b\'{"error":"Could not find client"}\'')
  694. res = admin.generate_client_secrets(
  695. client_id=admin.get_client_id(client_name="test-confidential")
  696. )
  697. assert res
  698. assert (
  699. admin.get_client_secrets(client_id=admin.get_client_id(client_name="test-confidential"))
  700. == res
  701. )
  702. def test_realm_roles(admin: KeycloakAdmin, realm: str):
  703. admin.realm_name = realm
  704. # Test get realm roles
  705. roles = admin.get_realm_roles()
  706. assert len(roles) == 3, roles
  707. role_names = [x["name"] for x in roles]
  708. assert "uma_authorization" in role_names, role_names
  709. assert "offline_access" in role_names, role_names
  710. # Test empty members
  711. with pytest.raises(KeycloakGetError) as err:
  712. admin.get_realm_role_members(role_name="does-not-exist")
  713. assert err.match('404: b\'{"error":"Could not find role"}\'')
  714. members = admin.get_realm_role_members(role_name="offline_access")
  715. assert members == list(), members
  716. # Test create realm role
  717. role_id = admin.create_realm_role(payload={"name": "test-realm-role"}, skip_exists=True)
  718. assert role_id, role_id
  719. with pytest.raises(KeycloakPostError) as err:
  720. admin.create_realm_role(payload={"name": "test-realm-role"})
  721. assert err.match('409: b\'{"errorMessage":"Role with name test-realm-role already exists"}\'')
  722. role_id_2 = admin.create_realm_role(payload={"name": "test-realm-role"}, skip_exists=True)
  723. assert role_id == role_id_2
  724. # Test update realm role
  725. res = admin.update_realm_role(
  726. role_name="test-realm-role", payload={"name": "test-realm-role-update"}
  727. )
  728. assert res == dict(), res
  729. with pytest.raises(KeycloakPutError) as err:
  730. admin.update_realm_role(
  731. role_name="test-realm-role", payload={"name": "test-realm-role-update"}
  732. )
  733. assert err.match('404: b\'{"error":"Could not find role"}\''), err
  734. # Test realm role user assignment
  735. user_id = admin.create_user(payload={"username": "role-testing", "email": "test@test.test"})
  736. with pytest.raises(KeycloakPostError) as err:
  737. admin.assign_realm_roles(user_id=user_id, roles=["bad"])
  738. assert err.match('500: b\'{"error":"unknown_error"}\'')
  739. res = admin.assign_realm_roles(
  740. user_id=user_id,
  741. roles=[
  742. admin.get_realm_role(role_name="offline_access"),
  743. admin.get_realm_role(role_name="test-realm-role-update"),
  744. ],
  745. )
  746. assert res == dict(), res
  747. assert admin.get_user(user_id=user_id)["username"] in [
  748. x["username"] for x in admin.get_realm_role_members(role_name="offline_access")
  749. ]
  750. assert admin.get_user(user_id=user_id)["username"] in [
  751. x["username"] for x in admin.get_realm_role_members(role_name="test-realm-role-update")
  752. ]
  753. roles = admin.get_realm_roles_of_user(user_id=user_id)
  754. assert len(roles) == 3
  755. assert "offline_access" in [x["name"] for x in roles]
  756. assert "test-realm-role-update" in [x["name"] for x in roles]
  757. with pytest.raises(KeycloakDeleteError) as err:
  758. admin.delete_realm_roles_of_user(user_id=user_id, roles=["bad"])
  759. assert err.match('500: b\'{"error":"unknown_error"}\'')
  760. res = admin.delete_realm_roles_of_user(
  761. user_id=user_id, roles=[admin.get_realm_role(role_name="offline_access")]
  762. )
  763. assert res == dict(), res
  764. assert admin.get_realm_role_members(role_name="offline_access") == list()
  765. roles = admin.get_realm_roles_of_user(user_id=user_id)
  766. assert len(roles) == 2
  767. assert "offline_access" not in [x["name"] for x in roles]
  768. assert "test-realm-role-update" in [x["name"] for x in roles]
  769. roles = admin.get_available_realm_roles_of_user(user_id=user_id)
  770. assert len(roles) == 2
  771. assert "offline_access" in [x["name"] for x in roles]
  772. assert "uma_authorization" in [x["name"] for x in roles]
  773. # Test realm role group assignment
  774. group_id = admin.create_group(payload={"name": "test-group"})
  775. with pytest.raises(KeycloakPostError) as err:
  776. admin.assign_group_realm_roles(group_id=group_id, roles=["bad"])
  777. assert err.match('500: b\'{"error":"unknown_error"}\'')
  778. res = admin.assign_group_realm_roles(
  779. group_id=group_id,
  780. roles=[
  781. admin.get_realm_role(role_name="offline_access"),
  782. admin.get_realm_role(role_name="test-realm-role-update"),
  783. ],
  784. )
  785. assert res == dict(), res
  786. roles = admin.get_group_realm_roles(group_id=group_id)
  787. assert len(roles) == 2
  788. assert "offline_access" in [x["name"] for x in roles]
  789. assert "test-realm-role-update" in [x["name"] for x in roles]
  790. with pytest.raises(KeycloakDeleteError) as err:
  791. admin.delete_group_realm_roles(group_id=group_id, roles=["bad"])
  792. assert err.match('500: b\'{"error":"unknown_error"}\'')
  793. res = admin.delete_group_realm_roles(
  794. group_id=group_id, roles=[admin.get_realm_role(role_name="offline_access")]
  795. )
  796. assert res == dict(), res
  797. roles = admin.get_group_realm_roles(group_id=group_id)
  798. assert len(roles) == 1
  799. assert "test-realm-role-update" in [x["name"] for x in roles]
  800. # Test composite realm roles
  801. composite_role = admin.create_realm_role(payload={"name": "test-composite-role"})
  802. with pytest.raises(KeycloakPostError) as err:
  803. admin.add_composite_realm_roles_to_role(role_name=composite_role, roles=["bad"])
  804. assert err.match('500: b\'{"error":"unknown_error"}\'')
  805. res = admin.add_composite_realm_roles_to_role(
  806. role_name=composite_role, roles=[admin.get_realm_role(role_name="test-realm-role-update")]
  807. )
  808. assert res == dict(), res
  809. res = admin.get_composite_realm_roles_of_role(role_name=composite_role)
  810. assert len(res) == 1
  811. assert "test-realm-role-update" in res[0]["name"]
  812. with pytest.raises(KeycloakGetError) as err:
  813. admin.get_composite_realm_roles_of_role(role_name="bad")
  814. assert err.match('404: b\'{"error":"Could not find role"}\'')
  815. res = admin.get_composite_realm_roles_of_user(user_id=user_id)
  816. assert len(res) == 4
  817. assert "offline_access" in {x["name"] for x in res}
  818. assert "test-realm-role-update" in {x["name"] for x in res}
  819. assert "uma_authorization" in {x["name"] for x in res}
  820. with pytest.raises(KeycloakGetError) as err:
  821. admin.get_composite_realm_roles_of_user(user_id="bad")
  822. assert err.match('404: b\'{"error":"User not found"}\'')
  823. with pytest.raises(KeycloakDeleteError) as err:
  824. admin.remove_composite_realm_roles_to_role(role_name=composite_role, roles=["bad"])
  825. assert err.match('500: b\'{"error":"unknown_error"}\'')
  826. res = admin.remove_composite_realm_roles_to_role(
  827. role_name=composite_role, roles=[admin.get_realm_role(role_name="test-realm-role-update")]
  828. )
  829. assert res == dict(), res
  830. res = admin.get_composite_realm_roles_of_role(role_name=composite_role)
  831. assert len(res) == 0
  832. # Test delete realm role
  833. res = admin.delete_realm_role(role_name=composite_role)
  834. assert res == dict(), res
  835. with pytest.raises(KeycloakDeleteError) as err:
  836. admin.delete_realm_role(role_name=composite_role)
  837. assert err.match('404: b\'{"error":"Could not find role"}\'')
  838. def test_client_roles(admin: KeycloakAdmin, client: str):
  839. # Test get client roles
  840. res = admin.get_client_roles(client_id=client)
  841. assert len(res) == 0
  842. with pytest.raises(KeycloakGetError) as err:
  843. admin.get_client_roles(client_id="bad")
  844. assert err.match('404: b\'{"error":"Could not find client"}\'')
  845. # Test create client role
  846. client_role_id = admin.create_client_role(
  847. client_role_id=client, payload={"name": "client-role-test"}, skip_exists=True
  848. )
  849. with pytest.raises(KeycloakPostError) as err:
  850. admin.create_client_role(client_role_id=client, payload={"name": "client-role-test"})
  851. assert err.match('409: b\'{"errorMessage":"Role with name client-role-test already exists"}\'')
  852. client_role_id_2 = admin.create_client_role(
  853. client_role_id=client, payload={"name": "client-role-test"}, skip_exists=True
  854. )
  855. assert client_role_id == client_role_id_2
  856. # Test get client role
  857. res = admin.get_client_role(client_id=client, role_name="client-role-test")
  858. assert res["name"] == client_role_id
  859. with pytest.raises(KeycloakGetError) as err:
  860. admin.get_client_role(client_id=client, role_name="bad")
  861. assert err.match('404: b\'{"error":"Could not find role"}\'')
  862. res_ = admin.get_client_role_id(client_id=client, role_name="client-role-test")
  863. assert res_ == res["id"]
  864. with pytest.raises(KeycloakGetError) as err:
  865. admin.get_client_role_id(client_id=client, role_name="bad")
  866. assert err.match('404: b\'{"error":"Could not find role"}\'')
  867. assert len(admin.get_client_roles(client_id=client)) == 1
  868. # Test update client role
  869. res = admin.update_client_role(
  870. client_role_id=client,
  871. role_name="client-role-test",
  872. payload={"name": "client-role-test-update"},
  873. )
  874. assert res == dict()
  875. with pytest.raises(KeycloakPutError) as err:
  876. res = admin.update_client_role(
  877. client_role_id=client,
  878. role_name="client-role-test",
  879. payload={"name": "client-role-test-update"},
  880. )
  881. assert err.match('404: b\'{"error":"Could not find role"}\'')
  882. # Test user with client role
  883. res = admin.get_client_role_members(client_id=client, role_name="client-role-test-update")
  884. assert len(res) == 0
  885. with pytest.raises(KeycloakGetError) as err:
  886. admin.get_client_role_members(client_id=client, role_name="bad")
  887. assert err.match('404: b\'{"error":"Could not find role"}\'')
  888. user_id = admin.create_user(payload={"username": "test", "email": "test@test.test"})
  889. with pytest.raises(KeycloakPostError) as err:
  890. admin.assign_client_role(user_id=user_id, client_id=client, roles=["bad"])
  891. assert err.match('500: b\'{"error":"unknown_error"}\'')
  892. res = admin.assign_client_role(
  893. user_id=user_id,
  894. client_id=client,
  895. roles=[admin.get_client_role(client_id=client, role_name="client-role-test-update")],
  896. )
  897. assert res == dict()
  898. assert (
  899. len(admin.get_client_role_members(client_id=client, role_name="client-role-test-update"))
  900. == 1
  901. )
  902. roles = admin.get_client_roles_of_user(user_id=user_id, client_id=client)
  903. assert len(roles) == 1, roles
  904. with pytest.raises(KeycloakGetError) as err:
  905. admin.get_client_roles_of_user(user_id=user_id, client_id="bad")
  906. assert err.match('404: b\'{"error":"Client not found"}\'')
  907. roles = admin.get_composite_client_roles_of_user(user_id=user_id, client_id=client)
  908. assert len(roles) == 1, roles
  909. with pytest.raises(KeycloakGetError) as err:
  910. admin.get_composite_client_roles_of_user(user_id=user_id, client_id="bad")
  911. assert err.match('404: b\'{"error":"Client not found"}\'')
  912. roles = admin.get_available_client_roles_of_user(user_id=user_id, client_id=client)
  913. assert len(roles) == 0, roles
  914. with pytest.raises(KeycloakGetError) as err:
  915. admin.get_composite_client_roles_of_user(user_id=user_id, client_id="bad")
  916. assert err.match('404: b\'{"error":"Client not found"}\'')
  917. with pytest.raises(KeycloakDeleteError) as err:
  918. admin.delete_client_roles_of_user(user_id=user_id, client_id=client, roles=["bad"])
  919. assert err.match('500: b\'{"error":"unknown_error"}\'')
  920. admin.delete_client_roles_of_user(
  921. user_id=user_id,
  922. client_id=client,
  923. roles=[admin.get_client_role(client_id=client, role_name="client-role-test-update")],
  924. )
  925. assert len(admin.get_client_roles_of_user(user_id=user_id, client_id=client)) == 0
  926. # Test groups and client roles
  927. res = admin.get_client_role_groups(client_id=client, role_name="client-role-test-update")
  928. assert len(res) == 0
  929. with pytest.raises(KeycloakGetError) as err:
  930. admin.get_client_role_groups(client_id=client, role_name="bad")
  931. assert err.match('404: b\'{"error":"Could not find role"}\'')
  932. group_id = admin.create_group(payload={"name": "test-group"})
  933. res = admin.get_group_client_roles(group_id=group_id, client_id=client)
  934. assert len(res) == 0
  935. with pytest.raises(KeycloakGetError) as err:
  936. admin.get_group_client_roles(group_id=group_id, client_id="bad")
  937. assert err.match('404: b\'{"error":"Client not found"}\'')
  938. with pytest.raises(KeycloakPostError) as err:
  939. admin.assign_group_client_roles(group_id=group_id, client_id=client, roles=["bad"])
  940. assert err.match('500: b\'{"error":"unknown_error"}\'')
  941. res = admin.assign_group_client_roles(
  942. group_id=group_id,
  943. client_id=client,
  944. roles=[admin.get_client_role(client_id=client, role_name="client-role-test-update")],
  945. )
  946. assert res == dict()
  947. assert (
  948. len(admin.get_client_role_groups(client_id=client, role_name="client-role-test-update"))
  949. == 1
  950. )
  951. assert len(admin.get_group_client_roles(group_id=group_id, client_id=client)) == 1
  952. with pytest.raises(KeycloakDeleteError) as err:
  953. admin.delete_group_client_roles(group_id=group_id, client_id=client, roles=["bad"])
  954. assert err.match('500: b\'{"error":"unknown_error"}\'')
  955. res = admin.delete_group_client_roles(
  956. group_id=group_id,
  957. client_id=client,
  958. roles=[admin.get_client_role(client_id=client, role_name="client-role-test-update")],
  959. )
  960. assert res == dict()
  961. # Test composite client roles
  962. with pytest.raises(KeycloakPostError) as err:
  963. admin.add_composite_client_roles_to_role(
  964. client_role_id=client, role_name="client-role-test-update", roles=["bad"]
  965. )
  966. assert err.match('500: b\'{"error":"unknown_error"}\'')
  967. res = admin.add_composite_client_roles_to_role(
  968. client_role_id=client,
  969. role_name="client-role-test-update",
  970. roles=[admin.get_realm_role(role_name="offline_access")],
  971. )
  972. assert res == dict()
  973. assert admin.get_client_role(client_id=client, role_name="client-role-test-update")[
  974. "composite"
  975. ]
  976. # Test delete of client role
  977. res = admin.delete_client_role(client_role_id=client, role_name="client-role-test-update")
  978. assert res == dict()
  979. with pytest.raises(KeycloakDeleteError) as err:
  980. admin.delete_client_role(client_role_id=client, role_name="client-role-test-update")
  981. assert err.match('404: b\'{"error":"Could not find role"}\'')
  982. def test_enable_token_exchange(admin: KeycloakAdmin, realm: str):
  983. # Test enabling token exchange between two confidential clients
  984. admin.realm_name = realm
  985. # Create test clients
  986. source_client_id = admin.create_client(
  987. payload={"name": "Source Client", "clientId": "source-client"}
  988. )
  989. target_client_id = admin.create_client(
  990. payload={"name": "Target Client", "clientId": "target-client"}
  991. )
  992. for c in admin.get_clients():
  993. if c["clientId"] == "realm-management":
  994. realm_management_id = c["id"]
  995. break
  996. else:
  997. raise AssertionError("Missing realm management client")
  998. # Enable permissions on the Superset client
  999. admin.update_client_management_permissions(
  1000. payload={"enabled": True}, client_id=target_client_id
  1001. )
  1002. # Fetch various IDs and strings needed when creating the permission
  1003. token_exchange_permission_id = admin.get_client_management_permissions(
  1004. client_id=target_client_id
  1005. )["scopePermissions"]["token-exchange"]
  1006. scopes = admin.get_client_authz_policy_scopes(
  1007. client_id=realm_management_id, policy_id=token_exchange_permission_id
  1008. )
  1009. for s in scopes:
  1010. if s["name"] == "token-exchange":
  1011. token_exchange_scope_id = s["id"]
  1012. break
  1013. else:
  1014. raise AssertionError("Missing token-exchange scope")
  1015. resources = admin.get_client_authz_policy_resources(
  1016. client_id=realm_management_id, policy_id=token_exchange_permission_id
  1017. )
  1018. for r in resources:
  1019. if r["name"] == f"client.resource.{target_client_id}":
  1020. token_exchange_resource_id = r["_id"]
  1021. break
  1022. else:
  1023. raise AssertionError("Missing client resource")
  1024. # Create a client policy for source client
  1025. client_policy_id = admin.create_client_authz_client_policy(
  1026. payload={
  1027. "type": "client",
  1028. "logic": "POSITIVE",
  1029. "decisionStrategy": "UNANIMOUS",
  1030. "name": "Exchange source client token with target client token",
  1031. "clients": [source_client_id],
  1032. },
  1033. client_id=realm_management_id,
  1034. )["id"]
  1035. # Update permissions on the target client to reference this policy
  1036. permission_name = admin.get_client_authz_scope_permission(
  1037. client_id=realm_management_id, scope_id=token_exchange_permission_id
  1038. )["name"]
  1039. admin.update_client_authz_scope_permission(
  1040. payload={
  1041. "id": token_exchange_permission_id,
  1042. "name": permission_name,
  1043. "type": "scope",
  1044. "logic": "POSITIVE",
  1045. "decisionStrategy": "UNANIMOUS",
  1046. "resources": [token_exchange_resource_id],
  1047. "scopes": [token_exchange_scope_id],
  1048. "policies": [client_policy_id],
  1049. },
  1050. client_id=realm_management_id,
  1051. scope_id=token_exchange_permission_id,
  1052. )
  1053. def test_email(admin: KeycloakAdmin, user: str):
  1054. # Emails will fail as we don't have SMTP test setup
  1055. with pytest.raises(KeycloakPutError) as err:
  1056. admin.send_update_account(user_id=user, payload=dict())
  1057. assert err.match('500: b\'{"error":"unknown_error"}\'')
  1058. admin.update_user(user_id=user, payload={"enabled": True})
  1059. with pytest.raises(KeycloakPutError) as err:
  1060. admin.send_verify_email(user_id=user)
  1061. assert err.match('500: b\'{"errorMessage":"Failed to send execute actions email"}\'')
  1062. def test_get_sessions(admin: KeycloakAdmin):
  1063. sessions = admin.get_sessions(user_id=admin.get_user_id(username=admin.username))
  1064. assert len(sessions) >= 1
  1065. with pytest.raises(KeycloakGetError) as err:
  1066. admin.get_sessions(user_id="bad")
  1067. assert err.match('404: b\'{"error":"User not found"}\'')
  1068. def test_get_client_installation_provider(admin: KeycloakAdmin, client: str):
  1069. with pytest.raises(KeycloakGetError) as err:
  1070. admin.get_client_installation_provider(client_id=client, provider_id="bad")
  1071. assert err.match('404: b\'{"error":"Unknown Provider"}\'')
  1072. installation = admin.get_client_installation_provider(
  1073. client_id=client, provider_id="keycloak-oidc-keycloak-json"
  1074. )
  1075. assert set(installation.keys()) == {
  1076. "auth-server-url",
  1077. "confidential-port",
  1078. "credentials",
  1079. "realm",
  1080. "resource",
  1081. "ssl-required",
  1082. }
  1083. def test_auth_flows(admin: KeycloakAdmin, realm: str):
  1084. admin.realm_name = realm
  1085. res = admin.get_authentication_flows()
  1086. assert len(res) == 8, res
  1087. assert set(res[0].keys()) == {
  1088. "alias",
  1089. "authenticationExecutions",
  1090. "builtIn",
  1091. "description",
  1092. "id",
  1093. "providerId",
  1094. "topLevel",
  1095. }
  1096. assert {x["alias"] for x in res} == {
  1097. "reset credentials",
  1098. "browser",
  1099. "http challenge",
  1100. "registration",
  1101. "docker auth",
  1102. "direct grant",
  1103. "first broker login",
  1104. "clients",
  1105. }
  1106. with pytest.raises(KeycloakGetError) as err:
  1107. admin.get_authentication_flow_for_id(flow_id="bad")
  1108. assert err.match('404: b\'{"error":"Could not find flow with id"}\'')
  1109. browser_flow_id = [x for x in res if x["alias"] == "browser"][0]["id"]
  1110. res = admin.get_authentication_flow_for_id(flow_id=browser_flow_id)
  1111. assert res["alias"] == "browser"
  1112. # Test copying
  1113. with pytest.raises(KeycloakPostError) as err:
  1114. admin.copy_authentication_flow(payload=dict(), flow_alias="bad")
  1115. assert err.match("404: b''")
  1116. res = admin.copy_authentication_flow(payload={"newName": "test-browser"}, flow_alias="browser")
  1117. assert res == b"", res
  1118. assert len(admin.get_authentication_flows()) == 9
  1119. # Test create
  1120. res = admin.create_authentication_flow(
  1121. payload={"alias": "test-create", "providerId": "basic-flow"}
  1122. )
  1123. assert res == b""
  1124. with pytest.raises(KeycloakPostError) as err:
  1125. admin.create_authentication_flow(payload={"alias": "test-create", "builtIn": False})
  1126. assert err.match('409: b\'{"errorMessage":"Flow test-create already exists"}\'')
  1127. assert admin.create_authentication_flow(
  1128. payload={"alias": "test-create"}, skip_exists=True
  1129. ) == {"msg": "Already exists"}
  1130. # Test flow executions
  1131. res = admin.get_authentication_flow_executions(flow_alias="browser")
  1132. assert len(res) == 8, res
  1133. with pytest.raises(KeycloakGetError) as err:
  1134. admin.get_authentication_flow_executions(flow_alias="bad")
  1135. assert err.match("404: b''")
  1136. exec_id = res[0]["id"]
  1137. res = admin.get_authentication_flow_execution(execution_id=exec_id)
  1138. assert set(res.keys()) == {
  1139. "alternative",
  1140. "authenticator",
  1141. "authenticatorFlow",
  1142. "conditional",
  1143. "disabled",
  1144. "enabled",
  1145. "id",
  1146. "parentFlow",
  1147. "priority",
  1148. "required",
  1149. "requirement",
  1150. }, res
  1151. with pytest.raises(KeycloakGetError) as err:
  1152. admin.get_authentication_flow_execution(execution_id="bad")
  1153. assert err.match('404: b\'{"error":"Illegal execution"}\'')
  1154. with pytest.raises(KeycloakPostError) as err:
  1155. admin.create_authentication_flow_execution(payload=dict(), flow_alias="browser")
  1156. assert err.match('400: b\'{"error":"It is illegal to add execution to a built in flow"}\'')
  1157. res = admin.create_authentication_flow_execution(
  1158. payload={"provider": "auth-cookie"}, flow_alias="test-create"
  1159. )
  1160. assert res == b""
  1161. assert len(admin.get_authentication_flow_executions(flow_alias="test-create")) == 1
  1162. with pytest.raises(KeycloakPutError) as err:
  1163. admin.update_authentication_flow_executions(
  1164. payload={"required": "yes"}, flow_alias="test-create"
  1165. )
  1166. assert err.match('400: b\'{"error":"Unrecognized field')
  1167. payload = admin.get_authentication_flow_executions(flow_alias="test-create")[0]
  1168. payload["displayName"] = "test"
  1169. res = admin.update_authentication_flow_executions(payload=payload, flow_alias="test-create")
  1170. assert res
  1171. exec_id = admin.get_authentication_flow_executions(flow_alias="test-create")[0]["id"]
  1172. res = admin.delete_authentication_flow_execution(execution_id=exec_id)
  1173. assert res == dict()
  1174. with pytest.raises(KeycloakDeleteError) as err:
  1175. admin.delete_authentication_flow_execution(execution_id=exec_id)
  1176. assert err.match('404: b\'{"error":"Illegal execution"}\'')
  1177. # Test subflows
  1178. res = admin.create_authentication_flow_subflow(
  1179. payload={
  1180. "alias": "test-subflow",
  1181. "provider": "basic-flow",
  1182. "type": "something",
  1183. "description": "something",
  1184. },
  1185. flow_alias="test-browser",
  1186. )
  1187. assert res == b""
  1188. with pytest.raises(KeycloakPostError) as err:
  1189. admin.create_authentication_flow_subflow(
  1190. payload={"alias": "test-subflow", "providerId": "basic-flow"},
  1191. flow_alias="test-browser",
  1192. )
  1193. assert err.match('409: b\'{"errorMessage":"New flow alias name already exists"}\'')
  1194. res = admin.create_authentication_flow_subflow(
  1195. payload={
  1196. "alias": "test-subflow",
  1197. "provider": "basic-flow",
  1198. "type": "something",
  1199. "description": "something",
  1200. },
  1201. flow_alias="test-create",
  1202. skip_exists=True,
  1203. )
  1204. assert res == {"msg": "Already exists"}
  1205. # Test delete auth flow
  1206. flow_id = [x for x in admin.get_authentication_flows() if x["alias"] == "test-browser"][0][
  1207. "id"
  1208. ]
  1209. res = admin.delete_authentication_flow(flow_id=flow_id)
  1210. assert res == dict()
  1211. with pytest.raises(KeycloakDeleteError) as err:
  1212. admin.delete_authentication_flow(flow_id=flow_id)
  1213. assert err.match('404: b\'{"error":"Could not find flow with id"}\'')
  1214. def test_authentication_configs(admin: KeycloakAdmin, realm: str):
  1215. admin.realm_name = realm
  1216. # Test list of auth providers
  1217. res = admin.get_authenticator_providers()
  1218. assert len(res) == 39
  1219. res = admin.get_authenticator_provider_config_description(provider_id="auth-cookie")
  1220. assert res == {
  1221. "helpText": "Validates the SSO cookie set by the auth server.",
  1222. "name": "Cookie",
  1223. "properties": [],
  1224. "providerId": "auth-cookie",
  1225. }
  1226. # Test authenticator config
  1227. # Currently unable to find a sustainable way to fetch the config id,
  1228. # therefore testing only failures
  1229. with pytest.raises(KeycloakGetError) as err:
  1230. admin.get_authenticator_config(config_id="bad")
  1231. assert err.match('404: b\'{"error":"Could not find authenticator config"}\'')
  1232. with pytest.raises(KeycloakPutError) as err:
  1233. admin.update_authenticator_config(payload=dict(), config_id="bad")
  1234. assert err.match('404: b\'{"error":"Could not find authenticator config"}\'')
  1235. with pytest.raises(KeycloakDeleteError) as err:
  1236. admin.delete_authenticator_config(config_id="bad")
  1237. assert err.match('404: b\'{"error":"Could not find authenticator config"}\'')
  1238. def test_sync_users(admin: KeycloakAdmin, realm: str):
  1239. admin.realm_name = realm
  1240. # Only testing the error message
  1241. with pytest.raises(KeycloakPostError) as err:
  1242. admin.sync_users(storage_id="does-not-exist", action="triggerFullSync")
  1243. assert err.match('404: b\'{"error":"Could not find component"}\'')
  1244. def test_client_scopes(admin: KeycloakAdmin, realm: str):
  1245. admin.realm_name = realm
  1246. # Test get client scopes
  1247. res = admin.get_client_scopes()
  1248. scope_names = {x["name"] for x in res}
  1249. assert len(res) == 10
  1250. assert "email" in scope_names
  1251. assert "profile" in scope_names
  1252. assert "offline_access" in scope_names
  1253. with pytest.raises(KeycloakGetError) as err:
  1254. admin.get_client_scope(client_scope_id="does-not-exist")
  1255. assert err.match('404: b\'{"error":"Could not find client scope"}\'')
  1256. scope = admin.get_client_scope(client_scope_id=res[0]["id"])
  1257. assert res[0] == scope
  1258. scope = admin.get_client_scope_by_name(client_scope_name=res[0]["name"])
  1259. assert res[0] == scope
  1260. # Test create client scope
  1261. res = admin.create_client_scope(payload={"name": "test-scope"}, skip_exists=True)
  1262. assert res
  1263. res2 = admin.create_client_scope(payload={"name": "test-scope"}, skip_exists=True)
  1264. assert res == res2
  1265. with pytest.raises(KeycloakPostError) as err:
  1266. admin.create_client_scope(payload={"name": "test-scope"}, skip_exists=False)
  1267. assert err.match('409: b\'{"errorMessage":"Client Scope test-scope already exists"}\'')
  1268. # Test update client scope
  1269. with pytest.raises(KeycloakPutError) as err:
  1270. admin.update_client_scope(client_scope_id="does-not-exist", payload=dict())
  1271. assert err.match('404: b\'{"error":"Could not find client scope"}\'')
  1272. res_update = admin.update_client_scope(
  1273. client_scope_id=res, payload={"name": "test-scope-update"}
  1274. )
  1275. assert res_update == dict()
  1276. admin.get_client_scope(client_scope_id=res)["name"] == "test-scope-update"
  1277. # Test get mappers
  1278. mappers = admin.get_mappers_from_client_scope(client_scope_id=res)
  1279. assert mappers == list()
  1280. # Test add mapper
  1281. with pytest.raises(KeycloakPostError) as err:
  1282. admin.add_mapper_to_client_scope(client_scope_id=res, payload=dict())
  1283. assert err.match('404: b\'{"error":"ProtocolMapper provider not found"}\'')
  1284. res_add = admin.add_mapper_to_client_scope(
  1285. client_scope_id=res,
  1286. payload={
  1287. "name": "test-mapper",
  1288. "protocol": "openid-connect",
  1289. "protocolMapper": "oidc-usermodel-attribute-mapper",
  1290. },
  1291. )
  1292. assert res_add == b""
  1293. assert len(admin.get_mappers_from_client_scope(client_scope_id=res)) == 1
  1294. # Test update mapper
  1295. test_mapper = admin.get_mappers_from_client_scope(client_scope_id=res)[0]
  1296. with pytest.raises(KeycloakPutError) as err:
  1297. admin.update_mapper_in_client_scope(
  1298. client_scope_id="does-not-exist", protocol_mapper_id=test_mapper["id"], payload=dict()
  1299. )
  1300. assert err.match('404: b\'{"error":"Could not find client scope"}\'')
  1301. test_mapper["config"]["user.attribute"] = "test"
  1302. res_update = admin.update_mapper_in_client_scope(
  1303. client_scope_id=res, protocol_mapper_id=test_mapper["id"], payload=test_mapper
  1304. )
  1305. assert res_update == dict()
  1306. assert (
  1307. admin.get_mappers_from_client_scope(client_scope_id=res)[0]["config"]["user.attribute"]
  1308. == "test"
  1309. )
  1310. # Test delete mapper
  1311. res_del = admin.delete_mapper_from_client_scope(
  1312. client_scope_id=res, protocol_mapper_id=test_mapper["id"]
  1313. )
  1314. assert res_del == dict()
  1315. with pytest.raises(KeycloakDeleteError) as err:
  1316. admin.delete_mapper_from_client_scope(
  1317. client_scope_id=res, protocol_mapper_id=test_mapper["id"]
  1318. )
  1319. assert err.match('404: b\'{"error":"Model not found"}\'')
  1320. # Test default default scopes
  1321. res_defaults = admin.get_default_default_client_scopes()
  1322. assert len(res_defaults) == 6
  1323. with pytest.raises(KeycloakPutError) as err:
  1324. admin.add_default_default_client_scope(scope_id="does-not-exist")
  1325. assert err.match('404: b\'{"error":"Client scope not found"}\'')
  1326. res_add = admin.add_default_default_client_scope(scope_id=res)
  1327. assert res_add == dict()
  1328. assert len(admin.get_default_default_client_scopes()) == 7
  1329. with pytest.raises(KeycloakDeleteError) as err:
  1330. admin.delete_default_default_client_scope(scope_id="does-not-exist")
  1331. assert err.match('404: b\'{"error":"Client scope not found"}\'')
  1332. res_del = admin.delete_default_default_client_scope(scope_id=res)
  1333. assert res_del == dict()
  1334. assert len(admin.get_default_default_client_scopes()) == 6
  1335. # Test default optional scopes
  1336. res_defaults = admin.get_default_optional_client_scopes()
  1337. assert len(res_defaults) == 4
  1338. with pytest.raises(KeycloakPutError) as err:
  1339. admin.add_default_optional_client_scope(scope_id="does-not-exist")
  1340. assert err.match('404: b\'{"error":"Client scope not found"}\'')
  1341. res_add = admin.add_default_optional_client_scope(scope_id=res)
  1342. assert res_add == dict()
  1343. assert len(admin.get_default_optional_client_scopes()) == 5
  1344. with pytest.raises(KeycloakDeleteError) as err:
  1345. admin.delete_default_optional_client_scope(scope_id="does-not-exist")
  1346. assert err.match('404: b\'{"error":"Client scope not found"}\'')
  1347. res_del = admin.delete_default_optional_client_scope(scope_id=res)
  1348. assert res_del == dict()
  1349. assert len(admin.get_default_optional_client_scopes()) == 4
  1350. # Test client scope delete
  1351. res_del = admin.delete_client_scope(client_scope_id=res)
  1352. assert res_del == dict()
  1353. with pytest.raises(KeycloakDeleteError) as err:
  1354. admin.delete_client_scope(client_scope_id=res)
  1355. assert err.match('404: b\'{"error":"Could not find client scope"}\'')
  1356. def test_components(admin: KeycloakAdmin, realm: str):
  1357. admin.realm_name = realm
  1358. # Test get components
  1359. res = admin.get_components()
  1360. assert len(res) == 12
  1361. with pytest.raises(KeycloakGetError) as err:
  1362. admin.get_component(component_id="does-not-exist")
  1363. assert err.match('404: b\'{"error":"Could not find component"}\'')
  1364. res_get = admin.get_component(component_id=res[0]["id"])
  1365. assert res_get == res[0]
  1366. # Test create component
  1367. with pytest.raises(KeycloakPostError) as err:
  1368. admin.create_component(payload={"bad": "dict"})
  1369. assert err.match('400: b\'{"error":"Unrecognized field')
  1370. res = admin.create_component(
  1371. payload={
  1372. "name": "Test Component",
  1373. "providerId": "max-clients",
  1374. "providerType": "org.keycloak.services.clientregistration."
  1375. + "policy.ClientRegistrationPolicy",
  1376. "config": {"max-clients": ["1000"]},
  1377. }
  1378. )
  1379. assert res
  1380. assert admin.get_component(component_id=res)["name"] == "Test Component"
  1381. # Test update component
  1382. component = admin.get_component(component_id=res)
  1383. component["name"] = "Test Component Update"
  1384. with pytest.raises(KeycloakPutError) as err:
  1385. admin.update_component(component_id="does-not-exist", payload=dict())
  1386. assert err.match('404: b\'{"error":"Could not find component"}\'')
  1387. res_upd = admin.update_component(component_id=res, payload=component)
  1388. assert res_upd == dict()
  1389. assert admin.get_component(component_id=res)["name"] == "Test Component Update"
  1390. # Test delete component
  1391. res_del = admin.delete_component(component_id=res)
  1392. assert res_del == dict()
  1393. with pytest.raises(KeycloakDeleteError) as err:
  1394. admin.delete_component(component_id=res)
  1395. assert err.match('404: b\'{"error":"Could not find component"}\'')
  1396. def test_keys(admin: KeycloakAdmin, realm: str):
  1397. admin.realm_name = realm
  1398. assert set(admin.get_keys()["active"].keys()) == {"AES", "HS256", "RS256", "RSA-OAEP"}
  1399. assert {k["algorithm"] for k in admin.get_keys()["keys"]} == {
  1400. "HS256",
  1401. "RSA-OAEP",
  1402. "AES",
  1403. "RS256",
  1404. }
  1405. def test_events(admin: KeycloakAdmin, realm: str):
  1406. admin.realm_name = realm
  1407. events = admin.get_events()
  1408. assert events == list()
  1409. with pytest.raises(KeycloakPutError) as err:
  1410. admin.set_events(payload={"bad": "conf"})
  1411. assert err.match('400: b\'{"error":"Unrecognized field')
  1412. res = admin.set_events(payload={"adminEventsDetailsEnabled": True, "adminEventsEnabled": True})
  1413. assert res == dict()
  1414. admin.create_client(payload={"name": "test", "clientId": "test"})
  1415. events = admin.get_events()
  1416. assert events == list()
  1417. def test_auto_refresh(admin: KeycloakAdmin, realm: str):
  1418. # Test get refresh
  1419. admin.auto_refresh_token = list()
  1420. admin.connection = ConnectionManager(
  1421. base_url=admin.server_url,
  1422. headers={"Authorization": "Bearer bad", "Content-Type": "application/json"},
  1423. timeout=60,
  1424. verify=admin.verify,
  1425. )
  1426. with pytest.raises(KeycloakAuthenticationError) as err:
  1427. admin.get_realm(realm_name=realm)
  1428. assert err.match('401: b\'{"error":"HTTP 401 Unauthorized"}\'')
  1429. admin.auto_refresh_token = ["get"]
  1430. del admin.token["refresh_token"]
  1431. assert admin.get_realm(realm_name=realm)
  1432. # Test bad refresh token
  1433. admin.connection = ConnectionManager(
  1434. base_url=admin.server_url,
  1435. headers={"Authorization": "Bearer bad", "Content-Type": "application/json"},
  1436. timeout=60,
  1437. verify=admin.verify,
  1438. )
  1439. admin.token["refresh_token"] = "bad"
  1440. with pytest.raises(KeycloakGetError) as err:
  1441. admin.get_realm(realm_name="test-refresh")
  1442. assert err.match(
  1443. '400: b\'{"error":"invalid_grant","error_description":"Invalid refresh token"}\''
  1444. )
  1445. admin.realm_name = "master"
  1446. admin.get_token()
  1447. admin.realm_name = realm
  1448. # Test post refresh
  1449. admin.connection = ConnectionManager(
  1450. base_url=admin.server_url,
  1451. headers={"Authorization": "Bearer bad", "Content-Type": "application/json"},
  1452. timeout=60,
  1453. verify=admin.verify,
  1454. )
  1455. with pytest.raises(KeycloakAuthenticationError) as err:
  1456. admin.create_realm(payload={"realm": "test-refresh"})
  1457. assert err.match('401: b\'{"error":"HTTP 401 Unauthorized"}\'')
  1458. admin.auto_refresh_token = ["get", "post"]
  1459. admin.realm_name = "master"
  1460. admin.user_logout(user_id=admin.get_user_id(username=admin.username))
  1461. assert admin.create_realm(payload={"realm": "test-refresh"}) == b""
  1462. admin.realm_name = realm
  1463. # Test update refresh
  1464. admin.connection = ConnectionManager(
  1465. base_url=admin.server_url,
  1466. headers={"Authorization": "Bearer bad", "Content-Type": "application/json"},
  1467. timeout=60,
  1468. verify=admin.verify,
  1469. )
  1470. with pytest.raises(KeycloakAuthenticationError) as err:
  1471. admin.update_realm(realm_name="test-refresh", payload={"accountTheme": "test"})
  1472. assert err.match('401: b\'{"error":"HTTP 401 Unauthorized"}\'')
  1473. admin.auto_refresh_token = ["get", "post", "put"]
  1474. assert (
  1475. admin.update_realm(realm_name="test-refresh", payload={"accountTheme": "test"}) == dict()
  1476. )
  1477. # Test delete refresh
  1478. admin.connection = ConnectionManager(
  1479. base_url=admin.server_url,
  1480. headers={"Authorization": "Bearer bad", "Content-Type": "application/json"},
  1481. timeout=60,
  1482. verify=admin.verify,
  1483. )
  1484. with pytest.raises(KeycloakAuthenticationError) as err:
  1485. admin.delete_realm(realm_name="test-refresh")
  1486. assert err.match('401: b\'{"error":"HTTP 401 Unauthorized"}\'')
  1487. admin.auto_refresh_token = ["get", "post", "put", "delete"]
  1488. assert admin.delete_realm(realm_name="test-refresh") == dict()