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.

1891 lines
70 KiB

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