Browse Source

fix: correctly pass query params in a_send_update_account and a_send_verify_email

pull/581/head
Philipp Böhm 10 months ago
parent
commit
314020fc82
  1. 22
      src/keycloak/connection.py
  2. 4
      src/keycloak/keycloak_admin.py
  3. 57
      tests/test_keycloak_admin.py

22
src/keycloak/connection.py

@ -307,7 +307,7 @@ class ConnectionManager(object):
try:
return await self.async_s.get(
urljoin(self.base_url, path),
params=kwargs,
params=self._filter_query_params(kwargs),
headers=self.headers,
timeout=self.timeout,
)
@ -331,7 +331,7 @@ class ConnectionManager(object):
return await self.async_s.request(
method="POST",
url=urljoin(self.base_url, path),
params=kwargs,
params=self._filter_query_params(kwargs),
data=data,
headers=self.headers,
timeout=self.timeout,
@ -355,7 +355,7 @@ class ConnectionManager(object):
try:
return await self.async_s.put(
urljoin(self.base_url, path),
params=kwargs,
params=self._filter_query_params(kwargs),
data=data,
headers=self.headers,
timeout=self.timeout,
@ -381,9 +381,23 @@ class ConnectionManager(object):
method="DELETE",
url=urljoin(self.base_url, path),
data=data or dict(),
params=kwargs,
params=self._filter_query_params(kwargs),
headers=self.headers,
timeout=self.timeout,
)
except Exception as e:
raise KeycloakConnectionError("Can't connect to server (%s)" % e)
@staticmethod
def _filter_query_params(query_params):
"""Explicitly filter query params with None values for compatibility.
Httpx and requests differ in the way they handle query params with the value None,
requests does not include params with the value None while httpx includes them as-is.
:param query_params: the query params
:type query_params: dict
:returns: the filtered query params
:rtype: dict
"""
return {k: v for k, v in query_params.items() if v is not None}

4
src/keycloak/keycloak_admin.py

@ -5073,7 +5073,7 @@ class KeycloakAdmin:
data_raw = await self.connection.a_raw_put(
urls_patterns.URL_ADMIN_SEND_UPDATE_ACCOUNT.format(**params_path),
data=json.dumps(payload),
kwargs=params_query,
**params_query,
)
return raise_error_from_response(data_raw, KeycloakPutError)
@ -5097,7 +5097,7 @@ class KeycloakAdmin:
data_raw = await self.connection.a_raw_put(
urls_patterns.URL_ADMIN_SEND_VERIFY_EMAIL.format(**params_path),
data={},
kwargs=params_query,
**params_query,
)
return raise_error_from_response(data_raw, KeycloakPutError)

57
tests/test_keycloak_admin.py

@ -5,6 +5,7 @@ import os
import uuid
from inspect import iscoroutinefunction, signature
from typing import Tuple
from unittest.mock import ANY, patch
import freezegun
import pytest
@ -12,7 +13,12 @@ from dateutil import parser as datetime_parser
from packaging.version import Version
import keycloak
from keycloak import KeycloakAdmin, KeycloakOpenID, KeycloakOpenIDConnection
from keycloak import (
KeycloakAdmin,
KeycloakConnectionError,
KeycloakOpenID,
KeycloakOpenIDConnection,
)
from keycloak.connection import ConnectionManager
from keycloak.exceptions import (
KeycloakAuthenticationError,
@ -5170,6 +5176,55 @@ async def test_a_email(admin: KeycloakAdmin, user: str):
assert err.match('500: b\'{"errorMessage":"Failed to send .*"}\'')
@pytest.mark.asyncio
async def test_a_email_query_param_handling(admin: KeycloakAdmin, user: str):
"""Test that the optional parameters are correctly transformed into query params.
:param admin: Keycloak Admin client
:type admin: KeycloakAdmin
:param user: Keycloak user
:type user: str
"""
with patch.object(
admin.connection.async_s, "put", side_effect=Exception("An expected error")
) as mock_put, pytest.raises(KeycloakConnectionError):
await admin.a_send_update_account(
user_id=user,
payload=["UPDATE_PASSWORD"],
client_id="update-account-client-id",
redirect_uri="https://example.com",
)
mock_put.assert_awaited_once_with(
ANY,
data='["UPDATE_PASSWORD"]',
params={
"client_id": "update-account-client-id",
"redirect_uri": "https://example.com",
},
headers=ANY,
timeout=60,
)
with patch.object(
admin.connection.async_s, "put", side_effect=Exception("An expected error")
) as mock_put, pytest.raises(KeycloakConnectionError):
await admin.a_send_verify_email(
user_id=user, client_id="verify-client-id", redirect_uri="https://example.com"
)
mock_put.assert_awaited_once_with(
ANY,
data=ANY,
params={
"client_id": "verify-client-id",
"redirect_uri": "https://example.com",
},
headers=ANY,
timeout=60,
)
@pytest.mark.asyncio
async def test_a_get_sessions(admin: KeycloakAdmin):
"""Test get sessions.

Loading…
Cancel
Save