From e7e89f6a4f315cb1000841c1379089c74a5c7a85 Mon Sep 17 00:00:00 2001 From: Johan Droz Date: Fri, 13 Apr 2018 07:46:46 +0200 Subject: [PATCH] tmp --- authentication_management.go | 12 +++++----- client_attribute_certificate.go | 20 ++++++++--------- client_initial_access.go | 4 ++-- client_role_mappings.go | 2 +- clients_test.go | 34 +++++++++++++++------------- keycloak_client.go | 14 +++++++++--- keycloak_client_test.go | 40 +++++++++++++++++++++++++++++++++ realm.go | 2 +- users.go | 2 +- users_test.go | 23 +++++++++++++++++++ 10 files changed, 114 insertions(+), 39 deletions(-) create mode 100644 keycloak_client_test.go create mode 100644 users_test.go diff --git a/authentication_management.go b/authentication_management.go index 25fca93..c13e4f8 100644 --- a/authentication_management.go +++ b/authentication_management.go @@ -49,7 +49,7 @@ func (c *Client) DeleteAuthenticatorConfig(realmName, configID string) error { // CreateAuthenticationExecution add new authentication execution func (c *Client) CreateAuthenticationExecution(realmName string, authExec AuthenticationExecutionRepresentation) error { - return c.post(url.Path(authenticationManagementPath+"/executions"), url.Param("realm", realmName), body.JSON(authExec)) + return c.post(nil, url.Path(authenticationManagementPath+"/executions"), url.Param("realm", realmName), body.JSON(authExec)) } // DeleteAuthenticationExecution deletes the execution. @@ -59,22 +59,22 @@ func (c *Client) DeleteAuthenticationExecution(realmName, executionID string) er // UpdateAuthenticationExecution update execution with new configuration. func (c *Client) UpdateAuthenticationExecution(realmName, executionID string, authConfig AuthenticatorConfigRepresentation) error { - return c.post(url.Path(authenticationManagementPath+"/executions/:id/config"), url.Param("realm", realmName), url.Param("id", executionID), body.JSON(authConfig)) + return c.post(nil, url.Path(authenticationManagementPath+"/executions/:id/config"), url.Param("realm", realmName), url.Param("id", executionID), body.JSON(authConfig)) } // LowerExecutionPriority lowers the execution’s priority. func (c *Client) LowerExecutionPriority(realmName, executionID string) error { - return c.post(url.Path(authenticationManagementPath+"/executions/:id/lower-priority"), url.Param("realm", realmName), url.Param("id", executionID)) + return c.post(nil, url.Path(authenticationManagementPath+"/executions/:id/lower-priority"), url.Param("realm", realmName), url.Param("id", executionID)) } // RaiseExecutionPriority raise the execution’s priority. func (c *Client) RaiseExecutionPriority(realmName, executionID string) error { - return c.post(url.Path(authenticationManagementPath+"/executions/:id/raise-priority"), url.Param("realm", realmName), url.Param("id", executionID)) + return c.post(nil, url.Path(authenticationManagementPath+"/executions/:id/raise-priority"), url.Param("realm", realmName), url.Param("id", executionID)) } // CreateAuthenticationFlow creates a new authentication flow. func (c *Client) CreateAuthenticationFlow(realmName string, authFlow AuthenticationFlowRepresentation) error { - return c.post(url.Path(authenticationManagementPath+"/flows"), url.Param("realm", realmName), body.JSON(authFlow)) + return c.post(nil, url.Path(authenticationManagementPath+"/flows"), url.Param("realm", realmName), body.JSON(authFlow)) } // GetAuthenticationFlows returns a list of authentication flows. @@ -89,7 +89,7 @@ func (c *Client) GetAuthenticationFlows(realmName string) ([]AuthenticationFlowR // 'newName' is the new name of the authentication flow. func (c *Client) CopyExistingAuthenticationFlow(realmName, flowAlias, newName string) error { var m = map[string]string{"newName": newName} - return c.post(url.Path(authenticationManagementPath+"/flows/:flowAlias/copy"), url.Param("realm", realmName), url.Param("flowAlias", flowAlias), body.JSON(m)) + return c.post(nil, url.Path(authenticationManagementPath+"/flows/:flowAlias/copy"), url.Param("realm", realmName), url.Param("flowAlias", flowAlias), body.JSON(m)) } // GetAuthenticationExecutionForFlow returns the authentication executions for a flow. diff --git a/client_attribute_certificate.go b/client_attribute_certificate.go index ff79e60..e6b166f 100644 --- a/client_attribute_certificate.go +++ b/client_attribute_certificate.go @@ -21,34 +21,34 @@ func (c *Client) GetKeyInfo(realmName, idClient, attr string) (CertificateRepres // GetKeyStore returns a keystore file for the client, containing private key and public certificate. idClient is the id of client (not client-id). func (c *Client) GetKeyStore(realmName, idClient, attr string, keyStoreConfig KeyStoreConfig) ([]byte, error) { var resp = []byte{} - var err = c.post(url.Path(clientAttrCertPath+"/download"), url.Param("realm", realmName), url.Param("id", idClient), url.Param("attr", attr), body.JSON(keyStoreConfig)) - return respfrompost, err + var err = c.post(&resp, url.Path(clientAttrCertPath+"/download"), url.Param("realm", realmName), url.Param("id", idClient), url.Param("attr", attr), body.JSON(keyStoreConfig)) + return resp, err } // GenerateCertificate generates a new certificate with new key pair. idClient is the id of client (not client-id). func (c *Client) GenerateCertificate(realmName, idClient, attr string) (CertificateRepresentation, error) { var resp = CertificateRepresentation{} - var err = c.post(url.Path(clientAttrCertPath+"/generate"), url.Param("realm", realmName), url.Param("id", idClient), url.Param("attr", attr)) - return respfrompost, err + var err = c.post(&resp, url.Path(clientAttrCertPath+"/generate"), url.Param("realm", realmName), url.Param("id", idClient), url.Param("attr", attr)) + return resp, err } // GenerateKeyPairAndCertificate generates a keypair and certificate and serves the private key in a specified keystore format. func (c *Client) GenerateKeyPairAndCertificate(realmName, idClient, attr string, keyStoreConfig KeyStoreConfig) ([]byte, error) { var resp = []byte{} - var err = c.post(url.Path(clientAttrCertPath+"/generate-and-download"), url.Param("realm", realmName), url.Param("id", idClient), url.Param("attr", attr), body.JSON(keyStoreConfig)) - return respfrompost, err + var err = c.post(&resp, url.Path(clientAttrCertPath+"/generate-and-download"), url.Param("realm", realmName), url.Param("id", idClient), url.Param("attr", attr), body.JSON(keyStoreConfig)) + return resp, err } // UploadCertificatePrivateKey uploads a certificate and eventually a private key. func (c *Client) UploadCertificatePrivateKey(realmName, idClient, attr string, file []byte) (CertificateRepresentation, error) { var resp = CertificateRepresentation{} - var err = c.post(url.Path(clientAttrCertPath+"/upload"), url.Param("realm", realmName), url.Param("id", idClient), url.Param("attr", attr), body.Reader(bytes.NewReader(file))) - return respfrompost, err + var err = c.post(&resp, url.Path(clientAttrCertPath+"/upload"), url.Param("realm", realmName), url.Param("id", idClient), url.Param("attr", attr), body.Reader(bytes.NewReader(file))) + return resp, err } // UploadCertificate uploads only a certificate, not the private key. func (c *Client) UploadCertificate(realmName, idClient, attr string, file []byte) (CertificateRepresentation, error) { var resp = CertificateRepresentation{} - var err = c.post(url.Path(clientAttrCertPath+"/upload-certificate"), url.Param("realm", realmName), url.Param("id", idClient), url.Param("attr", attr), body.Reader(bytes.NewReader(file))) - return respfrompost, err + var err = c.post(&resp, url.Path(clientAttrCertPath+"/upload-certificate"), url.Param("realm", realmName), url.Param("id", idClient), url.Param("attr", attr), body.Reader(bytes.NewReader(file))) + return resp, err } diff --git a/client_initial_access.go b/client_initial_access.go index 39fa52d..46aeb2d 100644 --- a/client_initial_access.go +++ b/client_initial_access.go @@ -12,8 +12,8 @@ const ( // CreateClientInitialAccess creates a new initial access token. func (c *Client) CreateClientInitialAccess(realmName string, access ClientInitialAccessCreatePresentation) (ClientInitialAccessPresentation, error) { var resp = ClientInitialAccessPresentation{} - var err = c.post(url.Path(clientInitialAccessPath), url.Param("realm", realmName), body.JSON(access)) - return respasf, err + var err = c.post(&resp, url.Path(clientInitialAccessPath), url.Param("realm", realmName), body.JSON(access)) + return resp, err } // GetClientInitialAccess returns a list of clients initial access. diff --git a/client_role_mappings.go b/client_role_mappings.go index 0aeb79e..0692f73 100644 --- a/client_role_mappings.go +++ b/client_role_mappings.go @@ -11,7 +11,7 @@ const ( // CreateClientsRoleMapping add client-level roles to the user role mapping. func (c *Client) CreateClientsRoleMapping(realmName, groupID, clientID string, roles []RoleRepresentation) error { - return c.post(url.Path(clientRoleMappingPath), url.Param("realm", realmName), url.Param("id", groupID), url.Param("client", clientID), body.JSON(roles)) + return c.post(nil, url.Path(clientRoleMappingPath), url.Param("realm", realmName), url.Param("id", groupID), url.Param("client", clientID), body.JSON(roles)) } // GetClientsRoleMapping gets client-level role mappings for the user, and the app. diff --git a/clients_test.go b/clients_test.go index a4e746c..0daf50c 100644 --- a/clients_test.go +++ b/clients_test.go @@ -1,28 +1,22 @@ package keycloak import ( + "encoding/json" "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") +func TestPlayground(t *testing.T) { + var client = initTest(t) + var clients, err = client.GetClients("master") + + for _, c := range clients { + printStruct(c) } - return client + + assert.Nil(t, err) } func TestCreateRealm(t *testing.T) { @@ -47,3 +41,13 @@ func TestGetSecret(t *testing.T) { fmt.Println(*(c.Value)) assert.Nil(t, err) } + +func printStruct(data interface{}) { + var s, err = json.Marshal(data) + if err != nil { + fmt.Println("could not marshal json") + return + } + fmt.Println(string(s)) + fmt.Println() +} diff --git a/keycloak_client.go b/keycloak_client.go index 644880f..b9b16cf 100644 --- a/keycloak_client.go +++ b/keycloak_client.go @@ -166,7 +166,7 @@ func (c *Client) get(data interface{}, plugins ...plugin.Plugin) error { } } -func (c *Client) post(plugins ...plugin.Plugin) error { +func (c *Client) post(data interface{}, plugins ...plugin.Plugin) error { var req = c.httpClient.Post() req = applyPlugins(req, c.accessToken, plugins...) var resp *gentleman.Response @@ -186,11 +186,19 @@ func (c *Client) post(plugins ...plugin.Plugin) error { return errors.Wrap(err, "could not get token") } } - return c.post(plugins...) + return c.post(data, plugins...) case resp.StatusCode >= 400: return fmt.Errorf("invalid status code: '%v': %v", resp.RawResponse.Status, string(resp.Bytes())) case resp.StatusCode >= 200: - return nil + switch resp.Header.Get("Content-Type") { + case "application/json": + return resp.JSON(data) + case "application/octet-stream": + data = resp.Bytes() + return nil + default: + return fmt.Errorf("unkown http content-type: %v", resp.Header.Get("Content-Type")) + } default: return fmt.Errorf("unknown response status code: %v", resp.StatusCode) } diff --git a/keycloak_client_test.go b/keycloak_client_test.go new file mode 100644 index 0000000..1220810 --- /dev/null +++ b/keycloak_client_test.go @@ -0,0 +1,40 @@ +package keycloak + +import ( + "flag" + "fmt" + "os" + "testing" + "time" + + "github.com/stretchr/testify/require" +) + +var ( + hostPort = flag.String("hostport", "10.244.18.2:80", "keycloak host:port") + username = flag.String("username", "admin", "keycloak user name") + password = flag.String("password", "admin", "keycloak password") + to = flag.Int("timeout", 20, "timeout in seconds") +) + +func TestMain(m *testing.M) { + flag.Parse() + result := m.Run() + os.Exit(result) +} + +func initTest(t *testing.T) *Client { + var config = Config{ + Addr: fmt.Sprintf("http://%s", *hostPort), + Username: *username, + Password: *password, + Timeout: time.Duration(*to) * time.Second, + } + var client *Client + { + var err error + client, err = New(config) + require.Nil(t, err, "could not create client") + } + return client +} diff --git a/realm.go b/realm.go index a67436a..a1207c4 100644 --- a/realm.go +++ b/realm.go @@ -20,7 +20,7 @@ func (c *Client) GetRealms() ([]RealmRepresentation, error) { // CreateRealm creates the realm from its RealmRepresentation. func (c *Client) CreateRealm(realm RealmRepresentation) error { - return c.post(url.Path(realmRootPath), body.JSON(realm)) + return c.post(nil, url.Path(realmRootPath), body.JSON(realm)) } // GetRealm get the top level represention of the realm. Nested information like users are diff --git a/users.go b/users.go index 36143f6..676b3de 100644 --- a/users.go +++ b/users.go @@ -30,7 +30,7 @@ func (c *Client) GetUsers(realmName string, paramKV ...string) ([]UserRepresenta // CreateUser creates the user from its UserRepresentation. The username must be unique. func (c *Client) CreateUser(realmName string, user UserRepresentation) error { - return c.post(url.Path(userPath), url.Param("realm", realmName), body.JSON(user)) + return c.post(nil, url.Path(userPath), url.Param("realm", realmName), body.JSON(user)) } // CountUsers returns the number of users in the realm. diff --git a/users_test.go b/users_test.go new file mode 100644 index 0000000..d3452b5 --- /dev/null +++ b/users_test.go @@ -0,0 +1,23 @@ +package keycloak + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestGetUsers(t *testing.T) { + var c = initTest(t) + var users []UserRepresentation + { + var err error + users, err = c.GetUsers("master") + require.Nil(t, err, "could not get users") + } + for _, i := range users { + fmt.Println(i.Credentials) + assert.NotZero(t, *i.Username) + } +}