Giter VIP home page Giter VIP logo

gocloak's Introduction

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

// GoCloak holds all methods a client should fulfill
type GoCloak interface {

 RestyClient() *resty.Client
 SetRestyClient(restyClient *resty.Client)

 GetToken(ctx context.Context, realm string, options TokenOptions) (*JWT, error)
 GetRequestingPartyToken(ctx context.Context, token, realm string, options RequestingPartyTokenOptions) (*JWT, error)
 GetRequestingPartyPermissions(ctx context.Context, token, realm string, options RequestingPartyTokenOptions) (*[]RequestingPartyPermission, error)
 GetRequestingPartyPermissionDecision(ctx context.Context, token, realm string, options RequestingPartyTokenOptions) (*RequestingPartyPermissionDecision, error)

 Login(ctx context.Context, clientID, clientSecret, realm, username, password string) (*JWT, error)
 LoginOtp(ctx context.Context, clientID, clientSecret, realm, username, password, totp string) (*JWT, error)
 Logout(ctx context.Context, clientID, clientSecret, realm, refreshToken string) error
 LogoutPublicClient(ctx context.Context, clientID, realm, accessToken, refreshToken string) error
 LogoutAllSessions(ctx context.Context, accessToken, realm, userID string) error
 RevokeUserConsents(ctx context.Context, accessToken, realm, userID, clientID string) error
 LogoutUserSession(ctx context.Context, accessToken, realm, session string) error
 LoginClient(ctx context.Context, clientID, clientSecret, realm string) (*JWT, error)
 LoginClientSignedJWT(ctx context.Context, clientID, realm string, key interface{}, signedMethod jwt.SigningMethod, expiresAt *jwt.Time) (*JWT, error)
 LoginAdmin(ctx context.Context, username, password, realm string) (*JWT, error)
 RefreshToken(ctx context.Context, refreshToken, clientID, clientSecret, realm string) (*JWT, error)
 DecodeAccessToken(ctx context.Context, accessToken, realm, expectedAudience string) (*jwt.Token, *jwt.MapClaims, error)
 DecodeAccessTokenCustomClaims(ctx context.Context, accessToken, realm, expectedAudience string, claims jwt.Claims) (*jwt.Token, error)
 RetrospectToken(ctx context.Context, accessToken, clientID, clientSecret, realm string) (*RetrospecTokenResult, error)
 GetIssuer(ctx context.Context, realm string) (*IssuerResponse, error)
 GetCerts(ctx context.Context, realm string) (*CertResponse, error)
 GetServerInfo(ctx context.Context, accessToken string) (*ServerInfoRepesentation, error)
 GetUserInfo(ctx context.Context, accessToken, realm string) (*UserInfo, error)
 GetRawUserInfo(ctx context.Context, accessToken, realm string) (map[string]interface{}, error)
 SetPassword(ctx context.Context, token, userID, realm, password string, temporary bool) error
 ExecuteActionsEmail(ctx context.Context, token, realm string, params ExecuteActionsEmail) error

 CreateUser(ctx context.Context, token, realm string, user User) (string, error)
 CreateGroup(ctx context.Context, accessToken, realm string, group Group) (string, error)
 CreateChildGroup(ctx context.Context, token, realm, groupID string, group Group) (string, error)
 CreateClientRole(ctx context.Context, accessToken, realm, idOfClient string, role Role) (string, error)
 CreateClient(ctx context.Context, accessToken, realm string, newClient Client) (string, error)
 CreateClientScope(ctx context.Context, accessToken, realm string, scope ClientScope) (string, error)
 CreateComponent(ctx context.Context, accessToken, realm string, component Component) (string, error)
 CreateClientScopeMappingsRealmRoles(ctx context.Context, token, realm, idOfClient string, roles []Role) error
 CreateClientScopeMappingsClientRoles(ctx context.Context, token, realm, idOfClient, idOfSelectedClient string, roles []Role) error
 CreateClientScopesScopeMappingsRealmRoles(ctx context.Context, token, realm, idOfCLientScope string, roles []Role) error
 CreateClientScopesScopeMappingsClientRoles(ctx context.Context, token, realm, idOfClientScope, idOfClient string, roles []Role) error

 UpdateUser(ctx context.Context, accessToken, realm string, user User) error
 UpdateGroup(ctx context.Context, accessToken, realm string, updatedGroup Group) error
 UpdateRole(ctx context.Context, accessToken, realm, idOfClient string, role Role) error
 UpdateClient(ctx context.Context, accessToken, realm string, updatedClient Client) error
 UpdateClientScope(ctx context.Context, accessToken, realm string, scope ClientScope) error

 DeleteUser(ctx context.Context, accessToken, realm, userID string) error
 DeleteComponent(ctx context.Context, accessToken, realm, componentID string) error
 DeleteGroup(ctx context.Context, accessToken, realm, groupID string) error
 DeleteClientRole(ctx context.Context, accessToken, realm, idOfClient, roleName string) error
 DeleteClientRoleFromUser(ctx context.Context, token, realm, idOfClient, userID string, roles []Role) error
 DeleteClient(ctx context.Context, accessToken, realm, idOfClient string) error
 DeleteClientScope(ctx context.Context, accessToken, realm, scopeID string) error
 DeleteClientScopeMappingsRealmRoles(ctx context.Context, token, realm, idOfClient string, roles []Role) error
 DeleteClientScopeMappingsClientRoles(ctx context.Context, token, realm, idOfClient, idOfSelectedClient string, roles []Role) error
 DeleteClientScopesScopeMappingsRealmRoles(ctx context.Context, token, realm, idOfCLientScope string, roles []Role) error
 DeleteClientScopesScopeMappingsClientRoles(ctx context.Context, token, realm, idOfClientScope, ifOfClient string, roles []Role) error

 GetClient(ctx context.Context, accessToken, realm, idOfClient string) (*Client, error)
 GetClientsDefaultScopes(ctx context.Context, token, realm, idOfClient string) ([]*ClientScope, error)
 AddDefaultScopeToClient(ctx context.Context, token, realm, idOfClient, scopeID string) error
 RemoveDefaultScopeFromClient(ctx context.Context, token, realm, idOfClient, scopeID string) error
 GetClientsOptionalScopes(ctx context.Context, token, realm, idOfClient string) ([]*ClientScope, error)
 AddOptionalScopeToClient(ctx context.Context, token, realm, idOfClient, scopeID string) error
 RemoveOptionalScopeFromClient(ctx context.Context, token, realm, idOfClient, scopeID string) error
 GetDefaultOptionalClientScopes(ctx context.Context, token, realm string) ([]*ClientScope, error)
 GetDefaultDefaultClientScopes(ctx context.Context, token, realm string) ([]*ClientScope, error)
 GetClientScope(ctx context.Context, token, realm, scopeID string) (*ClientScope, error)
 GetClientScopes(ctx context.Context, token, realm string) ([]*ClientScope, error)
 GetClientScopeMappings(ctx context.Context, token, realm, idOfClient string) (*MappingsRepresentation, error)
 GetClientScopeMappingsRealmRoles(ctx context.Context, token, realm, idOfClient string) ([]*Role, error)
 GetClientScopeMappingsRealmRolesAvailable(ctx context.Context, token, realm, idOfClient string) ([]*Role, error)
 GetClientScopesScopeMappingsRealmRolesAvailable(ctx context.Context, token, realm, idOfClientScope string) ([]*Role, error)
 GetClientScopesScopeMappingsClientRolesAvailable(ctx context.Context, token, realm, idOfClientScope, idOfClient string) ([]*Role, error)
 GetClientScopeMappingsClientRoles(ctx context.Context, token, realm, idOfClient, idOfSelectedClient string) ([]*Role, error)
 GetClientScopesScopeMappingsRealmRoles(ctx context.Context, token, realm, idOfClientScope string) ([]*Role, error)
 GetClientScopesScopeMappingsClientRoles(ctx context.Context, token, realm, idOfClientScope, idOfClient string) ([]*Role, error)
 GetClientScopeMappingsClientRolesAvailable(ctx context.Context, token, realm, idOfClient, idOfSelectedClient string) ([]*Role, error)
 GetClientSecret(ctx context.Context, token, realm, idOfClient string) (*CredentialRepresentation, error)
 GetClientServiceAccount(ctx context.Context, token, realm, idOfClient string) (*User, error)
 RegenerateClientSecret(ctx context.Context, token, realm, idOfClient string) (*CredentialRepresentation, error)
 GetKeyStoreConfig(ctx context.Context, accessToken, realm string) (*KeyStoreConfig, error)
 GetUserByID(ctx context.Context, accessToken, realm, userID string) (*User, error)
 GetUserCount(ctx context.Context, accessToken, realm string, params GetUsersParams) (int, error)
 GetUsers(ctx context.Context, accessToken, realm string, params GetUsersParams) ([]*User, error)
 GetUserGroups(ctx context.Context, accessToken, realm, userID string, params GetGroupsParams) ([]*UserGroup, error)
 AddUserToGroup(ctx context.Context, token, realm, userID, groupID string) error
 DeleteUserFromGroup(ctx context.Context, token, realm, userID, groupID string) error
 GetComponents(ctx context.Context, accessToken, realm string) ([]*Component, error)
 GetGroups(ctx context.Context, accessToken, realm string, params GetGroupsParams) ([]*Group, error)
 GetGroupsCount(ctx context.Context, token, realm string, params GetGroupsParams) (int, error)
 GetGroup(ctx context.Context, accessToken, realm, groupID string) (*Group, error)
 GetDefaultGroups(ctx context.Context, accessToken, realm string) ([]*Group, error)
 AddDefaultGroup(ctx context.Context, accessToken, realm, groupID string) error
 RemoveDefaultGroup(ctx context.Context, accessToken, realm, groupID string) error
 GetGroupMembers(ctx context.Context, accessToken, realm, groupID string, params GetGroupsParams) ([]*User, error)
 GetRoleMappingByGroupID(ctx context.Context, accessToken, realm, groupID string) (*MappingsRepresentation, error)
 GetRoleMappingByUserID(ctx context.Context, accessToken, realm, userID string) (*MappingsRepresentation, error)
 GetClientRoles(ctx context.Context, accessToken, realm, idOfClient string, params GetRoleParams) ([]*Role, error)
 GetClientRole(ctx context.Context, token, realm, idOfClient, roleName string) (*Role, error)
 GetClientRoleByID(ctx context.Context, accessToken, realm, roleID string) (*Role, error)
 GetClients(ctx context.Context, accessToken, realm string, params GetClientsParams) ([]*Client, error)
 AddClientRoleComposite(ctx context.Context, token, realm, roleID string, roles []Role) error
 DeleteClientRoleComposite(ctx context.Context, token, realm, roleID string, roles []Role) error
 GetUsersByRoleName(ctx context.Context, token, realm, roleName string) ([]*User, error)
 GetUsersByClientRoleName(ctx context.Context, token, realm, idOfClient, roleName string, params GetUsersByRoleParams) ([]*User, error)
 CreateClientProtocolMapper(ctx context.Context, token, realm, idOfClient string, mapper ProtocolMapperRepresentation) (string, error)
 UpdateClientProtocolMapper(ctx context.Context, token, realm, idOfClient, mapperID string, mapper ProtocolMapperRepresentation) error
 DeleteClientProtocolMapper(ctx context.Context, token, realm, idOfClient, mapperID string) error

 // *** Realm Roles ***

 CreateRealmRole(ctx context.Context, token, realm string, role Role) (string, error)
 GetRealmRole(ctx context.Context, token, realm, roleName string) (*Role, error)
 GetRealmRoles(ctx context.Context, accessToken, realm string, params GetRoleParams) ([]*Role, error)
 GetRealmRoleByID(ctx context.Context, token, realm, roleID string) (*Role, error)
 GetRealmRolesByUserID(ctx context.Context, accessToken, realm, userID string) ([]*Role, error)
 GetRealmRolesByGroupID(ctx context.Context, accessToken, realm, groupID string) ([]*Role, error)
 UpdateRealmRole(ctx context.Context, token, realm, roleName string, role Role) error
 UpdateRealmRoleByID(ctx context.Context, token, realm, roleID string, role Role) error
 DeleteRealmRole(ctx context.Context, token, realm, roleName string) error
 AddRealmRoleToUser(ctx context.Context, token, realm, userID string, roles []Role) error
 DeleteRealmRoleFromUser(ctx context.Context, token, realm, userID string, roles []Role) error
 AddRealmRoleToGroup(ctx context.Context, token, realm, groupID string, roles []Role) error
 DeleteRealmRoleFromGroup(ctx context.Context, token, realm, groupID string, roles []Role) error
 AddRealmRoleComposite(ctx context.Context, token, realm, roleName string, roles []Role) error
 DeleteRealmRoleComposite(ctx context.Context, token, realm, roleName string, roles []Role) error
 GetCompositeRealmRoles(ctx context.Context, token, realm, roleName string) ([]*Role, error)
 GetCompositeRealmRolesByRoleID(ctx context.Context, token, realm, roleID string) ([]*Role, error)
 GetCompositeRealmRolesByUserID(ctx context.Context, token, realm, userID string) ([]*Role, error)
 GetCompositeRealmRolesByGroupID(ctx context.Context, token, realm, groupID string) ([]*Role, error)
 GetAvailableRealmRolesByUserID(ctx context.Context, token, realm, userID string) ([]*Role, error)
 GetAvailableRealmRolesByGroupID(ctx context.Context, token, realm, groupID string) ([]*Role, error)

 // *** Client Roles ***

 AddClientRoleToUser(ctx context.Context, token, realm, idOfClient, userID string, roles []Role) error
 AddClientRoleToGroup(ctx context.Context, token, realm, idOfClient, groupID string, roles []Role) error
 DeleteClientRoleFromGroup(ctx context.Context, token, realm, idOfClient, groupID string, roles []Role) error
 GetCompositeClientRolesByRoleID(ctx context.Context, token, realm, idOfClient, roleID string) ([]*Role, error)
 GetClientRolesByUserID(ctx context.Context, token, realm, idOfClient, userID string) ([]*Role, error)
 GetClientRolesByGroupID(ctx context.Context, token, realm, idOfClient, groupID string) ([]*Role, error)
 GetCompositeClientRolesByUserID(ctx context.Context, token, realm, idOfClient, userID string) ([]*Role, error)
 GetCompositeClientRolesByGroupID(ctx context.Context, token, realm, idOfClient, groupID string) ([]*Role, error)
 GetAvailableClientRolesByUserID(ctx context.Context, token, realm, idOfClient, userID string) ([]*Role, error)
 GetAvailableClientRolesByGroupID(ctx context.Context, token, realm, idOfClient, groupID string) ([]*Role, error)

 // *** Realm ***

 GetRealm(ctx context.Context, token, realm string) (*RealmRepresentation, error)
 GetRealms(ctx context.Context, token string) ([]*RealmRepresentation, error)
 CreateRealm(ctx context.Context, token string, realm RealmRepresentation) (string, error)
 UpdateRealm(ctx context.Context, token string, realm RealmRepresentation) error
 DeleteRealm(ctx context.Context, token, realm string) error
 ClearRealmCache(ctx context.Context, token, realm string) error
 ClearUserCache(ctx context.Context, token, realm string) error
 ClearKeysCache(ctx context.Context, token, realm string) error

GetClientUserSessions(ctx context.Context, token, realm, idOfClient string, params ...GetClientUserSessionsParams) ([]*UserSessionRepresentation, error)
GetClientOfflineSessions(ctx context.Context, token, realm, idOfClient string, params ...GetClientUserSessionsParams) ([]*UserSessionRepresentation, error)
 GetUserSessions(ctx context.Context, token, realm, userID string) ([]*UserSessionRepresentation, error)
 GetUserOfflineSessionsForClient(ctx context.Context, token, realm, userID, idOfClient string) ([]*UserSessionRepresentation, error)

 // *** Protection API ***
 GetResource(ctx context.Context, token, realm, idOfClient, resourceID string) (*ResourceRepresentation, error)
 GetResources(ctx context.Context, token, realm, idOfClient string, params GetResourceParams) ([]*ResourceRepresentation, error)
 CreateResource(ctx context.Context, token, realm, idOfClient string, resource ResourceRepresentation) (*ResourceRepresentation, error)
 UpdateResource(ctx context.Context, token, realm, idOfClient string, resource ResourceRepresentation) error
 DeleteResource(ctx context.Context, token, realm, idOfClient, resourceID string) error

 GetResourceClient(ctx context.Context, token, realm, resourceID string) (*ResourceRepresentation, error)
 GetResourcesClient(ctx context.Context, token, realm string, params GetResourceParams) ([]*ResourceRepresentation, error)
 CreateResourceClient(ctx context.Context, token, realm string, resource ResourceRepresentation) (*ResourceRepresentation, error)
 UpdateResourceClient(ctx context.Context, token, realm string, resource ResourceRepresentation) error
 DeleteResourceClient(ctx context.Context, token, realm, resourceID string) error

 GetScope(ctx context.Context, token, realm, idOfClient, scopeID string) (*ScopeRepresentation, error)
 GetScopes(ctx context.Context, token, realm, idOfClient string, params GetScopeParams) ([]*ScopeRepresentation, error)
 CreateScope(ctx context.Context, token, realm, idOfClient string, scope ScopeRepresentation) (*ScopeRepresentation, error)
 UpdateScope(ctx context.Context, token, realm, idOfClient string, resource ScopeRepresentation) error
 DeleteScope(ctx context.Context, token, realm, idOfClient, scopeID string) error

 GetPolicy(ctx context.Context, token, realm, idOfClient, policyID string) (*PolicyRepresentation, error)
 GetPolicies(ctx context.Context, token, realm, idOfClient string, params GetPolicyParams) ([]*PolicyRepresentation, error)
 CreatePolicy(ctx context.Context, token, realm, idOfClient string, policy PolicyRepresentation) (*PolicyRepresentation, error)
 UpdatePolicy(ctx context.Context, token, realm, idOfClient string, policy PolicyRepresentation) error
 DeletePolicy(ctx context.Context, token, realm, idOfClient, policyID string) error

 GetResourcePolicy(ctx context.Context, token, realm, permissionID string) (*ResourcePolicyRepresentation, error)
 GetResourcePolicies(ctx context.Context, token, realm string, params GetResourcePoliciesParams) ([]*ResourcePolicyRepresentation, error)
 CreateResourcePolicy(ctx context.Context, token, realm, resourceID string, policy ResourcePolicyRepresentation) (*ResourcePolicyRepresentation, error)
 UpdateResourcePolicy(ctx context.Context, token, realm, permissionID string, policy ResourcePolicyRepresentation) error
 DeleteResourcePolicy(ctx context.Context, token, realm, permissionID string) error

 GetPermission(ctx context.Context, token, realm, idOfClient, permissionID string) (*PermissionRepresentation, error)
 GetPermissions(ctx context.Context, token, realm, idOfClient string, params GetPermissionParams) ([]*PermissionRepresentation, error)
 GetPermissionResources(ctx context.Context, token, realm, idOfClient, permissionID string) ([]*PermissionResource, error)
 GetPermissionScopes(ctx context.Context, token, realm, idOfClient, permissionID string) ([]*PermissionScope, error)
 GetDependentPermissions(ctx context.Context, token, realm, idOfClient, policyID string) ([]*PermissionRepresentation, error)
 CreatePermission(ctx context.Context, token, realm, idOfClient string, permission PermissionRepresentation) (*PermissionRepresentation, error)
 UpdatePermission(ctx context.Context, token, realm, idOfClient string, permission PermissionRepresentation) error
 DeletePermission(ctx context.Context, token, realm, idOfClient, permissionID string) error

 CreatePermissionTicket(ctx context.Context, token, realm string, permissions []CreatePermissionTicketParams) (*PermissionTicketResponseRepresentation, error)
 GrantUserPermission(ctx context.Context, token, realm string, permission PermissionGrantParams) (*PermissionGrantResponseRepresentation, error)
 UpdateUserPermission(ctx context.Context, token, realm string, permission PermissionGrantParams) (*PermissionGrantResponseRepresentation, error)
 GetUserPermissions(ctx context.Context, token, realm string, params GetUserPermissionParams) ([]*PermissionGrantResponseRepresentation, error)
 DeleteUserPermission(ctx context.Context, token, realm, ticketID string) error

 // *** Credentials API ***

 GetCredentialRegistrators(ctx context.Context, token, realm string) ([]string, error)
 GetConfiguredUserStorageCredentialTypes(ctx context.Context, token, realm, userID string) ([]string, error)
 GetCredentials(ctx context.Context, token, realm, UserID string) ([]*CredentialRepresentation, error)
 DeleteCredentials(ctx context.Context, token, realm, UserID, CredentialID string) error
 UpdateCredentialUserLabel(ctx context.Context, token, realm, userID, credentialID, userLabel string) error
 DisableAllCredentialsByType(ctx context.Context, token, realm, userID string, types []string) error
 MoveCredentialBehind(ctx context.Context, token, realm, userID, credentialID, newPreviousCredentialID string) error
 MoveCredentialToFirst(ctx context.Context, token, realm, userID, credentialID string) error

// *** Authentication Flows ***
GetAuthenticationFlows(ctx context.Context, token, realm string) ([]*AuthenticationFlowRepresentation, error)
GetAuthenticationFlow(ctx context.Context, token, realm string, authenticationFlowID string) (*AuthenticationFlowRepresentation, error)
CreateAuthenticationFlow(ctx context.Context, token, realm string, flow AuthenticationFlowRepresentation) error
UpdateAuthenticationFlow(ctx context.Context, token, realm string, flow AuthenticationFlowRepresentation, authenticationFlowID string) (*AuthenticationFlowRepresentation, error)
DeleteAuthenticationFlow(ctx context.Context, token, realm, flowID string) error

// *** Identity Providers ***

 CreateIdentityProvider(ctx context.Context, token, realm string, providerRep IdentityProviderRepresentation) (string, error)
 GetIdentityProvider(ctx context.Context, token, realm, alias string) (*IdentityProviderRepresentation, error)
 GetIdentityProviders(ctx context.Context, token, realm string) ([]*IdentityProviderRepresentation, error)
 UpdateIdentityProvider(ctx context.Context, token, realm, alias string, providerRep IdentityProviderRepresentation) error
 DeleteIdentityProvider(ctx context.Context, token, realm, alias string) error

 CreateIdentityProviderMapper(ctx context.Context, token, realm, alias string, mapper IdentityProviderMapper) (string, error)
 GetIdentityProviderMapper(ctx context.Context, token string, realm string, alias string, mapperID string) (*IdentityProviderMapper, error)
 CreateUserFederatedIdentity(ctx context.Context, token, realm, userID, providerID string, federatedIdentityRep FederatedIdentityRepresentation) error
 GetUserFederatedIdentities(ctx context.Context, token, realm, userID string) ([]*FederatedIdentityRepresentation, error)
 DeleteUserFederatedIdentity(ctx context.Context, token, realm, userID, providerID string) error

 // *** Events API ***
 GetEvents(ctx context.Context, token string, realm string, params GetEventsParams) ([]*EventRepresentation, error)

}

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

gocloak's People

Contributors

akoserwal avatar alexsn avatar amaury95 avatar bastianccm avatar carmo-evan avatar dependabot[bot] avatar dlisin avatar effoeffi avatar fridafino avatar jpughcs avatar kisamoto avatar krisztianganyi avatar kveselkov avatar manju754 avatar moritz-muecke avatar mpawlowski avatar nerzal avatar nityanandagohain avatar ondrej-li avatar pp010 avatar svilgelm avatar timdrysdale avatar tjololo avatar toddkazakov avatar tomqwpl avatar tyrannosaurus-becks avatar vennekilde avatar viniciussousazup avatar yue-wen avatar zaletniy 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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gocloak's Issues

fatal error: concurrent map writes (client.GetCerts())

Hi,

Lately, I experienced some crashes with gocloak involving the client.GetCerts (client.go) function.
I took a look to this function to understand why and I think I have a solid explaination.

This function tests if certs are present in client.certsLock. If they're present, it returns the map, end of the game. If they're not, the function fetch them with client.getNewCerts(realm) and writes them to client.certsCache. After that a goroutine waits a given delay and deletes the old certs.

When a customer comes back after that, certs are missing and the function manages to get new ones... Good game, but…

When a customer comes back at the exact moment the timer goes on certs deletion, 2 map read/writes occurs at the same moment and crash the whole process.

I'll send a PR in minutes to fix that using a Mutex to protect client.certsCache read and writes.

Have a good day :)

Get User Credentials API

Is your feature request related to a problem? Please describe.
Current there is no API to get user credentials

Describe the solution you'd like
API to get user credentials.

Additional context
Add any other context or screenshots about the feature request here.
Screenshot 2020-03-21 at 1 58 05 AM

curl 'https://SERVER/auth/admin/realms/{REALM}/users/{USERID}/credentials' 

RESPONSE:

[{"id":"12296c78-b9ad-4ef4-a272-e801f8ae44a6","type":"password","createdDate":1584731908202,"credentialData":"{\"hashIterations\":27500,\"algorithm\":\"pbkdf2-sha256\"}"}]

A little help needed

I'm trying to add gocloak module to mine as a dependency but something strange happens. Can you please explain to me what I'm doing wrong and why this is the result?

  1. add the import in my go file like this

import "github.com/Nerzal/gocloak"

  1. add this to my go.mod file

require github.com/Nerzal/gocloak v2.0.0

  1. I build with go build and my go.mod file got overridden like this

require github.com/Nerzal/gocloak v0.0.0-20190525151100-dfd1e50572f8

Keycloak token introspection always fails with {“active”:false}

Describe the bug
Testing the introspection to know if the token is in active state, it always gives false.
If there is another way to prove this, please describe it.

To Reproduce
Steps to reproduce the behavior:

	client := gocloak.NewClient(url)
	token, err := client.Login("account", client_secret, realm,username,password)
	if err != nil {
		panic("Login failed:"+ err.Error())
	}

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

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

Expected behavior
It should return token information and its active status

{"exp":1574658355,"iat":1574656555,"aud":aud,"active":true,"jti":jti,"typ":typ}

Additional context
Keycloak Version < 4.8 (gopkg.in/nerzal/gocloak.v1)

Investigating I found that the solution is to add the following data in the message body: client_id, client_secret, username.

// RetrospectToken calls the openid-connect introspect endpoint
func (client *gocloak) RetrospectToken(accessToken string, clientID, clientSecret string, realm string,username string) (*RetrospecTokenResult, error) {
	var result RetrospecTokenResult
	resp, err := getRequestWithBasicAuth(clientID, clientSecret).
		SetFormData(map[string]string{
			"client_id":     clientID,
			"client_secret": clientSecret,
			"username": username,
			"token":           accessToken,
		}).
		SetResult(&result).
		Post(client.basePath + authRealms + realm + tokenEndpoint + "/introspect")
	err = checkForError(resp, err)
	if err != nil {
		return nil, err
	}

	return &result, nil
}

Add support for client certificates

Is your feature request related to a problem? Please describe.
In order to securely connect to keycloak with client certificates I'd like gocloak to support it.

Describe the solution you'd like
Client certificate connection is described here: https://www.keycloak.org/docs/3.3/server_admin/topics/authentication/x509.html
The underlaying resty library can be configured to use client certificates: https://godoc.org/gopkg.in/resty.v1#Client.SetCertificates

Describe alternatives you've considered
Use another library to connect to keycloak (or default to go's HTTP client). This would take considerably more time and effort.

URL for GetGroup incorrect

Attempt to load group by id with GetGroup method fails. Client will try to use URL:

/admin/realms/{realm}/group/{id}

instead of

/admin/realms/{realm}/groups/{id}

Increase Test Coverage to >80%

In order to be more or less save for errors, when refactoring, we need a higher code coverage.
I'd say for v1 a Coverage of about 80% would be a good start

APIError as return type

Describe the bug
I see that from v5 is possible get more detail error as APIError but not sure how get from functions which are implemented in client because each function return standard error.

Expected behavior
Expected APIError as return type for every client function

Regenerate Client Secrets

Is your feature request related to a problem? Please describe.

It is not possible to trigger the regenerate secret endpoint for a client.

Describe the solution you'd like

A simple method to regenerate a client secret

Describe alternatives you've considered

Using the UpdateClient method or calling the API directly

Additional context

client skip checking connection SSL

Is your feature request related to a problem? Please describe.

client := gocloak.NewClient(serverURL)
token, err := client.LoginClient(clientID, clientSecretKey, realmName)

error: 
Post https://<domain>auth/auth/realms/avlcloud/protocol/openid-connect/token: x509: certificate signed by unknown authority

Describe the solution you'd like
add last argument "false", to skip checking connection ssl

 token, err := client.LoginClient(clientID, clientSecretKey, realmName, false)

like this python code

from keycloak import KeycloakOpenID
keycloak_openid = KeycloakOpenID(server_url=SERVER_URL,
                    client_id=CLIENT_ID,
                    realm_name=REALM_NAME,
                    client_secret_key=CLIENT_SECRET_KEY,
                    verify=False)

Not able to LoginClient

My keyclaok instance is set up in a corporate network and I am successfully able to generate token in POSTMAN but I am facing issue while handling it in my golang API.

client := gocloak.NewClient("https://keycloakt.iservice..corporateserver/auth/realms/i-service/protocol/openid-connect/auth")
clientID := "test-data"
clientSecret := "11550ca3-2437-451f-b66e-80bdf9dd8a5a"
realm := "I-service"
token, err := client.LoginClient(clientID, clientSecret, realm)
if err != nil {
	panic("Login failed:" + err.Error())
}

On run, its give panic saying - Login failed:404 not found.

'To configure client, I tried the access token URL as well as the issuer URL for keycloak client but in every case it gives Login failed:404 not found.

Is your library needs any proxy details to connect to keycloak server ?

Client.BaseURL JSON mapping has incorrect case

Describe the bug
When updating a Keycloak ClientRepresentation which contains a baseUrl field via UpdateClient, Keycloak responds with a 400 Bad Request: "Unrecognized field "baseURL" (class org.keycloak.representations.idm.ClientRepresentation), not marked as ignorable"

This is because the JSON mapping of Client.BaseURL has the incorrect case baseURL, rather than the expected baseUrl for the Keycloak API.

We are using Keycloak 7.0.

To Reproduce
Steps to reproduce the behavior:

  1. In Keycloak, create a Client, and set a Base URL.
  2. Execute the following code:
	client := gocloak.NewClient(conf.Server)
	token, err := client.Login(conf.AdminClientID, conf.AdminClientSecret, conf.AdminRealm, conf.AdminUser, conf.AdminPassword)
	if err != nil {
		err = errors.Wrap(err, "Something wrong with the credentials or url")
		return err
	}
	params := gocloak.GetClientsParams{
		ClientID:    clientID,
		ViewableOnly: false,
	}
        //Find the client you've created, with the given clientId
	appClients, err := client.GetClients(token.AccessToken, realm, params)

	if err != nil {
		err = errors.Wrapf(err, "Couldn't get client with id %v", clientID)
		return err
	}
	appClient := appClients[0]
	body, err := json.Marshal(*appClient)
	klog.V(2).Infof("Client Body:\n%v", string(body))
	err = client.UpdateClient(token.AccessToken, realm, *appClient)
	if err != nil {
		err = errors.Wrapf(err, "Failure updating client")
			return err
	}
  1. Get 400 error

Expected behavior
UpdateClient should PUT a well-formed ClientRepresentation JSON object and receive a 200 response.

Getting Realm roles for a user and a group

Is your feature request related to a problem? Please describe.
I need to receive all realm roles for a user and for a group.

Describe the solution you'd like
Would be great to have functions like GetRealmRolesByUserID, GetRealmRolesByGroupID

Support realm removal

Gocloak supports realm creation and realm listing but missing a realm deletion functionality.

Can we get it?

In essence it should just do a DELETE on the realm.

See official documentation for more.

runtime error: invalid memory address or nil pointer dereference

Describe the bug
Not checking nil

To Reproduce
Issue is here https://github.com/Nerzal/gocloak/blob/master/client.go#L245

The code:

usedKey := findUsedKey(decodedHeader.Kid, certResult.Keys)
token, err := jwx.DecodeAccessTokenCustomClaims(accessToken, usedKey.E, usedKey.N, claims)

usedKey is not checked for nil.

It should be:

usedKey := findUsedKey(decodedHeader.Kid, certResult.Keys)
if usedKey == nil {
  return nil, errors.New("cannot find a key to decode the token")
}

return  jwx.DecodeAccessTokenCustomClaims(accessToken, usedKey.E, usedKey.N, claims)

Expected behavior
Not to crash with a panic

Bumping versions

As we discussed in Slack, the repo is already mature enough to have the versions for each commit/sets of commits merged into master.

My suggestion is using the Semantic Versioning 2.0.0: https://semver.org/#semantic-versioning-200:

Given a version number MAJOR.MINOR.PATCH, increment the:

MAJOR version when you make incompatible API changes,
MINOR version when you add functionality in a backwards-compatible manner, and
PATCH version when you make backwards-compatible bug fixes.

To make it easier, I want to create a bump_version script, which will scan all tags, find the latest and increase the PATCH by one or use , then it should create a tag and push it.

Add method to set new password

Is your feature request related to a problem? Please describe.
Missing feature, which needs to be implemented

Describe the solution you'd like
Make a call to PUT /auth/admin/realms/master/users/{id}/reset-password
Example Body: { "type": "password", "temporary": false, "value": "my-new-password" }

Info comes from here

Boolean values set to "false" are ignored

When I send request with bool field set to false, this field is not present in JSON.

	keycloakClientUuid := uuid.New().String()
	keycloakClient := gocloak.Client{
		ID: keycloakClientUuid,
		ClientID: "test",
		Name: "test",
		Enabled: false,
	}
	if err := keycloak.CreateClient(token.AccessToken, "compaas", keycloakClient); err != nil {
		return "", err
	}

JSON send:

{
  "clientId": "test",
  "id": "f522f163-2f7a-4857-a1da-5d4a21aa2b2c",
  "name": "test"
}

I believe that bool fields in models should be pointers.

how to implement authorization functions?

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

Unable to create Client

When I'm creating client without Id field set, empty Id is send to Keycloak. In result Id is not auto-generated and Client can't be accessed.

	keycloakClient := gocloak.Client{
		ClientID: "test",
		Name: "test",
		Enabled: false,
	}
	return keycloak.CreateClient(token.AccessToken, "test", keycloakClient)

In database:

MariaDB [db4keycloak]> select ID, CLIENT_ID, NAME from CLIENT where NAME LIKE 'test';
+----+-----------+------+
| ID | CLIENT_ID | NAME |
+----+-----------+------+
|    | test      | test |
+----+-----------+------+

Add go dep support

Describe the bug
I tried to use this library in my project, where I use go dep.

Therefore, I added the following entry to my Gopkg.toml file:

[[constraint]]
  name = "github.com/Nerzal/gocloak"
  version = "v3.2.0"

However, when I run dep ensure, I receive the following error:

Solving failure: No versions of github.com/Nerzal/gocloak met constraints:
	v2.1.0: Could not introduce github.com/Nerzal/[email protected], as it is not allowed by constraint ^3.2.0 from project livestockfinder-server.
	v3.2.0: "github.com/Nerzal/gocloak" imports "github.com/Nerzal/gocloak/v3/pkg/jwx", which contains malformed code: no package exists at "github.com/Nerzal/gocloak/v3/pkg/jwx"
	v3.1.0: Could not introduce github.com/Nerzal/[email protected], as it is not allowed by constraint ^3.2.0 from project livestockfinder-server.
	v3.0.0: Could not introduce github.com/Nerzal/[email protected], as it is not allowed by constraint ^3.2.0 from project livestockfinder-server.
	v2.0.1: Could not introduce github.com/Nerzal/[email protected], as it is not allowed by constraint ^3.2.0 from project livestockfinder-server.
	v2.0.0: Could not introduce github.com/Nerzal/[email protected], as it is not allowed by constraint ^3.2.0 from project livestockfinder-server.
	v1.0.0: Could not introduce github.com/Nerzal/[email protected], as it is not allowed by constraint ^3.2.0 from project livestockfinder-server.
	master: Could not introduce github.com/Nerzal/gocloak@master, as it is not allowed by constraint ^3.2.0 from project livestockfinder-server.
	Nerzal-patch-1: Could not introduce github.com/Nerzal/gocloak@Nerzal-patch-1, as it is not allowed by constraint ^3.2.0 from project livestockfinder-server.
	change_clientscoperepresentation: Could not introduce github.com/Nerzal/gocloak@change_clientscoperepresentation, as it is not allowed by constraint ^3.2.0 from project livestockfinder-server.
	fix_executeActionsEmail: Could not introduce github.com/Nerzal/gocloak@fix_executeActionsEmail, as it is not allowed by constraint ^3.2.0 from project livestockfinder-server.
	v1.0: Could not introduce github.com/Nerzal/[email protected], as it is not allowed by constraint ^3.2.0 from project livestockfinder-server.
	v2: Could not introduce github.com/Nerzal/gocloak@v2, as it is not allowed by constraint ^3.2.0 from project livestockfinder-server.

To Reproduce
Add entry from above to Gopkg.toml file and run dep ensure.

Expected behavior
Whould be great if I could import this project with go dep for dependency management.

Desktop (please complete the following information):

  • OS: Windows 10
  • dep version:
dep:
 version     : v0.5.0
 build date  : 2018-07-26
 git hash    : 224a564
 go version  : go1.10.3
 go compiler : gc
 platform    : windows/amd64
 features    : ImportDuringSolve=false

Unknown client when try to get policies

Describe the bug
I try to get policies for my realm and client which I have created but always when I call GetPolicies by client I am getting 404 Not Found: Could not find client. The wierd think is that another API endpoints I am able to call.
Any hints where could be the problem becuase the client with realm should be OK.

Expected behavior
Get array of all policies.

Additional context
I am using gocloak v5 and the newest version of Keycloak which is 9.0.0.

It would be nice if CreateGroup returned the created group's id

I'd like the signature of CreateGroup to change from

CreateGroup(accessToken string, realm string, group Group) error

to

CreateGroup(accessToken string, realm string, group Group) (string, error)

This would match the signature of CreateUser which already returns a user id. I'd be happy to write a pull request for this but I wanted to run it by you first because I'm not sure if it's okay to change the interface of an existing method.

Thanks!

Add Go Module support

Is your feature request related to a problem? Please describe.
We have to add Go Module support.

Describe the solution you'd like
We have to add Go Module support.

Additional context
As some people started using gocloak we have to be aware, that possible breaking changes are not that nice anymore. As i want to keep on refactoring & extending the lib, we need to take care that these changes don't break existing projects.

Adding go module support is a step towards this direction, as users of this lib can chose which version they want to depent on.

Edit: Oh i forgot, there are old go.mod and go.sum files. I guess these need to be updated.

Manage federated identities of an user

Is your feature request related to a problem? Please describe.
No api to manage federated identity of an user (maybe I'm missing something)

Describe the solution you'd like
Functions for the following calls

  • GET /{realm}/users/{id}/federated-identity
  • POST /{realm}/users/{id}/federated-identity/{provider}
  • DELETE /{realm}/users/{id}/federated-identity/{provider}

Describe alternatives you've considered
I implement it myself. Unfortunately, there are also some supporting functions in gocloak private, which would make this a bit easier

Realm creation fails on NPEs

Describe the bug
Any attempt to create a realm with an incomplete realm model fails.

To Reproduce
Steps to reproduce the behavior:

  1. Create a simple RealmRepresentation - fill in the name only
  2. Call ...CreateRealm(jwt.AccessToken, realm)
  3. Call fails with various NPEs on the keycloak side
    e.g.
09:05:37,241 ERROR [org.keycloak.services.error.KeycloakErrorHandler] (default task-1) Uncaught server error: java.lang.NullPointerException
        at org.keycloak.models.jpa.RealmAdapter.setBrowserFlow(RealmAdapter.java:1393)
...

Expected behavior
Realm created after the call

Additional context
I have a fix and will file a PR if that's OK.

Variable Resources in PolicyRepresentation is always null

Issue description

When I call method GetPolicies am I getting all existing policies for my realm and client but when I try to access variable Resources in PolicyRepresentation I am getting always null and the resources exist because I have created them through admin ui.
Can be problem with mapping of the resources ?

Expecting behavior
Able to get resources through PolicyRepresentation.

UpdateClient doesn't work

Attempt to update client with UpdateClient method fails with error "405 Method Not Allowed".

Client will try execute PUT against wrong URL:

PUT /admin/realms/{realm}/clients

instead of

PUT /admin/realms/{realm}/clients/{id}

Use APIError

Is your feature request related to a problem? Please describe.
It would be nice to get the status code returned from Keycloak.

Describe the solution you'd like
Return APIErrors from gocloak calls. This could be tricky for errors resulting from things other than Keycloak API calls.

Describe alternatives you've considered
Can't think of any though I'm totally open to any existing solutions I'm unaware of.

Additional context
I have my own HTTP service in front of gocloak and right now it's hard to determine what errors and response codes I should return. For example I might get an error back like this "400 Bad Request: Password policy not met. See logs for details".

I'd like to be able to set my response code to 400 and set an appropriate error of "Password policy not met." The "See logs for details" part doesn't really make sense but I'm not sure there is anything that can be done to solve that.

How to skip (X509) certificate validation in gocloak?

I am trying to validate my token from keycloak using goloak and tyring the below code for that..

token:=""
client:= gocloak.NewClient("https://example.com")
_, err := client.RetrospectToken(token,"client-id" ,"client-secret", "realm")
log.Print(err.Error())
the I am getting below error,

Post https://example.com/auth/realms/realm/protocol/openid-connect/token/introspect: x509: certificate signed by unknown authority

is there any way to skip the certificate validation in gocloak.

Update readme to setup keycloak in docker and change parameter in tests

Is your feature request related to a problem? Please describe.
Currently you have to add a super.secret.go file containing constants, which let you run the tests.

Describe the solution you'd like
It would be super nice, if we add a section to the readme.md which provides a copy&paste solution to start a new keycloak instance.

The tests should use parameters to use this keycloak instance

omitempty string attributes break when empty

Describe the bug
Setting an user's Email attribute to an empty string and updating the user does not actually remove the user's email address. The same goes for basically every string attribute.

To Reproduce
Steps to reproduce the behavior:

  1. Create user with an email address in Keycloak Admin Console.
  2. Query that user using gocloak (GetUserByID()).
  3. Set user.Email = ""
  4. UpdateUser()
  5. Observe in the Keycloak Admin Console that the user still has the email address.

Expected behavior
The user's email address is removed. This is expected behavior as this works if you delete the email address in the Keycloak Admin Console.

Additional context
Probably all string attributes (and possibly other attributes as well) should not have the json omitempty tag.
This was already addressed and removed for bool attributes.

Add Method to initiate the reset password mechanism

Is your feature request related to a problem? Please describe.
The problem is easy. It's a missing feature.

Describe the solution you'd like
As described here we can trigger the "reset password" mechanism by calling the given URL.

Rather than specifying a new password manually a better security practice is to use the PUT /admin/realms/{realm}/users/{id}/execute-actions-email admin call with "UPDATE_PASSWORD" as the required action. This causes Keycloak to send an email to the user that gives a link for the user to set a new password.

Documentation:
https://www.keycloak.org/docs-api/4.8/rest-api/index.html#_users_resource

clientID is not that id by keycloak

gocloak version v5
keycloak verison 9.0.0

Every clientID argument is a uuid , not keycloak Client ID

My kaycloak Manage page show me Client ID is app,and that app url is

<hostname>/auth/admin/master/console/#/realms/demo/clients/8bb0f130-a60e-4575-a6fb-56d3bc2f85e2
8bb0f130-a60e-4575-a6fb-56d3bc2f85e2

is a clientID for argument ,
If I input app to clientID , It's 404

404 Not Found: Client not found

So, I consider it's not friendly

Adding and deleting client-level roles to the user role mapping

Hi,

I'm using gocloak to automate user management in keycloak, and I need to manage client roles for my users. I tried to use the AddRealmRoleToUser and DeleteRealmRoleFromUser functions with my client roles in the input parameters, but I get a 404 error (that's pretty predictable). Therefore I didn't find any methods in the gocloak package that handled these two methods.

API endpoints are described here: https://www.keycloak.org/docs-api/2.5/rest-api/index.html#_delete_client_level_roles_from_user_role_mapping_2

Actually, what I need is AddClientRoleToUser and DeleteClientRoleFromUser functions pointing to these methods' endpoints.

I'm thinking of adding theses functions on my own because I don't have much time to make it happen, maybe this is already possible and I didn't find how to do it ? So Before I start coding this on my side, I ask it here :)

Thanks !

Christophe.

Feature RememberMe handle by REST API

Feature RememberMe handle by REST API
I try to find way how can be handle feature RememberMe by REST API. Actually I cannot find API which will provide this kind feature. The remember me can be managed just by login page of the Keycloak if I am not wrong.

Solution
Would be great if the login method which is responsible for to login user also provide boolean parameter for rememberMe. But also should be exist some API from the Keycloak side.

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.