Coder Social home page Coder Social logo

keypunch's Introduction

Keypunch is a small client for Keycloak. Its main goal is to automate some administrative tasks like creating a user or trigger an email.

Install

Install latest version:

pip install git+ssh://[email protected]/b12consulting/keypunch

Install a specific version:

pip install git+ssh://[email protected]/b12consulting/keypunch@2c6496ca519

The revision specified in @.. can be replaced by a tag or a branch name.

Usage

Client & endpoint

The first thing to do once a client instance is created is to log in:

from keypunch import KClient

base_url = "http://localhost:8080"
kcli = KClient(base_url=base_url)

# Login
kcli.login("admin", "admin")

# Login with another user
base_url = "http://localhost:8080"
kcli = KClient(base_url=base_url, realm="custom-realm")
kcli.login(
    "[email protected]",
    "passwd",
)

The kcli object holds a requests session that manages the cookies, session refresh is not implemented so queries can fail after a few minutes (depending on your Keycloak settings).

The KClient class main job is to instanciate an Endpoint object based on a known path. For example in order to instanciate an endpoint for the "my-new-realm" realm we use the endpoint method that take as first argument the name of the endpoint and any extra argument needed to format the route:

ep = kcli.endpoint("realm", realm="my-new-realm")
print(ep.url)  #'http://localhost:8080/admin/realms/my-new-realm'

We can then trigger the actual query with either post, get, delete, put or form (form is like post but with "application/x-www-form-urlencoded" instead of the default "application/json"):

realm_info = ep.get()

To create a new realm (note that we use the "realms" endpoint this time):

ep = kcli.endpoint("realms")
ep.post(realm="another-new-realm")

In the example above the json payload {"realm":"another-new-realm"} will be sent in the request body.

For GET queries, the method argument will be used as query parameters, so this:

kcli.endpoint("clients", realm="master").get(max=1)

Will query this url: http://localhost:8080/admin/realms/master/clients?max=1

API support

The _paths attribute contains some pre-defined endpoints:

>>> pprint(KClient._paths)
{
 ...
 'realm': '/admin/realms/{realm}',
 ...
}

Only a few API endpoint are supported and are added in opportunistic fashion. You can easily add extra endpoints by updating the KClient._paths dictionary, like this:

KClient._paths.update({
    "roles": "/admin/{realm}/clients/{id}/roles",
    "client-scopes": "/admin//{realm}/client-scopes/{id}/scope-mappings/clients/{client}",
    })

Keycloak API is documented here: https://www.keycloak.org/docs-api/23.0.3/rest-api/index.html , Keycloak-orgs OpenAPI document: https://github.com/p2-inc/phasetwo-docs/blob/master/openapi.yaml

Logging

Enable logging

from keypunch.utils import logger
logger.setLevel("DEBUG")

Alternatively you can set the environment variable:

export KEYPUNCH_DEBUG=1

Testing

In order to run non-mocked test you will have to start a container:

docker run --name keypunch_test --rm -p 8080:8080 \
 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin -e KC_HTTP_RELATIVE_PATH=/ \
 quay.io/phasetwo/phasetwo-keycloak:22.0.5 \
start-dev --spi-email-template-provider=freemarker-plus-mustache \
 --spi-email-template-freemarker-plus-mustache-enabled=true --spi-theme-cache-themes=false

Install test dependencies

pip install ".[test]"

Run tests

pytest tests/

Examples

Realms

# Get master realm info
kcli.endpoint('realm').get()

# Get app realm info
kcli.endpoint("realm", realm="my-new-realm").get()

# List realms
kcli.endpoint("realms").get()

# Create realm
kcli.endpoint('realms').post(
    realm="another-new-realm",
)

# Delete realms
kcli.endpoint('realm', realm="another-new-realm").delete()

Users

# List users
kcli.endpoint('users', realm="my-new-realm").get()

# Create user
kcli.endpoint('users', realm="my-new-realm").post(username="new-user")

Organisation membership

# List orgs
kcli.endpoint('orgs', realm="my-new-realm").get()

# List members
kcli.endpoint(
    'members',
    realm="my-new-realm",
    org_id="c501122a-e007-46d0-b620-cdcc2aa13f4c",
).get()

# Get membership info
kcli.endpoint(
    'user',
    realm="my-new-realm",
    user_id="5db4613c-e740-4617-b86e-6830d2550590",
    org_id="c501122a-e007-46d0-b620-cdcc2aa13f4c",
).get()

Organisation invitations

# Create Invitations
kcli.endpoint(
    'invitations',
    realm="my-new-realm",
    org_id="c501122a-e007-46d0-b620-cdcc2aa13f4c",
).post(
    email="[email protected]",
    send=True,
)

# List Invitations
kcli.endpoint(
    "invitations",
    realm="my-new-realm",
    org_id="c501122a-e007-46d0-b620-cdcc2aa13f4c",
).get()

# Delete
kclient.endpoint(
        'invitation',
    realm="test-realm",
    org_id=org_id,
    invitation_id=invitation[0]["id"],
).delete()

Organisation roles

# Get user for a given org role in a realm
kcli.endpoint(
    'role-users',
    realm="gpc_analysis",
    org_id="e397aff2-1b0f-43b8-8305-5b94b9fc853b",
    role="manage-members",
).get()

Trigger mails

# Action email with "UPDATE_PASSWORD" payload -> can be used as forgot password or for first login
kcli.endpoint(
    "execute-actions-email",
    realm="my-new-realm",
    user_id="5db4613c-e740-4617-b86e-6830d2550590",
).put(["UPDATE_PASSWORD"])

# Force user to cycle password (so not a situation were the user
# has forgot it)

kcli.endpoint(
    "reset-password",
    realm="my-new-realm",
    user_id="5db4613c-e740-4617-b86e-6830d2550590",
).put(
    temporary=True,
    type="password",
    value="hamspam",
)

keypunch's People

Contributors

bertrand-chenal avatar jolivab12 avatar chris-adam-b12 avatar

Watchers

Olivier Martin avatar  avatar  avatar

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.