From e15e6573f715aac08af8260e9c3cae5f25ea459f Mon Sep 17 00:00:00 2001 From: Johan Droz Date: Tue, 27 Feb 2018 16:30:04 +0100 Subject: [PATCH] Add routes for clients --- client.go | 6 ++-- clients.go | 41 +++++++++++++++++++++++++++ clients_test.go | 49 ++++++++++++++++++++++++++++++++ definitions.go | 74 ++++++++++++++++++++++++------------------------- 4 files changed, 130 insertions(+), 40 deletions(-) create mode 100644 clients.go create mode 100644 clients_test.go diff --git a/client.go b/client.go index 34fa462..2588180 100644 --- a/client.go +++ b/client.go @@ -43,9 +43,9 @@ func New(config Config) (*Client, error) { } } - if u.Scheme != "http" { - return nil, fmt.Errorf("protocol not supported, your address must start with http://, not %v", u.Scheme) - } + // if u.Scheme != "http" { + // return nil, fmt.Errorf("protocol not supported, your address must start with http://, not %v", u.Scheme) + // } var httpClient = gentleman.New() { diff --git a/clients.go b/clients.go new file mode 100644 index 0000000..d22a02c --- /dev/null +++ b/clients.go @@ -0,0 +1,41 @@ +package keycloak + +import ( + "fmt" + + "gopkg.in/h2non/gentleman.v2/plugins/url" +) + +const ( + clientsPath = "/auth/admin/realms/:realm/clients" + clientIDPath = clientsPath + "/:id" + clientSecret = clientsPath + "/client-secret" +) + +// GetClients returns a list of clients belonging to the realm. +// Parameters: clientId (filter by clientId), +// viewableOnly (filter clients that cannot be viewed in full by admin, default="false") +func (c *Client) GetClients(realmName string, paramKV ...string) ([]ClientRepresentation, error) { + if len(paramKV)%2 != 0 { + return nil, fmt.Errorf("the number of key/val parameters should be even") + } + + var resp = []ClientRepresentation{} + var plugins = append(createQueryPlugins(paramKV...), url.Path(clientsPath), url.Param("realm", realmName)) + var err = c.get(&resp, plugins...) + return resp, err +} + +// GetClient get the representation of the client. idClient is the id of client (not client-id). +func (c *Client) GetClient(realmName, idClient string) (ClientRepresentation, error) { + var resp = ClientRepresentation{} + var err = c.get(&resp, url.Path(clientIDPath), url.Param("realm", realmName), url.Param("id", idClient)) + return resp, err +} + +// GetSecret get the client secret. idClient is the id of client (not client-id). +func (c *Client) GetSecret(realmName, idClient string) (CredentialRepresentation, error) { + var resp = CredentialRepresentation{} + var err = c.get(&resp, url.Path(clientSecret), url.Param("realm", realmName), url.Param("id", idClient)) + return resp, err +} diff --git a/clients_test.go b/clients_test.go new file mode 100644 index 0000000..a4e746c --- /dev/null +++ b/clients_test.go @@ -0,0 +1,49 @@ +package keycloak + +import ( + "fmt" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func initTest(t *testing.T) *Client { + var config = Config{ + Addr: "http://127.0.0.1", + Username: "admin", + Password: "admin", + Timeout: time.Second * 20, + } + var client *Client + { + var err error + client, err = New(config) + require.Nil(t, err, "could not create client") + } + return client +} + +func TestCreateRealm(t *testing.T) { + var client = initTest(t) + var clients, err = client.GetClients("master") + for i, c := range clients { + fmt.Println(i, *(c.Id), *c.ClientId) + } + assert.Nil(t, err) +} + +func TestGetClient(t *testing.T) { + var client = initTest(t) + var c, err = client.GetClient("318ab6db-c056-4d2f-b4f6-c0b585ee45b3", "master") + fmt.Println(*(c.Id), *c.ClientId, c.Secret) + assert.Nil(t, err) +} + +func TestGetSecret(t *testing.T) { + var client = initTest(t) + var c, err = client.GetSecret("318ab6db-c056-4d2f-b4f6-c0b585ee45b3", "master") + fmt.Println(*(c.Value)) + assert.Nil(t, err) +} diff --git a/definitions.go b/definitions.go index 9f248bf..f8e3e8d 100644 --- a/definitions.go +++ b/definitions.go @@ -107,43 +107,43 @@ type ClientMappingsRepresentation struct { } type ClientRepresentation struct { - Access *map[string]interface{} `json:"access,omitempty"` - AdminUrl *string `json:"adminUrl,omitempty"` - Attributes *map[string]interface{} `json:"attributes,omitempty"` - AuthorizationServicesEnabled *bool `json:"authorizationServicesEnabled,omitempty"` - AuthorizationSettings *ResourceServerRepresentation `json:"authorizationSettings,omitempty"` - BaseUrl *string `json:"baseUrl,omitempty"` - BearerOnly *bool `json:"bearerOnly,omitempty"` - ClientAuthenticatorType *string `json:"clientAuthenticatorType,omitempty"` - ClientId *string `json:"clientId,omitempty"` - ClientTemplate *string `json:"clientTemplate,omitempty"` - ConsentRequired *bool `json:"consentRequired,omitempty"` - DefaultRoles *[]string `json:"defaultRoles,omitempty"` - Description *string `json:"description,omitempty"` - DirectAccessGrantsEnabled *bool `json:"directAccessGrantsEnabled,omitempty"` - Enabled *bool `json:"enabled,omitempty"` - FrontchannelLogout *bool `json:"frontchannelLogout,omitempty"` - FullScopeAllowed *bool `json:"fullScopeAllowed,omitempty"` - Id *string `json:"id,omitempty"` - ImplicitFlowEnabled *bool `json:"implicitFlowEnabled,omitempty"` - Name *string `json:"name,omitempty"` - NodeReRegistrationTimeout *int32 `json:"nodeReRegistrationTimeout,omitempty"` - NotBefore *int32 `json:"notBefore,omitempty"` - Protocol *string `json:"protocol,omitempty"` - ProtocolMappers *ProtocolMapperRepresentation `json:"protocolMappers,omitempty"` - PublicClient *bool `json:"publicClient,omitempty"` - RedirectUris *[]string `json:"redirectUris,omitempty"` - RegisteredNodes *map[string]interface{} `json:"registeredNodes,omitempty"` - RegistrationAccessToken *string `json:"registrationAccessToken,omitempty"` - RootUrl *string `json:"rootUrl,omitempty"` - Secret *string `json:"secret,omitempty"` - ServiceAccountsEnabled *bool `json:"serviceAccountsEnabled,omitempty"` - StandardFlowEnabled *bool `json:"standardFlowEnabled,omitempty"` - SurrogateAuthRequired *bool `json:"surrogateAuthRequired,omitempty"` - UseTemplateConfig *bool `json:"useTemplateConfig,omitempty"` - UseTemplateMappers *bool `json:"useTemplateMappers,omitempty"` - UseTemplateScope *bool `json:"useTemplateScope,omitempty"` - WebOrigins *[]string `json:"webOrigins,omitempty"` + Access *map[string]interface{} `json:"access,omitempty"` + AdminUrl *string `json:"adminUrl,omitempty"` + Attributes *map[string]interface{} `json:"attributes,omitempty"` + AuthorizationServicesEnabled *bool `json:"authorizationServicesEnabled,omitempty"` + AuthorizationSettings *ResourceServerRepresentation `json:"authorizationSettings,omitempty"` + BaseUrl *string `json:"baseUrl,omitempty"` + BearerOnly *bool `json:"bearerOnly,omitempty"` + ClientAuthenticatorType *string `json:"clientAuthenticatorType,omitempty"` + ClientId *string `json:"clientId,omitempty"` + ClientTemplate *string `json:"clientTemplate,omitempty"` + ConsentRequired *bool `json:"consentRequired,omitempty"` + DefaultRoles *[]string `json:"defaultRoles,omitempty"` + Description *string `json:"description,omitempty"` + DirectAccessGrantsEnabled *bool `json:"directAccessGrantsEnabled,omitempty"` + Enabled *bool `json:"enabled,omitempty"` + FrontchannelLogout *bool `json:"frontchannelLogout,omitempty"` + FullScopeAllowed *bool `json:"fullScopeAllowed,omitempty"` + Id *string `json:"id,omitempty"` + ImplicitFlowEnabled *bool `json:"implicitFlowEnabled,omitempty"` + Name *string `json:"name,omitempty"` + NodeReRegistrationTimeout *int32 `json:"nodeReRegistrationTimeout,omitempty"` + NotBefore *int32 `json:"notBefore,omitempty"` + Protocol *string `json:"protocol,omitempty"` + ProtocolMappers *[]ProtocolMapperRepresentation `json:"protocolMappers,omitempty"` + PublicClient *bool `json:"publicClient,omitempty"` + RedirectUris *[]string `json:"redirectUris,omitempty"` + RegisteredNodes *map[string]interface{} `json:"registeredNodes,omitempty"` + RegistrationAccessToken *string `json:"registrationAccessToken,omitempty"` + RootUrl *string `json:"rootUrl,omitempty"` + Secret *string `json:"secret,omitempty"` + ServiceAccountsEnabled *bool `json:"serviceAccountsEnabled,omitempty"` + StandardFlowEnabled *bool `json:"standardFlowEnabled,omitempty"` + SurrogateAuthRequired *bool `json:"surrogateAuthRequired,omitempty"` + UseTemplateConfig *bool `json:"useTemplateConfig,omitempty"` + UseTemplateMappers *bool `json:"useTemplateMappers,omitempty"` + UseTemplateScope *bool `json:"useTemplateScope,omitempty"` + WebOrigins *[]string `json:"webOrigins,omitempty"` } type ClientTemplateRepresentation struct {