Skip to content

Latest commit

 

History

History
246 lines (176 loc) · 7.05 KB

README.md

File metadata and controls

246 lines (176 loc) · 7.05 KB

gocloak

codebeat badge Go Report Card Go Doc Build Status GitHub release codecov FOSSA Status

Golang Keycloak API Package

This client is based on: go-keycloak

For Questions either raise an issue, or come to the gopher-slack into the channel #gocloak

If u are using the echo framework have a look at gocloak-echo

Benchmarks can be found here

Contribution

(WIP) https://github.com/Nerzal/gocloak/wiki/Contribute

Changelog

For release notes please consult the specific releases here

Usage

Installation

go get github.com/Nerzal/gocloak/v13

Importing

 import "github.com/Nerzal/gocloak/v13"

Create New User

 client := gocloak.NewClient("https://mycool.keycloak.instance")
 ctx := context.Background()
 token, err := client.LoginAdmin(ctx, "user", "password", "realmName")
 if err != nil {
  panic("Something wrong with the credentials or url")
 }

 user := gocloak.User{
  FirstName: gocloak.StringP("Bob"),
  LastName:  gocloak.StringP("Uncle"),
  Email:     gocloak.StringP("[email protected]"),
  Enabled:   gocloak.BoolP(true),
  Username:  gocloak.StringP("CoolGuy"),
 }

 _, err = client.CreateUser(ctx, token.AccessToken, "realm", user)
 if err != nil {
  panic("Oh no!, failed to create user :(")
 }

Introspect Token

 client := gocloak.NewClient(hostname)
 ctx := context.Background()
 token, err := client.LoginClient(ctx, clientID, clientSecret, realm)
 if err != nil {
  panic("Login failed:"+ err.Error())
 }

 rptResult, err := client.RetrospectToken(ctx, token.AccessToken, clientID, clientSecret, realm)
 if err != nil {
  panic("Inspection failed:"+ err.Error())
 }

 if !*rptResult.Active {
  panic("Token is not active")
 }

 permissions := rptResult.Permissions
 // Do something with the permissions ;)

Get Client id

Client has 2 identity fields- id and clientId and both are unique in one realm.

  • id is generated automatically by Keycloak.
  • clientId is configured by users in Add client page.

To get the clientId from id, use GetClients method with GetClientsParams{ClientID: &clientName}.

 clients, err := c.Client.GetClients(
  c.Ctx,
  c.JWT.AccessToken,
  c.Realm,
  gocloak.GetClientsParams{
   ClientID: &clientName,
  },
 )
 if err != nil {
  panic("List clients failed:"+ err.Error())
 }
 for _, client := range clients {
  return *client.ID, nil
 }

Features

GoCloakIface holds all methods a client should fulfil.

Configure gocloak to skip TLS Insecure Verification

    client := gocloak.NewClient(serverURL)
    restyClient := client.RestyClient()
    restyClient.SetDebug(true)
    restyClient.SetTLSClientConfig(&tls.Config{ InsecureSkipVerify: true })

developing & testing

For local testing you need to start a docker container. Simply run following commands prior to starting the tests:

docker pull quay.io/keycloak/keycloak
docker run -d \
 -e KEYCLOAK_USER=admin \
 -e KEYCLOAK_PASSWORD=secret \
 -e KEYCLOAK_IMPORT=/tmp/gocloak-realm.json \
 -v "`pwd`/testdata/gocloak-realm.json:/tmp/gocloak-realm.json" \
 -p 8080:8080 \
 --name gocloak-test \
 quay.io/keycloak/keycloak:latest -Dkeycloak.profile.feature.upload_scripts=enabled

go test

Or you can run with docker compose using the run-tests script

./run-tests.sh

or

./run-tests.sh <TestCase>

Or you can run the tests on you own keycloak:

export GOCLOAK_TEST_CONFIG=/path/to/gocloak/config.json

All resources created as a result of unit tests will be deleted, except for the test user defined in the configuration file.

To remove running docker container after completion of tests:

docker stop gocloak-test
docker rm gocloak-test

Inspecting custom types

The custom types contain many pointers, so printing them yields mostly pointer values, which aren't much help when debugging your application. For example

someRealmRepresentation := gocloak.RealmRepresentation{
   <snip>
}

fmt.Println(someRealmRepresentation)

yields a large set of pointer values

{<nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> 0xc00000e960 <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> 0xc000093cf0 <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> null <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil>}

For convenience, the String() interface has been added so you can easily see the contents, even for nested custom types. For example,

fmt.Println(someRealmRepresentation.String())

yields

{
 "clients": [
  {
   "name": "someClient",
   "protocolMappers": [
    {
     "config": {
      "bar": "foo",
      "ping": "pong"
     },
     "name": "someMapper"
    }
   ]
  },
  {
   "name": "AnotherClient"
  }
 ],
 "displayName": "someRealm"
}

Note that empty parameters are not included, because of the use of omitempty in the type definitions.

Examples

License

FOSSA Status

Related Projects

GocloakSession