-
Notifications
You must be signed in to change notification settings - Fork 55
Description
Version 17.0.0 of keycloak has been released and includes a change which removes auth from the default context path making this library no longer work with that version by default. I'd like to use this library with a version 17.0.0 instance of keycloak without changing the http-relative-path on the server, would you be open to accepting a PR which introduces such support?
My plan for a solution would be to introduce a context_path argument to all relevant classes (KeycloakClient, KeycloakAdminBase, and any class that inherits from WellKnownMixin) which defaults to /auth, change every _paths definition to not include /auth, update the relevant classes to use the context_path when building urls e.g. in KeycloakAdminBase.get_path, and add the context_path argument to KeycloakRealm and pass it to each class returned by a method.
For example, the KeycloakClient.__init__ method would look like this:
class KeycloakClient(object):
_server_url = None
_context_path = None
_session = None
_headers = None
def __init__(self, server_url, headers=None, logger=None, context_path='/auth'):
"""
:param str server_url: The base URL where the Keycloak server can be
found
:param dict headers: Optional extra headers to send with requests to
the server
:param logging.Logger logger: Optional logger for client
:param str context_path: Optional context path for building urls (defaults to `/auth`)
"""
if logger is None:
if hasattr(self.__class__, '__qualname__'):
logger_name = self.__class__.__qualname__
else:
logger_name = self.__class__.__name__
logger = logging.getLogger(logger_name)
self.logger = logger
self._server_url = server_url
self._headers = headers or {}
self._context_path = context_pathThe KeycloakAdminBase class would look like:
class KeycloakAdminBase(object):
_client = None
_paths = None
def __init__(self, client):
"""
:param keycloak.admin.KeycloakAdmin client:
"""
self._client = client
def get_path(self, name, **kwargs):
if self._paths is None:
raise NotImplementedError()
formatted_path = self._paths[name].format(**kwargs)
return self.client._context_path + formatted_pathAnd the KeycloakRealm class would begin:
class KeycloakRealm(object):
_server_url = None
_realm_name = None
_context_path = None
_headers = None
_client = None
def __init__(self, server_url, realm_name, headers=None, context_path='/auth'):
"""
:param str server_url: The base URL where the Keycloak server can be
found
:param str realm_name: REALM name
:param dict headers: Optional extra headers to send with requests to
the server
:param str context_path: Optional context path for building urls (defaults to `/auth`)
"""
self._server_url = server_url
self._realm_name = realm_name
self._headers = headers
self._context_path = context_path
@property
def client(self):
"""
:rtype: keycloak.client.KeycloakClient
"""
if self._client is None:
self._client = KeycloakClient(server_url=self._server_url,
headers=self._headers, context_path=self._context_path)
return self._clientAnd every _paths object would remove the /auth at the beginning.
Then the API stays the same for most users but v17 users can pass context_path='' to remove the /auth part.
Let me know if this plan sounds acceptable to you, and if so I will begin implementing.