python-keycloak-client icon indicating copy to clipboard operation
python-keycloak-client copied to clipboard

Support Keycloak Version 17.0.0

Open predictap-droscoe opened this issue 3 years ago • 1 comments

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_path

The 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_path

And 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._client

And 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.

predictap-droscoe avatar Mar 12 '22 21:03 predictap-droscoe

Given that:

  • The Keycloak 17.0 release dates from February 2022
  • Releases prior to 17 (aka pre-Quarkus releases) have been deprecated ever since
  • The latest release is 22.0.5

It seems that Support Keycloak Version 17.0.0 these days de-facto means Support Keycloak.

My particular problem is with a project that uses this as a dependency. So it would be nice to have some idea of what to expect going forward.

As such, I'd really appreciate it if @Peter-Slump could share their thoughts on the matter. Obviously we're very appreciative of the work done so far. It's just a bit unclear what's going to happen going forward.

🙏

joostdecock avatar Nov 21 '23 10:11 joostdecock