GithubHelp home page GithubHelp logo

peter-slump / python-keycloak-client Goto Github PK

View Code? Open in Web Editor NEW
83.0 6.0 54.0 255 KB

Python Client for Keycloak identity and access management service

License: MIT License

Python 99.68% Makefile 0.32%

python-keycloak-client's Introduction

Python Keycloak Client

Build Status Documentation Status codecov Maintainability License Version Wheel Join the chat at https://gitter.im/Python-Keycloak/Client

Python Client for Keycloak identity and access management service

Documentation

http://www.keycloak.org/

https://github.com/Peter-Slump/python-keycloak-client

Development

Install development environment:

$ make install-python

Writing docs

Documentation is written using Sphinx and maintained in the docs folder.

To make it easy to write docs Docker support is available.

First build the Docker container:

$ docker build . -f DockerfileDocs -t python-keycloak-client-docs

Run the container

$ docker run -v `pwd`:/src --rm -t -i -p 8050:8050 python-keycloak-client-docs

Go in the browser to http://localhost:8050 and view the documentation which get refreshed and updated on every update in the documentation source.

Create release

$ git checkout master
$ git pull
-- Update release notes --
$ bumpversion release
$ make deploy-pypi
$ bumpversion --no-tag patch
$ git push origin master --tags

Release Notes

unreleased

v0.2.3

  • Bug fix: client_class on KeycloakRealm constructor (thanks to pcaro)

  • Improve Keycloak Client (thanks to ByJacob)

    • add delete in admin client
    • add manage groups in realm
    • add manage user roles
    • rename Roles to ClientRoles

v0.2.2

  • Added support for UMA1 for Keycloak < 4.0
  • Allow to query registered users (thanks to aberres)

v0.2.1

  • Including aio version in released package. (thanks to mackeyja92)

v0.2.0

  • Added async client based on aiohttp (thanks to nkoshell)

v0.1.4

  • Add support for password grant (thanks to scranen)
  • Bugfix: Prevent multiple values for keyword argument 'audience' in jwt.decode() (thanks to eugenejo)

python-keycloak-client's People

Contributors

aberres avatar arhimed avatar eugenejo avatar gitter-badger avatar native2k avatar nkoshell avatar peter-slump avatar scranen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

python-keycloak-client's Issues

@Peter

CMD sphinx-autobuild --host 0.0.0.0 --port 8050 -z src docs docs/_build/html

realm.open_id_connec code except throwing a missing argument error

I'm running code based on this excerpt:

from keycloak.realm import KeycloakRealm

realm = KeycloakRealm(server_url='https://example.com', realm_name='my_realm')

oidc_client = realm.open_id_connect(client_id='my-client',
                                    client_secret='very-secret-client-secret')

It is throwing the following error:

Missing argument in parameter list.
+ CategoryInfo : ParserError: ( : ) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : MissingArgument

I suspect that realm package has changed since the documentation was last updated and that it now needs a third argument, self - populated from the contents of config.py ?

aio module not included in 0.2.0 release

When installing the package from PyPI the aiomodule is not included.

$ pip3 install python-keycloak-client[aio]
Collecting python-keycloak-client[aio]
  ... truncated
Successfully built python-keycloak-client future yarl
Installing collected packages: certifi, chardet, urllib3, idna, requests, pyasn1, rsa, ecdsa, future, python-jose, multidict, yarl, attrs, async-timeout, aiohttp, python-keycloak-client
Successfully installed aiohttp-3.4.4 async-timeout-3.0.1 attrs-18.2.0 certifi-2018.11.29 chardet-3.0.4 ecdsa-0.13 future-0.17.1 idna-2.7 multidict-4.5.2 pyasn1-0.4.4 python-jose-3.0.1 python-keycloak-client-0.2.0 requests-2.20.1 rsa-4.0 urllib3-1.24.1 yarl-1.2.6

$ python -c "import keycloak; from keycloak.aio.realm import KeycloakRealm"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'keycloak.aio'

$ cd "$(python -c "import sys; print(sys.path[-1]);")/keycloak";
$ pwd
~/.venvs/test/lib/python3.7/site-packages/keycloak

$ ls -lah
total 96
drwxr-xr-x  13 user  group   416B Dec  8 10:01 .
drwxr-xr-x  60 user  group   1.9K Dec  8 10:01 ..
-rw-r--r--   1 user  group     0B Dec  8 10:01 __init__.py
drwxr-xr-x  11 user  group   352B Dec  8 10:01 __pycache__
drwxr-xr-x   8 user  group   256B Dec  8 10:01 admin
-rw-r--r--   1 user  group   5.5K Dec  8 10:01 authz.py
-rw-r--r--   1 user  group   3.0K Dec  8 10:01 client.py
-rw-r--r--   1 user  group   251B Dec  8 10:01 exceptions.py
-rw-r--r--   1 user  group   554B Dec  8 10:01 mixins.py
-rw-r--r--   1 user  group    12K Dec  8 10:01 openid_connect.py
-rw-r--r--   1 user  group   2.2K Dec  8 10:01 realm.py
-rw-r--r--   1 user  group   7.2K Dec  8 10:01 uma.py
-rw-r--r--   1 user  group   962B Dec  8 10:01 well_known.py

Faulty rtype in docstring

The rtype annotation in KeycloakUMA.resource_set_create is wrong, or at least incomplete.
It indicates that the return value will be a str when KeycloakClient._handle_response tries to return a deserialized json object.

This can be confusing/annoying when you try to maintain proper type annotations in a large project and your IDE tells you something is wrong.
The UMA specs for that particular endpoint also state that the response should be some json with an "_id" key which (translated to Python) the function does return.

Investigate note on refresh code

@pehala added a note to his pull request which should be investigated.

I am not sure about validity of refreshing code for authentication by client_id and client_secret

How to create new REALM

Hi there,
according to documentation currently there is no ability to create new realm using python-kycloak-client... . So question is whether is there any workaround for it ... or do you plan in near feature add this functionality into python-keycloak-client?

Thanks,

401 Client Error: Unauthorized for url: How to specify username/password for admin

Hi,
I would like to access the admin api by providing the username and client. How do I specify that information? I tried the following for e.g. but it did not work.

headers = dict(grant_type='password', username='admin_user', password='testingxxx')
realm = KeycloakRealm(server_url=conf['keycloak_url'], realm_name='master', headers=headers)
users = realm.admin.realms.by_name('master').users
print(users.all())

Timeout Support

Hello,
There is no support to set a timeout for the requests.
The requests module have the timeout field, as such it needs to be added to each request and be customizable.

I have no time right now to dig deeper, but It seems fairly easy to implement. Meanwhile, if I manage to get some time I can try to implement.

Best regards

Admin API Version compatibility

The URLs used for the Admin API client are based on the URLS for Keycloak 3.3 and previous versions. Later versions have dropped the /admin part of the URL.
For example: /auth/admin/realms/{realm}/clients is /auth/realms/{realm}/clients for v3.4 and later.

To support later versions I would suggest setting these URLs conditionally based on the version.

Remove Python 2 support

Remove Python 2 support as support ends at the end of this year. By doing this we can make use of the fully potential of Python 3 features.

There is no KeycloakClientError function inside exceptions.py

I removed this function from exceptions but I would still prefer to fix the bug.

Traceback (most recent call last):
File "main.py", line 1, in
from keycloak.aio.realm import KeycloakRealm
File "/usr/local/lib/python3.7/dist-packages/keycloak/aio/init.py", line 8, in
from .authz import * # noqa: F403
File "/usr/local/lib/python3.7/dist-packages/keycloak/aio/authz.py", line 7, in
from keycloak.exceptions import KeycloakClientError
ImportError: cannot import name 'KeycloakClientError' from 'keycloak.exceptions' (/usr/local/lib/python3.7/dist-packages/keycloak/exceptions.py)

Python 2.7.15 install fail

Trying to install with pip2.7 on a Centos 6 machine.
pip2.7 install -Iv https://github.com/Peter-Slump/python-keycloak-client/archive/v0.2.2.zip

Possibly a distutils version issue?

Returns error code 1 with:

    /usr/local/lib/python2.7/distutils/dist.py:267: UserWarning: Unknown distribution option: 'python_requires'
      warnings.warn(msg)
    zip_safe flag not set; analyzing archive contents...

    Installed /tmp/pip-req-build-elsdTF/.eggs/pytest_runner-4.4-py2.7.egg
    error in python-keycloak-client setup command: 'extras_require' must be a dictionary whose values are strings or lists of strings containing valid project/version requirement specifiers.
Cleaning up...
  Removing source in /tmp/pip-req-build-elsdTF
Removed https://github.com/Peter-Slump/python-keycloak-client/archive/v0.2.2.zip from build tracker '/tmp/pip-req-tracker-7np39i'
Removed build tracker '/tmp/pip-req-tracker-7np39i'
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-req-build-elsdTF/
Exception information:
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/site-packages/pip/_internal/cli/base_command.py", line 179, in main
    status = self.run(options, args)
  File "/usr/local/lib/python2.7/site-packages/pip/_internal/commands/install.py", line 315, in run
    resolver.resolve(requirement_set)
  File "/usr/local/lib/python2.7/site-packages/pip/_internal/resolve.py", line 131, in resolve
    self._resolve_one(requirement_set, req)
  File "/usr/local/lib/python2.7/site-packages/pip/_internal/resolve.py", line 294, in _resolve_one
    abstract_dist = self._get_abstract_dist_for(req_to_install)
  File "/usr/local/lib/python2.7/site-packages/pip/_internal/resolve.py", line 242, in _get_abstract_dist_for
    self.require_hashes
  File "/usr/local/lib/python2.7/site-packages/pip/_internal/operations/prepare.py", line 349, in prepare_linked_requirement
    abstract_dist.prep_for_dist(finder, self.build_isolation)
  File "/usr/local/lib/python2.7/site-packages/pip/_internal/operations/prepare.py", line 158, in prep_for_dist
    self.req.prepare_metadata()
  File "/usr/local/lib/python2.7/site-packages/pip/_internal/req/req_install.py", line 530, in prepare_metadata
    self.run_egg_info()
  File "/usr/local/lib/python2.7/site-packages/pip/_internal/req/req_install.py", line 609, in run_egg_info
    command_desc='python setup.py egg_info')
  File "/usr/local/lib/python2.7/site-packages/pip/_internal/utils/misc.py", line 761, in call_subprocess
    % (command_desc, proc.returncode, cwd))
InstallationError: Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-req-build-elsdTF/ ```

Support Keycloak Version 17.0.0

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.

New release?

I'd like to use this for my purposes, but currently the official release seems to lack support for access roles with the admin client. Any chance to push out a release including those changes?

Update docblocks

Remove :param and :return etc. since this is in most of the cases not needed anymore because Typehinting is added. Follow PEP 257?

Documentation image build fails with unsatisfied constraints error

Seems that latest Alpine image doesn't have some dependency packages. Changing py2-pip to py3-pip and python-dev to python3-dev respectively resolves the issue.

-> docker build . -f DockerfileDocs -t python-keycloak-client-docs
Sending build context to Docker daemon  559.1kB
Step 1/10 : FROM alpine:latest
latest: Pulling from library/alpine
df20fa9351a1: Pull complete
Digest: sha256:185518070891758909c9f839cf4ca393ee977ac378609f700f60a771a2dfe321
Status: Downloaded newer image for alpine:latest
 ---> a24bb4013296
Step 2/10 : RUN apk --no-cache add   py2-pip   python-dev   make   git   gcc   alpine-sdk
 ---> Running in e54edacaf9d3
fetch http://dl-cdn.alpinelinux.org/alpine/v3.12/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.12/community/x86_64/APKINDEX.tar.gz
ERROR: unsatisfiable constraints:
  py2-pip (missing):
    required by: world[py2-pip]
  python-dev (missing):
    required by: world[python-dev]
The command '/bin/sh -c apk --no-cache add   py2-pip   python-dev   make   git   gcc   alpine-sdk' returned a non-zero code: 2

Is this still under active development?

Hey Peter,

We're looking to switch from our current library( 'python-keycloak') to an asynchronous one such as yours. Is this still under active development? And, if not are there any other projects you can recommend?

We're worried about compatibility issues with newer versions of Keycloak.

Thanks,
Conor

keycloak api questions

Hi Peter,
thanks for your project python-keycloak-client. I would like to ask a few questions... .

  • in your documentation I can see only a few methods/apis which can I use for Keycloak. I'm looking for some way how can I create e.g. new 'realm', 'component - like LDAP provider' .. is there some generic for it?

  • some methods in your project have as parameter 'token' ... Could you please explain why it's necessary to pass client into the methods? I thought that token is obtained/refreshed by default according the settings/credentials for realms object / oaidc_client. Why is necessary put token directly into method?

  • how can I obtain the token .. there is 'client_credentials' method but returns more than access_token. ... so I would like to know what is correct way for using e.g. 'userinfo(token)' ...

  • should I call 'client_credentials' first and parse 'access_token' from respnose... and than use this 'access_token' as token for userinfo method? Am I right or is there better/straightforward way how to do it?

Thanks Peter!

Ivan

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.