{"id":17957516,"url":"https://github.com/itinance/gocloakex","last_synced_at":"2025-04-03T17:32:17.003Z","repository":{"id":57531184,"uuid":"276724907","full_name":"itinance/gocloakex","owner":"itinance","description":null,"archived":false,"fork":false,"pushed_at":"2021-12-28T12:42:24.000Z","size":1453,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-09T06:16:03.719Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/itinance.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-07-02T19:01:20.000Z","updated_at":"2021-04-09T08:02:35.000Z","dependencies_parsed_at":"2022-09-26T18:22:05.244Z","dependency_job_id":null,"html_url":"https://github.com/itinance/gocloakex","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itinance%2Fgocloakex","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itinance%2Fgocloakex/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itinance%2Fgocloakex/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itinance%2Fgocloakex/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/itinance","download_url":"https://codeload.github.com/itinance/gocloakex/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247046706,"owners_count":20874705,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-29T10:55:27.041Z","updated_at":"2025-04-03T17:32:16.964Z","avatar_url":"https://github.com/itinance.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# gocloak\n[![codebeat badge](https://codebeat.co/badges/c699bc56-aa5f-4cf5-893f-5cf564391b94)](https://codebeat.co/projects/github-com-nerzal-gocloak-master)\n[![Go Report Card](https://goreportcard.com/badge/github.com/Nerzal/gocloak)](https://goreportcard.com/report/github.com/Nerzal/gocloak)\n[![Go Doc](https://godoc.org/github.com/Nerzal/gocloak?status.svg)](https://godoc.org/github.com/Nerzal/gocloak)\n[![Build Status](https://github.com/Nerzal/gocloak/workflows/Tests/badge.svg)](https://github.com/Nerzal/gocloak/actions?query=branch%3Amaster+event%3Apush)\n[![GitHub release](https://img.shields.io/github/tag/Nerzal/gocloak.svg)](https://GitHub.com/Nerzal/gocloak/releases/)\n[![codecov](https://codecov.io/gh/Nerzal/gocloak/branch/master/graph/badge.svg)](https://codecov.io/gh/Nerzal/gocloak)\n[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2FNerzal%2Fgocloak.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2FNerzal%2Fgocloak?ref=badge_shield)\n\n\nGolang Keycloak API Package\n\nThis client is based on: [go-keycloak](https://github.com/PhilippHeuer/go-keycloak)\n\nFor Questions either raise an issue, or come to the [gopher-slack](https://invite.slack.golangbridge.org/) into the channel [#gocloak](https://gophers.slack.com/app_redirect?channel=gocloak)\n\nIf u are using the echo framework have a look at [gocloak-echo](https://github.com/Nerzal/gocloak-echo)\n\nBenchmarks: https://nerzal.github.io/gocloak/dev/bench/\n\n\n## Contribution\n(WIP) https://github.com/Nerzal/gocloak/wiki/Contribute\n\n## Changelog\n\n### v6:\nThere are several backward incompatible changes\n* all client functions now take `context.Context` as first argument.\n* `UserAttributeContains` was moved from client method to package function.\n* all structures now use pointers for the array types ([]string -\u003e *[]string)\n\n### v5:\nThere is only one change, but it's backward incompatible:\n* Wrap Errors and use APIError struct to also provide the httpstatus code. ([#146](https://github.com/Nerzal/gocloak/pull/146))\n\n### v4:\nThere are a lot of backward incompatible changes:\n* all functions what create an object now return an ID of the created object. The return statement of those functions has been changed from (error) to (string, error)\n* All structures now use pointers instead of general types (bool -\u003e *bool, string -\u003e *string). It has been done to properly use omitempty tag, otherwise it was impossible to set a false value for any of the bool propertires.\n\n## Usage\n\n\n\n### Importing\n\n```go\n\timport \"github.com/itinance/gocloak/v6\"\n```\n\nor v3 (latest release is v3.10.0):\n\n```go\n\timport \"github.com/Nerzal/gocloak/v3\"\n```\n\n### Create New User\n```go\n\tclient := gocloak.NewClient(\"https://mycool.keycloak.instance\")\n\tctx := context.Background()\n\ttoken, err := client.LoginAdmin(ctx, \"user\", \"password\", \"realmName\")\n\tif err != nil {\n\t\tpanic(\"Something wrong with the credentials or url\")\n\t}\n\tuser := gocloak.User{\n\t\tFirstName: \"Bob\",\n\t\tLastName:  \"Uncle\",\n\t\tEmail:     \"something@really.wrong\",\n\t\tEnabled:   true,\n\t\tUsername:  \"CoolGuy\",\n\t}\n\t_, err = client.CreateUser(ctx, token.AccessToken, \"realm\", user)\n\tif err != nil {\n\t\tpanic(\"Oh no!, failed to create user :(\")\n\t}\n```\n\n### Introspect Token\n```go\n\tclient := gocloak.NewClient(hostname)\n\tctx := context.Background()\n\ttoken, err := client.LoginClient(ctx, clientid, clientSecret, realm)\n\tif err != nil {\n\t\tpanic(\"Login failed:\"+ err.Error())\n\t}\n\n\trptResult, err := client.RetrospectToken(ctx, token.AccessToken, clientid, clientSecret, realm)\n\tif err != nil {\n\t\tpanic(\"Inspection failed:\"+ err.Error())\n\t}\n\n\tif !rptResult.Active {\n\t\tpanic(\"Token is not active\")\n\t}\n\n\tpermissions := rptResult.Permissions\n\t// Do something with the permissions ;)\n```\n\n## Features\n\n```go\n// GoCloak holds all methods a client should fullfill\ntype GoCloak interface {\n\tGetRequestingPartyToken(, ctx context.Contexttoken, realm string, options RequestingPartyTokenOptions) (*JWT, error)\n\n\tLogin(ctx context.Context, clientID, clientSecret, realm, username, password string) (*JWT, error)\n\tLoginOtp(ctx context.Context, clientID, clientSecret, realm, username, password, totp string) (*JWT, error)\n\tLogout(ctx context.Context, clientID, clientSecret, realm, refreshToken string) error\n\tLogoutPublicClient(ctx context.Context, clientID, realm, accessToken, refreshToken string) error\n\tLogoutAllSessions(ctx context.Context, accessToken, realm, userID string) error\n\tLoginClient(ctx context.Context, clientID, clientSecret, realm string) (*JWT, error)\n\tLoginClientSignedJWT(ctx context.Context, clientID, realm string, key interface{}, signedMethod jwt.SigningMethod, expiresAt int64) (*JWT, error)\n\tLoginAdmin(ctx context.Context, username, password, realm string) (*JWT, error)\n\tRequestPermission(ctx context.Context, clientID, clientSecret, realm, username, password, permission string) (*JWT, error)\n\tRefreshToken(ctx context.Context, refreshToken, clientID, clientSecret, realm string) (*JWT, error)\n\tDecodeAccessToken(ctx context.Context, accessToken, realm string) (*jwt.Token, *jwt.MapClaims, error)\n\tDecodeAccessTokenCustomClaims(ctx context.Context, accessToken, realm string, claims jwt.Claims) (*jwt.Token, error)\n\tRetrospectToken(ctx context.Context, accessToken, clientID, clientSecret, realm string) (*RetrospecTokenResult, error)\n\tGetIssuer(ctx context.Context, realm string) (*IssuerResponse, error)\n\tGetCerts(ctx context.Context, realm string) (*CertResponse, error)\n\tGetServerInfo(ctx context.Context, accessToken string) (*ServerInfoRepesentation, error)\n\tGetUserInfo(ctx context.Context, accessToken, realm string) (*UserInfo, error)\n\tGetRawUserInfo(ctx context.Context, accessToken, realm string) (map[string]interface{}, error)\n\tSetPassword(ctx context.Context, token, userID, realm, password string, temporary bool) error\n\tExecuteActionsEmail(ctx context.Context, token, realm string, params ExecuteActionsEmail) error\n\n\tCreateUser(ctx context.Context, token, realm string, user User) (string, error)\n\tCreateGroup(ctx context.Context, accessToken, realm string, group Group) error\n\tCreateChildGroup(ctx context.Context, token, realm, groupID string, group Group) (string, error)\n\tCreateClientRole(ctx context.Context, accessToken, realm, clientID string, role Role) error\n\tCreateClient(ctx context.Context, accessToken, realm string, clientID Client) error\n\tCreateClientScope(ctx context.Context, accessToken, realm string, scope ClientScope) error\n\tCreateComponent(ctx context.Context, accessToken string, realm, component Component) error\n\n\tUpdateUser(ctx context.Context, accessToken, realm string, user User) error\n\tUpdateGroup(ctx context.Context, accessToken, realm string, updatedGroup Group) error\n\tUpdateRole(ctx context.Context, accessToken, realm, clientID string, role Role) error\n\tUpdateClient(ctx context.Context, accessToken, realm string, updatedClient Client) error\n\tUpdateClientScope(ctx context.Context, accessToken, realm string, scope ClientScope) error\n\n\tDeleteUser(ctx context.Context, accessToken, realm, userID string) error\n\tDeleteComponent(ctx context.Context, accessToken, realm, componentID string) error\n\tDeleteGroup(ctx context.Context, accessToken, realm, groupID string) error\n\tDeleteClientRole(ctx context.Context, accessToken, realm, clientID, roleName string) error\n\tDeleteClient(ctx context.Context, accessToken, realm, clientID string) error\n\tDeleteClientScope(ctx context.Context, accessToken, realm, scopeID string) error\n\n\tGetClient(ctx context.Context, accessToken, realm, clientID string) (*Client, error)\n\tGetClientsDefaultScopes(ctx context.Context, token, realm, clientID string) ([]*ClientScope, error)\n\tAddDefaultScopeToClient(ctx context.Context, token, realm, clientID, scopeID string) error\n\tRemoveDefaultScopeFromClient(ctx context.Context, token, realm, clientID, scopeID string) error\n\tGetClientsOptionalScopes(ctx context.Context, token, realm, clientID string) ([]*ClientScope, error)\n\tAddOptionalScopeToClient(ctx context.Context, token, realm, clientID, scopeID string) error\n\tRemoveOptionalScopeFromClient(ctx context.Context, token, realm, clientID, scopeID string) error\n\tGetDefaultOptionalClientScopes(ctx context.Context, token, realm string) ([]*ClientScope, error)\n\tGetDefaultDefaultClientScopes(ctx context.Context, token, realm string) ([]*ClientScope, error)\n\tGetClientScope(ctx context.Context, token, realm, scopeID string) (*ClientScope, error)\n\tGetClientScopes(ctx context.Context, token, realm string) ([]*ClientScope, error)\n\tGetClientSecret(ctx context.Context, token, realm, clientID string) (*CredentialRepresentation, error)\n\tGetClientServiceAccount(ctx context.Context, token, realm, clientID string) (*User, error)\n\tRegenerateClientSecret(ctx context.Context, token, realm, clientID string) (*CredentialRepresentation, error)\n\tGetKeyStoreConfig(ctx context.Context, accessToken, realm string) (*KeyStoreConfig, error)\n\tGetUserByID(ctx context.Context, accessToken, realm, userID string) (*User, error)\n\tGetUserCount(ctx context.Context, accessToken, realm string, params GetUsersParams) (int, error)\n\tGetUsers(ctx context.Context, accessToken, realm string, params GetUsersParams) ([]*User, error)\n\tGetUserGroups(ctx context.Context, accessToken, realm, userID string) ([]*UserGroup, error)\n\tGetComponents(ctx context.Context, accessToken, realm string) ([]*Component, error)\n\tGetGroups(ctx context.Context, accessToken, realm string, params GetGroupsParams) ([]*Group, error)\n\tGetGroupsCount(ctx context.Context, token, realm string, params GetGroupsParams) (int, error)\n\tGetGroup(ctx context.Context, accessToken, realm, groupID string) (*Group, error)\n\tGetDefaultGroups(ctx context.Context, accessToken, realm string) ([]*Group, error)\n\tAddDefaultGroup(ctx context.Context, accessToken, realm, groupID string) error\n\tRemoveDefaultGroup(ctx context.Context, accessToken, realm, groupID string) error\n\tGetGroupMembers(ctx context.Context, accessToken, realm, groupID string, params GetGroupsParams) ([]*User, error)\n\tGetRoleMappingByGroupID(ctx context.Context, accessToken, realm, groupID string) (*MappingsRepresentation, error)\n\tGetRoleMappingByUserID(ctx context.Context, accessToken, realm, userID string) (*MappingsRepresentation, error)\n\tGetClientRoles(ctx context.Context, accessToken, realm, clientID string) ([]*Role, error)\n\tGetClientRole(ctx context.Context, token, realm, clientID, roleName string) (*Role, error)\n\tGetClients(ctx context.Context, accessToken, realm string, params GetClientsParams) ([]*Client, error)\n\tAddClientRoleComposite(ctx context.Context, token, realm, roleID string, roles []Role) error\n\tDeleteClientRoleComposite(ctx context.Context, token, realm, roleID string, roles []Role) error\n\tGetUsersByRoleName(ctx context.Context, token, realm, roleName string) ([]*User, error)\n\tGetUsersByClientRoleName(ctx context.Context, token, realm, clientID, roleName string, params GetUsersByRoleParams) ([]*User, error)\n\tCreateClientProtocolMapper(ctx context.Context, token, realm, clientID string, mapper ProtocolMapperRepresentation) error\n\tUpdateClientProtocolMapper(ctx context.Context, token, realm, clientID, mapperID string, mapper ProtocolMapperRepresentation) error\n\tDeleteClientProtocolMapper(ctx context.Context, token, realm, clientID, mapperID string) error\n\n\t// *** Realm Roles ***\n\n\tCreateRealmRole(ctx context.Context, token, realm string, role Role) error\n\tGetRealmRole(ctx context.Context, token, realm, roleName string) (*Role, error)\n\tGetRealmRoles(ctx context.Context, accessToken, realm string) ([]*Role, error)\n\tGetRealmRolesByUserID(ctx context.Context, accessToken, realm, userID string) ([]*Role, error)\n\tGetRealmRolesByGroupID(ctx context.Context, accessToken, realm, groupID string) ([]*Role, error)\n\tUpdateRealmRole(ctx context.Context, token, realm, roleName string, role Role) error\n\tDeleteRealmRole(ctx context.Context, token, realm, roleName string) error\n\tAddRealmRoleToUser(ctx context.Context, token, realm, userID string, roles []Role) error\n\tDeleteRealmRoleFromUser(ctx context.Context, token, realm, userID string, roles []Role) error\n\tAddRealmRoleToGroup(ctx context.Context, token, realm, groupID string, roles []Role) error\n\tDeleteRealmRoleFromGroup(ctx context.Context, token, realm, groupID string, roles []Role) error\n\tAddRealmRoleComposite(ctx context.Context, token, realm, roleName string, roles []Role) error\n\tDeleteRealmRoleComposite(ctx context.Context, token, realm, roleName string, roles []Role) error\n\n\n\t// *** Client Roles ***\n\n\tAddClientRoleToGroup(ctx context.Context, token, realm, clientID, groupID string, roles []Role) error\n\tDeleteClientRoleFromGroup(ctx context.Context, token, realm, clientID, groupID string, roles []Role) error\n\tGetCompositeClientRolesByRoleID(ctx context.Context, token, realm, clientID, roleID string) ([]*Role, error)\n\tGetClientRolesByUserID(ctx context.Context, token, realm, clientID, userID string) ([]*Role, error)\n\tGetClientRolesByGroupID(ctx context.Context, token, realm, clientID, groupID string) ([]*Role, error)\n\tGetCompositeClientRolesByUserID(ctx context.Context, token, realm, clientID, userID string) ([]*Role, error)\n\tGetCompositeClientRolesByGroupID(ctx context.Context, token, realm, clientID, groupID string) ([]*Role, error)\n\tGetAvailableClientRolesByUserID(ctx context.Context, token, realm, clientID, userID string) ([]*Role, error)\n\n\t// *** Realm ***\n\n\tGetRealm(ctx context.Context, token, realm string) (*RealmRepresentation, error)\n\tGetRealms(ctx context.Context, token string) ([]*RealmRepresentation, error)\n\tCreateRealm(ctx context.Context, token string, realm RealmRepresentation) (string, error)\n\tUpdateRealm(ctx context.Context, token string, realm RealmRepresentation) error\n\tDeleteRealm(ctx context.Context, token, realm string) error\n\tClearRealmCache(ctx context.Context, token, realm string) error\n\tClearUserCache(ctx context.Context, token, realm string) error\n\tClearKeysCache(ctx context.Context, token, realm string) error\n\n\tGetClientUserSessions(ctx context.Context, token, realm, clientID string) ([]*UserSessionRepresentation, error)\n\tGetClientOfflineSessions(ctx context.Context, token, realm, clientID string) ([]*UserSessionRepresentation, error)\n\tGetUserSessions(ctx context.Context, token, realm, userID string) ([]*UserSessionRepresentation, error)\n\tGetUserOfflineSessionsForClient(ctx context.Context, token, realm, userID, clientID string) ([]*UserSessionRepresentation, error)\n\n\t// *** Protection API ***\n\tGetResource(ctx context.Context, token, realm, clientID, resourceID string) (*Resource, error)\n\tGetResources(ctx context.Context, token, realm, clientID string) ([]*Resource, error)\n\tCreateResource(ctx context.Context, token, realm, clientID string, resource Resource) (*Resource, error)\n\tUpdateResource(ctx context.Context, token, realm, clientID string, resource Resource) error\n\tDeleteResource(ctx context.Context, token, realm, clientID, resourceID string) error\n\n\tGetScope(ctx context.Context, token, realm, clientID, scopeID string) (*ScopeRepresentation, error)\n\tGetScopes(ctx context.Context, token, realm, clientID string, params GetScopeParams) ([]*ScopeRepresentation, error)\n\tCreateScope(ctx context.Context, token, realm, clientID string, scope ScopeRepresentation) (*ScopeRepresentation, error)\n\tUpdateScope(ctx context.Context, token, realm, clientID string, resource ScopeRepresentation) error\n\tDeleteScope(ctx context.Context, token, realm, clientID, scopeID string) error\n\n\tGetPolicy(ctx context.Context, token, realm, clientID, policyID string) (*PolicyRepresentation, error)\n\tGetPolicies(ctx context.Context, token, realm, clientID string, params GetPolicyParams) ([]*PolicyRepresentation, error)\n\tCreatePolicy(ctx context.Context, token, realm, clientID string, policy PolicyRepresentation) (*PolicyRepresentation, error)\n\tUpdatePolicy(ctx context.Context, token, realm, clientID string, policy PolicyRepresentation) error\n\tDeletePolicy(ctx context.Context, token, realm, clientID string, policyID string) error\n\n\tGetPermission(ctx context.Context, token, realm, clientID, permissionID string) (*PermissionRepresentation, error)\n\tGetPermissions(ctx context.Context, token, realm, clientID string, params GetPermissionParams) ([]*PermissionRepresentation, error)\n\tCreatePermission(ctx context.Context, token, realm, clientID string, permission PermissionRepresentation) (*PermissionRepresentation, error)\n\tUpdatePermission(ctx context.Context, token, realm, clientID string, permission PermissionRepresentation) error\n\tDeletePermission(ctx context.Context, token, realm, clientID, permissionID string) error\n\n\t// *** Credentials API ***\n\n\tGetCredentialRegistrators(ctx context.Context, token, realm string) ([]string, error)\n\tGetConfiguredUserStorageCredentialTypes(ctx context.Context, token, realm, userID string) ([]string, error)\n\tGetCredentials(ctx context.Context, token, realm, UserID string) ([]*CredentialRepresentation, error)\n\tDeleteCredentials(ctx context.Context, token, realm, UserID, CredentialID string) error\n\tUpdateCredentialUserLabel(ctx context.Context, token, realm, userID, credentialID, userLabel string) error\n\tDisableAllCredentialsByType(ctx context.Context, token, realm, userID string, types []string) error\n\tMoveCredentialBehind(ctx context.Context, token, realm, userID, credentialID, newPreviousCredentialID string) error\n\tMoveCredentialToFirst(ctx context.Context, token, realm, userID, credentialID string) error\n}\n```\n\n## Configure gocloak to skip TLS Insecure Verification\n\n```go\n    client := gocloak.NewClient(serverURL)\n    restyClient := client.RestyClient()\n    restyClient.SetDebug(true)\n    restyClient.SetTLSClientConfig(\u0026tls.Config{ InsecureSkipVerify: true }\n```\n\n## developing \u0026 testing\nFor local testing you need to start a docker container. Simply run following commands prior to starting the tests:\n\n```bash\ndocker pull quay.io/keycloak/keycloak\ndocker run -d \\\n\t-e KEYCLOAK_USER=admin \\\n\t-e KEYCLOAK_PASSWORD=secret \\\n\t-e KEYCLOAK_IMPORT=/tmp/gocloak-realm.json \\\n\t-v \"`pwd`/testdata/gocloak-realm.json:/tmp/gocloak-realm.json\" \\\n\t-p 8080:8080 \\\n\t--name gocloak-test \\\n\tquay.io/keycloak/keycloak:latest -Dkeycloak.profile.feature.upload_scripts=enabled\n\ngo test\n```\n\nOr you can run with docker compose using the run-tests script\n```bash\n./run-tests.sh\n```\nor\n```bash\n./run-tests.sh \u003cTestCase\u003e\n```\n\n\nOr you can run the tests on you own keycloak:\n```bash\nexport GOCLOAK_TEST_CONFIG=/path/to/gocloak/config.json\n```\n\nAll resources created as a result of unit tests will be deleted, except for the test user defined in the configuration file.\n\nTo remove running docker container after completion of tests:\n\n```bash\ndocker stop gocloak-test\ndocker rm gocloak-test\n```\n\n## License\n[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2FNerzal%2Fgocloak.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2FNerzal%2Fgocloak?ref=badge_large)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fitinance%2Fgocloakex","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fitinance%2Fgocloakex","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fitinance%2Fgocloakex/lists"}