Skip to content

Commit 05763ae

Browse files
Ujifmanryshoooo
andauthored
feat: implement authz import request (#685)
* feat: implement authz import request * chore: linting * chore: fixing docs --------- Co-authored-by: Richard Nemeth <ryshoooo@gmail.com>
1 parent dacef71 commit 05763ae

3 files changed

Lines changed: 125 additions & 0 deletions

File tree

src/keycloak/keycloak_admin.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2216,6 +2216,33 @@ def get_client_authz_settings(self, client_id: str) -> dict:
22162216
)
22172217
return raise_error_from_response(data_raw, KeycloakGetError)
22182218

2219+
def import_client_authz_config(self, client_id: str, payload: dict) -> dict:
2220+
"""
2221+
Import client authorization configuration.
2222+
2223+
ResourceServerRepresentation
2224+
https://www.keycloak.org/docs-api/latest/rest-api/index.html#ResourceServerRepresentation
2225+
2226+
:param client_id: id in ClientRepresentation
2227+
https://www.keycloak.org/docs-api/24.0.2/rest-api/index.html#_clientrepresentation
2228+
:type client_id: str
2229+
:param payload: ResourceServerRepresentation
2230+
:type payload: dict
2231+
2232+
:return: None
2233+
"""
2234+
params_path = {"realm-name": self.connection.realm_name, "id": client_id}
2235+
data_raw = self.connection.raw_post(
2236+
urls_patterns.URL_ADMIN_CLIENT_AUTHZ_IMPORT.format(**params_path),
2237+
data=json.dumps(payload),
2238+
)
2239+
2240+
return raise_error_from_response(
2241+
data_raw,
2242+
KeycloakPostError,
2243+
expected_codes=[HTTP_NO_CONTENT],
2244+
)
2245+
22192246
def create_client_authz_resource(
22202247
self,
22212248
client_id: str,
@@ -7527,6 +7554,33 @@ async def a_get_client_authz_settings(self, client_id: str) -> dict:
75277554
)
75287555
return raise_error_from_response(data_raw, KeycloakGetError)
75297556

7557+
async def a_import_client_authz_config(self, client_id: str, payload: dict) -> dict:
7558+
"""
7559+
Import client authorization configuration asynchronously.
7560+
7561+
ResourceServerRepresentation
7562+
https://www.keycloak.org/docs-api/latest/rest-api/index.html#ResourceServerRepresentation
7563+
7564+
:param client_id: id in ClientRepresentation
7565+
https://www.keycloak.org/docs-api/24.0.2/rest-api/index.html#_clientrepresentation
7566+
:type client_id: str
7567+
:param payload: ResourceServerRepresentation
7568+
:type payload: dict
7569+
7570+
:return: None
7571+
"""
7572+
params_path = {"realm-name": self.connection.realm_name, "id": client_id}
7573+
data_raw = await self.connection.a_raw_post(
7574+
urls_patterns.URL_ADMIN_CLIENT_AUTHZ_IMPORT.format(**params_path),
7575+
data=json.dumps(payload),
7576+
)
7577+
7578+
return raise_error_from_response(
7579+
data_raw,
7580+
KeycloakPostError,
7581+
expected_codes=[HTTP_NO_CONTENT],
7582+
)
7583+
75307584
async def a_create_client_authz_resource(
75317585
self,
75327586
client_id: str,

src/keycloak/urls_patterns.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@
115115

116116
URL_ADMIN_CLIENT_AUTHZ = URL_ADMIN_CLIENT + "/authz/resource-server"
117117
URL_ADMIN_CLIENT_AUTHZ_SETTINGS = URL_ADMIN_CLIENT_AUTHZ + "/settings"
118+
URL_ADMIN_CLIENT_AUTHZ_IMPORT = URL_ADMIN_CLIENT_AUTHZ + "/import"
118119
URL_ADMIN_CLIENT_AUTHZ_RESOURCE = URL_ADMIN_CLIENT_AUTHZ + "/resource/{resource-id}"
119120
URL_ADMIN_CLIENT_AUTHZ_RESOURCES = URL_ADMIN_CLIENT_AUTHZ + "/resource"
120121
URL_ADMIN_CLIENT_AUTHZ_SCOPES = URL_ADMIN_CLIENT_AUTHZ + "/scope"

tests/test_keycloak_admin.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1434,6 +1434,41 @@ def test_clients(admin: KeycloakAdmin, realm: str) -> None:
14341434
UNKOWN_ERROR_REGEX,
14351435
)
14361436

1437+
# Test import authz
1438+
authz_config = admin.get_client_authz_settings(client_id=auth_client_id)
1439+
1440+
authz_config["resources"] = [{"name": "test-import-resource"}]
1441+
authz_config["policies"] = [
1442+
{
1443+
"name": "test-import-policy",
1444+
"type": "time",
1445+
"config": {"hourEnd": "18", "hour": "9"},
1446+
}
1447+
]
1448+
admin.import_client_authz_config(client_id=auth_client_id, payload=authz_config)
1449+
exported = admin.get_client_authz_settings(client_id=auth_client_id)
1450+
assert (
1451+
len(
1452+
[
1453+
resource
1454+
for resource in exported["resources"]
1455+
if resource["name"] == "test-import-resource"
1456+
]
1457+
)
1458+
== 1
1459+
)
1460+
1461+
assert (
1462+
len(
1463+
[
1464+
resource
1465+
for resource in exported["policies"]
1466+
if resource["name"] == "test-import-policy"
1467+
]
1468+
)
1469+
== 1
1470+
)
1471+
14371472
# Test delete client
14381473
res = admin.delete_client(client_id=auth_client_id)
14391474
assert res == {}, res
@@ -5042,6 +5077,41 @@ async def test_a_clients(admin: KeycloakAdmin, realm: str) -> None:
50425077
UNKOWN_ERROR_REGEX,
50435078
)
50445079

5080+
# Test async import authz
5081+
authz_config = await admin.a_get_client_authz_settings(client_id=auth_client_id)
5082+
5083+
authz_config["resources"] = [{"name": "test-import-resource"}]
5084+
authz_config["policies"] = [
5085+
{
5086+
"name": "test-import-policy",
5087+
"type": "time",
5088+
"config": {"hourEnd": "18", "hour": "9"},
5089+
}
5090+
]
5091+
await admin.a_import_client_authz_config(client_id=auth_client_id, payload=authz_config)
5092+
exported = await admin.a_get_client_authz_settings(client_id=auth_client_id)
5093+
assert (
5094+
len(
5095+
[
5096+
resource
5097+
for resource in exported["resources"]
5098+
if resource["name"] == "test-import-resource"
5099+
]
5100+
)
5101+
== 1
5102+
)
5103+
5104+
assert (
5105+
len(
5106+
[
5107+
resource
5108+
for resource in exported["policies"]
5109+
if resource["name"] == "test-import-policy"
5110+
]
5111+
)
5112+
== 1
5113+
)
5114+
50455115
# Test delete client
50465116
res = await admin.a_delete_client(client_id=auth_client_id)
50475117
assert res == {}, res

0 commit comments

Comments
 (0)